diff --git a/lib/vagrant/errors.rb b/lib/vagrant/errors.rb index 619803022..5a219570e 100644 --- a/lib/vagrant/errors.rb +++ b/lib/vagrant/errors.rb @@ -936,6 +936,10 @@ module Vagrant error_key(:virtualbox_disks_controller_not_found) end + class VirtualBoxDisksPrimaryNotFound < VagrantError + error_key(:virtualbox_disks_primary_not_found) + end + class VirtualBoxGuestPropertyNotFound < VagrantError error_key(:virtualbox_guest_property_not_found) end diff --git a/plugins/providers/virtualbox/cap/cleanup_disks.rb b/plugins/providers/virtualbox/cap/cleanup_disks.rb index c6c0ce466..ec95c604d 100644 --- a/plugins/providers/virtualbox/cap/cleanup_disks.rb +++ b/plugins/providers/virtualbox/cap/cleanup_disks.rb @@ -27,12 +27,16 @@ module VagrantPlugins # @param [Hash] disk_meta - A hash of all the previously defined disks from the last configure_disk action def self.handle_cleanup_disk(machine, defined_disks, disk_meta) controller = machine.provider.driver.get_controller('SATA') - primary_disk = controller.attachments.detect { |a| a[:port] == "0" && a[:device] == "0" }[:uuid] + primary = controller.attachments.detect { |a| a[:port] == "0" && a[:device] == "0" } + if primary.nil? + raise Vagrant::Errors::VirtualBoxDisksPrimaryNotFound + end + primary_uuid = primary[:uuid] if disk_meta disk_meta.each do |d| dsk = defined_disks.select { |dk| dk.name == d["name"] } - if !dsk.empty? || d["uuid"] == primary_disk + if !dsk.empty? || d["uuid"] == primary_uuid next else LOGGER.warn("Found disk not in Vagrantfile config: '#{d["name"]}'. Removing disk from guest #{machine.name}") diff --git a/plugins/providers/virtualbox/cap/configure_disks.rb b/plugins/providers/virtualbox/cap/configure_disks.rb index 14913fac3..2edb557f8 100644 --- a/plugins/providers/virtualbox/cap/configure_disks.rb +++ b/plugins/providers/virtualbox/cap/configure_disks.rb @@ -69,6 +69,9 @@ module VagrantPlugins # always come in port order, but primary is always Port 0 Device 0. controller = machine.provider.driver.get_controller('SATA') primary = controller.attachments.detect { |a| a[:port] == "0" && a[:device] == "0" } + if primary.nil? + raise Vagrant::Errors::VirtualBoxDisksPrimaryNotFound + end primary_uuid = primary[:uuid] current_disk = all_disks.select { |d| d["UUID"] == primary_uuid }.first diff --git a/templates/locales/en.yml b/templates/locales/en.yml index a553b68e3..a6a27b877 100644 --- a/templates/locales/en.yml +++ b/templates/locales/en.yml @@ -1683,6 +1683,10 @@ en: '%{storage_bus}', but no such controller was found. Please add the proper controller to your guest using provider-specific customizations. + virtualbox_disks_primary_not_found: |- + Vagrant was not able to detect a primary disk attached to the SATA + controller. Vagrant Disks requires that the primary disk be attached + to the first port of the SATA controller in order to manage it. virtualbox_disks_defined_exceed_limit: |- VirtualBox only allows up to 30 disks to be attached to a single guest using the SATA Controller, including the primray disk. 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 a505a1d1b..6eedf57db 100644 --- a/test/unit/plugins/providers/virtualbox/cap/cleanup_disks_test.rb +++ b/test/unit/plugins/providers/virtualbox/cap/cleanup_disks_test.rb @@ -63,6 +63,12 @@ describe VagrantPlugins::ProviderVirtualBox::Cap::CleanupDisks do subject.cleanup_disks(machine, defined_disks, disk_meta_file) end + + it "raises an error if primary disk can't be found" do + allow(sata_controller).to receive(:attachments).and_return([]) + expect { subject.cleanup_disks(machine, defined_disks, disk_meta_file) }. + to raise_error(Vagrant::Errors::VirtualBoxDisksPrimaryNotFound) + end end context "with dvd attached" do diff --git a/test/unit/plugins/providers/virtualbox/cap/configure_disks_test.rb b/test/unit/plugins/providers/virtualbox/cap/configure_disks_test.rb index 9cc5fa682..5ae19f423 100644 --- a/test/unit/plugins/providers/virtualbox/cap/configure_disks_test.rb +++ b/test/unit/plugins/providers/virtualbox/cap/configure_disks_test.rb @@ -142,6 +142,12 @@ describe VagrantPlugins::ProviderVirtualBox::Cap::ConfigureDisks do expect(primary_disk).to eq(all_disks.first) end + it "raises an error if primary disk can't be found" do + allow(sata_controller).to receive(:attachments).and_return([]) + expect { subject.get_current_disk(machine, defined_disks.first, all_disks) }. + to raise_error(Vagrant::Errors::VirtualBoxDisksPrimaryNotFound) + end + it "finds the disk to configure" do disk = subject.get_current_disk(machine, defined_disks[1], all_disks) expect(disk).to eq(all_disks[1])