Merge pull request #7854 from bbrala/import-vmcx-script
Add support for vmcx (Hyper-V binary config format) to the Hyper-V import script
This commit is contained in:
commit
1b04d3da26
|
@ -35,13 +35,28 @@ module VagrantPlugins
|
||||||
end
|
end
|
||||||
|
|
||||||
config_path = nil
|
config_path = nil
|
||||||
|
config_type = nil
|
||||||
vm_dir.each_child do |f|
|
vm_dir.each_child do |f|
|
||||||
if f.extname.downcase == ".xml"
|
if f.extname.downcase == '.xml'
|
||||||
config_path = f
|
config_path = f
|
||||||
|
config_type = 'xml'
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Only check for .vmcx if there is no XML found to not
|
||||||
|
# risk breaking older vagrant boxes that added an XML
|
||||||
|
# file manually
|
||||||
|
if config_type == nil
|
||||||
|
vm_dir.each_child do |f|
|
||||||
|
if f.extname.downcase == '.vmcx'
|
||||||
|
config_path = f
|
||||||
|
config_type = 'vmcx'
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
image_path = nil
|
image_path = nil
|
||||||
image_ext = nil
|
image_ext = nil
|
||||||
image_filename = nil
|
image_filename = nil
|
||||||
|
@ -49,7 +64,7 @@ module VagrantPlugins
|
||||||
if %w{.vhd .vhdx}.include?(f.extname.downcase)
|
if %w{.vhd .vhdx}.include?(f.extname.downcase)
|
||||||
image_path = f
|
image_path = f
|
||||||
image_ext = f.extname.downcase
|
image_ext = f.extname.downcase
|
||||||
image_filename = File.basename(f,image_ext)
|
image_filename = File.basename(f, image_ext)
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -100,19 +115,27 @@ module VagrantPlugins
|
||||||
|
|
||||||
env[:ui].detail("Cloning virtual hard drive...")
|
env[:ui].detail("Cloning virtual hard drive...")
|
||||||
source_path = image_path.to_s
|
source_path = image_path.to_s
|
||||||
dest_path = env[:machine].data_dir.join("#{image_filename}#{image_ext}").to_s
|
dest_path = env[:machine].data_dir.join("Virtual Hard Disks").join("#{image_filename}#{image_ext}").to_s
|
||||||
|
|
||||||
|
# Still hard copy the disk of old XML configurations
|
||||||
|
if config_type == 'xml'
|
||||||
if differencing_disk
|
if differencing_disk
|
||||||
env[:machine].provider.driver.execute("clone_vhd.ps1", {Source: source_path, Destination: dest_path})
|
env[:machine].provider.driver.execute("clone_vhd.ps1", {Source: source_path, Destination: dest_path})
|
||||||
else
|
else
|
||||||
|
FileUtils.mkdir_p(env[:machine].data_dir.join("Virtual Hard Disks"))
|
||||||
FileUtils.cp(source_path, dest_path)
|
FileUtils.cp(source_path, dest_path)
|
||||||
end
|
end
|
||||||
|
end
|
||||||
image_path = dest_path
|
image_path = dest_path
|
||||||
|
|
||||||
# We have to normalize the paths to be Windows paths since
|
# We have to normalize the paths to be Windows paths since
|
||||||
# we're executing PowerShell.
|
# we're executing PowerShell.
|
||||||
options = {
|
options = {
|
||||||
vm_xml_config: config_path.to_s.gsub("/", "\\"),
|
vm_config_file: config_path.to_s.gsub("/", "\\"),
|
||||||
image_path: image_path.to_s.gsub("/", "\\")
|
vm_config_type: config_type,
|
||||||
|
source_path: source_path.to_s,
|
||||||
|
dest_path: dest_path,
|
||||||
|
data_path: env[:machine].data_dir.to_s.gsub("/", "\\")
|
||||||
}
|
}
|
||||||
options[:switchname] = switch if switch
|
options[:switchname] = switch if switch
|
||||||
options[:memory] = memory if memory
|
options[:memory] = memory if memory
|
||||||
|
@ -121,6 +144,7 @@ module VagrantPlugins
|
||||||
options[:vmname] = vmname if vmname
|
options[:vmname] = vmname if vmname
|
||||||
options[:auto_start_action] = auto_start_action if auto_start_action
|
options[:auto_start_action] = auto_start_action if auto_start_action
|
||||||
options[:auto_stop_action] = auto_stop_action if auto_stop_action
|
options[:auto_stop_action] = auto_stop_action if auto_stop_action
|
||||||
|
options[:differencing_disk] = differencing_disk if differencing_disk
|
||||||
|
|
||||||
env[:ui].detail("Creating and registering the VM...")
|
env[:ui].detail("Creating and registering the VM...")
|
||||||
server = env[:machine].provider.driver.import(options)
|
server = env[:machine].provider.driver.import(options)
|
||||||
|
|
|
@ -74,7 +74,15 @@ module VagrantPlugins
|
||||||
end
|
end
|
||||||
|
|
||||||
def import(options)
|
def import(options)
|
||||||
execute('import_vm.ps1', options)
|
config_type = options.delete(:vm_config_type)
|
||||||
|
if config_type === "vmcx"
|
||||||
|
execute('import_vm_vmcx.ps1', options)
|
||||||
|
else
|
||||||
|
options.delete(:data_path)
|
||||||
|
options.delete(:source_path)
|
||||||
|
options.delete(:differencing_disk)
|
||||||
|
execute('import_vm_xml.ps1', options)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def net_set_vlan(vlan_id)
|
def net_set_vlan(vlan_id)
|
||||||
|
|
|
@ -0,0 +1,154 @@
|
||||||
|
Param(
|
||||||
|
[Parameter(Mandatory=$true)]
|
||||||
|
[string]$vm_config_file,
|
||||||
|
[Parameter(Mandatory=$true)]
|
||||||
|
[string]$source_path,
|
||||||
|
[Parameter(Mandatory=$true)]
|
||||||
|
[string]$dest_path,
|
||||||
|
[Parameter(Mandatory=$true)]
|
||||||
|
[string]$data_path,
|
||||||
|
|
||||||
|
[string]$switchname=$null,
|
||||||
|
[string]$memory=$null,
|
||||||
|
[string]$maxmemory=$null,
|
||||||
|
[string]$cpus=$null,
|
||||||
|
[string]$vmname=$null,
|
||||||
|
[string]$auto_start_action=$null,
|
||||||
|
[string]$auto_stop_action=$null,
|
||||||
|
[string]$differencing_disk=$null
|
||||||
|
)
|
||||||
|
|
||||||
|
# Include the following modules
|
||||||
|
$Dir = Split-Path $script:MyInvocation.MyCommand.Path
|
||||||
|
. ([System.IO.Path]::Combine($Dir, "utils\write_messages.ps1"))
|
||||||
|
|
||||||
|
$VmProperties = @{
|
||||||
|
Path = $vm_config_file
|
||||||
|
SnapshotFilePath = Join-Path $data_path 'Snapshots'
|
||||||
|
VhdDestinationPath = Join-Path $data_path 'Virtual Hard Disks'
|
||||||
|
VirtualMachinePath = $data_path
|
||||||
|
}
|
||||||
|
|
||||||
|
$vmConfig = (Compare-VM -Copy -GenerateNewID @VmProperties)
|
||||||
|
|
||||||
|
$generation = $vmConfig.VM.Generation
|
||||||
|
|
||||||
|
if (!$vmname) {
|
||||||
|
# Get the name of the vm
|
||||||
|
$vm_name = $vmconfig.VM.VMName
|
||||||
|
}else {
|
||||||
|
$vm_name = $vmname
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$cpus) {
|
||||||
|
# Get the processorcount of the VM
|
||||||
|
$processors = (Get-VMProcessor -VM $vmConfig.VM).Count
|
||||||
|
}else {
|
||||||
|
$processors = $cpus
|
||||||
|
}
|
||||||
|
|
||||||
|
function GetUniqueName($name) {
|
||||||
|
Get-VM | ForEach-Object -Process {
|
||||||
|
if ($name -eq $_.Name) {
|
||||||
|
$name = $name + "_1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $name
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
$name = $vm_name
|
||||||
|
$vm_name = GetUniqueName $name
|
||||||
|
} while ($vm_name -ne $name)
|
||||||
|
|
||||||
|
if (!$memory) {
|
||||||
|
$configMemory = Get-VMMemory -VM $vmConfig.VM
|
||||||
|
$dynamicmemory = $configMemory.DynamicMemoryEnabled
|
||||||
|
|
||||||
|
$MemoryMaximumBytes = ($configMemory.Maximum)
|
||||||
|
$MemoryStartupBytes = ($configMemory.Startup)
|
||||||
|
$MemoryMinimumBytes = ($configMemory.Minimum)
|
||||||
|
} else {
|
||||||
|
if (!$maxmemory){
|
||||||
|
$dynamicmemory = $False
|
||||||
|
$MemoryMaximumBytes = ($memory -as [int]) * 1MB
|
||||||
|
$MemoryStartupBytes = ($memory -as [int]) * 1MB
|
||||||
|
$MemoryMinimumBytes = ($memory -as [int]) * 1MB
|
||||||
|
} else {
|
||||||
|
$dynamicmemory = $True
|
||||||
|
$MemoryMaximumBytes = ($maxmemory -as [int]) * 1MB
|
||||||
|
$MemoryStartupBytes = ($memory -as [int]) * 1MB
|
||||||
|
$MemoryMinimumBytes = ($memory -as [int]) * 1MB
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$switchname) {
|
||||||
|
$switchname = (Get-VMNetworkAdapter -VM $vmConfig.VM).SwitchName
|
||||||
|
}
|
||||||
|
|
||||||
|
Connect-VMNetworkAdapter -VMNetworkAdapter (Get-VMNetworkAdapter -VM $vmConfig.VM) -SwitchName $switchname
|
||||||
|
Set-VM -VM $vmConfig.VM -NewVMName $vm_name -MemoryStartupBytes $MemoryStartupBytes
|
||||||
|
Set-VM -VM $vmConfig.VM -ErrorAction "Stop" -ProcessorCount $processors
|
||||||
|
|
||||||
|
If ($dynamicmemory) {
|
||||||
|
Set-VM -VM $vmConfig.VM -DynamicMemory
|
||||||
|
Set-VM -VM $vmConfig.VM -MemoryMinimumBytes $MemoryMinimumBytes -MemoryMaximumBytes $MemoryMaximumBytes
|
||||||
|
} else {
|
||||||
|
Set-VM -VM $vmConfig.VM -StaticMemory
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($notes) {
|
||||||
|
Set-VM -VM $vmConfig.VM -Notes $notes
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($auto_start_action) {
|
||||||
|
Set-VM -VM $vmConfig.VM -AutomaticStartAction $auto_start_action
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($auto_stop_action) {
|
||||||
|
Set-VM -VM $vmConfig.VM -AutomaticStartAction $auto_stop_action
|
||||||
|
}
|
||||||
|
|
||||||
|
# Only set EFI secure boot for Gen 2 machines, not gen 1
|
||||||
|
if ($generation -ne 1) {
|
||||||
|
Set-VMFirmware -VM $vmConfig.VM -EnableSecureBoot (Get-VMFirmware -VM $vmConfig.VM).SecureBoot
|
||||||
|
}
|
||||||
|
|
||||||
|
$report = Compare-VM -CompatibilityReport $vmConfig
|
||||||
|
|
||||||
|
# Stop if there are incompatibilities
|
||||||
|
if($report.Incompatibilities.Length -gt 0){
|
||||||
|
Write-Error-Message $(ConvertTo-Json $($report.Incompatibilities | Select -ExpandProperty Message))
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if($differencing_disk){
|
||||||
|
# Get all controller on the VM, first scsi, then IDE if it is a Gen 1 device
|
||||||
|
$controllers = Get-VMScsiController -VM $vmConfig.VM
|
||||||
|
if($generation -eq 1){
|
||||||
|
$controllers = @($controllers) + @(Get-VMIdeController -VM $vmConfig.VM)
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach($controller in $controllers){
|
||||||
|
foreach($drive in $controller.Drives){
|
||||||
|
if([System.IO.Path]::GetFileName($drive.Path) -eq [System.IO.Path]::GetFileName($source_path)){
|
||||||
|
# Remove the old disk and replace it with a differencing version
|
||||||
|
$path = $drive.Path
|
||||||
|
Remove-VMHardDiskDrive $drive
|
||||||
|
New-VHD -Path $dest_path -ParentPath $source_path -ErrorAction Stop
|
||||||
|
Add-VMHardDiskDrive -VM $vmConfig.VM -Path $dest_path
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Import-VM -CompatibilityReport $vmConfig
|
||||||
|
|
||||||
|
$vm_id = (Get-VM $vm_name).id.guid
|
||||||
|
$resultHash = @{
|
||||||
|
name = $vm_name
|
||||||
|
id = $vm_id
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = ConvertTo-Json $resultHash
|
||||||
|
Write-Output-Message $result
|
|
@ -1,8 +1,8 @@
|
||||||
Param(
|
Param(
|
||||||
[Parameter(Mandatory=$true)]
|
[Parameter(Mandatory=$true)]
|
||||||
[string]$vm_xml_config,
|
[string]$vm_config_file,
|
||||||
[Parameter(Mandatory=$true)]
|
[Parameter(Mandatory=$true)]
|
||||||
[string]$image_path,
|
[string]$dest_path,
|
||||||
|
|
||||||
[string]$switchname=$null,
|
[string]$switchname=$null,
|
||||||
[string]$memory=$null,
|
[string]$memory=$null,
|
||||||
|
@ -17,7 +17,7 @@ Param(
|
||||||
$Dir = Split-Path $script:MyInvocation.MyCommand.Path
|
$Dir = Split-Path $script:MyInvocation.MyCommand.Path
|
||||||
. ([System.IO.Path]::Combine($Dir, "utils\write_messages.ps1"))
|
. ([System.IO.Path]::Combine($Dir, "utils\write_messages.ps1"))
|
||||||
|
|
||||||
[xml]$vmconfig = Get-Content -Path $vm_xml_config
|
[xml]$vmconfig = Get-Content -Path $vm_config_file
|
||||||
|
|
||||||
$generation = [int]($vmconfig.configuration.properties.subtype.'#text')+1
|
$generation = [int]($vmconfig.configuration.properties.subtype.'#text')+1
|
||||||
|
|
||||||
|
@ -190,7 +190,7 @@ foreach ($controller in $controllers) {
|
||||||
|
|
||||||
$addDriveParam = @{
|
$addDriveParam = @{
|
||||||
ControllerNumber = $rx.Match($controller.node.name).value
|
ControllerNumber = $rx.Match($controller.node.name).value
|
||||||
Path = $image_path
|
Path = $dest_path
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($drive.pool_id."#text") {
|
if ($drive.pool_id."#text") {
|
Loading…
Reference in New Issue