Make use of driver instead of directly referencing hyper

Move inline powershell to hyperv
This commit is contained in:
Taliesin Sisson 2015-10-30 08:23:30 +00:00
parent cd6213eb55
commit 422efeeaf6
20 changed files with 432 additions and 246 deletions

View File

@ -15,6 +15,12 @@ type Driver interface {
// Checks if the VM named is running.
IsRunning(string) (bool, error)
// Checks if the VM named is off.
IsOff(string) (bool, error)
//How long has VM been on
Uptime(vmName string) (uint64, error)
// Start starts a VM specified by the name given.
Start(string) error
@ -32,9 +38,63 @@ type Driver interface {
// Finds the IP address of a VM connected that uses DHCP by its MAC address
IpAddress(string) (string, error)
// Finds the hostname for the ip address
GetHostName(string) (string, error)
// Finds the IP address of a host adapter connected to switch
GetHostAdapterIpAddressForSwitch(string) (string, error)
// Type scan codes to virtual keyboard of vm
TypeScanCodes(string, string) error
//Get the ip address for network adaptor
GetVirtualMachineNetworkAdapterAddress(string) (string, error)
//Set the vlan to use for switch
SetNetworkAdapterVlanId(string, string) error
//Set the vlan to use for machine
SetVirtualMachineVlanId(string, string) error
UntagVirtualMachineNetworkAdapterVlan(string, string) error
CreateExternalVirtualSwitch(string, string) error
GetVirtualMachineSwitchName(string) (string, error)
ConnectVirtualMachineNetworkAdapterToSwitch(string, string) error
CreateVirtualSwitch(string, string) (bool, error)
DeleteVirtualSwitch(string) error
CreateVirtualMachine(string, string, int64, int64, string, uint) error
DeleteVirtualMachine(string) error
SetVirtualMachineCpu(string, uint) error
SetSecureBoot(string, bool) error
EnableVirtualMachineIntegrationService(string, string) error
ExportVirtualMachine(string, string) error
CompactDisks(string, string) error
CopyExportedVirtualMachine(string, string, string, string) error
RestartVirtualMachine(string) error
CreateDvdDrive(string, uint) (uint, uint, error)
MountDvdDrive(string, string) error
MountDvdDriveByLocation(string, string, uint, uint) error
UnmountDvdDrive(string) error
DeleteDvdDrive(string, string, string) error
UnmountFloppyDrive(vmName string) error
}

View File

@ -39,6 +39,14 @@ func (d *HypervPS4Driver) IsRunning(vmName string) (bool, error) {
return hyperv.IsRunning(vmName)
}
func (d *HypervPS4Driver) IsOff(vmName string) (bool, error) {
return hyperv.IsOff(vmName)
}
func (d *HypervPS4Driver) Uptime(vmName string) (uint64, error) {
return hyperv.Uptime(vmName)
}
// Start starts a VM specified by the name given.
func (d *HypervPS4Driver) Start(vmName string) error {
return hyperv.StartVirtualMachine(vmName)
@ -97,6 +105,11 @@ func (d *HypervPS4Driver) IpAddress(mac string) (string, error) {
return res, err
}
// Get host name from ip address
func (d *HypervPS4Driver) GetHostName(ip string) (string, error) {
return powershell.GetHostName(ip)
}
// Finds the IP address of a host adapter connected to switch
func (d *HypervPS4Driver) GetHostAdapterIpAddressForSwitch(switchName string) (string, error) {
res, err := hyperv.GetHostAdapterIpAddressForSwitch(switchName)
@ -117,6 +130,105 @@ func (d *HypervPS4Driver) TypeScanCodes(vmName string, scanCodes string) error {
return hyperv.TypeScanCodes(vmName, scanCodes)
}
// Get network adapter address
func (d *HypervPS4Driver) GetVirtualMachineNetworkAdapterAddress(vmName string) (string, error) {
return hyperv.GetVirtualMachineNetworkAdapterAddress(vmName)
}
//Set the vlan to use for switch
func (d *HypervPS4Driver) SetNetworkAdapterVlanId(switchName string, vlanId string) error {
return hyperv.SetNetworkAdapterVlanId(switchName, vlanId)
}
//Set the vlan to use for machine
func (d *HypervPS4Driver) SetVirtualMachineVlanId(vmName string, vlanId string) error {
return hyperv.SetVirtualMachineVlanId(vmName, vlanId)
}
func (d *HypervPS4Driver) UntagVirtualMachineNetworkAdapterVlan(vmName string, switchName string) error {
return hyperv.UntagVirtualMachineNetworkAdapterVlan(vmName, switchName)
}
func (d *HypervPS4Driver) CreateExternalVirtualSwitch(vmName string, switchName string) error {
return hyperv.CreateExternalVirtualSwitch(vmName, switchName)
}
func (d *HypervPS4Driver) GetVirtualMachineSwitchName(vmName string) (string, error) {
return hyperv.GetVirtualMachineSwitchName(vmName)
}
func (d *HypervPS4Driver) ConnectVirtualMachineNetworkAdapterToSwitch(vmName string, switchName string) error {
return hyperv.ConnectVirtualMachineNetworkAdapterToSwitch(vmName, switchName)
}
func (d *HypervPS4Driver) DeleteVirtualSwitch(switchName string) error {
return hyperv.DeleteVirtualSwitch(switchName)
}
func (d *HypervPS4Driver) CreateVirtualSwitch(switchName string, switchType string) (bool, error) {
return hyperv.CreateVirtualSwitch(switchName, switchType)
}
func (d *HypervPS4Driver) CreateVirtualMachine(vmName string, path string, ram int64, diskSize int64, switchName string, generation uint) error {
return hyperv.CreateVirtualMachine(vmName, path, ram, diskSize, switchName, generation)
}
func (d *HypervPS4Driver) DeleteVirtualMachine(vmName string) error {
return hyperv.DeleteVirtualMachine(vmName)
}
func (d *HypervPS4Driver) SetVirtualMachineCpu(vmName string, cpu uint) error {
return hyperv.SetVirtualMachineCpu(vmName, cpu)
}
func (d *HypervPS4Driver) SetSecureBoot(vmName string, enable bool) error {
return hyperv.SetSecureBoot(vmName, enable)
}
func (d *HypervPS4Driver) EnableVirtualMachineIntegrationService(vmName string, integrationServiceName string) error {
return hyperv.EnableVirtualMachineIntegrationService(vmName, integrationServiceName)
}
func (d *HypervPS4Driver) ExportVirtualMachine(vmName string, path string) error {
return hyperv.ExportVirtualMachine(vmName, path)
}
func (d *HypervPS4Driver) CompactDisks(expPath string, vhdDir string) error {
return hyperv.CompactDisks(expPath, vhdDir)
}
func (d *HypervPS4Driver) CopyExportedVirtualMachine(expPath string, outputPath string, vhdDir string, vmDir string) error {
return hyperv.CopyExportedVirtualMachine(expPath, outputPath, vhdDir, vmDir)
}
func (d *HypervPS4Driver) RestartVirtualMachine(vmName string) error {
return hyperv.RestartVirtualMachine(vmName)
}
func (d *HypervPS4Driver) CreateDvdDrive(vmName string, generation uint) (uint, uint, error) {
return hyperv.CreateDvdDrive(vmName, generation)
}
func (d *HypervPS4Driver) MountDvdDrive(vmName string, path string) error {
return hyperv.MountDvdDrive(vmName, path)
}
func (d *HypervPS4Driver) MountDvdDriveByLocation(vmName string, path string, controllerNumber uint, controllerLocation uint) error {
return hyperv.MountDvdDriveByLocation(vmName, path, controllerNumber, controllerLocation)
}
func (d *HypervPS4Driver) UnmountDvdDrive(vmName string) error {
return hyperv.UnmountDvdDrive(vmName)
}
func (d *HypervPS4Driver) DeleteDvdDrive(vmName string, controllerNumber string, controllerLocation string) error {
return hyperv.DeleteDvdDrive(vmName, controllerNumber, controllerLocation)
}
func (d *HypervPS4Driver) UnmountFloppyDrive(vmName string) error {
return hyperv.UnmountFloppyDrive(vmName)
}
func (d *HypervPS4Driver) verifyPSVersion() error {
log.Printf("Enter method: %s", "verifyPSVersion")

View File

@ -8,19 +8,16 @@ import (
"fmt"
"github.com/mitchellh/multistep"
"github.com/mitchellh/packer/packer"
"log"
"strings"
"time"
"log"
powershell "github.com/mitchellh/packer/powershell"
"github.com/mitchellh/packer/powershell/hyperv"
)
type StepConfigureIp struct {
}
func (s *StepConfigureIp) Run(state multistep.StateBag) multistep.StepAction {
// driver := state.Get("driver").(Driver)
driver := state.Get("driver").(Driver)
ui := state.Get("ui").(packer.Ui)
errorMsg := "Error configuring ip address: %s"
@ -34,7 +31,7 @@ func (s *StepConfigureIp) Run(state multistep.StateBag) multistep.StepAction {
var ip string
for count != 0 {
cmdOut, err := hyperv.GetVirtualMachineNetworkAdapterAddress(vmName)
cmdOut, err := driver.GetVirtualMachineNetworkAdapterAddress(vmName)
if err != nil {
err := fmt.Errorf(errorMsg, err)
state.Put("error", err)
@ -45,7 +42,7 @@ func (s *StepConfigureIp) Run(state multistep.StateBag) multistep.StepAction {
ip = strings.TrimSpace(string(cmdOut))
if ip != "False" {
break;
break
}
log.Println(fmt.Sprintf("Waiting for another %v minutes...", uint(duration)))
@ -53,7 +50,7 @@ func (s *StepConfigureIp) Run(state multistep.StateBag) multistep.StepAction {
count--
}
if(count == 0){
if count == 0 {
err := fmt.Errorf(errorMsg, "IP address assigned to the adapter is empty")
state.Put("error", err)
ui.Error(err.Error())
@ -62,7 +59,7 @@ func (s *StepConfigureIp) Run(state multistep.StateBag) multistep.StepAction {
ui.Say("ip address is " + ip)
hostName, err := powershell.GetHostName(ip);
hostName, err := driver.GetHostName(ip)
if err != nil {
state.Put("error", err)
ui.Error(err.Error())
@ -80,4 +77,3 @@ func (s *StepConfigureIp) Run(state multistep.StateBag) multistep.StepAction {
func (s *StepConfigureIp) Cleanup(state multistep.StateBag) {
// do nothing
}

View File

@ -8,20 +8,14 @@ import (
"fmt"
"github.com/mitchellh/multistep"
"github.com/mitchellh/packer/packer"
"github.com/mitchellh/packer/powershell/hyperv"
)
const(
vlanId = "1724"
)
type StepConfigureVlan struct {
vlanId string
}
func (s *StepConfigureVlan) Run(state multistep.StateBag) multistep.StepAction {
//config := state.Get("config").(*config)
//driver := state.Get("driver").(Driver)
driver := state.Get("driver").(Driver)
ui := state.Get("ui").(packer.Ui)
errorMsg := "Error configuring vlan: %s"
@ -30,7 +24,13 @@ func (s *StepConfigureVlan) Run(state multistep.StateBag) multistep.StepAction {
ui.Say("Configuring vlan...")
err := hyperv.SetNetworkAdapterVlanId(switchName, vlanId)
vlanId := s.vlanId
if vlanId == "" {
vlanId = "1724"
}
err := driver.SetNetworkAdapterVlanId(switchName, vlanId)
if err != nil {
err := fmt.Errorf(errorMsg, err)
state.Put("error", err)
@ -38,7 +38,7 @@ func (s *StepConfigureVlan) Run(state multistep.StateBag) multistep.StepAction {
return multistep.ActionHalt
}
err = hyperv.SetVirtualMachineVlanId(vmName, vlanId)
err = driver.SetVirtualMachineVlanId(vmName, vlanId)
if err != nil {
err := fmt.Errorf(errorMsg, err)
state.Put("error", err)

View File

@ -5,11 +5,10 @@
package common
import (
"code.google.com/p/go-uuid/uuid"
"fmt"
"github.com/mitchellh/multistep"
"github.com/mitchellh/packer/packer"
"code.google.com/p/go-uuid/uuid"
"github.com/mitchellh/packer/powershell/hyperv"
)
// This step creates switch for VM.
@ -17,12 +16,12 @@ import (
// Produces:
// SwitchName string - The name of the Switch
type StepCreateExternalSwitch struct {
SwitchName string
SwitchName string
oldSwitchName string
}
func (s *StepCreateExternalSwitch) Run(state multistep.StateBag) multistep.StepAction {
//driver := state.Get("driver").(Driver)
driver := state.Get("driver").(Driver)
ui := state.Get("ui").(packer.Ui)
vmName := state.Get("vmName").(string)
@ -33,16 +32,16 @@ func (s *StepCreateExternalSwitch) Run(state multistep.StateBag) multistep.StepA
packerExternalSwitchName := "paes_" + uuid.New()
err = hyperv.CreateExternalVirtualSwitch(vmName, packerExternalSwitchName)
err = driver.CreateExternalVirtualSwitch(vmName, packerExternalSwitchName)
if err != nil {
err := fmt.Errorf("Error creating switch: %s", err)
state.Put(errorMsg, err)
ui.Error(err.Error())
s.SwitchName = "";
s.SwitchName = ""
return multistep.ActionHalt
}
switchName, err := hyperv.GetVirtualMachineSwitchName(vmName)
switchName, err := driver.GetVirtualMachineSwitchName(vmName)
if err != nil {
err := fmt.Errorf(errorMsg, err)
state.Put("error", err)
@ -59,10 +58,10 @@ func (s *StepCreateExternalSwitch) Run(state multistep.StateBag) multistep.StepA
ui.Say("External switch name is: '" + switchName + "'")
if(switchName != packerExternalSwitchName){
if switchName != packerExternalSwitchName {
s.SwitchName = ""
} else {
s.SwitchName = packerExternalSwitchName
s.SwitchName = packerExternalSwitchName
s.oldSwitchName = state.Get("SwitchName").(string)
}
@ -76,7 +75,7 @@ func (s *StepCreateExternalSwitch) Cleanup(state multistep.StateBag) {
if s.SwitchName == "" {
return
}
//driver := state.Get("driver").(Driver)
driver := state.Get("driver").(Driver)
ui := state.Get("ui").(packer.Ui)
vmName := state.Get("vmName").(string)
@ -92,7 +91,7 @@ func (s *StepCreateExternalSwitch) Cleanup(state multistep.StateBag) {
return
}
err = hyperv.ConnectVirtualMachineNetworkAdapterToSwitch(vmName, s.oldSwitchName)
err = driver.ConnectVirtualMachineNetworkAdapterToSwitch(vmName, s.oldSwitchName)
if err != nil {
ui.Error(fmt.Sprintf(errMsg, err))
return
@ -100,7 +99,7 @@ func (s *StepCreateExternalSwitch) Cleanup(state multistep.StateBag) {
state.Put("SwitchName", s.oldSwitchName)
err = hyperv.DeleteVirtualSwitch(s.SwitchName)
err = driver.DeleteVirtualSwitch(s.SwitchName)
if err != nil {
ui.Error(fmt.Sprintf(errMsg, err))
}

View File

@ -8,13 +8,12 @@ import (
"fmt"
"github.com/mitchellh/multistep"
"github.com/mitchellh/packer/packer"
"github.com/mitchellh/packer/powershell/hyperv"
)
const (
SwitchTypeInternal = "Internal"
SwitchTypePrivate = "Private"
DefaultSwitchType = SwitchTypeInternal
SwitchTypePrivate = "Private"
DefaultSwitchType = SwitchTypeInternal
)
// This step creates switch for VM.
@ -23,21 +22,21 @@ const (
// SwitchName string - The name of the Switch
type StepCreateSwitch struct {
// Specifies the name of the switch to be created.
SwitchName string
SwitchName string
// Specifies the type of the switch to be created. Allowed values are Internal and Private. To create an External
// virtual switch, specify either the NetAdapterInterfaceDescription or the NetAdapterName parameter, which
// implicitly set the type of the virtual switch to External.
SwitchType string
SwitchType string
// Specifies the name of the network adapter to be bound to the switch to be created.
NetAdapterName string
// Specifies the interface description of the network adapter to be bound to the switch to be created.
NetAdapterInterfaceDescription string
createdSwitch bool
createdSwitch bool
}
func (s *StepCreateSwitch) Run(state multistep.StateBag) multistep.StepAction {
//driver := state.Get("driver").(Driver)
driver := state.Get("driver").(Driver)
ui := state.Get("ui").(packer.Ui)
if len(s.SwitchType) == 0 {
@ -46,12 +45,12 @@ func (s *StepCreateSwitch) Run(state multistep.StateBag) multistep.StepAction {
ui.Say(fmt.Sprintf("Creating switch '%v' if required...", s.SwitchName))
createdSwitch, err := hyperv.CreateVirtualSwitch(s.SwitchName, s.SwitchType)
createdSwitch, err := driver.CreateVirtualSwitch(s.SwitchName, s.SwitchType)
if err != nil {
err := fmt.Errorf("Error creating switch: %s", err)
state.Put("error", err)
ui.Error(err.Error())
s.SwitchName = "";
s.SwitchName = ""
return multistep.ActionHalt
}
@ -72,11 +71,11 @@ func (s *StepCreateSwitch) Cleanup(state multistep.StateBag) {
return
}
//driver := state.Get("driver").(Driver)
driver := state.Get("driver").(Driver)
ui := state.Get("ui").(packer.Ui)
ui.Say("Unregistering and deleting switch...")
err := hyperv.DeleteVirtualSwitch(s.SwitchName)
err := driver.DeleteVirtualSwitch(s.SwitchName)
if err != nil {
ui.Error(fmt.Sprintf("Error deleting switch: %s", err))
}

View File

@ -8,8 +8,6 @@ import (
"fmt"
"github.com/mitchellh/multistep"
"github.com/mitchellh/packer/packer"
"github.com/mitchellh/packer/powershell/hyperv"
"strconv"
)
// This step creates the actual virtual machine.
@ -17,50 +15,47 @@ import (
// Produces:
// VMName string - The name of the VM
type StepCreateVM struct {
VMName string
SwitchName string
RamSizeMB uint
DiskSize uint
Generation uint
Cpu uint
VMName string
SwitchName string
RamSizeMB uint
DiskSize uint
Generation uint
Cpu uint
EnabeSecureBoot bool
}
func (s *StepCreateVM) Run(state multistep.StateBag) multistep.StepAction {
driver := state.Get("driver").(Driver)
ui := state.Get("ui").(packer.Ui)
ui.Say("Creating virtual machine...")
path := state.Get("packerTempDir").(string)
// convert the MB to bytes
ramBytes := int64(s.RamSizeMB * 1024 * 1024)
diskSizeBytes := int64(s.DiskSize * 1024 * 1024)
ram := int64(s.RamSizeMB * 1024 * 1024)
diskSize := int64(s.DiskSize * 1024 * 1024)
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)
enabeSecureBoot := s.EnabeSecureBoot
err := hyperv.CreateVirtualMachine(s.VMName, path, ram, diskSize, switchName, generation)
err := driver.CreateVirtualMachine(s.VMName, path, ram, diskSize, switchName, s.Generation)
if err != nil {
err := fmt.Errorf("Error creating virtual machine: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
err = hyperv.SetVirtualMachineCpu(s.VMName, cpu)
err = driver.SetVirtualMachineCpu(s.VMName, s.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
}
if generation == "2" {
err = hyperv.SetSecureBoot(s.VMName, enabeSecureBoot)
if s.Generation == 2 {
err = driver.SetSecureBoot(s.VMName, enabeSecureBoot)
if err != nil {
err := fmt.Errorf("Error setting secure boot: %s", err)
state.Put("error", err)
@ -80,11 +75,11 @@ func (s *StepCreateVM) Cleanup(state multistep.StateBag) {
return
}
//driver := state.Get("driver").(Driver)
driver := state.Get("driver").(Driver)
ui := state.Get("ui").(packer.Ui)
ui.Say("Unregistering and deleting virtual machine...")
err := hyperv.DeleteVirtualMachine(s.VMName)
err := driver.DeleteVirtualMachine(s.VMName)
if err != nil {
ui.Error(fmt.Sprintf("Error deleting virtual machine: %s", err))
}

View File

@ -8,15 +8,13 @@ import (
"fmt"
"github.com/mitchellh/multistep"
"github.com/mitchellh/packer/packer"
"github.com/mitchellh/packer/powershell/hyperv"
)
type StepDisableVlan struct {
}
func (s *StepDisableVlan) Run(state multistep.StateBag) multistep.StepAction {
//config := state.Get("config").(*config)
//driver := state.Get("driver").(Driver)
driver := state.Get("driver").(Driver)
ui := state.Get("ui").(packer.Ui)
errorMsg := "Error disabling vlan: %s"
@ -25,7 +23,7 @@ func (s *StepDisableVlan) Run(state multistep.StateBag) multistep.StepAction {
ui.Say("Disabling vlan...")
err := hyperv.UntagVirtualMachineNetworkAdapterVlan(vmName, switchName)
err := driver.UntagVirtualMachineNetworkAdapterVlan(vmName, switchName)
if err != nil {
err := fmt.Errorf(errorMsg, err)
state.Put("error", err)

View File

@ -8,7 +8,6 @@ import (
"fmt"
"github.com/mitchellh/multistep"
"github.com/mitchellh/packer/packer"
"github.com/mitchellh/packer/powershell/hyperv"
)
type StepEnableIntegrationService struct {
@ -16,13 +15,14 @@ type StepEnableIntegrationService struct {
}
func (s *StepEnableIntegrationService) Run(state multistep.StateBag) multistep.StepAction {
driver := state.Get("driver").(Driver)
ui := state.Get("ui").(packer.Ui)
ui.Say("Enabling Integration Service...")
vmName := state.Get("vmName").(string)
s.name = "Guest Service Interface"
err := hyperv.EnableVirtualMachineIntegrationService(vmName, s.name)
err := driver.EnableVirtualMachineIntegrationService(vmName, s.name)
if err != nil {
err := fmt.Errorf("Error enabling Integration Service: %s", err)

View File

@ -8,7 +8,6 @@ import (
"fmt"
"github.com/mitchellh/multistep"
"github.com/mitchellh/packer/packer"
"github.com/mitchellh/packer/powershell/hyperv"
"io/ioutil"
"path/filepath"
)
@ -24,6 +23,7 @@ type StepExportVm struct {
}
func (s *StepExportVm) Run(state multistep.StateBag) multistep.StepAction {
driver := state.Get("driver").(Driver)
ui := state.Get("ui").(packer.Ui)
var err error
@ -45,7 +45,7 @@ func (s *StepExportVm) Run(state multistep.StateBag) multistep.StepAction {
ui.Say("Exporting vm...")
err = hyperv.ExportVirtualMachine(vmName, vmExportPath)
err = driver.ExportVirtualMachine(vmName, vmExportPath)
if err != nil {
errorMsg = "Error exporting vm: %s"
err := fmt.Errorf(errorMsg, err)
@ -61,7 +61,7 @@ func (s *StepExportVm) Run(state multistep.StateBag) multistep.StepAction {
ui.Say("Skipping disk compaction...")
} else {
ui.Say("Compacting disks...")
err = hyperv.CompactDisks(expPath, vhdDir)
err = driver.CompactDisks(expPath, vhdDir)
if err != nil {
errorMsg = "Error compacting disks: %s"
err := fmt.Errorf(errorMsg, err)
@ -72,7 +72,7 @@ func (s *StepExportVm) Run(state multistep.StateBag) multistep.StepAction {
}
ui.Say("Coping to output dir...")
err = hyperv.CopyExportedVirtualMachine(expPath, outputPath, vhdDir, vmDir)
err = driver.CopyExportedVirtualMachine(expPath, outputPath, vhdDir, vmDir)
if err != nil {
errorMsg = "Error exporting vm: %s"
err := fmt.Errorf(errorMsg, err)

View File

@ -9,7 +9,6 @@ import (
"github.com/mitchellh/multistep"
"github.com/mitchellh/packer/packer"
powershell "github.com/mitchellh/packer/powershell"
"github.com/mitchellh/packer/powershell/hyperv"
)
type StepMountDvdDrive struct {
@ -18,7 +17,7 @@ type StepMountDvdDrive struct {
}
func (s *StepMountDvdDrive) Run(state multistep.StateBag) multistep.StepAction {
//driver := state.Get("driver").(Driver)
driver := state.Get("driver").(Driver)
ui := state.Get("ui").(packer.Ui)
errorMsg := "Error mounting dvd drive: %s"
@ -56,7 +55,7 @@ func (s *StepMountDvdDrive) Run(state multistep.StateBag) multistep.StepAction {
ui.Say("Mounting dvd drive...")
err = hyperv.MountDvdDrive(vmName, isoPath)
err = driver.MountDvdDrive(vmName, isoPath)
if err != nil {
err := fmt.Errorf(errorMsg, err)
state.Put("error", err)
@ -74,6 +73,8 @@ func (s *StepMountDvdDrive) Cleanup(state multistep.StateBag) {
return
}
driver := state.Get("driver").(Driver)
errorMsg := "Error unmounting dvd drive: %s"
vmName := state.Get("vmName").(string)
@ -81,7 +82,7 @@ func (s *StepMountDvdDrive) Cleanup(state multistep.StateBag) {
ui.Say("Unmounting dvd drive...")
err := hyperv.UnmountDvdDrive(vmName)
err := driver.UnmountDvdDrive(vmName)
if err != nil {
ui.Error(fmt.Sprintf(errorMsg, err))
}

View File

@ -6,28 +6,24 @@ package common
import (
"fmt"
"os"
"strings"
"github.com/mitchellh/multistep"
"github.com/mitchellh/packer/packer"
"github.com/mitchellh/packer/powershell"
"github.com/mitchellh/packer/powershell/hyperv"
"log"
"io"
"io/ioutil"
"log"
"os"
"path/filepath"
"strings"
)
const(
const (
FloppyFileName = "assets.vfd"
)
type StepSetUnattendedProductKey struct {
Files []string
Files []string
ProductKey string
}
@ -36,15 +32,15 @@ func (s *StepSetUnattendedProductKey) Run(state multistep.StateBag) multistep.St
if s.ProductKey == "" {
ui.Say("No product key specified...")
return multistep.ActionContinue
return multistep.ActionContinue
}
index := -1
for i, value := range s.Files {
if s.caseInsensitiveContains(value, "Autounattend.xml") {
index = i
break
}
if s.caseInsensitiveContains(value, "Autounattend.xml") {
index = i
break
}
}
ui.Say("Setting product key in Autounattend.xml...")
@ -59,10 +55,9 @@ func (s *StepSetUnattendedProductKey) Run(state multistep.StateBag) multistep.St
return multistep.ActionContinue
}
func (s *StepSetUnattendedProductKey) caseInsensitiveContains(str, substr string) bool {
str, substr = strings.ToUpper(str), strings.ToUpper(substr)
return strings.Contains(str, substr)
str, substr = strings.ToUpper(str), strings.ToUpper(substr)
return strings.Contains(str, substr)
}
func (s *StepSetUnattendedProductKey) copyAutounattend(path string) (string, error) {
@ -92,12 +87,9 @@ func (s *StepSetUnattendedProductKey) copyAutounattend(path string) (string, err
return autounattend, nil
}
func (s *StepSetUnattendedProductKey) Cleanup(state multistep.StateBag) {
}
type StepMountFloppydrive struct {
floppyPath string
}
@ -119,7 +111,7 @@ func (s *StepMountFloppydrive) Run(state multistep.StateBag) multistep.StepActio
if err != nil {
state.Put("error", fmt.Errorf("Error preparing floppy: %s", err))
return multistep.ActionHalt
}
}
ui := state.Get("ui").(packer.Ui)
vmName := state.Get("vmName").(string)
@ -135,7 +127,8 @@ func (s *StepMountFloppydrive) Run(state multistep.StateBag) multistep.StepActio
// Track the path so that we can unregister it from Hyper-V later
s.floppyPath = floppyPath
return multistep.ActionContinue}
return multistep.ActionContinue
}
func (s *StepMountFloppydrive) Cleanup(state multistep.StateBag) {
if s.floppyPath == "" {

View File

@ -8,9 +8,10 @@ import (
"fmt"
"github.com/mitchellh/multistep"
"github.com/mitchellh/packer/packer"
powershell "github.com/mitchellh/packer/powershell"
hyperv "github.com/mitchellh/packer/powershell/hyperv"
"log"
"os"
"strconv"
)
type StepMountSecondaryDvdImages struct {
@ -88,67 +89,22 @@ func (s *StepMountSecondaryDvdImages) addAndMountIntegrationServicesSetupDisk(vm
}
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)
controllerNumber, controllerLocation, err := hyperv.CreateDvdDrive(vmName, s.Generation)
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
}
properties.ControllerNumber = strconv.FormatInt(int64(controllerNumber), 10)
properties.ControllerLocation = strconv.FormatInt(int64(controllerLocation), 10)
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)
err = hyperv.MountDvdDriveByLocation(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
}

View File

@ -5,15 +5,14 @@
package common
import (
"bytes"
"fmt"
"github.com/mitchellh/multistep"
"github.com/mitchellh/packer/packer"
"time"
// "net"
"log"
"os/exec"
"strings"
"bytes"
"time"
)
const port string = "13000"
@ -29,36 +28,6 @@ func (s *StepPollingInstalation) Run(state multistep.StateBag) multistep.StepAct
vmIp := state.Get("ip").(string)
ui.Say("Start polling VM to check the installation is complete...")
/*
count := 30
var minutes time.Duration = 1
sleepMin := time.Minute * minutes
host := vmIp + ":" + port
timeoutSec := time.Second * 15
for count > 0 {
ui.Say(fmt.Sprintf("Connecting vm (%s)...", host ))
conn, err := net.DialTimeout("tcp", host, timeoutSec)
if err == nil {
ui.Say("Done!")
conn.Close()
break;
}
log.Println(err)
ui.Say(fmt.Sprintf("Waiting more %v minutes...", uint(minutes)))
time.Sleep(sleepMin)
count--
}
if count == 0 {
err := fmt.Errorf(errorMsg, "a signal from vm was not received in a given time period ")
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
*/
host := "'" + vmIp + "'," + port
var blockBuffer bytes.Buffer
@ -73,7 +42,7 @@ func (s *StepPollingInstalation) Run(state multistep.StateBag) multistep.StepAct
var res string
for count > 0 {
log.Println(fmt.Sprintf("Connecting vm (%s)...", host ))
log.Println(fmt.Sprintf("Connecting vm (%s)...", host))
cmd := exec.Command("powershell", blockBuffer.String())
cmdOut, err := cmd.Output()
if err != nil {
@ -88,8 +57,8 @@ func (s *StepPollingInstalation) Run(state multistep.StateBag) multistep.StepAct
if res != "False" {
ui.Say("Signal was received from the VM")
// Sleep before starting provision
time.Sleep(time.Second*30)
break;
time.Sleep(time.Second * 30)
break
}
log.Println(fmt.Sprintf("Slipping for more %v seconds...", uint(duration)))

View File

@ -9,14 +9,13 @@ import (
"github.com/mitchellh/multistep"
"github.com/mitchellh/packer/packer"
"time"
"github.com/mitchellh/packer/powershell/hyperv"
)
type StepRebootVm struct {
}
func (s *StepRebootVm) Run(state multistep.StateBag) multistep.StepAction {
//driver := state.Get("driver").(Driver)
driver := state.Get("driver").(Driver)
ui := state.Get("ui").(packer.Ui)
errorMsg := "Error rebooting vm: %s"
@ -24,7 +23,7 @@ func (s *StepRebootVm) Run(state multistep.StateBag) multistep.StepAction {
ui.Say("Rebooting vm...")
err := hyperv.RestartVirtualMachine(vmName)
err := driver.RestartVirtualMachine(vmName)
if err != nil {
err := fmt.Errorf(errorMsg, err)
state.Put("error", err)

View File

@ -8,22 +8,20 @@ import (
"fmt"
"github.com/mitchellh/multistep"
"github.com/mitchellh/packer/packer"
"github.com/mitchellh/packer/powershell/hyperv"
)
type StepUnmountDvdDrive struct {
}
func (s *StepUnmountDvdDrive) Run(state multistep.StateBag) multistep.StepAction {
//driver := state.Get("driver").(Driver)
driver := state.Get("driver").(Driver)
ui := state.Get("ui").(packer.Ui)
vmName := state.Get("vmName").(string)
ui.Say("Unmounting dvd drive...")
err := hyperv.UnmountDvdDrive(vmName)
err := driver.UnmountDvdDrive(vmName)
if err != nil {
err := fmt.Errorf("Error unmounting dvd drive: %s", err)
state.Put("error", err)

View File

@ -8,7 +8,6 @@ import (
"fmt"
"github.com/mitchellh/multistep"
"github.com/mitchellh/packer/packer"
"github.com/mitchellh/packer/powershell/hyperv"
)
type StepUnmountFloppyDrive struct {
@ -16,7 +15,7 @@ type StepUnmountFloppyDrive struct {
}
func (s *StepUnmountFloppyDrive) Run(state multistep.StateBag) multistep.StepAction {
//driver := state.Get("driver").(Driver)
driver := state.Get("driver").(Driver)
ui := state.Get("ui").(packer.Ui)
if s.Generation > 1 {
@ -28,7 +27,7 @@ func (s *StepUnmountFloppyDrive) Run(state multistep.StateBag) multistep.StepAct
ui.Say("Unmounting floppy drive (Run)...")
err := hyperv.UnmountFloppyDrive(vmName)
err := driver.UnmountFloppyDrive(vmName)
if err != nil {
err := fmt.Errorf(errorMsg, err)
state.Put("error", err)

View File

@ -8,7 +8,6 @@ import (
"fmt"
"github.com/mitchellh/multistep"
"github.com/mitchellh/packer/packer"
powershell "github.com/mitchellh/packer/powershell"
"log"
)
@ -16,6 +15,7 @@ type StepUnmountSecondaryDvdImages struct {
}
func (s *StepUnmountSecondaryDvdImages) Run(state multistep.StateBag) multistep.StepAction {
driver := state.Get("driver").(Driver)
ui := state.Get("ui").(packer.Ui)
ui.Say("Unmounting Integration Services Setup Disk...")
@ -28,17 +28,7 @@ func (s *StepUnmountSecondaryDvdImages) Run(state multistep.StateBag) multistep.
log.Println(fmt.Sprintf("Found DVD properties %d", 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)
err := driver.DeleteDvdDrive(vmName, dvdProperty.ControllerNumber, dvdProperty.ControllerLocation)
if err != nil {
state.Put("error", err)
ui.Error(err.Error())

View File

@ -8,10 +8,7 @@ import (
"fmt"
"github.com/mitchellh/multistep"
"github.com/mitchellh/packer/packer"
"strings"
"strconv"
"time"
powershell "github.com/mitchellh/packer/powershell"
)
const (
@ -22,29 +19,25 @@ type StepWaitForPowerOff struct {
}
func (s *StepWaitForPowerOff) Run(state multistep.StateBag) multistep.StepAction {
driver := state.Get("driver").(Driver)
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);
isOff, err := driver.IsOff(vmName)
if err != nil {
err := fmt.Errorf("Error checking VM's state: %s", err)
err := fmt.Errorf("Error checking if vm is off: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
if cmdOut == "True" {
if isOff {
break
} else {
time.Sleep(time.Second * SleepSeconds);
time.Sleep(time.Second * SleepSeconds)
}
}
@ -56,29 +49,24 @@ func (s *StepWaitForPowerOff) Cleanup(state multistep.StateBag) {
type StepWaitForInstallToComplete struct {
ExpectedRebootCount uint
ActionName string
ActionName string
}
func (s *StepWaitForInstallToComplete) Run(state multistep.StateBag) multistep.StepAction {
driver := state.Get("driver").(Driver)
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))
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);
uptime, err := driver.Uptime(vmName)
if err != nil {
err := fmt.Errorf("Error checking uptime: %s", err)
state.Put("error", err)
@ -86,20 +74,18 @@ func (s *StepWaitForInstallToComplete) Run(state multistep.StateBag) multistep.S
return multistep.ActionHalt
}
uptime, _ := strconv.ParseUint(strings.TrimSpace(string(cmdOut)), 10, 64)
if uint64(uptime) < lastUptime {
if 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);
if rebootCount < s.ExpectedRebootCount {
time.Sleep(time.Second * SleepSeconds)
}
}
return multistep.ActionContinue
}

View File

@ -2,6 +2,7 @@ package hyperv
import (
"github.com/mitchellh/packer/powershell"
"strconv"
"strings"
)
@ -50,6 +51,73 @@ $ip
return cmdOut, err
}
func CreateDvdDrive(vmName string, generation uint) (uint, uint, error) {
var ps powershell.PowerShellCmd
var script string
var controllerNumber uint
controllerNumber = 0
if 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 = `
param([string]$vmName)
$dvdDrives = (Get-VMDvdDrive -VMName $vmName)
$lastControllerNumber = $dvdDrives | Sort-Object ControllerNumber | Select-Object -Last 1 | %{$_.ControllerNumber}
if (!$lastControllerNumber) {
$lastControllerNumber = 0
} elseif (!$lastControllerNumber -or ($dvdDrives | ?{ $_.ControllerNumber -eq $lastControllerNumber} | measure).count -gt 1) {
$lastControllerNumber += 1
}
$lastControllerNumber
`
cmdOut, err := ps.Output(script, vmName)
if err != nil {
return 0, 0, err
}
controllerNumberTemp, err := strconv.ParseUint(strings.TrimSpace(cmdOut), 10, 64)
if err != nil {
return 0, 0, err
}
controllerNumber = uint(controllerNumberTemp)
if controllerNumber != 0 && controllerNumber != 1 {
//There are only 2 ide controllers, try to use the one the hdd is attached too
controllerNumber = 0
}
}
script = `
param([string]$vmName,[int]$controllerNumber)
Add-VMDvdDrive -VMName $vmName -ControllerNumber $controllerNumber
`
cmdOut, err := ps.Output(script, vmName)
if err != nil {
return controllerNumber, 0, 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 = `
param([string]$vmName)
(Get-VMDvdDrive -VMName $vmName | Where-Object {$_.Path -eq $null}).ControllerLocation
`
cmdOut, err = ps.Output(script, vmName)
if err != nil {
return controllerNumber, 0, err
}
controllerLocationTemp, err := strconv.ParseUint(strings.TrimSpace(cmdOut), 10, 64)
if err != nil {
return controllerNumber, 0, err
}
controllerLocation := uint(controllerLocationTemp)
return controllerNumber, controllerLocation, err
}
func MountDvdDrive(vmName string, path string) error {
var script = `
@ -62,6 +130,18 @@ Set-VMDvdDrive -VMName $vmName -Path $path
return err
}
func MountDvdDriveByLocation(vmName string, path string, controllerNumber uint, controllerLocation uint) error {
var script = `
param([string]$vmName,[string]$path,[string]$controllerNumber,[string]$controllerLocation)
Set-VMDvdDrive -VMName $vmName -Path $path -ControllerNumber $controllerNumber -ControllerLocation $controllerLocation
`
var ps powershell.PowerShellCmd
err := ps.Run(script, vmName, path, strconv.FormatInt(int64(controllerNumber), 10), strconv.FormatInt(int64(controllerLocation), 10))
return err
}
func UnmountDvdDrive(vmName string) error {
var script = `
param([string]$vmName)
@ -73,6 +153,19 @@ Get-VMDvdDrive -VMName $vmName | Set-VMDvdDrive -Path $null
return err
}
func DeleteDvdDrive(vmName string, controllerNumber string, controllerLocation string) error {
var script = `
param([string]$vmName,[int]$controllerNumber,[int]$controllerLocation)
$vmDvdDrive = Get-VMDvdDrive -VMName $vmName -ControllerNumber $controllerNumber -ControllerLocation $controllerLocation
if (!$vmDvdDrive) {throw 'unable to find dvd drive'}
Remove-VMDvdDrive -VMName $vmName -ControllerNumber $controllerNumber -ControllerLocation $controllerLocation
`
var ps powershell.PowerShellCmd
err := ps.Run(script, vmName, controllerNumber, controllerLocation)
return err
}
func MountFloppyDrive(vmName string, path string) error {
var script = `
param([string]$vmName, [string]$path)
@ -96,9 +189,9 @@ Set-VMFloppyDiskDrive -VMName $vmName -Path $null
return err
}
func CreateVirtualMachine(vmName string, path string, ram string, diskSize string, switchName string, generation string) error {
func CreateVirtualMachine(vmName string, path string, ram int64, diskSize int64, switchName string, generation uint) error {
if generation == "2" {
if generation == 2 {
var script = `
param([string]$vmName, [string]$path, [long]$memoryStartupBytes, [long]$newVHDSizeBytes, [string]$switchName, [int]$generation)
$vhdx = $vmName + '.vhdx'
@ -106,7 +199,7 @@ $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)
err := ps.Run(script, vmName, path, strconv.FormatInt(ram, 10), strconv.FormatInt(diskSize, 10), switchName, strconv.FormatInt(int64(generation), 10))
return err
} else {
var script = `
@ -116,12 +209,12 @@ $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)
err := ps.Run(script, vmName, path, strconv.FormatInt(ram, 10), strconv.FormatInt(diskSize, 10), switchName)
return err
}
}
func SetVirtualMachineCpu(vmName string, cpu string) error {
func SetVirtualMachineCpu(vmName string, cpu uint) error {
var script = `
param([string]$vmName, [int]$cpu)
@ -129,7 +222,7 @@ Set-VMProcessor -VMName $vmName -Count $cpu
`
var ps powershell.PowerShellCmd
err := ps.Run(script, vmName, cpu)
err := ps.Run(script, vmName, strconv.FormatInt(int64(cpu), 10))
return err
}
@ -425,10 +518,53 @@ $vm.State -eq [Microsoft.HyperV.PowerShell.VMState]::Running
var ps powershell.PowerShellCmd
cmdOut, err := ps.Output(script, vmName)
if err != nil {
return false, err
}
var isRunning = strings.TrimSpace(cmdOut) == "True"
return isRunning, err
}
func IsOff(vmName string) (bool, error) {
var script = `
param([string]$vmName)
$vm = Get-VM -Name $vmName -ErrorAction SilentlyContinue
$vm.State -eq [Microsoft.HyperV.PowerShell.VMState]::Off
`
var ps powershell.PowerShellCmd
cmdOut, err := ps.Output(script, vmName)
if err != nil {
return false, err
}
var isRunning = strings.TrimSpace(cmdOut) == "True"
return isRunning, err
}
func Uptime(vmName string) (uint64, error) {
var script = `
param([string]$vmName)
$vm = Get-VM -Name $vmName -ErrorAction SilentlyContinue
$vm.Uptime.TotalSeconds
`
var ps powershell.PowerShellCmd
cmdOut, err := ps.Output(script, vmName)
if err != nil {
return 0, err
}
uptime, err := strconv.ParseUint(strings.TrimSpace(string(cmdOut)), 10, 64)
return uptime, err
}
func Mac(vmName string) (string, error) {
var script = `
param([string]$vmName, [int]$adapterIndex)