From 86ffbe5d32b82911a0c35f68e53337aa54b3c8f4 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Wed, 10 Mar 2010 14:54:12 -0800 Subject: [PATCH] Provision class now properly figures out the provisioner and executes it --- lib/vagrant/actions/vm/provision.rb | 39 ++++++++++ test/vagrant/actions/vm/provision_test.rb | 87 +++++++++++++++++++++++ 2 files changed, 126 insertions(+) diff --git a/lib/vagrant/actions/vm/provision.rb b/lib/vagrant/actions/vm/provision.rb index 9a42d87b1..f712652d1 100644 --- a/lib/vagrant/actions/vm/provision.rb +++ b/lib/vagrant/actions/vm/provision.rb @@ -2,6 +2,45 @@ module Vagrant module Actions module VM class Provision < Base + attr_reader :provisioner + + def intialize(*args) + super + + @provisioner = nil + end + + def prepare + provisioner = Vagrant.config.vm.provisioner + + if provisioner.nil? + logger.info("Provisioning not enabled, ignoring this step") + return + end + + if provisioner.is_a?(Class) + @provisioner = provisioner.new + raise ActionException.new("Provisioners must be an instance of Vagrant::Provisioners::Base") unless @provisioner.is_a?(Provisioners::Base) + elsif provisioner.is_a?(Symbol) + # We have a few hard coded provisioners for built-ins + mapping = { + :chef_solo => Provisioners::ChefSolo + } + + provisioner_klass = mapping[provisioner] + raise ActionException.new("Unknown provisioner type: #{provisioner}") if provisioner_klass.nil? + @provisioner = provisioner_klass.new + end + + logger.info "Provisioning enabld with #{@provisioner.class}" + end + + def execute! + if provisioner + logger.info "Beginning provisining process..." + provisioner.provision! + end + end end end end diff --git a/test/vagrant/actions/vm/provision_test.rb b/test/vagrant/actions/vm/provision_test.rb index 70f90afcc..74cf5c95f 100644 --- a/test/vagrant/actions/vm/provision_test.rb +++ b/test/vagrant/actions/vm/provision_test.rb @@ -5,4 +5,91 @@ class ProvisionActionTest < Test::Unit::TestCase @runner, @vm, @action = mock_action(Vagrant::Actions::VM::Provision) mock_config end + + context "initialization" do + should "have a nil provisioner by default" do + assert_nil @action.provisioner + end + end + + context "executing" do + should "do nothing if the provisioner is nil" do + @action.expects(:provisioner).returns(nil) + assert_nothing_raised { @action.execute! } + end + + should "call `provision!` on the provisioner" do + provisioner = mock("provisioner") + provisioner.expects(:provision!).once + @action.expects(:provisioner).twice.returns(provisioner) + @action.execute! + end + end + + context "preparing" do + context "with a nil provisioner" do + setup do + mock_config do |config| + config.vm.provisioner = nil + end + end + + should "not set a provisioner if set to nil" do + @action.prepare + assert_nil @action.provisioner + end + end + + context "with a Class provisioner" do + setup do + @instance = mock("instance") + @instance.stubs(:is_a?).with(Vagrant::Provisioners::Base).returns(true) + @klass = mock("klass") + @klass.stubs(:is_a?).with(Class).returns(true) + @klass.stubs(:new).returns(@instance) + + mock_config do |config| + config.vm.provisioner = @klass + end + end + + should "set the provisioner to an instantiation of the class" do + @klass.expects(:new).once.returns(@instance) + assert_nothing_raised { @action.prepare } + assert_equal @instance, @action.provisioner + end + + should "raise an exception if the class is not a subclass of the provisioner base" do + @instance.expects(:is_a?).with(Vagrant::Provisioners::Base).returns(false) + assert_raises(Vagrant::Actions::ActionException) { + @action.prepare + } + end + end + + context "with a Symbol provisioner" do + def provisioner_expectation(symbol, provisioner) + mock_config do |config| + config.vm.provisioner = symbol + end + + assert_nothing_raised { @action.prepare } + assert @action.provisioner.is_a?(provisioner) + end + + should "raise an ActionException if its an unknown symbol" do + mock_config do |config| + config.vm.provisioner = :this_will_never_exist + end + + assert_raises(Vagrant::Actions::ActionException) { + @action.prepare + } + end + + should "set :chef_solo to the ChefSolo provisioner" do + provisioner_expectation(:chef_solo, Vagrant::Provisioners::ChefSolo) + end + end + end end