From 94ebf9553a8d44d05b095dea17c8d55226a9dcb2 Mon Sep 17 00:00:00 2001 From: Guillaume Giamarchi Date: Wed, 6 May 2015 10:46:02 +0200 Subject: [PATCH 1/2] Support meta-args for shell provisioner Fix #205 --- .../lib/vagrant-openstack-provider/action.rb | 5 +- .../action/provision.rb | 60 +++++++++++++++++++ .../action/read_ssh_info.rb | 4 ++ 3 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 source/lib/vagrant-openstack-provider/action/provision.rb diff --git a/source/lib/vagrant-openstack-provider/action.rb b/source/lib/vagrant-openstack-provider/action.rb index 684b2a5..ce55cec 100644 --- a/source/lib/vagrant-openstack-provider/action.rb +++ b/source/lib/vagrant-openstack-provider/action.rb @@ -33,7 +33,7 @@ def self.action_provision if env[:machine_state_id] == :not_created b2.use Message, I18n.t('vagrant_openstack.not_created') else - b2.use Provision + b2.use ProvisionWrapper b2.use SyncFolders end end @@ -99,7 +99,7 @@ def self.action_up case env[:machine_state_id] when :not_created ssh_disabled = env[:machine].provider_config.ssh_disabled - b2.use Provision unless ssh_disabled + b2.use ProvisionWrapper unless ssh_disabled b2.use SyncFolders b2.use CreateStack b2.use CreateServer @@ -212,6 +212,7 @@ def self.action_reload autoload :SyncFolders, action_root.join('sync_folders') autoload :Suspend, action_root.join('suspend') autoload :Resume, action_root.join('resume') + autoload :ProvisionWrapper, action_root.join('provision') autoload :WaitForServerToStop, action_root.join('wait_stop') autoload :WaitForServerToBeActive, action_root.join('wait_active') autoload :WaitForServerToBeAccessible, action_root.join('wait_accessible') diff --git a/source/lib/vagrant-openstack-provider/action/provision.rb b/source/lib/vagrant-openstack-provider/action/provision.rb new file mode 100644 index 0000000..fc65a4e --- /dev/null +++ b/source/lib/vagrant-openstack-provider/action/provision.rb @@ -0,0 +1,60 @@ +require 'log4r' + +require 'vagrant/action/builder' + +require 'vagrant-openstack-provider/action/abstract_action' +require 'vagrant-openstack-provider/action/read_ssh_info' + +module VagrantPlugins + module Openstack + module Action + include Vagrant::Action::Builtin + + class ProvisionWrapper < AbstractAction + def initialize(app, env) + @app = app + @env = env + @logger = Log4r::Logger.new('vagrant_openstack::action::provision_wrapper') + end + + def execute(env) + @logger.info 'Run provisioning' + InternalProvisionWrapper.new(@app, @env).call(@env) + @app.call(env) + end + end + + class InternalProvisionWrapper < Vagrant::Action::Builtin::Provision + def initialize(app, env) + @logger = Log4r::Logger.new('vagrant_openstack::action::internal_provision_wrapper') + super app, env + end + + def run_provisioner(env) + if env[:provisioner].class == VagrantPlugins::Shell::Provisioner + handle_shell_meta_args(env) + end + env[:provisioner].provision + end + + private + + def handle_shell_meta_args(env) + config = env[:provisioner].config + args = config.args.nil? ? [] : [config.args].flatten + config.args = [] + @logger.info "Shell provisioner args: #{args}" + args.each do |arg| + if '@@ssh_ip@@'.eql? arg + ssh_info = VagrantPlugins::Openstack::Action.get_ssh_info(env) + @logger.info "Replace meta-arg #{arg} by value #{ssh_info[:host]}" + config.args << ssh_info[:host] + else + config.args << arg + end + end + end + end + end + end +end diff --git a/source/lib/vagrant-openstack-provider/action/read_ssh_info.rb b/source/lib/vagrant-openstack-provider/action/read_ssh_info.rb index 3b7cbc9..67a29ac 100644 --- a/source/lib/vagrant-openstack-provider/action/read_ssh_info.rb +++ b/source/lib/vagrant-openstack-provider/action/read_ssh_info.rb @@ -63,6 +63,10 @@ def initialize @ssh_info = {} end end + + def self.get_ssh_info(env) + SSHInfoHolder.instance.ssh_info[env[:machine].id.to_sym] + end end end end From a95507a4c939a97424a0018b98df99d4fa031eb7 Mon Sep 17 00:00:00 2001 From: Guillaume Giamarchi Date: Mon, 10 Aug 2015 02:10:03 +0200 Subject: [PATCH 2/2] Unit tests for meta-args (shell provisioner) --- .../action/provision_spec.rb | 104 ++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 source/spec/vagrant-openstack-provider/action/provision_spec.rb diff --git a/source/spec/vagrant-openstack-provider/action/provision_spec.rb b/source/spec/vagrant-openstack-provider/action/provision_spec.rb new file mode 100644 index 0000000..976804c --- /dev/null +++ b/source/spec/vagrant-openstack-provider/action/provision_spec.rb @@ -0,0 +1,104 @@ +require 'vagrant-openstack-provider/spec_helper' + +# +# Stubing all the interactions using the real +# provisioner classes is somehow complicated... +# +class FakeProvisioner + def provision + end +end + +class FakeShellProvisioner < FakeProvisioner + attr_accessor :config + + def initialize(config) + @config = config + end +end + +# +# Monkeypatch the VagrantPlugins::Shell module +# to enabled using an FakeShellProvisioner in +# place of a the real shell provisioner class +# +module VagrantPlugins + module Shell + Provisioner = FakeShellProvisioner + end +end + +describe VagrantPlugins::Openstack::Action::ProvisionWrapper do + let(:app) do + double + end + + let(:internal_provision_wrapper) do + double + end + + before :each do + @action = ProvisionWrapper.new(app, nil) + end + + describe 'execute' do + it 'call InternalProvisionWrapper and conitnue the middleware chain' do + expect(internal_provision_wrapper).to receive(:call) + InternalProvisionWrapper.stub(:new) { internal_provision_wrapper } + app.stub(:call) {} + @action.execute nil + end + end +end + +describe VagrantPlugins::Openstack::Action::InternalProvisionWrapper do + let(:env) do + {} + end + + before :each do + @action = InternalProvisionWrapper.new(nil, env) + end + + describe 'run_provisioner' do + context 'when running a shell provisioner' do + context 'without meta-arg' do + it 'does not change the provisioner config' do + env[:provisioner] = FakeShellProvisioner.new(OpenStruct.new.tap do |c| + c.args = %w(arg1 arg2) + end) + + expect(env[:provisioner]).to receive(:provision) + expect(@action).to receive(:handle_shell_meta_args) + + @action.run_provisioner(env) + expect(env[:provisioner].config.args).to eq(%w(arg1 arg2)) + end + end + + context 'with @@ssh_ip@@ meta-arg' do + it 'replace the meta-args in the provisioner config' do + env[:provisioner] = FakeShellProvisioner.new(OpenStruct.new.tap do |c| + c.args = ['arg1', '@@ssh_ip@@', 'arg3'] + end) + + VagrantPlugins::Openstack::Action.stub(:get_ssh_info).and_return host: '192.168.0.1' + expect(env[:provisioner]).to receive(:provision) + + @action.run_provisioner(env) + expect(env[:provisioner].config.args).to eq(%w(arg1 192.168.0.1 arg3)) + end + end + end + + context 'when running a provisioner other that the shell provisioner' do + it 'does not call handle_shell_meta_args' do + env[:provisioner] = FakeProvisioner.new + expect(@action).should_not_receive(:handle_shell_meta_args) + expect(env[:provisioner]).to receive(:provision) + + @action.run_provisioner(env) + end + end + end +end