2014-02-26 19:56:37 +00:00
|
|
|
require "fileutils"
|
|
|
|
|
2014-02-15 23:29:16 +00:00
|
|
|
require "log4r"
|
2014-02-15 23:38:11 +00:00
|
|
|
|
2014-02-15 23:29:16 +00:00
|
|
|
module VagrantPlugins
|
|
|
|
module HyperV
|
|
|
|
module Action
|
|
|
|
class Import
|
|
|
|
def initialize(app, env)
|
2016-10-08 14:44:24 +00:00
|
|
|
@app = app
|
2014-02-16 02:13:39 +00:00
|
|
|
@logger = Log4r::Logger.new("vagrant::hyperv::import")
|
2014-02-15 23:29:16 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def call(env)
|
2014-02-16 02:13:39 +00:00
|
|
|
vm_dir = env[:machine].box.directory.join("Virtual Machines")
|
|
|
|
hd_dir = env[:machine].box.directory.join("Virtual Hard Disks")
|
2015-01-14 14:59:01 +00:00
|
|
|
memory = env[:machine].provider_config.memory
|
|
|
|
maxmemory = env[:machine].provider_config.maxmemory
|
|
|
|
cpus = env[:machine].provider_config.cpus
|
|
|
|
vmname = env[:machine].provider_config.vmname
|
2016-03-01 15:23:38 +00:00
|
|
|
differencing_disk = env[:machine].provider_config.differencing_disk
|
2016-07-26 12:41:01 +00:00
|
|
|
auto_start_action = env[:machine].provider_config.auto_start_action
|
2016-07-26 12:56:20 +00:00
|
|
|
auto_stop_action = env[:machine].provider_config.auto_stop_action
|
2016-08-18 05:41:32 +00:00
|
|
|
enable_virtualization_extensions = env[:machine].provider_config.enable_virtualization_extensions
|
2017-03-15 21:12:19 +00:00
|
|
|
vm_integration_services = env[:machine].provider_config.vm_integration_services
|
2015-01-14 14:59:01 +00:00
|
|
|
|
2016-02-16 14:58:42 +00:00
|
|
|
env[:ui].output("Configured Dynamic memory allocation, maxmemory is #{maxmemory}") if maxmemory
|
2015-01-14 14:59:01 +00:00
|
|
|
env[:ui].output("Configured startup memory is #{memory}") if memory
|
|
|
|
env[:ui].output("Configured cpus number is #{cpus}") if cpus
|
2016-08-18 05:41:32 +00:00
|
|
|
env[:ui].output("Configured enable virtualization extensions is #{enable_virtualization_extensions}") if enable_virtualization_extensions
|
2015-01-14 14:59:01 +00:00
|
|
|
env[:ui].output("Configured vmname is #{vmname}") if vmname
|
2016-03-01 15:23:38 +00:00
|
|
|
env[:ui].output("Configured differencing disk instead of cloning") if differencing_disk
|
2016-07-26 12:41:01 +00:00
|
|
|
env[:ui].output("Configured automatic start action is #{auto_start_action}") if auto_start_action
|
2016-07-26 12:56:20 +00:00
|
|
|
env[:ui].output("Configured automatic stop action is #{auto_stop_action}") if auto_stop_action
|
2014-02-16 02:13:39 +00:00
|
|
|
|
|
|
|
if !vm_dir.directory? || !hd_dir.directory?
|
|
|
|
raise Errors::BoxInvalid
|
|
|
|
end
|
|
|
|
|
|
|
|
config_path = nil
|
2016-10-02 14:10:58 +00:00
|
|
|
config_type = nil
|
2014-02-16 02:13:39 +00:00
|
|
|
vm_dir.each_child do |f|
|
2016-10-02 14:10:58 +00:00
|
|
|
if f.extname.downcase == '.xml'
|
2016-12-14 14:14:56 +00:00
|
|
|
@logger.debug("Found XML config...")
|
2016-10-02 14:10:58 +00:00
|
|
|
config_path = f
|
|
|
|
config_type = 'xml'
|
|
|
|
break
|
|
|
|
end
|
2016-10-07 18:38:05 +00:00
|
|
|
end
|
|
|
|
|
2017-06-13 17:20:48 +00:00
|
|
|
vmcx_support = env[:machine].provider.driver.execute("has_vmcx_support.ps1", {})['result']
|
2016-12-14 14:14:56 +00:00
|
|
|
if vmcx_support
|
2016-10-07 18:38:05 +00:00
|
|
|
vm_dir.each_child do |f|
|
|
|
|
if f.extname.downcase == '.vmcx'
|
2016-12-14 14:14:56 +00:00
|
|
|
@logger.debug("Found VMCX config and support...")
|
2016-10-07 18:38:05 +00:00
|
|
|
config_path = f
|
|
|
|
config_type = 'vmcx'
|
|
|
|
break
|
|
|
|
end
|
2014-02-16 02:13:39 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-07-17 09:50:51 +00:00
|
|
|
image_path = nil
|
|
|
|
image_ext = nil
|
2016-02-16 14:57:53 +00:00
|
|
|
image_filename = nil
|
2014-02-16 02:13:39 +00:00
|
|
|
hd_dir.each_child do |f|
|
2014-07-17 09:50:51 +00:00
|
|
|
if %w{.vhd .vhdx}.include?(f.extname.downcase)
|
|
|
|
image_path = f
|
|
|
|
image_ext = f.extname.downcase
|
2016-10-08 14:44:24 +00:00
|
|
|
image_filename = File.basename(f, image_ext)
|
2014-02-16 02:13:39 +00:00
|
|
|
break
|
|
|
|
end
|
2014-02-15 23:29:16 +00:00
|
|
|
end
|
|
|
|
|
2014-07-17 09:50:51 +00:00
|
|
|
if !config_path || !image_path
|
2014-02-16 02:13:39 +00:00
|
|
|
raise Errors::BoxInvalid
|
2014-02-15 23:29:16 +00:00
|
|
|
end
|
|
|
|
|
2014-02-26 19:56:37 +00:00
|
|
|
env[:ui].output("Importing a Hyper-V instance")
|
2014-02-27 16:08:02 +00:00
|
|
|
|
|
|
|
switches = env[:machine].provider.driver.execute("get_switches.ps1", {})
|
|
|
|
raise Errors::NoSwitches if switches.empty?
|
|
|
|
|
2015-01-17 09:06:56 +00:00
|
|
|
switch = nil
|
|
|
|
env[:machine].config.vm.networks.each do |type, opts|
|
|
|
|
next if type != :public_network && type != :private_network
|
|
|
|
|
2015-01-17 19:39:32 +00:00
|
|
|
switchToFind = opts[:bridge]
|
2015-01-17 09:06:56 +00:00
|
|
|
|
|
|
|
if switchToFind
|
2018-04-27 23:52:16 +00:00
|
|
|
@logger.debug("Looking for switch with name: #{switchToFind}")
|
|
|
|
switch = switches.find { |s| s["Name"].downcase == switchToFind.downcase }["Id"]
|
|
|
|
@logger.debug("Found switch: #{switch}")
|
2014-02-27 16:08:02 +00:00
|
|
|
end
|
2015-01-17 09:06:56 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
if switch.nil?
|
|
|
|
if switches.length > 1
|
|
|
|
env[:ui].detail(I18n.t("vagrant_hyperv.choose_switch") + "\n ")
|
|
|
|
switches.each_index do |i|
|
|
|
|
switch = switches[i]
|
|
|
|
env[:ui].detail("#{i+1}) #{switch["Name"]}")
|
|
|
|
end
|
|
|
|
env[:ui].detail(" ")
|
|
|
|
|
|
|
|
switch = nil
|
|
|
|
while !switch
|
|
|
|
switch = env[:ui].ask("What switch would you like to use? ")
|
|
|
|
next if !switch
|
|
|
|
switch = switch.to_i - 1
|
|
|
|
switch = nil if switch < 0 || switch >= switches.length
|
|
|
|
end
|
2018-04-27 23:52:16 +00:00
|
|
|
switch = switches[switch]["Id"]
|
2015-01-17 09:06:56 +00:00
|
|
|
else
|
2018-04-27 23:52:16 +00:00
|
|
|
switch = switches[0]["Id"]
|
2014-02-27 16:08:02 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-02-26 19:56:37 +00:00
|
|
|
env[:ui].detail("Cloning virtual hard drive...")
|
2016-10-08 14:44:24 +00:00
|
|
|
source_path = image_path.to_s
|
2016-10-09 19:10:56 +00:00
|
|
|
dest_path = env[:machine].data_dir.join("Virtual Hard Disks").join("#{image_filename}#{image_ext}").to_s
|
2016-10-08 14:38:42 +00:00
|
|
|
|
|
|
|
# Still hard copy the disk of old XML configurations
|
|
|
|
if config_type == 'xml'
|
|
|
|
if differencing_disk
|
|
|
|
env[:machine].provider.driver.execute("clone_vhd.ps1", {Source: source_path, Destination: dest_path})
|
|
|
|
else
|
2016-10-09 19:10:56 +00:00
|
|
|
FileUtils.mkdir_p(env[:machine].data_dir.join("Virtual Hard Disks"))
|
2016-10-08 14:38:42 +00:00
|
|
|
FileUtils.cp(source_path, dest_path)
|
|
|
|
end
|
2016-03-01 15:23:38 +00:00
|
|
|
end
|
2014-07-17 09:50:51 +00:00
|
|
|
image_path = dest_path
|
2014-02-26 19:56:37 +00:00
|
|
|
|
2014-02-16 02:13:39 +00:00
|
|
|
# We have to normalize the paths to be Windows paths since
|
|
|
|
# we're executing PowerShell.
|
2014-02-15 23:29:16 +00:00
|
|
|
options = {
|
2016-10-08 14:44:24 +00:00
|
|
|
vm_config_file: config_path.to_s.gsub("/", "\\"),
|
|
|
|
vm_config_type: config_type,
|
|
|
|
source_path: source_path.to_s,
|
2016-10-09 19:10:56 +00:00
|
|
|
dest_path: dest_path,
|
2016-10-08 14:44:24 +00:00
|
|
|
data_path: env[:machine].data_dir.to_s.gsub("/", "\\")
|
2014-02-15 23:29:16 +00:00
|
|
|
}
|
2014-02-27 16:08:02 +00:00
|
|
|
options[:switchname] = switch if switch
|
2016-02-16 14:57:53 +00:00
|
|
|
options[:memory] = memory if memory
|
2015-01-14 14:59:01 +00:00
|
|
|
options[:maxmemory] = maxmemory if maxmemory
|
|
|
|
options[:cpus] = cpus if cpus
|
2016-02-16 14:57:53 +00:00
|
|
|
options[:vmname] = vmname if vmname
|
2016-07-26 12:41:01 +00:00
|
|
|
options[:auto_start_action] = auto_start_action if auto_start_action
|
2016-07-26 12:56:20 +00:00
|
|
|
options[:auto_stop_action] = auto_stop_action if auto_stop_action
|
2016-10-08 14:38:42 +00:00
|
|
|
options[:differencing_disk] = differencing_disk if differencing_disk
|
2017-12-10 01:09:49 +00:00
|
|
|
options[:enable_virtualization_extensions] = "True" if enable_virtualization_extensions and enable_virtualization_extensions == true
|
2014-02-15 23:29:16 +00:00
|
|
|
|
2014-02-26 19:56:37 +00:00
|
|
|
env[:ui].detail("Creating and registering the VM...")
|
2014-03-06 16:51:07 +00:00
|
|
|
server = env[:machine].provider.driver.import(options)
|
2017-03-15 21:12:19 +00:00
|
|
|
|
|
|
|
env[:ui].detail("Setting VM Integration Services")
|
|
|
|
vm_integration_services.each do |key, value|
|
|
|
|
state = false
|
|
|
|
if value === true
|
|
|
|
state = "enabled"
|
|
|
|
elsif value === false
|
|
|
|
state = "disabled"
|
|
|
|
end
|
|
|
|
env[:ui].output("#{key} is #{state}") if state
|
|
|
|
end
|
|
|
|
|
|
|
|
vm_integration_services[:VmId] = server["id"]
|
|
|
|
env[:machine].provider.driver.set_vm_integration_services(vm_integration_services)
|
|
|
|
|
2014-02-26 19:12:24 +00:00
|
|
|
env[:ui].detail("Successfully imported a VM with name: #{server['name']}")
|
2014-02-15 23:29:16 +00:00
|
|
|
env[:machine].id = server["id"]
|
|
|
|
@app.call(env)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|