plugins/providers/virtualbox/driver/version_5_0.rb in vagrant-unbundled-2.2.9.0 vs plugins/providers/virtualbox/driver/version_5_0.rb in vagrant-unbundled-2.2.10.0
- old
+ new
@@ -20,24 +20,26 @@
# SATA Controller-ImageUUID-0-0 (sub out ImageUUID)
# - Controller: SATA Controller
# - Port: 0
# - Device: 0
#
+ # @param [String] controller_name - name of storage controller to attach disk to
# @param [String] port - port on device to attach disk to
# @param [String] device - device on controller for disk
- # @param [String] file - disk file path
# @param [String] type - type of disk to attach
+ # @param [String] file - disk file path
# @param [Hash] opts - additional options
- def attach_disk(port, device, file, type="hdd", **opts)
- # Maybe only support SATA Controller for `:disk`???
- controller = "SATA Controller"
-
+ def attach_disk(controller_name, port, device, type, file, **opts)
comment = "This disk is managed externally by Vagrant. Removing or adjusting settings could potentially cause issues with Vagrant."
- execute('storageattach', @uuid, '--storagectl', controller, '--port',
- port.to_s, '--device', device.to_s, '--type', type, '--medium',
- file, '--comment', comment)
+ execute('storageattach', @uuid,
+ '--storagectl', controller_name,
+ '--port', port.to_s,
+ '--device', device.to_s,
+ '--type', type,
+ '--medium', file,
+ '--comment', comment)
end
def clear_forwarded_ports
retryable(on: Vagrant::Errors::VBoxManageError, tries: 3, sleep: 1) do
args = []
@@ -222,16 +224,19 @@
d = e.extra_data
return [] if d[:stderr].include?("does not have") || d[:stdout].include?("does not have")
raise
end
+ # @param [String] controller_name - controller name to remove disk from
# @param [String] port - port on device to attach disk to
# @param [String] device - device on controller for disk
- # @param [Hash] opts - additional options
- def remove_disk(port, device)
- controller = "SATA Controller"
- execute('storageattach', @uuid, '--storagectl', controller, '--port', port.to_s, '--device', device.to_s, '--medium', "none")
+ def remove_disk(controller_name, port, device)
+ execute('storageattach', @uuid,
+ '--storagectl', controller_name,
+ '--port', port.to_s,
+ '--device', device.to_s,
+ '--medium', "none")
end
# @param [String] disk_file
# @param [Integer] disk_size in bytes
# @param [Hash] opts - additional options
@@ -386,25 +391,26 @@
end
# Returns port and device for an attached disk given a disk uuid. Returns
# empty hash if disk is not attachd to guest
#
- # @param [Hash] vm_info - A guests information from vboxmanage
# @param [String] disk_uuid - the UUID for the disk we are searching for
# @return [Hash] disk_info - Contains a device and port number
def get_port_and_device(disk_uuid)
- vm_info = show_vm_info
-
disk = {}
- disk_info_key = vm_info.key(disk_uuid)
- return disk if !disk_info_key
- disk_info = disk_info_key.split("-")
+ storage_controllers = read_storage_controllers
+ storage_controllers.each do |controller|
+ controller.attachments.each do |attachment|
+ if disk_uuid == attachment[:uuid]
+ disk[:port] = attachment[:port]
+ disk[:device] = attachment[:device]
+ return disk
+ end
+ end
+ end
- disk[:port] = disk_info[2]
- disk[:device] = disk_info[3]
-
return disk
end
def halt
execute("controlvm", @uuid, "poweroff", retryable: true)
@@ -800,10 +806,30 @@
# Add the shared folder
execute("sharedfolder", "add", @uuid, *args, retryable: true)
end
end
+ # Returns information for a given disk
+ #
+ # @param [String] disk_type - can be "disk", "dvd", or "floppy"
+ # @param [String] disk_uuid_or_file
+ # @return [Hash] disk
+ def show_medium_info(disk_type, disk_uuid_or_file)
+ disk = {}
+ execute('showmediuminfo', disk_type, disk_uuid_or_file, retryable: true).split("\n").each do |line|
+ parts = line.partition(":")
+ key = parts.first.strip
+ value = parts.last.strip
+ disk[key] = value
+
+ if key == "Location"
+ disk["Disk Name"] = File.basename(value, ".*")
+ end
+ end
+ disk
+ end
+
def ssh_port(expected_port)
@logger.debug("Searching for SSH port: #{expected_port.inspect}")
# Look for the forwarded port. Valid based on the guest port, but will do
# scoring based matching to determine best value when multiple results are
@@ -919,9 +945,58 @@
destination = File.join(File.dirname(source), File.basename(source, ".*")) + ".vmdk"
clone_disk(source, destination, 'VMDK')
destination
+ end
+
+ # Helper method to get a list of storage controllers added to the
+ # current VM
+ #
+ # @return [VagrantPlugins::ProviderVirtualBox::Model::StorageControllerArray]
+ def read_storage_controllers
+ vm_info = show_vm_info
+ count = vm_info.count { |key, value| key.match(/^storagecontrollername\d+$/) }
+ all_disks = list_hdds
+
+ storage_controllers = Model::StorageControllerArray.new
+
+ (0..count - 1).each do |n|
+ # basic controller metadata
+ name = vm_info["storagecontrollername#{n}"]
+ type = vm_info["storagecontrollertype#{n}"]
+ maxportcount = vm_info["storagecontrollermaxportcount#{n}"].to_i
+
+ # build attachments array
+ attachments = []
+ vm_info.each do |k, v|
+ if /^#{name}-ImageUUID-(\d+)-(\d+)$/ =~ k
+ port = $1.to_s
+ device = $2.to_s
+ uuid = v
+ location = vm_info["#{name}-#{port}-#{device}"]
+
+ extra_disk_data = all_disks.detect { |d| d["UUID"] == uuid }
+
+ attachment = { port: port,
+ device: device,
+ uuid: uuid,
+ location: location }
+
+ extra_disk_data&.each do |dk,dv|
+ # NOTE: We convert the keys from VirtualBox to symbols
+ # to be consistent with the other keys
+ attachment[dk.downcase.gsub(' ', '_').to_sym] = dv
+ end
+
+ attachments << attachment
+ end
+ end
+
+ storage_controllers << Model::StorageController.new(name, type, maxportcount, attachments)
+ end
+
+ storage_controllers
end
protected
def valid_ip_address?(ip)