From 028c941b77534026a8999b0a60affa52bcd18ea4 Mon Sep 17 00:00:00 2001 From: Sander Saares Date: Tue, 1 Aug 2017 12:23:19 +0300 Subject: [PATCH] Enable use of separate temp path for Hyper-V VHD --- .gitignore | 1 + builder/hyperv/common/driver.go | 2 +- builder/hyperv/common/driver_ps_4.go | 4 ++-- builder/hyperv/common/step_create_tempdir.go | 21 ++++++++++++++++++-- builder/hyperv/common/step_create_vm.go | 3 ++- builder/hyperv/iso/builder.go | 8 +++++++- common/powershell/hyperv/hyperv.go | 14 ++++++------- 7 files changed, 39 insertions(+), 14 deletions(-) diff --git a/.gitignore b/.gitignore index a23e18aec..e419e93cd 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,4 @@ packer-test*.log .idea/ *.iml Thumbs.db +/packer.exe \ No newline at end of file diff --git a/builder/hyperv/common/driver.go b/builder/hyperv/common/driver.go index 9446c0410..fce6da7df 100644 --- a/builder/hyperv/common/driver.go +++ b/builder/hyperv/common/driver.go @@ -64,7 +64,7 @@ type Driver interface { DeleteVirtualSwitch(string) error - CreateVirtualMachine(string, string, int64, int64, string, uint) error + CreateVirtualMachine(string, string, string, int64, int64, string, uint) error DeleteVirtualMachine(string) error diff --git a/builder/hyperv/common/driver_ps_4.go b/builder/hyperv/common/driver_ps_4.go index b608c2afd..bcdb9ca53 100644 --- a/builder/hyperv/common/driver_ps_4.go +++ b/builder/hyperv/common/driver_ps_4.go @@ -166,8 +166,8 @@ func (d *HypervPS4Driver) CreateVirtualSwitch(switchName string, switchType stri return hyperv.CreateVirtualSwitch(switchName, switchType) } -func (d *HypervPS4Driver) CreateVirtualMachine(vmName string, path string, ram int64, diskSize int64, switchName string, generation uint) error { - return hyperv.CreateVirtualMachine(vmName, path, ram, diskSize, switchName, generation) +func (d *HypervPS4Driver) CreateVirtualMachine(vmName string, path string, vhdPath string, ram int64, diskSize int64, switchName string, generation uint) error { + return hyperv.CreateVirtualMachine(vmName, path, vhdPath, ram, diskSize, switchName, generation) } func (d *HypervPS4Driver) DeleteVirtualMachine(vmName string) error { diff --git a/builder/hyperv/common/step_create_tempdir.go b/builder/hyperv/common/step_create_tempdir.go index c1ca46fa2..56215a742 100644 --- a/builder/hyperv/common/step_create_tempdir.go +++ b/builder/hyperv/common/step_create_tempdir.go @@ -10,8 +10,9 @@ import ( ) type StepCreateTempDir struct { - TempPath string - dirPath string + TempPath string + VhdTempPath string + dirPath string } func (s *StepCreateTempDir) Run(state multistep.StateBag) multistep.StepAction { @@ -34,6 +35,22 @@ func (s *StepCreateTempDir) Run(state multistep.StateBag) multistep.StepAction { s.dirPath = packerTempDir state.Put("packerTempDir", packerTempDir) + if s.VhdTempPath == "" { + // Fall back to regular temp dir if no separate VHD temp dir set. + state.Put("packerVhdTempDir", packerTempDir) + } else { + packerVhdTempDir, err := ioutil.TempDir(s.VhdTempPath, "packerhv-vhd") + if err != nil { + err := fmt.Errorf("Error creating temporary VHD directory: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + s.dirPath = packerVhdTempDir + state.Put("packerVhdTempDir", packerVhdTempDir) + } + // ui.Say("packerTempDir = '" + packerTempDir + "'") return multistep.ActionContinue diff --git a/builder/hyperv/common/step_create_vm.go b/builder/hyperv/common/step_create_vm.go index 13dd37e1f..351d17eb3 100644 --- a/builder/hyperv/common/step_create_vm.go +++ b/builder/hyperv/common/step_create_vm.go @@ -30,12 +30,13 @@ func (s *StepCreateVM) Run(state multistep.StateBag) multistep.StepAction { ui.Say("Creating virtual machine...") path := state.Get("packerTempDir").(string) + vhdPath := state.Get("packerVhdTempDir").(string) // convert the MB to bytes ramSize := int64(s.RamSize * 1024 * 1024) diskSize := int64(s.DiskSize * 1024 * 1024) - err := driver.CreateVirtualMachine(s.VMName, path, ramSize, diskSize, s.SwitchName, s.Generation) + err := driver.CreateVirtualMachine(s.VMName, path, vhdPath, ramSize, diskSize, s.SwitchName, s.Generation) if err != nil { err := fmt.Errorf("Error creating virtual machine: %s", err) state.Put("error", err) diff --git a/builder/hyperv/iso/builder.go b/builder/hyperv/iso/builder.go index 9b4065d8c..f7f206408 100644 --- a/builder/hyperv/iso/builder.go +++ b/builder/hyperv/iso/builder.go @@ -82,6 +82,11 @@ type Config struct { EnableVirtualizationExtensions bool `mapstructure:"enable_virtualization_extensions"` TempPath string `mapstructure:"temp_path"` + // A separate path can 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 path while exporting the VM) to eliminate a single-disk bottleneck. + VhdTempPath string `mapstructure:"vhd_temp_path"` + Communicator string `mapstructure:"communicator"` SkipCompaction bool `mapstructure:"skip_compaction"` @@ -296,7 +301,8 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe steps := []multistep.Step{ &hypervcommon.StepCreateTempDir{ - TempPath: b.config.TempPath, + TempPath: b.config.TempPath, + VhdTempPath: b.config.VhdTempPath, }, &hypervcommon.StepOutputDir{ Force: b.config.PackerForce, diff --git a/common/powershell/hyperv/hyperv.go b/common/powershell/hyperv/hyperv.go index 6e2b9dc7e..4a0982982 100644 --- a/common/powershell/hyperv/hyperv.go +++ b/common/powershell/hyperv/hyperv.go @@ -187,27 +187,27 @@ Set-VMFloppyDiskDrive -VMName $vmName -Path $null return err } -func CreateVirtualMachine(vmName string, path string, ram int64, diskSize int64, switchName string, generation uint) error { +func CreateVirtualMachine(vmName string, path string, vhdRoot string, ram int64, diskSize int64, switchName string, generation uint) error { if generation == 2 { var script = ` -param([string]$vmName, [string]$path, [long]$memoryStartupBytes, [long]$newVHDSizeBytes, [string]$switchName, [int]$generation) +param([string]$vmName, [string]$path, [string]$vhdRoot, [long]$memoryStartupBytes, [long]$newVHDSizeBytes, [string]$switchName, [int]$generation) $vhdx = $vmName + '.vhdx' -$vhdPath = Join-Path -Path $path -ChildPath $vhdx +$vhdPath = Join-Path -Path $vhdRoot -ChildPath $vhdx New-VM -Name $vmName -Path $path -MemoryStartupBytes $memoryStartupBytes -NewVHDPath $vhdPath -NewVHDSizeBytes $newVHDSizeBytes -SwitchName $switchName -Generation $generation ` var ps powershell.PowerShellCmd - err := ps.Run(script, vmName, path, strconv.FormatInt(ram, 10), strconv.FormatInt(diskSize, 10), switchName, strconv.FormatInt(int64(generation), 10)) + err := ps.Run(script, vmName, path, vhdRoot, strconv.FormatInt(ram, 10), strconv.FormatInt(diskSize, 10), switchName, strconv.FormatInt(int64(generation), 10)) return err } else { var script = ` -param([string]$vmName, [string]$path, [long]$memoryStartupBytes, [long]$newVHDSizeBytes, [string]$switchName) +param([string]$vmName, [string]$path, [string]$vhdRoot, [long]$memoryStartupBytes, [long]$newVHDSizeBytes, [string]$switchName) $vhdx = $vmName + '.vhdx' -$vhdPath = Join-Path -Path $path -ChildPath $vhdx +$vhdPath = Join-Path -Path $vhdRoot -ChildPath $vhdx New-VM -Name $vmName -Path $path -MemoryStartupBytes $memoryStartupBytes -NewVHDPath $vhdPath -NewVHDSizeBytes $newVHDSizeBytes -SwitchName $switchName ` var ps powershell.PowerShellCmd - err := ps.Run(script, vmName, path, strconv.FormatInt(ram, 10), strconv.FormatInt(diskSize, 10), switchName) + err := ps.Run(script, vmName, path, vhdRoot, strconv.FormatInt(ram, 10), strconv.FormatInt(diskSize, 10), switchName) if err != nil { return err