From 55ae8038523db36e2d637763d7f75d1383b51076 Mon Sep 17 00:00:00 2001 From: William Brooks Date: Sun, 9 Feb 2020 13:08:22 -0600 Subject: [PATCH] Add Hyper-V support for Gen-1 boot order with ISO --- builder/hyperv/common/config.go | 7 +++++++ builder/hyperv/common/driver.go | 2 +- builder/hyperv/common/driver_ps_4.go | 4 ++-- builder/hyperv/common/step_mount_dvddrive.go | 3 ++- builder/hyperv/iso/builder.go | 3 ++- builder/hyperv/vmcx/builder.go | 3 ++- common/powershell/hyperv/hyperv.go | 12 ++++++++++-- 7 files changed, 26 insertions(+), 8 deletions(-) diff --git a/builder/hyperv/common/config.go b/builder/hyperv/common/config.go index 152868e1d..1cba3e393 100644 --- a/builder/hyperv/common/config.go +++ b/builder/hyperv/common/config.go @@ -148,6 +148,13 @@ type CommonConfig struct { // built. When this value is set to true, the machine will start without a // console. Headless bool `mapstructure:"headless" required:"false"` + // Over time the Hyper-V builder has been modified to change the original + // boot order that is used when an ISO is mounted. Hyper-V's default is to + // boot from the CD first, the original Hyper-V builder included code to + // codify this setting when the primary ISO is mounted, that code was eventually + // modified to place the IDE adapter before the the CD (only in generation 1). + // Setting this value to true, forces the original method of operation. + LegacyGen1BootOrder bool `mapstructure:"legacy_gen1_boot_order" required:"false"` } func (c *CommonConfig) Prepare(ctx *interpolate.Context, pc *common.PackerConfig) ([]error, []string) { diff --git a/builder/hyperv/common/driver.go b/builder/hyperv/common/driver.go index 29b282611..545596bee 100644 --- a/builder/hyperv/common/driver.go +++ b/builder/hyperv/common/driver.go @@ -111,7 +111,7 @@ type Driver interface { MountDvdDrive(string, string, uint, uint) error - SetBootDvdDrive(string, uint, uint, uint) error + SetBootDvdDrive(string, uint, uint, uint, bool) error UnmountDvdDrive(string, uint, uint) error diff --git a/builder/hyperv/common/driver_ps_4.go b/builder/hyperv/common/driver_ps_4.go index d365ae2e7..5b072a72e 100644 --- a/builder/hyperv/common/driver_ps_4.go +++ b/builder/hyperv/common/driver_ps_4.go @@ -263,8 +263,8 @@ func (d *HypervPS4Driver) MountDvdDrive(vmName string, path string, controllerNu } func (d *HypervPS4Driver) SetBootDvdDrive(vmName string, controllerNumber uint, controllerLocation uint, - generation uint) error { - return hyperv.SetBootDvdDrive(vmName, controllerNumber, controllerLocation, generation) + generation uint, legacyGen1BootOrder bool) error { + return hyperv.SetBootDvdDrive(vmName, controllerNumber, controllerLocation, generation, legacyGen1BootOrder) } func (d *HypervPS4Driver) UnmountDvdDrive(vmName string, controllerNumber uint, controllerLocation uint) error { diff --git a/builder/hyperv/common/step_mount_dvddrive.go b/builder/hyperv/common/step_mount_dvddrive.go index 88b084c6c..3f54bcbcb 100644 --- a/builder/hyperv/common/step_mount_dvddrive.go +++ b/builder/hyperv/common/step_mount_dvddrive.go @@ -13,6 +13,7 @@ import ( type StepMountDvdDrive struct { Generation uint + LegacyGen1BootOrder bool } func (s *StepMountDvdDrive) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { @@ -58,7 +59,7 @@ func (s *StepMountDvdDrive) Run(ctx context.Context, state multistep.StateBag) m state.Put("os.dvd.properties", dvdControllerProperties) ui.Say(fmt.Sprintf("Setting boot drive to os dvd drive %s ...", isoPath)) - err = driver.SetBootDvdDrive(vmName, controllerNumber, controllerLocation, s.Generation) + err = driver.SetBootDvdDrive(vmName, controllerNumber, controllerLocation, s.Generation, s.LegacyGen1BootOrder) if err != nil { err := fmt.Errorf(errorMsg, err) state.Put("error", err) diff --git a/builder/hyperv/iso/builder.go b/builder/hyperv/iso/builder.go index 2990ea9c6..a39da7b7b 100644 --- a/builder/hyperv/iso/builder.go +++ b/builder/hyperv/iso/builder.go @@ -242,7 +242,8 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack &hypervcommon.StepEnableIntegrationService{}, &hypervcommon.StepMountDvdDrive{ - Generation: b.config.Generation, + Generation: b.config.Generation, + LegacyGen1BootOrder: b.config.LegacyGen1BootOrder, }, &hypervcommon.StepMountFloppydrive{ Generation: b.config.Generation, diff --git a/builder/hyperv/vmcx/builder.go b/builder/hyperv/vmcx/builder.go index d07bf8b02..f151354a6 100644 --- a/builder/hyperv/vmcx/builder.go +++ b/builder/hyperv/vmcx/builder.go @@ -282,7 +282,8 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack &hypervcommon.StepEnableIntegrationService{}, &hypervcommon.StepMountDvdDrive{ - Generation: b.config.Generation, + Generation: b.config.Generation, + LegacyGen1BootOrder: b.config.LegacyGen1BootOrder, }, &hypervcommon.StepMountFloppydrive{ Generation: b.config.Generation, diff --git a/common/powershell/hyperv/hyperv.go b/common/powershell/hyperv/hyperv.go index a80624609..6aa8726c0 100644 --- a/common/powershell/hyperv/hyperv.go +++ b/common/powershell/hyperv/hyperv.go @@ -156,13 +156,21 @@ Hyper-V\Set-VMDvdDrive -VMName $vmName -ControllerNumber $controllerNumber -Cont return err } -func SetBootDvdDrive(vmName string, controllerNumber uint, controllerLocation uint, generation uint) error { +func SetBootDvdDrive(vmName string, controllerNumber uint, controllerLocation uint, generation uint, legacyGen1BootOrder bool) error { if generation < 2 { - script := ` + var script string + if (legacyGen1BootOrder) { + script = ` +param([string]$vmName) +Hyper-V\Set-VMBios -VMName $vmName -StartupOrder @("CD","IDE","LegacyNetworkAdapter","Floppy") +` + } else { + script = ` param([string]$vmName) Hyper-V\Set-VMBios -VMName $vmName -StartupOrder @("IDE","CD","LegacyNetworkAdapter","Floppy") ` + } var ps powershell.PowerShellCmd err := ps.Run(script, vmName) return err