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 *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 *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)
}
Example #4
0
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 *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 *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
}