Skip to content

Commit

Permalink
Merge pull request #229 from ggiamarchi/issue#205
Browse files Browse the repository at this point in the history
👍 Support meta-args for shell provisioner
  • Loading branch information
julienvey committed Aug 10, 2015
2 parents d4d9f43 + a95507a commit 92d8687
Show file tree
Hide file tree
Showing 4 changed files with 171 additions and 2 deletions.
5 changes: 3 additions & 2 deletions source/lib/vagrant-openstack-provider/action.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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')
Expand Down
60 changes: 60 additions & 0 deletions source/lib/vagrant-openstack-provider/action/provision.rb
Original file line number Diff line number Diff line change
@@ -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
4 changes: 4 additions & 0 deletions source/lib/vagrant-openstack-provider/action/read_ssh_info.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
104 changes: 104 additions & 0 deletions source/spec/vagrant-openstack-provider/action/provision_spec.rb
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 92d8687

Please sign in to comment.