Permalink
Browse files

feat(scm): Support configurable location of git_ssh_wrapper (#121)

Fixes #120
  • Loading branch information...
nickmarden authored and ajgon committed Oct 6, 2017
1 parent bc9daf0 commit de153bf434446235765d4e5f9c4b7ec4ade440e7
View
@@ -142,6 +142,8 @@ suites:
- copytruncate
- sharedscripts
logrotate_template_group: 'www-data'
scm:
generated_ssh_wrapper: '/var/tmp/my-generated-ssh-wrapper.sh'
webserver:
logrotate_options:
- missingok
@@ -231,6 +231,15 @@ scm
This cookbook provides one of those scripts for you, so you shouldn’t
alter this variable unless you know what you’re doing.
- ``app['scm']['generated_ssh_wrapper']``
- **Default:** ``/tmp/ssh-git-wrapper.sh``
- If the cookbook generates an SSH wrapper for you, this is where it
will generate it. For users whose /tmp partitions are mounted ``noexec``
(a good security practice to prevent code injection exploits), this
attribute allows you to override that location to a partition where
execution of the generated shell script is allowed.
- ``app['scm']['enabled_submodules']``
- If set to ``true``, any submodules included in the repository, will
@@ -24,10 +24,6 @@ def after_deploy
end
alias after_undeploy after_deploy
def out
handle_output(raw_out)
end
def validate_app_engine; end
def webserver_config_params
@@ -16,14 +16,30 @@ def output
self.class.output.presence || (self.class.superclass.respond_to?(:output) && self.class.superclass.output)
end
def handle_output(out)
def out
handle_output(raw_out)
end
def handle_output(unfiltered)
if output[:filter] && output[:filter].is_a?(Array)
out = out.select { |k, _v| output[:filter].include?(k.to_sym) }
unfiltered.select { |k, _v| output[:filter].include?(k.to_sym) }
else
unfiltered
end
out
end
def raw_out
settings.each_with_object({}) do |(k, v), hsh|
hsh[k] = case v
when Proc
v.call(self, settings)
else
v
end
end
end
def settings
node['defaults'][driver_type].merge(
node['deploy'][app['shortname']][driver_type] || {}
).symbolize_keys
@@ -27,10 +27,6 @@ def deploy_before_restart
assets_precompile if out[:assets_precompile]
end
def out
handle_output(raw_out)
end
def validate_app_engine; end
def migrate?
@@ -9,7 +9,7 @@ class Hanami < Drivers::Framework::Base
migrate migration_command deploy_environment assets_precompile assets_precompilation_command
]
def raw_out
def settings
assets_command = node['deploy'][app['shortname']][driver_type]['assets_precompilation_command'] ||
'/usr/local/bin/bundle exec hanami assets precompile'
migration_command = node['deploy'][app['shortname']][driver_type]['migration_command'] ||
@@ -7,7 +7,7 @@ class Null < Drivers::Framework::Base
allowed_engines :null
output filter: [:deploy_environment]
def raw_out
def settings
super.merge(deploy_environment: { 'RACK_ENV' => deploy_env })
end
end
@@ -9,7 +9,7 @@ class Padrino < Drivers::Framework::Base
migrate migration_command deploy_environment assets_precompile assets_precompilation_command
]
def raw_out
def settings
super.merge(
deploy_environment: { 'RACK_ENV' => deploy_env, 'DATABASE_URL' => database_url },
assets_precompile: node['deploy'][app['shortname']][driver_type]['assets_precompile']
@@ -14,7 +14,7 @@ class Rails < Drivers::Framework::Base
File.join(context.send(:deploy_dir, context.app), 'shared', 'log', '*.log')
}
def raw_out
def settings
super.merge(deploy_environment: { 'RAILS_ENV' => deploy_env })
end
@@ -13,20 +13,16 @@ def setup
handle_packages
end
def out
handle_output(raw_out)
end
def raw_out
return out_defaults if configuration_data_source == :node_engine
def settings
return default_settings if configuration_data_source == :node_engine
app_source = app['app_source']
out_defaults.merge(
default_settings.merge(
scm_provider: adapter.constantize, repository: app_source['url'], revision: app_source['revision']
)
end
def out_defaults
def default_settings
base = node['defaults'][driver_type].merge(
node['deploy'][app['shortname']][driver_type] || {}
).symbolize_keys.merge(scm_provider: adapter.constantize)
@@ -7,7 +7,9 @@ class Git < Drivers::Scm::Base
allowed_engines :git
packages :git
output filter: %i[scm_provider repository revision enable_submodules ssh_wrapper remove_scm_files]
defaults enable_submodules: true, ssh_wrapper: '/tmp/ssh-git-wrapper.sh'
defaults enable_submodules: true,
ssh_wrapper: proc { |_driver, settings| settings[:generated_ssh_wrapper] },
generated_ssh_wrapper: '/tmp/ssh-git-wrapper.sh'
def before_deploy
add_git_wrapper_script
@@ -24,7 +26,7 @@ def after_deploy
end
end
def raw_out
def settings
ssh_key = app['app_source'].try(:[], 'ssh_key') ||
node['deploy'][app['shortname']][driver_type].try(:[], 'ssh_key')
super.merge(ssh_key: ssh_key)
@@ -33,7 +35,8 @@ def raw_out
private
def add_git_wrapper_script
context.template File.join('/', 'tmp', 'ssh-git-wrapper.sh') do
return unless raw_out[:ssh_wrapper] == raw_out[:generated_ssh_wrapper]
context.template raw_out[:generated_ssh_wrapper] do
source 'ssh-git-wrapper.sh.erb'
mode '0770'
owner node['deployer']['user'] || 'root'
@@ -24,7 +24,7 @@ def self.passenger_supported?
true
end
def raw_out
def settings
output = super.merge(
log_dir: node['deploy'][app['shortname']][driver_type]['log_dir'] || "/var/log/#{service_name}"
)
@@ -16,10 +16,6 @@ def configure
configure_logrotate
end
def out
handle_output(raw_out)
end
def passenger?
Drivers::Appserver::Factory.build(context, app).adapter == 'passenger'
end
@@ -18,7 +18,7 @@ class Nginx < Drivers::Webserver::Base
end
}
def raw_out
def settings
output = node['defaults']['webserver'].merge(node['nginx']).merge(
node['deploy'][app['shortname']]['webserver'] || {}
).symbolize_keys
@@ -10,10 +10,6 @@ def setup
handle_packages
end
def out
handle_output(raw_out)
end
def validate_app_engine; end
protected
@@ -13,7 +13,7 @@ def after_deploy
end
alias after_undeploy after_deploy
def raw_out
def settings
super.merge(queues: node['deploy'][app['shortname']][driver_type]['queues'] || '')
end
@@ -9,12 +9,18 @@
require 'spec_helper'
describe 'opsworks_ruby::deploy' do
let(:chef_run) do
let(:chef_runner) do
ChefSpec::SoloRunner.new(platform: 'ubuntu', version: '14.04') do |solo_node|
deploy = node['deploy']
deploy['dummy_project']['scm'].delete('ssh_wrapper')
solo_node.set['deploy'] = deploy
end.converge(described_recipe)
end
end
let(:chef_run) do
chef_runner.converge(described_recipe)
end
let(:chef_run_rhel) do
chef_runner_rhel.converge(described_recipe)
end
before do
stub_search(:aws_opsworks_app, '*:*').and_return([aws_opsworks_app])
@@ -26,19 +32,19 @@
end
context 'DEPRECATION' do
let(:chef_run) do
let(:chef_runner) do
ChefSpec::SoloRunner.new(platform: 'ubuntu', version: '14.04') do |solo_node|
deploy = node['deploy']
deploy['dummy_project']['keep_releases'] = 10
solo_node.set['deploy'] = deploy
end.converge(described_recipe)
end
end
let(:chef_run_rhel) do
let(:chef_runner_rhel) do
ChefSpec::SoloRunner.new(platform: 'ubuntu', version: '14.04') do |solo_node|
deploy = node['deploy']
deploy['dummy_project']['keep_releases'] = 10
solo_node.set['deploy'] = deploy
end.converge(described_recipe)
end
end
let(:logs) { [] }
@@ -104,30 +110,45 @@
expect(service).to do_nothing
end
context 'when the location of the generated Git SSH wrapper is overridden' do
let(:chef_runner) do
ChefSpec::SoloRunner.new(platform: 'ubuntu', version: '14.04') do |solo_node|
deploy = node['deploy']
deploy['dummy_project']['scm'].delete('ssh_wrapper')
deploy['dummy_project']['scm']['generated_ssh_wrapper'] = '/var/tmp/my-git-ssh-wrapper.sh'
solo_node.set['deploy'] = deploy
end
end
it 'creates git wrapper script in the specified location' do
expect(chef_run).to create_template('/var/tmp/my-git-ssh-wrapper.sh')
end
end
it 'restarts sidekiqs via monit' do
expect(chef_run).to run_execute("monit restart sidekiq_#{aws_opsworks_app['shortname']}-1")
expect(chef_run).to run_execute("monit restart sidekiq_#{aws_opsworks_app['shortname']}-2")
end
end
context 'Puma + Apache + resque' do
let(:chef_run) do
let(:chef_runner) do
ChefSpec::SoloRunner.new(platform: 'ubuntu', version: '14.04') do |solo_node|
deploy = node['deploy']
deploy['dummy_project']['appserver']['adapter'] = 'puma'
deploy['dummy_project']['webserver']['adapter'] = 'apache2'
deploy['dummy_project']['worker']['adapter'] = 'resque'
solo_node.set['deploy'] = deploy
end.converge(described_recipe)
end
end
let(:chef_run_rhel) do
let(:chef_runner_rhel) do
ChefSpec::SoloRunner.new(platform: 'amazon', version: '2016.03') do |solo_node|
deploy = node['deploy']
deploy['dummy_project']['appserver']['adapter'] = 'puma'
deploy['dummy_project']['webserver']['adapter'] = 'apache2'
deploy['dummy_project']['worker']['adapter'] = 'resque'
solo_node.set['deploy'] = deploy
end.converge(described_recipe)
end
end
it 'performs a deploy on debian' do
@@ -153,21 +174,21 @@
end
context 'Thin + delayed_job' do
let(:chef_run) do
let(:chef_runner) do
ChefSpec::SoloRunner.new(platform: 'ubuntu', version: '14.04') do |solo_node|
deploy = node['deploy']
deploy['dummy_project']['appserver']['adapter'] = 'thin'
deploy['dummy_project']['worker']['adapter'] = 'delayed_job'
solo_node.set['deploy'] = deploy
end.converge(described_recipe)
end
end
let(:chef_run_rhel) do
let(:chef_runner_rhel) do
ChefSpec::SoloRunner.new(platform: 'amazon', version: '2016.03') do |solo_node|
deploy = node['deploy']
deploy['dummy_project']['appserver']['adapter'] = 'thin'
deploy['dummy_project']['worker']['adapter'] = 'delayed_job'
solo_node.set['deploy'] = deploy
end.converge(described_recipe)
end
end
it 'performs a deploy on debian' do
@@ -236,14 +257,14 @@
])
end
let(:chef_run) do
let(:chef_runner) do
ChefSpec::SoloRunner.new(platform: 'ubuntu', version: '14.04') do |solo_node|
solo_node.set['lsb'] = node['lsb']
solo_node.set['deploy'] = { 'a1' => {} }
if deploy_dir
solo_node.set['deploy']['a1']['global']['deploy_dir'] = deploy_dir
end
end.converge(described_recipe)
end
end
context 'when deploy_dir is not specified' do
@@ -221,6 +221,10 @@
describe 'opsworks_ruby::deploy' do
context 'scm' do
describe file('/tmp/ssh-git-wrapper.sh') do
it { should_not exist }
end
describe file('/var/tmp/my-generated-ssh-wrapper.sh') do
its(:content) { should include 'exec ssh -o UserKnownHostsFile=/dev/null' }
end

0 comments on commit de153bf

Please sign in to comment.