Add use_fixed_vhd_format Hyper-V ISO option

This commit is contained in:
Adam Robinson 2018-04-20 15:13:12 -04:00
parent bda2d8c947
commit 3aebd5f462
8 changed files with 104 additions and 11 deletions

View File

@ -66,7 +66,7 @@ type Driver interface {
DeleteVirtualSwitch(string) error
CreateVirtualMachine(string, string, string, string, int64, int64, int64, string, uint, bool) error
CreateVirtualMachine(string, string, string, string, int64, int64, int64, string, uint, bool, bool) error
AddVirtualMachineHardDrive(string, string, string, int64, int64, string) error

View File

@ -127,6 +127,7 @@ type DriverMock struct {
CreateVirtualMachine_SwitchName string
CreateVirtualMachine_Generation uint
CreateVirtualMachine_DifferentialDisk bool
CreateVirtualMachine_FixedVHD bool
CreateVirtualMachine_Err error
CloneVirtualMachine_Called bool
@ -390,7 +391,7 @@ func (d *DriverMock) AddVirtualMachineHardDrive(vmName string, vhdFile string, v
return d.AddVirtualMachineHardDrive_Err
}
func (d *DriverMock) CreateVirtualMachine(vmName string, path string, harddrivePath string, vhdPath string, ram int64, diskSize int64, diskBlockSize int64, switchName string, generation uint, diffDisks bool) error {
func (d *DriverMock) CreateVirtualMachine(vmName string, path string, harddrivePath string, vhdPath string, ram int64, diskSize int64, diskBlockSize int64, switchName string, generation uint, diffDisks bool, fixedVHD bool) error {
d.CreateVirtualMachine_Called = true
d.CreateVirtualMachine_VmName = vmName
d.CreateVirtualMachine_Path = path

View File

@ -178,8 +178,8 @@ func (d *HypervPS4Driver) AddVirtualMachineHardDrive(vmName string, vhdFile stri
return hyperv.AddVirtualMachineHardDiskDrive(vmName, vhdFile, vhdName, vhdSizeBytes, diskBlockSize, controllerType)
}
func (d *HypervPS4Driver) CreateVirtualMachine(vmName string, path string, harddrivePath string, vhdPath string, ram int64, diskSize int64, diskBlockSize int64, switchName string, generation uint, diffDisks bool) error {
return hyperv.CreateVirtualMachine(vmName, path, harddrivePath, vhdPath, ram, diskSize, diskBlockSize, switchName, generation, diffDisks)
func (d *HypervPS4Driver) CreateVirtualMachine(vmName string, path string, harddrivePath string, vhdPath string, ram int64, diskSize int64, diskBlockSize int64, switchName string, generation uint, diffDisks bool, fixedVHD bool) error {
return hyperv.CreateVirtualMachine(vmName, path, harddrivePath, vhdPath, ram, diskSize, diskBlockSize, switchName, generation, diffDisks, fixedVHD)
}
func (d *HypervPS4Driver) CloneVirtualMachine(cloneFromVmxcPath string, cloneFromVmName string, cloneFromSnapshotName string, cloneAllSnapshots bool, vmName string, path string, harddrivePath string, ram int64, switchName string) error {

View File

@ -33,6 +33,7 @@ type StepCreateVM struct {
MacAddress string
SkipExport bool
OutputDir string
FixedVHD bool
}
func (s *StepCreateVM) Run(_ context.Context, state multistep.StateBag) multistep.StepAction {
@ -67,7 +68,7 @@ func (s *StepCreateVM) Run(_ context.Context, state multistep.StateBag) multiste
diskSize := int64(s.DiskSize * 1024 * 1024)
diskBlockSize := int64(s.DiskBlockSize * 1024 * 1024)
err := driver.CreateVirtualMachine(s.VMName, path, harddrivePath, vhdPath, ramSize, diskSize, diskBlockSize, s.SwitchName, s.Generation, s.DifferencingDisk)
err := driver.CreateVirtualMachine(s.VMName, path, harddrivePath, vhdPath, ramSize, diskSize, diskBlockSize, s.SwitchName, s.Generation, s.DifferencingDisk, s.FixedVHD)
if err != nil {
err := fmt.Errorf("Error creating virtual machine: %s", err)
state.Put("error", err)

View File

@ -24,6 +24,7 @@ const (
DefaultDiskSize = 40 * 1024 // ~40GB
MinDiskSize = 256 // 256MB
MaxDiskSize = 64 * 1024 * 1024 // 64TB
MaxVHDSize = 2040 * 1024 // 2040GB
DefaultDiskBlockSize = 32 // 32MB
MinDiskBlockSize = 1 // 1MB
@ -110,6 +111,9 @@ type Config struct {
// Use differencing disk
DifferencingDisk bool `mapstructure:"differencing_disk"`
// Create the VM with a Fixed VHD format disk instead of Dynamic VHDX
FixedVHD bool `mapstructure:"use_fixed_vhd_format"`
ctx interpolate.Context
}
@ -270,6 +274,21 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
}
}
if b.config.Generation > 1 && b.config.FixedVHD {
err = errors.New("Fixed VHD disks are only supported on Generation 1 virtual machines.")
errs = packer.MultiErrorAppend(errs, err)
}
if !b.config.SkipCompaction && b.config.FixedVHD {
err = errors.New("Fixed VHD disks do not support compaction.")
errs = packer.MultiErrorAppend(errs, err)
}
if b.config.DifferencingDisk && b.config.FixedVHD {
err = errors.New("Fixed VHD disks are not supported with differencing disks.")
errs = packer.MultiErrorAppend(errs, err)
}
// Warnings
if b.config.ShutdownCommand == "" {
@ -379,6 +398,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
SkipExport: b.config.SkipExport,
OutputDir: b.config.OutputDir,
MacAddress: b.config.MacAddress,
FixedVHD: b.config.FixedVHD,
},
&hypervcommon.StepEnableIntegrationService{},
@ -501,8 +521,10 @@ func (b *Builder) checkDiskSize() error {
if b.config.DiskSize < MinDiskSize {
return fmt.Errorf("disk_size: Virtual machine requires disk space >= %v GB, but defined: %v", MinDiskSize, b.config.DiskSize/1024)
} else if b.config.DiskSize > MaxDiskSize {
} else if b.config.DiskSize > MaxDiskSize && !b.config.FixedVHD {
return fmt.Errorf("disk_size: Virtual machine requires disk space <= %v GB, but defined: %v", MaxDiskSize, b.config.DiskSize/1024)
} else if b.config.DiskSize > MaxVHDSize && b.config.FixedVHD {
return fmt.Errorf("disk_size: Virtual machine requires disk space <= %v GB, but defined: %v", MaxVHDSize/1024, b.config.DiskSize/1024)
}
return nil

View File

@ -139,6 +139,59 @@ func TestBuilderPrepare_DiskBlockSize(t *testing.T) {
}
}
func TestBuilderPrepare_FixedVHDFormat(t *testing.T) {
var b Builder
config := testConfig()
config["use_fixed_vhd_format"] = true
config["generation"] = 1
config["skip_compaction"] = true
config["differencing_disk"] = false
//use_fixed_vhd_format should work with generation = 1, skip_compaction = true, and differencing_disk = false
warns, err := b.Prepare(config)
if len(warns) > 0 {
t.Fatalf("bad: %#v", warns)
}
if err != nil {
t.Fatalf("bad err: %s", err)
}
//use_fixed_vhd_format should not work with differencing_disk = true
config["differencing_disk"] = true
b = Builder{}
warns, err = b.Prepare(config)
if len(warns) > 0 {
t.Fatalf("bad: %#v", warns)
}
if err == nil {
t.Fatal("should have error")
}
config["differencing_disk"] = false
//use_fixed_vhd_format should not work with skip_compaction = false
config["skip_compaction"] = false
b = Builder{}
warns, err = b.Prepare(config)
if len(warns) > 0 {
t.Fatalf("bad: %#v", warns)
}
if err == nil {
t.Fatal("should have error")
}
config["skip_compaction"] = true
//use_fixed_vhd_format should not work with generation = 2
config["generation"] = 2
b = Builder{}
warns, err = b.Prepare(config)
if len(warns) > 0 {
t.Fatalf("bad: %#v", warns)
}
if err == nil {
t.Fatal("should have error")
}
}
func TestBuilderPrepare_FloppyFiles(t *testing.T) {
var b Builder
config := testConfig()

View File

@ -187,7 +187,7 @@ Hyper-V\Set-VMFloppyDiskDrive -VMName $vmName -Path $null
return err
}
func CreateVirtualMachine(vmName string, path string, harddrivePath string, vhdRoot string, ram int64, diskSize int64, diskBlockSize int64, switchName string, generation uint, diffDisks bool) error {
func CreateVirtualMachine(vmName string, path string, harddrivePath string, vhdRoot string, ram int64, diskSize int64, diskBlockSize int64, switchName string, generation uint, diffDisks bool, fixedVHD bool) error {
if generation == 2 {
var script = `
@ -214,8 +214,13 @@ if ($harddrivePath){
return DisableAutomaticCheckpoints(vmName)
} else {
var script = `
param([string]$vmName, [string]$path, [string]$harddrivePath, [string]$vhdRoot, [long]$memoryStartupBytes, [long]$newVHDSizeBytes, [long]$vhdBlockSizeBytes, [string]$switchName, [string]$diffDisks)
$vhdx = $vmName + '.vhdx'
param([string]$vmName, [string]$path, [string]$harddrivePath, [string]$vhdRoot, [long]$memoryStartupBytes, [long]$newVHDSizeBytes, [long]$vhdBlockSizeBytes, [string]$switchName, [string]$diffDisks, [string]$fixedVHD)
if($fixedVHD -eq "true"){
$vhdx = $vmName + '.vhd'
}
else{
$vhdx = $vmName + '.vhdx'
}
$vhdPath = Join-Path -Path $vhdRoot -ChildPath $vhdx
if ($harddrivePath){
if($diffDisks -eq "true"){
@ -226,12 +231,17 @@ if ($harddrivePath){
}
Hyper-V\New-VM -Name $vmName -Path $path -MemoryStartupBytes $memoryStartupBytes -VHDPath $vhdPath -SwitchName $switchName
} else {
Hyper-V\New-VHD -Path $vhdPath -SizeBytes $newVHDSizeBytes -BlockSizeBytes $vhdBlockSizeBytes
if($fixedVHD -eq "true"){
Hyper-V\New-VHD -Path $vhdPath -Fixed -SizeBytes $newVHDSizeBytes
}
else {
Hyper-V\New-VHD -Path $vhdPath -SizeBytes $newVHDSizeBytes -BlockSizeBytes $vhdBlockSizeBytes
}
Hyper-V\New-VM -Name $vmName -Path $path -MemoryStartupBytes $memoryStartupBytes -VHDPath $vhdPath -SwitchName $switchName
}
`
var ps powershell.PowerShellCmd
if err := ps.Run(script, vmName, path, harddrivePath, vhdRoot, strconv.FormatInt(ram, 10), strconv.FormatInt(diskSize, 10), strconv.FormatInt(diskBlockSize, 10), switchName, strconv.FormatBool(diffDisks)); err != nil {
if err := ps.Run(script, vmName, path, harddrivePath, vhdRoot, strconv.FormatInt(ram, 10), strconv.FormatInt(diskSize, 10), strconv.FormatInt(diskBlockSize, 10), switchName, strconv.FormatBool(diffDisks), strconv.FormatBool(fixedVHD)); err != nil {
return err
}

View File

@ -212,6 +212,12 @@ can be configured for this builder.
By default none is set. If none is set then a vlan is not set on the switch's network card.
If this value is set it should match the vlan specified in by `vlan_id`.
- `use_fixed_vhd_format` (boolean) - If true, creates the boot disk on the virtual machine as
a fixed VHD format disk. The default is false, which creates a dynamic VHDX format disk. This
option requires setting `generation` to 1, `skip_compaction` to true, and `differencing_disk` to false.
Additionally, any value entered for `disk_block_size` will be ignored. The most likely use case for this
option is outputing a disk that is in the format required for upload to Azure.
- `vhd_temp_path` (string) - A separate path to be used for storing the VM's
disk image. The purpose is to enable reading and writing to take place on
different physical disks (read from VHD temp path, write to regular temp