func (s *StepWaitForPowerOff) Run(state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) vmName := state.Get("vmName").(string) ui.Say("Waiting for vm to be powered down...") var script powershell.ScriptBuilder script.WriteLine("param([string]$vmName)") script.WriteLine("(Get-VM -Name $vmName).State -eq [Microsoft.HyperV.PowerShell.VMState]::Off") isOffScript := script.String() for { powershell := new(powershell.PowerShellCmd) cmdOut, err := powershell.Output(isOffScript, vmName) if err != nil { err := fmt.Errorf("Error checking VM's state: %s", err) state.Put("error", err) ui.Error(err.Error()) return multistep.ActionHalt } if cmdOut == "True" { break } else { time.Sleep(time.Second * SleepSeconds) } } return multistep.ActionContinue }
func (s *StepUpdateIntegrationServices) Cleanup(state multistep.StateBag) { vmName := state.Get("vmName").(string) var script powershell.ScriptBuilder script.WriteLine("param([string]$vmName)") script.WriteLine("Set-VMDvdDrive -VMName $vmName -Path $null") powershell := new(powershell.PowerShellCmd) _ = powershell.Run(script.String(), vmName) }
func (s *StepWaitForInstallToComplete) Run(state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) vmName := state.Get("vmName").(string) if len(s.ActionName) > 0 { ui.Say(fmt.Sprintf("%v ! Waiting for VM to reboot %v times...", s.ActionName, s.ExpectedRebootCount)) } var rebootCount uint var lastUptime uint64 var script powershell.ScriptBuilder script.WriteLine("param([string]$vmName)") script.WriteLine("(Get-VM -Name $vmName).Uptime.TotalSeconds") uptimeScript := script.String() for rebootCount < s.ExpectedRebootCount { powershell := new(powershell.PowerShellCmd) cmdOut, err := powershell.Output(uptimeScript, vmName) if err != nil { err := fmt.Errorf("Error checking uptime: %s", err) state.Put("error", err) ui.Error(err.Error()) return multistep.ActionHalt } uptime, _ := strconv.ParseUint(strings.TrimSpace(string(cmdOut)), 10, 64) if uint64(uptime) < lastUptime { rebootCount++ ui.Say(fmt.Sprintf("%v -> Detected reboot %v after %v seconds...", s.ActionName, rebootCount, lastUptime)) } lastUptime = uptime if rebootCount < s.ExpectedRebootCount { time.Sleep(time.Second * SleepSeconds) } } return multistep.ActionContinue }
func (s *StepUnmountSecondaryDvdImages) Run(state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) ui.Say("Unmounting Integration Services Setup Disk...") vmName := state.Get("vmName").(string) // todo: should this message say removing the dvd? dvdProperties := state.Get("secondary.dvd.properties").([]DvdControllerProperties) log.Println(fmt.Sprintf("Found DVD properties %s", len(dvdProperties))) for _, dvdProperty := range dvdProperties { controllerNumber := dvdProperty.ControllerNumber controllerLocation := dvdProperty.ControllerLocation var script powershell.ScriptBuilder powershell := new(powershell.PowerShellCmd) script.WriteLine("param([string]$vmName,[int]$controllerNumber,[int]$controllerLocation)") script.WriteLine("$vmDvdDrive = Get-VMDvdDrive -VMName $vmName -ControllerNumber $controllerNumber -ControllerLocation $controllerLocation") script.WriteLine("if (!$vmDvdDrive) {throw 'unable to find dvd drive'}") script.WriteLine("Remove-VMDvdDrive -VMName $vmName -ControllerNumber $controllerNumber -ControllerLocation $controllerLocation") err := powershell.Run(script.String(), vmName, controllerNumber, controllerLocation) if err != nil { state.Put("error", err) ui.Error(err.Error()) return multistep.ActionHalt } } return multistep.ActionContinue }
func (s *StepMountDvdDrive) Run(state multistep.StateBag) multistep.StepAction { //driver := state.Get("driver").(Driver) ui := state.Get("ui").(packer.Ui) errorMsg := "Error mounting dvd drive: %s" 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") script.WriteLine("$dvdDrive = Get-VMDvdDrive -VMName $vmName | Select-Object -first 1") script.WriteLine("Set-VMFirmware -VMName $vmName -FirstBootDevice $dvdDrive") 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) if err != nil { err := fmt.Errorf(errorMsg, err) state.Put("error", err) ui.Error(err.Error()) return multistep.ActionHalt } s.path = isoPath return multistep.ActionContinue }
func (s *StepUpdateIntegrationServices) mountIntegrationServicesSetupDisk(vmName string) (dvdDriveProperties, error) { var dvdProperties dvdDriveProperties var script powershell.ScriptBuilder script.WriteLine("param([string]$vmName)") script.WriteLine("Add-VMDvdDrive -VMName $vmName") powershell := new(powershell.PowerShellCmd) err := powershell.Run(script.String(), vmName) if err != nil { return dvdProperties, err } script.Reset() script.WriteLine("param([string]$vmName)") script.WriteLine("(Get-VMDvdDrive -VMName $vmName | Where-Object {$_.Path -eq $null}).ControllerLocation") controllerLocation, err := powershell.Output(script.String(), vmName) if err != nil { return dvdProperties, err } script.Reset() script.WriteLine("param([string]$vmName)") script.WriteLine("(Get-VMDvdDrive -VMName $vmName | Where-Object {$_.Path -eq $null}).ControllerNumber") controllerNumber, err := powershell.Output(script.String(), vmName) if err != nil { return dvdProperties, err } isoPath := os.Getenv("WINDIR") + "\\system32\\vmguest.iso" script.Reset() script.WriteLine("param([string]$vmName,[string]$path,[string]$controllerNumber,[string]$controllerLocation)") script.WriteLine("Set-VMDvdDrive -VMName $vmName -Path $path -ControllerNumber $controllerNumber -ControllerLocation $controllerLocation") err = powershell.Run(script.String(), vmName, isoPath, controllerNumber, controllerLocation) if err != nil { return dvdProperties, err } dvdProperties.ControllerNumber = controllerNumber dvdProperties.ControllerLocation = controllerLocation return dvdProperties, err }
func (s *StepMountSecondaryDvdImages) addAndMountDvdDisk(vmName string, isoPath string) (DvdControllerProperties, error) { var properties DvdControllerProperties var script powershell.ScriptBuilder powershell := new(powershell.PowerShellCmd) controllerNumber := "0" if s.Generation < 2 { // get the controller number that the OS install disk is mounted on // generation 1 requires dvd to be added to ide controller, generation 2 uses scsi for dvd drives script.Reset() script.WriteLine("param([string]$vmName)") script.WriteLine("$dvdDrives = (Get-VMDvdDrive -VMName $vmName)") script.WriteLine("$lastControllerNumber = $dvdDrives | Sort-Object ControllerNumber | Select-Object -Last 1 | %{$_.ControllerNumber}") script.WriteLine("if (!$lastControllerNumber) {") script.WriteLine(" $lastControllerNumber = 0") script.WriteLine("} elseif (!$lastControllerNumber -or ($dvdDrives | ?{ $_.ControllerNumber -eq $lastControllerNumber} | measure).count -gt 1) {") script.WriteLine(" $lastControllerNumber += 1") script.WriteLine("}") script.WriteLine("$lastControllerNumber") controllerNumber, err := powershell.Output(script.String(), vmName) if err != nil { return properties, err } if controllerNumber != "0" || controllerNumber != "1" { //There are only 2 ide controllers, try to use the one the hdd is attached too controllerNumber = "0" } } script.Reset() script.WriteLine("param([string]$vmName,[int]$controllerNumber)") script.WriteLine("Add-VMDvdDrive -VMName $vmName -ControllerNumber $controllerNumber") err := powershell.Run(script.String(), vmName, controllerNumber) if err != nil { return properties, err } // we could try to get the controller location and number in one call, but this way we do not // need to parse the output script.Reset() script.WriteLine("param([string]$vmName)") script.WriteLine("(Get-VMDvdDrive -VMName $vmName | Where-Object {$_.Path -eq $null}).ControllerLocation") controllerLocation, err := powershell.Output(script.String(), vmName) if err != nil { return properties, err } script.Reset() script.WriteLine("param([string]$vmName,[string]$path,[string]$controllerNumber,[string]$controllerLocation)") script.WriteLine("Set-VMDvdDrive -VMName $vmName -Path $path -ControllerNumber $controllerNumber -ControllerLocation $controllerLocation") err = powershell.Run(script.String(), vmName, isoPath, controllerNumber, controllerLocation) if err != nil { return properties, err } log.Println(fmt.Sprintf("ISO %s mounted on DVD controller %v, location %v", isoPath, controllerNumber, controllerLocation)) properties.ControllerNumber = controllerNumber properties.ControllerLocation = controllerLocation return properties, nil }