From 87b3dec3d20e1d659788356a918708fbbd385b10 Mon Sep 17 00:00:00 2001 From: Taliesin Sisson Date: Sun, 21 Jun 2015 19:35:32 +0100 Subject: [PATCH] Wait until WinRM is available, before continuing with install. This is how other system like VeeWee do it. Add support for number of cpus to use for vm Add support for vm generation --- builder/hyperv/common/step_create_vm.go | 24 ++++++++++---- .../step_wait_for_install_to_complete.go | 17 ---------- builder/hyperv/iso/builder.go | 31 +++++++++++-------- powershell/hyperv/hyperv.go | 20 +++++++++--- 4 files changed, 52 insertions(+), 40 deletions(-) diff --git a/builder/hyperv/common/step_create_vm.go b/builder/hyperv/common/step_create_vm.go index 6a172ada8..1ea4530d8 100644 --- a/builder/hyperv/common/step_create_vm.go +++ b/builder/hyperv/common/step_create_vm.go @@ -6,10 +6,10 @@ package common import ( "fmt" - "strconv" "github.com/mitchellh/multistep" "github.com/mitchellh/packer/packer" "github.com/mitchellh/packer/powershell/hyperv" + "strconv" ) // This step creates the actual virtual machine. @@ -17,17 +17,19 @@ import ( // Produces: // VMName string - The name of the VM type StepCreateVM struct { - VMName string + VMName string SwitchName string - RamSizeMB uint - DiskSize uint + RamSizeMB uint + DiskSize uint + Generation uint + Cpu uint } func (s *StepCreateVM) Run(state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) ui.Say("Creating virtual machine...") - path := state.Get("packerTempDir").(string) + path := state.Get("packerTempDir").(string) // convert the MB to bytes ramBytes := int64(s.RamSizeMB * 1024 * 1024) @@ -36,8 +38,10 @@ func (s *StepCreateVM) Run(state multistep.StateBag) multistep.StepAction { ram := strconv.FormatInt(ramBytes, 10) diskSize := strconv.FormatInt(diskSizeBytes, 10) switchName := s.SwitchName + generation := strconv.FormatInt(int64(s.Generation), 10) + cpu := strconv.FormatInt(int64(s.Cpu), 10) - err := hyperv.CreateVirtualMachine(s.VMName, path, ram, diskSize, switchName) + err := hyperv.CreateVirtualMachine(s.VMName, path, ram, diskSize, switchName, generation) if err != nil { err := fmt.Errorf("Error creating virtual machine: %s", err) state.Put("error", err) @@ -45,6 +49,14 @@ func (s *StepCreateVM) Run(state multistep.StateBag) multistep.StepAction { return multistep.ActionHalt } + err = hyperv.SetVirtualMachineCpu(s.VMName, cpu) + if err != nil { + err := fmt.Errorf("Error creating setting virtual machine cpu: %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_wait_for_install_to_complete.go b/builder/hyperv/common/step_wait_for_install_to_complete.go index 22da371c8..efd8bd8b7 100644 --- a/builder/hyperv/common/step_wait_for_install_to_complete.go +++ b/builder/hyperv/common/step_wait_for_install_to_complete.go @@ -111,20 +111,3 @@ func (s *StepWaitForInstallToComplete) Run(state multistep.StateBag) multistep.S func (s *StepWaitForInstallToComplete) Cleanup(state multistep.StateBag) { } - - -type StepWaitForWinRm struct { -} - -func (s *StepWaitForWinRm) Run(state multistep.StateBag) multistep.StepAction { - ui := state.Get("ui").(packer.Ui) - //vmName := state.Get("vmName").(string) - - ui.Say("Waiting for WinRM to be ready...") - - return multistep.ActionContinue -} - -func (s *StepWaitForWinRm) Cleanup(state multistep.StateBag) { - -} diff --git a/builder/hyperv/iso/builder.go b/builder/hyperv/iso/builder.go index f9501511e..cf7e776a0 100644 --- a/builder/hyperv/iso/builder.go +++ b/builder/hyperv/iso/builder.go @@ -96,6 +96,8 @@ type Config struct { VMName string `mapstructure:"vm_name"` SwitchName string `mapstructure:"switch_name"` + Cpu uint `mapstructure:"cpu"` + Generation uint `mapstructure:"generation"` Communicator string `mapstructure:"communicator"` @@ -155,6 +157,14 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { } } + if b.config.Cpu < 1 { + b.config.Cpu = 1 + } + + if b.config.Generation != 2 { + b.config.Generation = 1 + } + log.Println(fmt.Sprintf("Using switch %s", b.config.SwitchName)) log.Println(fmt.Sprintf("%s: %v", "SwitchName", b.config.SwitchName)) @@ -269,6 +279,8 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe SwitchName: b.config.SwitchName, RamSizeMB: b.config.RamSizeMB, DiskSize: b.config.DiskSize, + Generation: b.config.Generation, + Cpu: b.config.Cpu, }, &hypervcommon.StepEnableIntegrationService{}, @@ -283,19 +295,6 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe Reason: "OS installation", }, - // wait for the vm to be powered off - &hypervcommon.StepWaitForPowerOff{}, - - // remove the integration services dvd drive - // after we power down - &hypervcommon.StepUnmountSecondaryDvdImages{}, - - // - &hypervcommon.StepStartVm{ - Reason: "provisioning", - StartUpDelay: 60, - }, - // configure the communicator ssh, winrm &communicator.StepConnect{ Config: &b.config.SSHConfig.Comm, @@ -306,6 +305,9 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe // provision requires communicator to be setup &common.StepProvision{}, + // remove the integration services dvd drive + // after we power down + &hypervcommon.StepUnmountSecondaryDvdImages{}, &hypervcommon.StepUnmountFloppyDrive{}, &hypervcommon.StepUnmountDvdDrive{}, @@ -314,6 +316,9 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe Timeout: b.config.ShutdownTimeout, }, + // wait for the vm to be powered off + &hypervcommon.StepWaitForPowerOff{}, + &hypervcommon.StepExportVm{ OutputDir: b.config.OutputDir, }, diff --git a/powershell/hyperv/hyperv.go b/powershell/hyperv/hyperv.go index afddc928b..250722eff 100644 --- a/powershell/hyperv/hyperv.go +++ b/powershell/hyperv/hyperv.go @@ -74,17 +74,29 @@ Set-VMFloppyDiskDrive -VMName $vmName -Path $null return err } -func CreateVirtualMachine(vmName string, path string, ram string, diskSize string, switchName string) error { +func CreateVirtualMachine(vmName string, path string, ram string, diskSize string, switchName string, generation string) error { var script = ` -param([string]$vmName, [string]$path, [long]$memoryStartupBytes, [long]$newVHDSizeBytes, [string]$switchName) +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 +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) + err := ps.Run(script, vmName, path, ram, diskSize, switchName, generation) + return err +} + +func SetVirtualMachineCpu(vmName string, cpu string) error { + + var script = ` +param([string]$vmName, [int]cpu) +Set-VMProcessor -VMName $vmName –Count $cpu +` + + var ps powershell.PowerShellCmd + err := ps.Run(script, vmName, cpu) return err }