github.com/rahart/packer@v0.12.2-0.20161229105310-282bb6ad370f/builder/hyperv/common/driver_ps_4.go (about)

     1  package common
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"runtime"
     7  	"strconv"
     8  	"strings"
     9  
    10  	"github.com/mitchellh/packer/common/powershell"
    11  	"github.com/mitchellh/packer/common/powershell/hyperv"
    12  )
    13  
    14  type HypervPS4Driver struct {
    15  }
    16  
    17  func NewHypervPS4Driver() (Driver, error) {
    18  	appliesTo := "Applies to Windows 8.1, Windows PowerShell 4.0, Windows Server 2012 R2 only"
    19  
    20  	// Check this is Windows
    21  	if runtime.GOOS != "windows" {
    22  		err := fmt.Errorf("%s", appliesTo)
    23  		return nil, err
    24  	}
    25  
    26  	ps4Driver := &HypervPS4Driver{}
    27  
    28  	if err := ps4Driver.Verify(); err != nil {
    29  		return nil, err
    30  	}
    31  
    32  	return ps4Driver, nil
    33  }
    34  
    35  func (d *HypervPS4Driver) IsRunning(vmName string) (bool, error) {
    36  	return hyperv.IsRunning(vmName)
    37  }
    38  
    39  func (d *HypervPS4Driver) IsOff(vmName string) (bool, error) {
    40  	return hyperv.IsOff(vmName)
    41  }
    42  
    43  func (d *HypervPS4Driver) Uptime(vmName string) (uint64, error) {
    44  	return hyperv.Uptime(vmName)
    45  }
    46  
    47  // Start starts a VM specified by the name given.
    48  func (d *HypervPS4Driver) Start(vmName string) error {
    49  	return hyperv.StartVirtualMachine(vmName)
    50  }
    51  
    52  // Stop stops a VM specified by the name given.
    53  func (d *HypervPS4Driver) Stop(vmName string) error {
    54  	return hyperv.StopVirtualMachine(vmName)
    55  }
    56  
    57  func (d *HypervPS4Driver) Verify() error {
    58  
    59  	if err := d.verifyPSVersion(); err != nil {
    60  		return err
    61  	}
    62  
    63  	if err := d.verifyPSHypervModule(); err != nil {
    64  		return err
    65  	}
    66  
    67  	if err := d.verifyElevatedMode(); err != nil {
    68  		return err
    69  	}
    70  
    71  	return nil
    72  }
    73  
    74  // Get mac address for VM.
    75  func (d *HypervPS4Driver) Mac(vmName string) (string, error) {
    76  	res, err := hyperv.Mac(vmName)
    77  
    78  	if err != nil {
    79  		return res, err
    80  	}
    81  
    82  	if res == "" {
    83  		err := fmt.Errorf("%s", "No mac address.")
    84  		return res, err
    85  	}
    86  
    87  	return res, err
    88  }
    89  
    90  // Get ip address for mac address.
    91  func (d *HypervPS4Driver) IpAddress(mac string) (string, error) {
    92  	res, err := hyperv.IpAddress(mac)
    93  
    94  	if err != nil {
    95  		return res, err
    96  	}
    97  
    98  	if res == "" {
    99  		err := fmt.Errorf("%s", "No ip address.")
   100  		return res, err
   101  	}
   102  	return res, err
   103  }
   104  
   105  // Get host name from ip address
   106  func (d *HypervPS4Driver) GetHostName(ip string) (string, error) {
   107  	return powershell.GetHostName(ip)
   108  }
   109  
   110  // Finds the IP address of a host adapter connected to switch
   111  func (d *HypervPS4Driver) GetHostAdapterIpAddressForSwitch(switchName string) (string, error) {
   112  	res, err := hyperv.GetHostAdapterIpAddressForSwitch(switchName)
   113  
   114  	if err != nil {
   115  		return res, err
   116  	}
   117  
   118  	if res == "" {
   119  		err := fmt.Errorf("%s", "No ip address.")
   120  		return res, err
   121  	}
   122  	return res, err
   123  }
   124  
   125  // Type scan codes to virtual keyboard of vm
   126  func (d *HypervPS4Driver) TypeScanCodes(vmName string, scanCodes string) error {
   127  	return hyperv.TypeScanCodes(vmName, scanCodes)
   128  }
   129  
   130  // Get network adapter address
   131  func (d *HypervPS4Driver) GetVirtualMachineNetworkAdapterAddress(vmName string) (string, error) {
   132  	return hyperv.GetVirtualMachineNetworkAdapterAddress(vmName)
   133  }
   134  
   135  //Set the vlan to use for switch
   136  func (d *HypervPS4Driver) SetNetworkAdapterVlanId(switchName string, vlanId string) error {
   137  	return hyperv.SetNetworkAdapterVlanId(switchName, vlanId)
   138  }
   139  
   140  //Set the vlan to use for machine
   141  func (d *HypervPS4Driver) SetVirtualMachineVlanId(vmName string, vlanId string) error {
   142  	return hyperv.SetVirtualMachineVlanId(vmName, vlanId)
   143  }
   144  
   145  func (d *HypervPS4Driver) UntagVirtualMachineNetworkAdapterVlan(vmName string, switchName string) error {
   146  	return hyperv.UntagVirtualMachineNetworkAdapterVlan(vmName, switchName)
   147  }
   148  
   149  func (d *HypervPS4Driver) CreateExternalVirtualSwitch(vmName string, switchName string) error {
   150  	return hyperv.CreateExternalVirtualSwitch(vmName, switchName)
   151  }
   152  
   153  func (d *HypervPS4Driver) GetVirtualMachineSwitchName(vmName string) (string, error) {
   154  	return hyperv.GetVirtualMachineSwitchName(vmName)
   155  }
   156  
   157  func (d *HypervPS4Driver) ConnectVirtualMachineNetworkAdapterToSwitch(vmName string, switchName string) error {
   158  	return hyperv.ConnectVirtualMachineNetworkAdapterToSwitch(vmName, switchName)
   159  }
   160  
   161  func (d *HypervPS4Driver) DeleteVirtualSwitch(switchName string) error {
   162  	return hyperv.DeleteVirtualSwitch(switchName)
   163  }
   164  
   165  func (d *HypervPS4Driver) CreateVirtualSwitch(switchName string, switchType string) (bool, error) {
   166  	return hyperv.CreateVirtualSwitch(switchName, switchType)
   167  }
   168  
   169  func (d *HypervPS4Driver) CreateVirtualMachine(vmName string, path string, ram int64, diskSize int64, switchName string, generation uint) error {
   170  	return hyperv.CreateVirtualMachine(vmName, path, ram, diskSize, switchName, generation)
   171  }
   172  
   173  func (d *HypervPS4Driver) DeleteVirtualMachine(vmName string) error {
   174  	return hyperv.DeleteVirtualMachine(vmName)
   175  }
   176  
   177  func (d *HypervPS4Driver) SetVirtualMachineCpuCount(vmName string, cpu uint) error {
   178  	return hyperv.SetVirtualMachineCpuCount(vmName, cpu)
   179  }
   180  
   181  func (d *HypervPS4Driver) SetVirtualMachineMacSpoofing(vmName string, enable bool) error {
   182  	return hyperv.SetVirtualMachineMacSpoofing(vmName, enable)
   183  }
   184  
   185  func (d *HypervPS4Driver) SetVirtualMachineDynamicMemory(vmName string, enable bool) error {
   186  	return hyperv.SetVirtualMachineDynamicMemory(vmName, enable)
   187  }
   188  
   189  func (d *HypervPS4Driver) SetVirtualMachineSecureBoot(vmName string, enable bool) error {
   190  	return hyperv.SetVirtualMachineSecureBoot(vmName, enable)
   191  }
   192  
   193  func (d *HypervPS4Driver) SetVirtualMachineVirtualizationExtensions(vmName string, enable bool) error {
   194  	return hyperv.SetVirtualMachineVirtualizationExtensions(vmName, enable)
   195  }
   196  
   197  func (d *HypervPS4Driver) EnableVirtualMachineIntegrationService(vmName string, integrationServiceName string) error {
   198  	return hyperv.EnableVirtualMachineIntegrationService(vmName, integrationServiceName)
   199  }
   200  
   201  func (d *HypervPS4Driver) ExportVirtualMachine(vmName string, path string) error {
   202  	return hyperv.ExportVirtualMachine(vmName, path)
   203  }
   204  
   205  func (d *HypervPS4Driver) CompactDisks(expPath string, vhdDir string) error {
   206  	return hyperv.CompactDisks(expPath, vhdDir)
   207  }
   208  
   209  func (d *HypervPS4Driver) CopyExportedVirtualMachine(expPath string, outputPath string, vhdDir string, vmDir string) error {
   210  	return hyperv.CopyExportedVirtualMachine(expPath, outputPath, vhdDir, vmDir)
   211  }
   212  
   213  func (d *HypervPS4Driver) RestartVirtualMachine(vmName string) error {
   214  	return hyperv.RestartVirtualMachine(vmName)
   215  }
   216  
   217  func (d *HypervPS4Driver) CreateDvdDrive(vmName string, isoPath string, generation uint) (uint, uint, error) {
   218  	return hyperv.CreateDvdDrive(vmName, isoPath, generation)
   219  }
   220  
   221  func (d *HypervPS4Driver) MountDvdDrive(vmName string, path string, controllerNumber uint, controllerLocation uint) error {
   222  	return hyperv.MountDvdDrive(vmName, path, controllerNumber, controllerLocation)
   223  }
   224  
   225  func (d *HypervPS4Driver) SetBootDvdDrive(vmName string, controllerNumber uint, controllerLocation uint, generation uint) error {
   226  	return hyperv.SetBootDvdDrive(vmName, controllerNumber, controllerLocation, generation)
   227  }
   228  
   229  func (d *HypervPS4Driver) UnmountDvdDrive(vmName string, controllerNumber uint, controllerLocation uint) error {
   230  	return hyperv.UnmountDvdDrive(vmName, controllerNumber, controllerLocation)
   231  }
   232  
   233  func (d *HypervPS4Driver) DeleteDvdDrive(vmName string, controllerNumber uint, controllerLocation uint) error {
   234  	return hyperv.DeleteDvdDrive(vmName, controllerNumber, controllerLocation)
   235  }
   236  
   237  func (d *HypervPS4Driver) MountFloppyDrive(vmName string, path string) error {
   238  	return hyperv.MountFloppyDrive(vmName, path)
   239  }
   240  
   241  func (d *HypervPS4Driver) UnmountFloppyDrive(vmName string) error {
   242  	return hyperv.UnmountFloppyDrive(vmName)
   243  }
   244  
   245  func (d *HypervPS4Driver) verifyPSVersion() error {
   246  
   247  	log.Printf("Enter method: %s", "verifyPSVersion")
   248  	// check PS is available and is of proper version
   249  	versionCmd := "$host.version.Major"
   250  
   251  	var ps powershell.PowerShellCmd
   252  	cmdOut, err := ps.Output(versionCmd)
   253  	if err != nil {
   254  		return err
   255  	}
   256  
   257  	versionOutput := strings.TrimSpace(string(cmdOut))
   258  	log.Printf("%s output: %s", versionCmd, versionOutput)
   259  
   260  	ver, err := strconv.ParseInt(versionOutput, 10, 32)
   261  
   262  	if err != nil {
   263  		return err
   264  	}
   265  
   266  	if ver < 4 {
   267  		err := fmt.Errorf("%s", "Windows PowerShell version 4.0 or higher is expected")
   268  		return err
   269  	}
   270  
   271  	return nil
   272  }
   273  
   274  func (d *HypervPS4Driver) verifyPSHypervModule() error {
   275  
   276  	log.Printf("Enter method: %s", "verifyPSHypervModule")
   277  
   278  	versionCmd := "function foo(){try{ $commands = Get-Command -Module Hyper-V;if($commands.Length -eq 0){return $false} }catch{return $false}; return $true} foo"
   279  
   280  	var ps powershell.PowerShellCmd
   281  	cmdOut, err := ps.Output(versionCmd)
   282  	if err != nil {
   283  		return err
   284  	}
   285  
   286  	res := strings.TrimSpace(string(cmdOut))
   287  
   288  	if res == "False" {
   289  		err := fmt.Errorf("%s", "PS Hyper-V module is not loaded. Make sure Hyper-V feature is on.")
   290  		return err
   291  	}
   292  
   293  	return nil
   294  }
   295  
   296  func (d *HypervPS4Driver) verifyElevatedMode() error {
   297  
   298  	log.Printf("Enter method: %s", "verifyElevatedMode")
   299  
   300  	isAdmin, _ := powershell.IsCurrentUserAnAdministrator()
   301  
   302  	if !isAdmin {
   303  		err := fmt.Errorf("%s", "Please restart your shell in elevated mode")
   304  		return err
   305  	}
   306  
   307  	return nil
   308  }