diff --git a/plugins/providers/virtualbox/action.rb b/plugins/providers/virtualbox/action.rb index 1de27463b..5d75e9e11 100644 --- a/plugins/providers/virtualbox/action.rb +++ b/plugins/providers/virtualbox/action.rb @@ -9,12 +9,17 @@ module VagrantPlugins autoload :CheckPortCollisions, File.expand_path("../action/check_port_collisions", __FILE__) autoload :CheckRunning, File.expand_path("../action/check_running", __FILE__) autoload :CheckVirtualbox, File.expand_path("../action/check_virtualbox", __FILE__) + autoload :CleanMachineFolder, File.expand_path("../action/clean_machine_folder", __FILE__) autoload :Created, File.expand_path("../action/created", __FILE__) + autoload :Destroy, File.expand_path("../action/destroy", __FILE__) autoload :DestroyConfirm, File.expand_path("../action/destroy_confirm", __FILE__) + autoload :DestroyUnusedNetworkInterfaces, File.expand_path("../action/destroy_unused_network_interfaces", __FILE__) autoload :DiscardState, File.expand_path("../action/discard_state", __FILE__) autoload :Halt, File.expand_path("../action/halt", __FILE__) autoload :MessageNotCreated, File.expand_path("../action/message_not_created", __FILE__) autoload :MessageWillNotDestroy, File.expand_path("../action/message_will_not_destroy", __FILE__) + autoload :ProvisionerCleanup, File.expand_path("../action/provisioner_cleanup", __FILE__) + autoload :PruneNFSExports, File.expand_path("../action/prune_nfs_exports", __FILE__) autoload :Resume, File.expand_path("../action/resume", __FILE__) autoload :Suspend, File.expand_path("../action/suspend", __FILE__) @@ -39,6 +44,11 @@ module VagrantPlugins b3.use CheckAccessible b3.use EnvSet, :force => true b3.use action_halt + b3.use ProvisionerCleanup + b3.use PruneNFSExports + b3.use Destroy + b3.use CleanMachineFolder + b3.use DestroyUnusedNetworkInterfaces else b3.use MessageWillNotDestroy end diff --git a/plugins/providers/virtualbox/action/clean_machine_folder.rb b/plugins/providers/virtualbox/action/clean_machine_folder.rb new file mode 100644 index 000000000..3007cbd0f --- /dev/null +++ b/plugins/providers/virtualbox/action/clean_machine_folder.rb @@ -0,0 +1,43 @@ +require "fileutils" + +module VagrantPlugins + module ProviderVirtualBox + module Action + # Cleans up the VirtualBox machine folder for any ".xml-prev" + # files which VirtualBox may have left over. This is a bug in + # VirtualBox. As soon as this is fixed, this middleware can and + # will be removed. + class CleanMachineFolder + def initialize(app, env) + @app = app + end + + def call(env) + clean_machine_folder(env[:machine].provider.driver.read_machine_folder) + @app.call(env) + end + + def clean_machine_folder(machine_folder) + folder = File.join(machine_folder, "*") + + # Small safeguard against potentially unwanted rm-rf, since the default + # machine folder will typically always be greater than 10 characters long. + # For users with it < 10, out of luck? + return if folder.length < 10 + + Dir[folder].each do |f| + next unless File.directory?(f) + + keep = Dir["#{f}/**/*"].find do |d| + # Find a file that doesn't have ".xml-prev" as the suffix, + # which signals that we want to keep this folder + File.file?(d) && !(File.basename(d) =~ /\.vbox-prev$/) + end + + FileUtils.rm_rf(f) if !keep + end + end + end + end + end +end diff --git a/plugins/providers/virtualbox/action/destroy.rb b/plugins/providers/virtualbox/action/destroy.rb new file mode 100644 index 000000000..dcf8a8201 --- /dev/null +++ b/plugins/providers/virtualbox/action/destroy.rb @@ -0,0 +1,19 @@ +module VagrantPlugins + module ProviderVirtualBox + module Action + class Destroy + def initialize(app, env) + @app = app + end + + def call(env) + env[:ui].info I18n.t("vagrant.actions.vm.destroy.destroying") + env[:machine].provider.driver.delete + env[:machine].id = nil + + @app.call(env) + end + end + end + end +end diff --git a/plugins/providers/virtualbox/action/destroy_unused_network_interfaces.rb b/plugins/providers/virtualbox/action/destroy_unused_network_interfaces.rb new file mode 100644 index 000000000..0897ef6dd --- /dev/null +++ b/plugins/providers/virtualbox/action/destroy_unused_network_interfaces.rb @@ -0,0 +1,16 @@ +module VagrantPlugins + module ProviderVirtualBox + module Action + class DestroyUnusedNetworkInterfaces + def initialize(app, env) + @app = app + end + + def call(env) + env[:machine].provider.driver.delete_unused_host_only_networks + @app.call(env) + end + end + end + end +end diff --git a/plugins/providers/virtualbox/action/provisioner_cleanup.rb b/plugins/providers/virtualbox/action/provisioner_cleanup.rb new file mode 100644 index 000000000..c97e3334e --- /dev/null +++ b/plugins/providers/virtualbox/action/provisioner_cleanup.rb @@ -0,0 +1,25 @@ +module VagrantPlugins + module ProviderVirtualBox + module Action + class ProvisionerCleanup + def initialize(app, env) + @app = app + end + + def call(env) + # Instantiate all the enabled provisioners + provisioners = env[:machine].config.vm.provisioners.map do |provisioner| + provisioner.provisioner.new(env, provisioner.config) + end + + # Call cleanup on each + provisioners.each do |instance| + instance.cleanup + end + + @app.call(env) + end + end + end + end +end diff --git a/plugins/providers/virtualbox/action/prune_nfs_exports.rb b/plugins/providers/virtualbox/action/prune_nfs_exports.rb new file mode 100644 index 000000000..e74f176fc --- /dev/null +++ b/plugins/providers/virtualbox/action/prune_nfs_exports.rb @@ -0,0 +1,20 @@ +module VagrantPlugins + module ProviderVirtualBox + module Action + class PruneNFSExports + def initialize(app, env) + @app = app + end + + def call(env) + if env[:host] + valid_ids = env[:machine].provider.driver.read_vms + env[:host].nfs_prune(valid_ids) + end + + @app.call(env) + end + end + end + end +end diff --git a/plugins/providers/virtualbox/provider.rb b/plugins/providers/virtualbox/provider.rb index ba41289e5..9d9d5c9c8 100644 --- a/plugins/providers/virtualbox/provider.rb +++ b/plugins/providers/virtualbox/provider.rb @@ -38,6 +38,8 @@ module VagrantPlugins # # @return [Symbol] def state + # XXX: What happens if we destroy the VM but the UUID is still + # set here? return :not_created if !@driver.uuid state = @driver.read_state return :unknown if !state