2014-04-06 13:21:22 -04:00
|
|
|
|
package common
|
|
|
|
|
|
|
|
|
|
import (
|
2014-08-20 07:49:29 -04:00
|
|
|
|
"fmt"
|
2014-04-06 13:21:22 -04:00
|
|
|
|
"log"
|
|
|
|
|
"os/exec"
|
2014-08-20 07:49:29 -04:00
|
|
|
|
"runtime"
|
2016-07-02 16:18:54 -04:00
|
|
|
|
"strconv"
|
2014-08-20 07:49:29 -04:00
|
|
|
|
"strings"
|
2014-04-06 13:21:22 -04:00
|
|
|
|
)
|
|
|
|
|
|
2016-12-11 17:37:41 -05:00
|
|
|
|
// Driver is the interface that talks to Parallels and performs certain
|
2014-04-06 13:21:22 -04:00
|
|
|
|
// operations with it. Some of the operations on here may seem overly
|
|
|
|
|
// specific, but they were built specifically in mind to handle features
|
|
|
|
|
// of the Parallels builder for Packer, and to abstract differences in
|
|
|
|
|
// versions out of the builder steps, so sometimes the methods are
|
|
|
|
|
// extremely specific.
|
|
|
|
|
type Driver interface {
|
2015-06-21 06:34:35 -04:00
|
|
|
|
// Compact a virtual disk image.
|
|
|
|
|
CompactDisk(string) error
|
|
|
|
|
|
2014-09-17 07:01:54 -04:00
|
|
|
|
// Adds new CD/DVD drive to the VM and returns name of this device
|
2016-12-11 13:49:54 -05:00
|
|
|
|
DeviceAddCDROM(string, string) (string, error)
|
2014-09-17 07:01:54 -04:00
|
|
|
|
|
2015-06-21 05:17:06 -04:00
|
|
|
|
// Get path to the first virtual disk image
|
|
|
|
|
DiskPath(string) (string, error)
|
|
|
|
|
|
2014-04-06 13:21:22 -04:00
|
|
|
|
// Import a VM
|
2014-08-12 08:52:27 -04:00
|
|
|
|
Import(string, string, string, bool) error
|
2014-04-06 13:21:22 -04:00
|
|
|
|
|
|
|
|
|
// Checks if the VM with the given name is running.
|
|
|
|
|
IsRunning(string) (bool, error)
|
|
|
|
|
|
|
|
|
|
// Stop stops a running machine, forcefully.
|
|
|
|
|
Stop(string) error
|
|
|
|
|
|
|
|
|
|
// Prlctl executes the given Prlctl command
|
|
|
|
|
Prlctl(...string) error
|
|
|
|
|
|
2014-08-22 05:06:55 -04:00
|
|
|
|
// Get the path to the Parallels Tools ISO for the given flavor.
|
2016-12-11 13:49:54 -05:00
|
|
|
|
ToolsISOPath(string) (string, error)
|
2014-08-22 05:06:55 -04:00
|
|
|
|
|
2014-04-06 13:21:22 -04:00
|
|
|
|
// Verify checks to make sure that this driver should function
|
|
|
|
|
// properly. If there is any indication the driver can't function,
|
|
|
|
|
// this will return an error.
|
|
|
|
|
Verify() error
|
|
|
|
|
|
|
|
|
|
// Version reads the version of Parallels that is installed.
|
|
|
|
|
Version() (string, error)
|
|
|
|
|
|
2014-09-11 18:44:22 -04:00
|
|
|
|
// Send scancodes to the vm using the prltype python script.
|
2014-04-06 13:21:22 -04:00
|
|
|
|
SendKeyScanCodes(string, ...string) error
|
|
|
|
|
|
2015-06-18 05:04:02 -04:00
|
|
|
|
// Apply default сonfiguration settings to the virtual machine
|
|
|
|
|
SetDefaultConfiguration(string) error
|
|
|
|
|
|
2014-04-06 13:21:22 -04:00
|
|
|
|
// Finds the MAC address of the NIC nic0
|
2016-12-11 13:49:54 -05:00
|
|
|
|
MAC(string) (string, error)
|
2014-04-06 13:21:22 -04:00
|
|
|
|
|
|
|
|
|
// Finds the IP address of a VM connected that uses DHCP by its MAC address
|
2016-12-11 13:49:54 -05:00
|
|
|
|
IPAddress(string) (string, error)
|
2014-04-06 13:21:22 -04:00
|
|
|
|
}
|
|
|
|
|
|
2016-12-16 14:51:55 -05:00
|
|
|
|
// NewDriver returns a new driver implementation for this version of Parallels
|
|
|
|
|
// Desktop, or an error if the driver couldn't be initialized.
|
2014-04-06 13:21:22 -04:00
|
|
|
|
func NewDriver() (Driver, error) {
|
2014-08-20 07:49:29 -04:00
|
|
|
|
var drivers map[string]Driver
|
2014-04-06 13:21:22 -04:00
|
|
|
|
var prlctlPath string
|
2015-08-22 07:15:59 -04:00
|
|
|
|
var prlsrvctlPath string
|
2014-08-20 07:49:29 -04:00
|
|
|
|
var supportedVersions []string
|
2016-12-11 13:49:54 -05:00
|
|
|
|
DHCPLeaseFile := "/Library/Preferences/Parallels/parallels_dhcp_leases"
|
2014-04-06 13:21:22 -04:00
|
|
|
|
|
2014-08-11 02:18:35 -04:00
|
|
|
|
if runtime.GOOS != "darwin" {
|
|
|
|
|
return nil, fmt.Errorf(
|
|
|
|
|
"Parallels builder works only on \"darwin\" platform!")
|
|
|
|
|
}
|
|
|
|
|
|
2014-04-06 13:21:22 -04:00
|
|
|
|
if prlctlPath == "" {
|
|
|
|
|
var err error
|
|
|
|
|
prlctlPath, err = exec.LookPath("prlctl")
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
log.Printf("prlctl path: %s", prlctlPath)
|
2014-08-20 07:49:29 -04:00
|
|
|
|
|
2015-08-22 07:15:59 -04:00
|
|
|
|
if prlsrvctlPath == "" {
|
|
|
|
|
var err error
|
|
|
|
|
prlsrvctlPath, err = exec.LookPath("prlsrvctl")
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
log.Printf("prlsrvctl path: %s", prlsrvctlPath)
|
|
|
|
|
|
2014-08-20 07:49:29 -04:00
|
|
|
|
drivers = map[string]Driver{
|
2015-08-22 07:15:59 -04:00
|
|
|
|
"11": &Parallels11Driver{
|
2015-06-10 01:41:12 -04:00
|
|
|
|
Parallels9Driver: Parallels9Driver{
|
2016-12-11 13:49:54 -05:00
|
|
|
|
PrlctlPath: prlctlPath,
|
|
|
|
|
PrlsrvctlPath: prlsrvctlPath,
|
|
|
|
|
dhcpLeaseFile: DHCPLeaseFile,
|
2015-06-10 01:41:12 -04:00
|
|
|
|
},
|
|
|
|
|
},
|
2014-08-20 07:49:29 -04:00
|
|
|
|
"10": &Parallels10Driver{
|
|
|
|
|
Parallels9Driver: Parallels9Driver{
|
2016-12-11 13:49:54 -05:00
|
|
|
|
PrlctlPath: prlctlPath,
|
|
|
|
|
PrlsrvctlPath: prlsrvctlPath,
|
|
|
|
|
dhcpLeaseFile: DHCPLeaseFile,
|
2014-08-20 07:49:29 -04:00
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
"9": &Parallels9Driver{
|
2016-12-11 13:49:54 -05:00
|
|
|
|
PrlctlPath: prlctlPath,
|
|
|
|
|
PrlsrvctlPath: prlsrvctlPath,
|
|
|
|
|
dhcpLeaseFile: DHCPLeaseFile,
|
2014-08-20 07:49:29 -04:00
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for v, d := range drivers {
|
|
|
|
|
version, _ := d.Version()
|
|
|
|
|
if strings.HasPrefix(version, v) {
|
2015-08-22 07:15:59 -04:00
|
|
|
|
if err := d.Verify(); err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
2014-08-20 07:49:29 -04:00
|
|
|
|
return d, nil
|
|
|
|
|
}
|
|
|
|
|
supportedVersions = append(supportedVersions, v)
|
2014-04-06 13:21:22 -04:00
|
|
|
|
}
|
|
|
|
|
|
2016-07-02 16:18:54 -04:00
|
|
|
|
latestDriver := 11
|
|
|
|
|
version, _ := drivers[strconv.Itoa(latestDriver)].Version()
|
|
|
|
|
majVer, _ := strconv.Atoi(strings.SplitN(version, ".", 2)[0])
|
|
|
|
|
if majVer > latestDriver {
|
|
|
|
|
log.Printf("Your version of Parallels Desktop for Mac is %s, Packer will use driver for version %d.", version, latestDriver)
|
|
|
|
|
return drivers[strconv.Itoa(latestDriver)], nil
|
|
|
|
|
}
|
|
|
|
|
|
2014-08-20 07:49:29 -04:00
|
|
|
|
return nil, fmt.Errorf(
|
|
|
|
|
"Unable to initialize any driver. Supported Parallels Desktop versions: "+
|
|
|
|
|
"%s\n", strings.Join(supportedVersions, ", "))
|
2014-04-06 13:21:22 -04:00
|
|
|
|
}
|