From 02db76801861a74d1367828da5dc9a1f56fe08b3 Mon Sep 17 00:00:00 2001 From: Taliesin Sisson Date: Mon, 29 Jun 2015 21:18:25 +0100 Subject: [PATCH] With generation 2 machine by default a dvd drive is not created. So create a dvd drive for os if it does not exist. Allow secure boot mode to be configured from config. --- builder/hyperv/common/step_create_vm.go | 14 ++++++- builder/hyperv/common/step_mount_dvddrive.go | 33 ++++++++++++++-- builder/hyperv/iso/builder.go | 22 ++++++----- powershell/hyperv/hyperv.go | 40 ++++++++++++++++---- 4 files changed, 88 insertions(+), 21 deletions(-) diff --git a/builder/hyperv/common/step_create_vm.go b/builder/hyperv/common/step_create_vm.go index 1ea4530d8..6418dbea0 100644 --- a/builder/hyperv/common/step_create_vm.go +++ b/builder/hyperv/common/step_create_vm.go @@ -23,6 +23,7 @@ type StepCreateVM struct { DiskSize uint Generation uint Cpu uint + EnabeSecureBoot bool } func (s *StepCreateVM) Run(state multistep.StateBag) multistep.StepAction { @@ -40,6 +41,7 @@ func (s *StepCreateVM) Run(state multistep.StateBag) multistep.StepAction { switchName := s.SwitchName generation := strconv.FormatInt(int64(s.Generation), 10) cpu := strconv.FormatInt(int64(s.Cpu), 10) + enabeSecureBoot := s.EnabeSecureBoot err := hyperv.CreateVirtualMachine(s.VMName, path, ram, diskSize, switchName, generation) if err != nil { @@ -48,7 +50,7 @@ func (s *StepCreateVM) Run(state multistep.StateBag) multistep.StepAction { ui.Error(err.Error()) return multistep.ActionHalt } - + err = hyperv.SetVirtualMachineCpu(s.VMName, cpu) if err != nil { err := fmt.Errorf("Error creating setting virtual machine cpu: %s", err) @@ -56,6 +58,16 @@ func (s *StepCreateVM) Run(state multistep.StateBag) multistep.StepAction { ui.Error(err.Error()) return multistep.ActionHalt } + + if generation == "2" { + err = hyperv.SetSecureBoot(s.VMName, enabeSecureBoot) + if err != nil { + err := fmt.Errorf("Error setting secure boot: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + } // Set the final name in the state bag so others can use it state.Put("vmName", s.VMName) diff --git a/builder/hyperv/common/step_mount_dvddrive.go b/builder/hyperv/common/step_mount_dvddrive.go index d5e9b4ef3..8077dd7d1 100644 --- a/builder/hyperv/common/step_mount_dvddrive.go +++ b/builder/hyperv/common/step_mount_dvddrive.go @@ -8,13 +8,13 @@ import ( "fmt" "github.com/mitchellh/multistep" "github.com/mitchellh/packer/packer" + powershell "github.com/mitchellh/packer/powershell" "github.com/mitchellh/packer/powershell/hyperv" ) - type StepMountDvdDrive struct { RawSingleISOUrl string - path string + path string } func (s *StepMountDvdDrive) Run(state multistep.StateBag) multistep.StepAction { @@ -25,9 +25,36 @@ func (s *StepMountDvdDrive) Run(state multistep.StateBag) multistep.StepAction { vmName := state.Get("vmName").(string) isoPath := s.RawSingleISOUrl + // Check that there is a virtual dvd drive + var script powershell.ScriptBuilder + powershell := new(powershell.PowerShellCmd) + + script.Reset() + script.WriteLine("param([string]$vmName)") + script.WriteLine("(Get-VMDvdDrive -VMName $vmName).ControllerNumber") + controllerNumber, err := powershell.Output(script.String(), vmName) + if err != nil { + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + if controllerNumber == "" { + // Add a virtual dvd drive as there is none + script.Reset() + script.WriteLine("param([string]$vmName)") + script.WriteLine("Add-VMDvdDrive -VMName $vmName") + err = powershell.Run(script.String(), vmName) + if err != nil { + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + } + ui.Say("Mounting dvd drive...") - err := hyperv.MountDvdDrive(vmName, isoPath) + err = hyperv.MountDvdDrive(vmName, isoPath) 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 89f98ef83..010b06cc7 100644 --- a/builder/hyperv/iso/builder.go +++ b/builder/hyperv/iso/builder.go @@ -95,10 +95,11 @@ type Config struct { // By default this is "packer-BUILDNAME", where "BUILDNAME" is the name of the build. VMName string `mapstructure:"vm_name"` - BootCommand []string `mapstructure:"boot_command"` - SwitchName string `mapstructure:"switch_name"` - Cpu uint `mapstructure:"cpu"` - Generation uint `mapstructure:"generation"` + BootCommand []string `mapstructure:"boot_command"` + SwitchName string `mapstructure:"switch_name"` + Cpu uint `mapstructure:"cpu"` + Generation uint `mapstructure:"generation"` + EnableSecureBoot bool `mapstructure:"enable_secure_boot"` Communicator string `mapstructure:"communicator"` @@ -285,12 +286,13 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe SwitchName: b.config.SwitchName, }, &hypervcommon.StepCreateVM{ - VMName: b.config.VMName, - SwitchName: b.config.SwitchName, - RamSizeMB: b.config.RamSizeMB, - DiskSize: b.config.DiskSize, - Generation: b.config.Generation, - Cpu: b.config.Cpu, + VMName: b.config.VMName, + SwitchName: b.config.SwitchName, + RamSizeMB: b.config.RamSizeMB, + DiskSize: b.config.DiskSize, + Generation: b.config.Generation, + Cpu: b.config.Cpu, + EnabeSecureBoot: b.config.EnableSecureBoot, }, &hypervcommon.StepEnableIntegrationService{}, diff --git a/powershell/hyperv/hyperv.go b/powershell/hyperv/hyperv.go index 1a2c5956a..f1581b4d9 100644 --- a/powershell/hyperv/hyperv.go +++ b/powershell/hyperv/hyperv.go @@ -98,16 +98,27 @@ Set-VMFloppyDiskDrive -VMName $vmName -Path $null func CreateVirtualMachine(vmName string, path string, ram string, diskSize string, switchName string, generation string) error { - var script = ` + if generation == "2" { + var script = ` param([string]$vmName, [string]$path, [long]$memoryStartupBytes, [long]$newVHDSizeBytes, [string]$switchName, [int]$generation) $vhdx = $vmName + '.vhdx' $vhdPath = Join-Path -Path $path -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, ram, diskSize, switchName, generation) - return err + var ps powershell.PowerShellCmd + err := ps.Run(script, vmName, path, ram, diskSize, switchName, generation) + return err + } else { + var script = ` +param([string]$vmName, [string]$path, [long]$memoryStartupBytes, [long]$newVHDSizeBytes, [string]$switchName) +$vhdx = $vmName + '.vhdx' +$vhdPath = Join-Path -Path $path -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, ram, diskSize, switchName) + return err + } } func SetVirtualMachineCpu(vmName string, cpu string) error { @@ -122,6 +133,23 @@ Set-VMProcessor -VMName $vmName -Count $cpu return err } +func SetSecureBoot(vmName string, enable bool) error { + var script = ` +param([string]$vmName, $enableSecureBoot) +Set-VMFirmware -VMName $vmName -EnableSecureBoot $enableSecureBoot +` + + var ps powershell.PowerShellCmd + + enableSecureBoot := "Off" + if enable { + enableSecureBoot = "On" + } + + err := ps.Run(script, vmName, enableSecureBoot) + return err +} + func DeleteVirtualMachine(vmName string) error { var script = ` @@ -635,8 +663,6 @@ param([string]$vmName, [string]$scanCodes) $vmConsole.TypeScancodes($_) } } - - ` var ps powershell.PowerShellCmd