diff --git a/lib/vagrant/action/builtin.rb b/lib/vagrant/action/builtin.rb index 47d87e661..91a43e4e9 100644 --- a/lib/vagrant/action/builtin.rb +++ b/lib/vagrant/action/builtin.rb @@ -61,6 +61,7 @@ module Vagrant # destroy - Halts, cleans up, and destroys an existing VM register(:destroy, Builder.new do use Action[:halt], :force => true + use VM::ProvisionerCleanup use VM::ClearNFSExports use VM::Destroy use VM::CleanMachineFolder diff --git a/lib/vagrant/action/vm.rb b/lib/vagrant/action/vm.rb index 3aaee8cc9..c1e3ea2c2 100644 --- a/lib/vagrant/action/vm.rb +++ b/lib/vagrant/action/vm.rb @@ -23,6 +23,7 @@ module Vagrant autoload :Package, 'vagrant/action/vm/package' autoload :PackageVagrantfile, 'vagrant/action/vm/package_vagrantfile' autoload :Provision, 'vagrant/action/vm/provision' + autoload :ProvisionerCleanup, 'vagrant/action/vm/provisioner_cleanup' autoload :Resume, 'vagrant/action/vm/resume' autoload :ShareFolders, 'vagrant/action/vm/share_folders' autoload :Suspend, 'vagrant/action/vm/suspend' diff --git a/lib/vagrant/action/vm/provisioner_cleanup.rb b/lib/vagrant/action/vm/provisioner_cleanup.rb new file mode 100644 index 000000000..2dfb2a8be --- /dev/null +++ b/lib/vagrant/action/vm/provisioner_cleanup.rb @@ -0,0 +1,26 @@ +module Vagrant + class Action + module VM + class ProvisionerCleanup + def initialize(app, env) + @app = app + @env = env + end + + def call(env) + enabled_provisioners.each do |instance| + instance.cleanup + end + + @app.call(env) + end + + def enabled_provisioners + @env["config"].vm.provisioners.map do |provisioner| + provisioner.provisioner.new(@env, provisioner.config) + end + end + end + end + end +end diff --git a/lib/vagrant/provisioners/base.rb b/lib/vagrant/provisioners/base.rb index d45f54b42..7d467a98b 100644 --- a/lib/vagrant/provisioners/base.rb +++ b/lib/vagrant/provisioners/base.rb @@ -58,6 +58,10 @@ module Vagrant # is expected to do whatever necessary to provision the system (create files, # SSH, etc.) def provision!; end + + # This is the method called to when the system is being destroyed + # and allows the provisioners to engage in any cleanup tasks necessary. + def cleanup; end end end end diff --git a/test/vagrant/action/vm/provision_test.rb b/test/vagrant/action/vm/provision_test.rb index 665f9213a..b9dfcf7f8 100644 --- a/test/vagrant/action/vm/provision_test.rb +++ b/test/vagrant/action/vm/provision_test.rb @@ -43,11 +43,6 @@ class ProvisionVMActionTest < Test::Unit::TestCase end context "calling" do - setup do - Vagrant::Provisioners::ChefSolo.any_instance.stubs(:prepare) - @env["config"].vm.provision :chef_solo - end - should "provision and continue chain" do provisioners = [mock("one"), mock("two")] seq = sequence("seq") diff --git a/test/vagrant/action/vm/provisioner_cleanup_test.rb b/test/vagrant/action/vm/provisioner_cleanup_test.rb new file mode 100644 index 000000000..132a7eb30 --- /dev/null +++ b/test/vagrant/action/vm/provisioner_cleanup_test.rb @@ -0,0 +1,56 @@ +require "test_helper" + +class ProvisionerCleanupVMActionTest < Test::Unit::TestCase + setup do + @klass = Vagrant::Action::VM::ProvisionerCleanup + @app, @env = action_env + + @vm = mock("vm") + @env["vm"] = @vm + + @internal_vm = mock("internal") + @vm.stubs(:vm).returns(@internal_vm) + end + + context "with an instance" do + setup do + # Set provisioner to nil so the provisioner isn't loaded on init + @env["config"].vm.provisioners.clear + @instance = @klass.new(@app, @env) + end + + context "loading a provisioner" do + should "instantiate and prepare each provisioner" do + @env["config"].vm.provision :chef_solo + @env["config"].vm.provision :chef_solo + provisioners = @instance.enabled_provisioners + + assert_equal 2, provisioners.length + end + + should "set the config for each provisioner" do + @env["config"].vm.provision :chef_solo do |chef| + chef.cookbooks_path = "foo" + end + + provisioners = @instance.enabled_provisioners + + assert_equal "foo", provisioners.first.config.cookbooks_path + end + end + + context "calling" do + should "provision and continue chain" do + provisioners = [mock("one"), mock("two")] + seq = sequence("seq") + @instance.stubs(:enabled_provisioners).returns(provisioners) + provisioners.each do |prov| + prov.expects(:cleanup).in_sequence(seq) + end + @app.expects(:call).with(@env).in_sequence(seq) + + @instance.call(@env) + end + end + end +end