On Windows the File::SEPARATOR ends up being `/` which causes issues with the new way the path is being extracted from the vbox information. When on Windows (even with WSL), automatically convert the path to use common forward slash separator. This fixes path modifications used for storing guest disks.
103 lines
3.7 KiB
Ruby
103 lines
3.7 KiB
Ruby
require File.expand_path("../version_5_0", __FILE__)
|
|
|
|
module VagrantPlugins
|
|
module ProviderVirtualBox
|
|
module Driver
|
|
# Driver for VirtualBox 6.0.x
|
|
class Version_6_0 < Version_5_0
|
|
def initialize(uuid)
|
|
super
|
|
|
|
@logger = Log4r::Logger.new("vagrant::provider::virtualbox_6_0")
|
|
end
|
|
|
|
def import(ovf)
|
|
ovf = Vagrant::Util::Platform.windows_path(ovf)
|
|
|
|
output = ""
|
|
total = ""
|
|
last = 0
|
|
|
|
# Dry-run the import to get the suggested name and path
|
|
@logger.debug("Doing dry-run import to determine parallel-safe name...")
|
|
output = execute("import", "-n", ovf)
|
|
result = /Suggested VM name "(.+?)"/.match(output)
|
|
if !result
|
|
raise Vagrant::Errors::VirtualBoxNoName, output: output
|
|
end
|
|
suggested_name = result[1].to_s
|
|
|
|
# Append millisecond plus a random to the path in case we're
|
|
# importing the same box elsewhere.
|
|
specified_name = "#{suggested_name}_#{(Time.now.to_f * 1000.0).to_i}_#{rand(100000)}"
|
|
@logger.debug("-- Parallel safe name: #{specified_name}")
|
|
|
|
# Build the specified name param list
|
|
name_params = [
|
|
"--vsys", "0",
|
|
"--vmname", specified_name,
|
|
]
|
|
|
|
# Target path for disks is no longer a full path. Extract the path for the
|
|
# settings file to determine the base directory which we can then use to
|
|
# build the disk paths
|
|
result = /Suggested VM settings file name "(?<settings_path>.+?)"/.match(output)
|
|
if !result
|
|
@logger.warn("Failed to locate base path for disks. Using current working directory.")
|
|
base_path = "."
|
|
else
|
|
base_path = result[:settings_path]
|
|
if Vagrant::Util::Platform.windows? || Vagrant::Util::Platform.wsl?
|
|
base_path.gsub!('\\', '/')
|
|
end
|
|
base_path = File.dirname(base_path)
|
|
end
|
|
|
|
@logger.info("Base path for disk import: #{base_path}")
|
|
|
|
# Extract the disks list and build the disk target params
|
|
disk_params = []
|
|
disks = output.scan(/(\d+): Hard disk image: source image=.+, target path=(.+),/)
|
|
disks.each do |unit_num, path|
|
|
path = File.join(base_path, File.basename(path))
|
|
disk_params << "--vsys"
|
|
disk_params << "0"
|
|
disk_params << "--unit"
|
|
disk_params << unit_num
|
|
disk_params << "--disk"
|
|
disk_params << path.reverse.sub("/#{suggested_name}/".reverse, "/#{specified_name}/".reverse).reverse # Replace only last occurrence
|
|
end
|
|
|
|
execute("import", ovf , *name_params, *disk_params, retryable: true) do |type, data|
|
|
if type == :stdout
|
|
# Keep track of the stdout so that we can get the VM name
|
|
output << data
|
|
elsif type == :stderr
|
|
# Append the data so we can see the full view
|
|
total << data.gsub("\r", "")
|
|
|
|
# Break up the lines. We can't get the progress until we see an "OK"
|
|
lines = total.split("\n")
|
|
if lines.include?("OK.")
|
|
# The progress of the import will be in the last line. Do a greedy
|
|
# regular expression to find what we're looking for.
|
|
match = /.+(\d{2})%/.match(lines.last)
|
|
if match
|
|
current = match[1].to_i
|
|
if current > last
|
|
last = current
|
|
yield current if block_given?
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
return get_machine_id specified_name
|
|
end
|
|
|
|
end
|
|
end
|
|
end
|
|
end
|