From fc2d695b0fbbc9041ccff80b14c09f2a745f4afa Mon Sep 17 00:00:00 2001 From: Mikhail Zholobov Date: Wed, 20 Aug 2014 15:49:29 +0400 Subject: [PATCH] builder/parallels: Added compatibility with Parallels Desktop 10 --- builder/parallels/common/driver.go | 30 +++++++++++++++++--- builder/parallels/common/driver_10.go | 6 ++++ builder/parallels/common/driver_9.go | 41 +++++++++++++++------------ 3 files changed, 55 insertions(+), 22 deletions(-) create mode 100644 builder/parallels/common/driver_10.go diff --git a/builder/parallels/common/driver.go b/builder/parallels/common/driver.go index 5b91771a3..ab9693461 100644 --- a/builder/parallels/common/driver.go +++ b/builder/parallels/common/driver.go @@ -1,8 +1,11 @@ package common import ( + "fmt" "log" "os/exec" + "runtime" + "strings" ) // A driver is able to talk to Parallels and perform certain @@ -43,7 +46,9 @@ type Driver interface { } func NewDriver() (Driver, error) { + var drivers map[string]Driver var prlctlPath string + var supportedVersions []string if runtime.GOOS != "darwin" { return nil, fmt.Errorf( @@ -59,10 +64,27 @@ func NewDriver() (Driver, error) { } log.Printf("prlctl path: %s", prlctlPath) - driver := &Parallels9Driver{prlctlPath} - if err := driver.Verify(); err != nil { - return nil, err + + drivers = map[string]Driver{ + "10": &Parallels10Driver{ + Parallels9Driver: Parallels9Driver{ + PrlctlPath: prlctlPath, + }, + }, + "9": &Parallels9Driver{ + PrlctlPath: prlctlPath, + }, + } + + for v, d := range drivers { + version, _ := d.Version() + if strings.HasPrefix(version, v) { + return d, nil + } + supportedVersions = append(supportedVersions, v) } - return driver, nil + return nil, fmt.Errorf( + "Unable to initialize any driver. Supported Parallels Desktop versions: "+ + "%s\n", strings.Join(supportedVersions, ", ")) } diff --git a/builder/parallels/common/driver_10.go b/builder/parallels/common/driver_10.go new file mode 100644 index 000000000..ae39240f4 --- /dev/null +++ b/builder/parallels/common/driver_10.go @@ -0,0 +1,6 @@ +package common + +// Parallels10Driver are inherited from Parallels9Driver. +type Parallels10Driver struct { + Parallels9Driver +} diff --git a/builder/parallels/common/driver_9.go b/builder/parallels/common/driver_9.go index 20255beb9..54e93a4bf 100644 --- a/builder/parallels/common/driver_9.go +++ b/builder/parallels/common/driver_9.go @@ -13,7 +13,6 @@ import ( "github.com/going/toolkit/xmlpath" ) -// Driver supporting Parallels Desktop for Mac v. 9 & 10 type Parallels9Driver struct { // This is the path to the "prlctl" application. PrlctlPath string @@ -72,6 +71,20 @@ func getConfigValueFromXpath(path, xpath string) (string, error) { return value, nil } +// Finds an application bundle by identifier (for "darwin" platform only) +func getAppPath(bundleId string) (string, error) { + cmd := exec.Command("mdfind", "kMDItemCFBundleIdentifier ==", bundleId) + out, err := cmd.Output() + if err != nil { + return "", err + } + if string(out) == "" { + return "", fmt.Errorf( + "Could not detect Parallels Desktop! Make sure it is properly installed.") + } + return string(out), nil +} + func (d *Parallels9Driver) IsRunning(name string) (bool, error) { var stdout bytes.Buffer @@ -136,32 +149,24 @@ func (d *Parallels9Driver) Prlctl(args ...string) error { } func (d *Parallels9Driver) Verify() error { - version, _ := d.Version() - if !(strings.HasPrefix(version, "9.") || strings.HasPrefix(version, "10.")) { - return fmt.Errorf("The packer-parallels builder plugin only supports Parallels Desktop v. 9 & 10. You have: %s!\n", version) - } return nil } func (d *Parallels9Driver) Version() (string, error) { - var stdout bytes.Buffer - - cmd := exec.Command(d.PrlctlPath, "--version") - cmd.Stdout = &stdout - if err := cmd.Run(); err != nil { + out, err := exec.Command(d.PrlctlPath, "--version").Output() + if err != nil { return "", err } - versionOutput := strings.TrimSpace(stdout.String()) - re := regexp.MustCompile("prlctl version ([0-9\\.]+)") - verMatch := re.FindAllStringSubmatch(versionOutput, 1) - - if len(verMatch) != 1 { - return "", fmt.Errorf("prlctl version not found!\n") + versionRe := regexp.MustCompile(`prlctl version (\d+\.\d+.\d+)`) + matches := versionRe.FindStringSubmatch(string(out)) + if matches == nil { + return "", fmt.Errorf( + "Could not find Parallels Desktop version in output:\n%s", string(out)) } - version := verMatch[0][1] - log.Printf("prlctl version: %s\n", version) + version := matches[1] + log.Printf("Parallels Desktop version: %s", version) return version, nil }