diff --git a/plugins/providers/virtualbox/cap/cleanup_disks.rb b/plugins/providers/virtualbox/cap/cleanup_disks.rb index b03883bd2..707aa90e2 100644 --- a/plugins/providers/virtualbox/cap/cleanup_disks.rb +++ b/plugins/providers/virtualbox/cap/cleanup_disks.rb @@ -52,13 +52,18 @@ module VagrantPlugins machine.ui.warn(I18n.t("vagrant.cap.cleanup_disks.disk_cleanup", name: d["name"]), prefix: true) controller = storage_controllers.detect { |c| c.name == d["controller"] } - disk_info = controller.attachments.detect { |a| a[:port] == d["port"] && - a[:device] == d["device"] } + attachment = controller.attachments.detect { |a| a[:port] == d["port"] && + a[:device] == d["device"] } - if disk_info.nil? + # Retry lookup by UUID + if attachment.nil? + attachment = controller.attachments.detect { |a| a[:uuid] == d["uuid"] } + end + + if attachment.nil? LOGGER.warn("Disk '#{d["name"]}' not attached to guest, but still exists.") else - machine.provider.driver.remove_disk(d["controller"], d["port"], d["device"]) + machine.provider.driver.remove_disk(controller.name, attachment[:port], attachment[:device]) end machine.provider.driver.close_medium(d["uuid"]) @@ -79,7 +84,18 @@ module VagrantPlugins else LOGGER.warn("Found dvd not in Vagrantfile config: '#{d["name"]}'. Removing dvd from guest #{machine.name}") machine.ui.warn("DVD '#{d["name"]}' no longer exists in Vagrant config. Removing medium from guest...", prefix: true) - machine.provider.driver.remove_disk(d["controller"], d["port"], d["device"]) + + storage_controllers = machine.provider.driver.read_storage_controllers + controller = storage_controllers.detect { |c| c.name == d["controller"] } + attachment = controller.attachments.detect { |a| a[:port] == d["port"] && + a[:device] == d["device"] } + + # Retry lookup by UUID + if attachment.nil? + attachment = controller.attachments.detect { |a| a[:uuid] == d["uuid"] } + end + + machine.provider.driver.remove_disk(controller.name, attachment[:port], attachment[:device]) end end end diff --git a/test/unit/plugins/providers/virtualbox/cap/cleanup_disks_test.rb b/test/unit/plugins/providers/virtualbox/cap/cleanup_disks_test.rb index 2ee853c13..8280acc50 100644 --- a/test/unit/plugins/providers/virtualbox/cap/cleanup_disks_test.rb +++ b/test/unit/plugins/providers/virtualbox/cap/cleanup_disks_test.rb @@ -84,7 +84,6 @@ describe VagrantPlugins::ProviderVirtualBox::Cap::CleanupDisks do let(:disk_meta_file) { { disk: [{ "uuid" => "67890", "name" => "storage", "controller" => "controller", "port" => "1", "device" => "0" }], floppy: [], dvd: [] } } let(:defined_disks) { [] } - let(:device_info) { {port: "1", device: "0"} } it "removes and closes medium from guest" do expect(driver).to receive(:remove_disk).with("controller", "1", "0").and_return(true) @@ -112,12 +111,23 @@ describe VagrantPlugins::ProviderVirtualBox::Cap::CleanupDisks do to raise_error(Vagrant::Errors::VirtualBoxDisksControllerNotFound) end end + + context "when attachment is not found at the expected device" do + let(:attachments) { [{port: "0", device: "0", uuid: "12345"}, + {port: "2", device: "0", uuid: "67890"}] } + + it "removes the disk from the correct device" do + expect(driver).to receive(:remove_disk).with("controller", "2", "0").and_return(true) + expect(driver).to receive(:close_medium).with("67890").and_return(true) + + subject.handle_cleanup_disk(machine, defined_disks, disk_meta_file[:disk]) + end + end end describe "#handle_cleanup_dvd" do - let(:attachments) { [{port: "0", device: "0", uuid: "1234"}] } - let(:disk_meta_file) { {dvd: [{"uuid" => "1234", "name" => "iso", "port" => "0", "device" => "0", "controller" => "controller" }]} } + let(:attachments) { [{port: "0", device: "0", uuid: "1234"}] } let(:defined_disks) { [] } @@ -126,5 +136,15 @@ describe VagrantPlugins::ProviderVirtualBox::Cap::CleanupDisks do subject.handle_cleanup_dvd(machine, defined_disks, disk_meta_file[:dvd]) end + + context "when attachment is not found at the expected device" do + let(:attachments) { [{port: "0", device: "1", uuid: "1234"}] } + + it "removes the disk from the correct device" do + expect(driver).to receive(:remove_disk).with("controller", "0", "1").and_return(true) + + subject.handle_cleanup_dvd(machine, defined_disks, disk_meta_file[:dvd]) + end + end end end