github.phpd.cn/hashicorp/packer@v1.3.2/builder/parallels/common/driver.go (about)

     1  package common
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"os/exec"
     7  	"runtime"
     8  	"strconv"
     9  	"strings"
    10  )
    11  
    12  // Driver is the interface that talks to Parallels and performs certain
    13  // operations with it. Some of the operations on here may seem overly
    14  // specific, but they were built specifically in mind to handle features
    15  // of the Parallels builder for Packer, and to abstract differences in
    16  // versions out of the builder steps, so sometimes the methods are
    17  // extremely specific.
    18  type Driver interface {
    19  	// Compact a virtual disk image.
    20  	CompactDisk(string) error
    21  
    22  	// Adds new CD/DVD drive to the VM and returns name of this device
    23  	DeviceAddCDROM(string, string) (string, error)
    24  
    25  	// Get path to the first virtual disk image
    26  	DiskPath(string) (string, error)
    27  
    28  	// Import a VM
    29  	Import(string, string, string, bool) error
    30  
    31  	// Checks if the VM with the given name is running.
    32  	IsRunning(string) (bool, error)
    33  
    34  	// Stop stops a running machine, forcefully.
    35  	Stop(string) error
    36  
    37  	// Prlctl executes the given Prlctl command
    38  	Prlctl(...string) error
    39  
    40  	// Get the path to the Parallels Tools ISO for the given flavor.
    41  	ToolsISOPath(string) (string, error)
    42  
    43  	// Verify checks to make sure that this driver should function
    44  	// properly. If there is any indication the driver can't function,
    45  	// this will return an error.
    46  	Verify() error
    47  
    48  	// Version reads the version of Parallels that is installed.
    49  	Version() (string, error)
    50  
    51  	// Send scancodes to the vm using the prltype python script.
    52  	SendKeyScanCodes(string, ...string) error
    53  
    54  	// Apply default configuration settings to the virtual machine
    55  	SetDefaultConfiguration(string) error
    56  
    57  	// Finds the MAC address of the NIC nic0
    58  	MAC(string) (string, error)
    59  
    60  	// Finds the IP address of a VM connected that uses DHCP by its MAC address
    61  	IPAddress(string) (string, error)
    62  }
    63  
    64  // NewDriver returns a new driver implementation for this version of Parallels
    65  // Desktop, or an error if the driver couldn't be initialized.
    66  func NewDriver() (Driver, error) {
    67  	var drivers map[string]Driver
    68  	var prlctlPath string
    69  	var prlsrvctlPath string
    70  	var supportedVersions []string
    71  	DHCPLeaseFile := "/Library/Preferences/Parallels/parallels_dhcp_leases"
    72  
    73  	if runtime.GOOS != "darwin" {
    74  		return nil, fmt.Errorf(
    75  			"Parallels builder works only on \"darwin\" platform!")
    76  	}
    77  
    78  	if prlctlPath == "" {
    79  		var err error
    80  		prlctlPath, err = exec.LookPath("prlctl")
    81  		if err != nil {
    82  			return nil, err
    83  		}
    84  	}
    85  
    86  	log.Printf("prlctl path: %s", prlctlPath)
    87  
    88  	if prlsrvctlPath == "" {
    89  		var err error
    90  		prlsrvctlPath, err = exec.LookPath("prlsrvctl")
    91  		if err != nil {
    92  			return nil, err
    93  		}
    94  	}
    95  
    96  	log.Printf("prlsrvctl path: %s", prlsrvctlPath)
    97  
    98  	drivers = map[string]Driver{
    99  		"11": &Parallels11Driver{
   100  			Parallels9Driver: Parallels9Driver{
   101  				PrlctlPath:    prlctlPath,
   102  				PrlsrvctlPath: prlsrvctlPath,
   103  				dhcpLeaseFile: DHCPLeaseFile,
   104  			},
   105  		},
   106  		"10": &Parallels10Driver{
   107  			Parallels9Driver: Parallels9Driver{
   108  				PrlctlPath:    prlctlPath,
   109  				PrlsrvctlPath: prlsrvctlPath,
   110  				dhcpLeaseFile: DHCPLeaseFile,
   111  			},
   112  		},
   113  		"9": &Parallels9Driver{
   114  			PrlctlPath:    prlctlPath,
   115  			PrlsrvctlPath: prlsrvctlPath,
   116  			dhcpLeaseFile: DHCPLeaseFile,
   117  		},
   118  	}
   119  
   120  	for v, d := range drivers {
   121  		version, _ := d.Version()
   122  		if strings.HasPrefix(version, v) {
   123  			if err := d.Verify(); err != nil {
   124  				return nil, err
   125  			}
   126  			return d, nil
   127  		}
   128  		supportedVersions = append(supportedVersions, v)
   129  	}
   130  
   131  	latestDriver := 11
   132  	version, _ := drivers[strconv.Itoa(latestDriver)].Version()
   133  	majVer, _ := strconv.Atoi(strings.SplitN(version, ".", 2)[0])
   134  	log.Printf("Parallels version: %s", version)
   135  	if majVer > latestDriver {
   136  		log.Printf("Your version of Parallels Desktop for Mac is %s, Packer will use driver for version %d.", version, latestDriver)
   137  		return drivers[strconv.Itoa(latestDriver)], nil
   138  	}
   139  
   140  	return nil, fmt.Errorf(
   141  		"Unable to initialize any driver. Supported Parallels Desktop versions: "+
   142  			"%s\n", strings.Join(supportedVersions, ", "))
   143  }