From 19eaddcd3a9a81b8ddf68998292fb87b752aa6a7 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Wed, 6 Jul 2011 23:02:19 -0700 Subject: [PATCH] Action to call `cleanup` method on provisioners during destroy. --- lib/vagrant/action/builtin.rb | 1 + lib/vagrant/action/vm.rb | 1 + lib/vagrant/action/vm/provisioner_cleanup.rb | 26 +++++++++ lib/vagrant/provisioners/base.rb | 4 ++ test/vagrant/action/vm/provision_test.rb | 5 -- .../action/vm/provisioner_cleanup_test.rb | 56 +++++++++++++++++++ 6 files changed, 88 insertions(+), 5 deletions(-) create mode 100644 lib/vagrant/action/vm/provisioner_cleanup.rb create mode 100644 test/vagrant/action/vm/provisioner_cleanup_test.rb 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