Merge pull request #1440 from legal90/master
Enhancements for Parallels builder
This commit is contained in:
commit
b0161f40fe
|
@ -1,8 +1,11 @@
|
||||||
package common
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"runtime"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// A driver is able to talk to Parallels and perform certain
|
// A driver is able to talk to Parallels and perform certain
|
||||||
|
@ -43,7 +46,14 @@ type Driver interface {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDriver() (Driver, error) {
|
func NewDriver() (Driver, error) {
|
||||||
|
var drivers map[string]Driver
|
||||||
var prlctlPath string
|
var prlctlPath string
|
||||||
|
var supportedVersions []string
|
||||||
|
|
||||||
|
if runtime.GOOS != "darwin" {
|
||||||
|
return nil, fmt.Errorf(
|
||||||
|
"Parallels builder works only on \"darwin\" platform!")
|
||||||
|
}
|
||||||
|
|
||||||
if prlctlPath == "" {
|
if prlctlPath == "" {
|
||||||
var err error
|
var err error
|
||||||
|
@ -54,10 +64,27 @@ func NewDriver() (Driver, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("prlctl path: %s", prlctlPath)
|
log.Printf("prlctl path: %s", prlctlPath)
|
||||||
driver := &Parallels9Driver{prlctlPath}
|
|
||||||
if err := driver.Verify(); err != nil {
|
drivers = map[string]Driver{
|
||||||
return nil, err
|
"10": &Parallels10Driver{
|
||||||
|
Parallels9Driver: Parallels9Driver{
|
||||||
|
PrlctlPath: prlctlPath,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"9": &Parallels9Driver{
|
||||||
|
PrlctlPath: prlctlPath,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
return driver, nil
|
for v, d := range drivers {
|
||||||
|
version, _ := d.Version()
|
||||||
|
if strings.HasPrefix(version, v) {
|
||||||
|
return d, nil
|
||||||
|
}
|
||||||
|
supportedVersions = append(supportedVersions, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, fmt.Errorf(
|
||||||
|
"Unable to initialize any driver. Supported Parallels Desktop versions: "+
|
||||||
|
"%s\n", strings.Join(supportedVersions, ", "))
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
package common
|
||||||
|
|
||||||
|
// Parallels10Driver are inherited from Parallels9Driver.
|
||||||
|
type Parallels10Driver struct {
|
||||||
|
Parallels9Driver
|
||||||
|
}
|
|
@ -13,7 +13,6 @@ import (
|
||||||
"github.com/going/toolkit/xmlpath"
|
"github.com/going/toolkit/xmlpath"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Driver supporting Parallels Desktop for Mac v. 9 & 10
|
|
||||||
type Parallels9Driver struct {
|
type Parallels9Driver struct {
|
||||||
// This is the path to the "prlctl" application.
|
// This is the path to the "prlctl" application.
|
||||||
PrlctlPath string
|
PrlctlPath string
|
||||||
|
@ -72,6 +71,20 @@ func getConfigValueFromXpath(path, xpath string) (string, error) {
|
||||||
return value, nil
|
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) {
|
func (d *Parallels9Driver) IsRunning(name string) (bool, error) {
|
||||||
var stdout bytes.Buffer
|
var stdout bytes.Buffer
|
||||||
|
|
||||||
|
@ -136,32 +149,24 @@ func (d *Parallels9Driver) Prlctl(args ...string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Parallels9Driver) Verify() 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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Parallels9Driver) Version() (string, error) {
|
func (d *Parallels9Driver) Version() (string, error) {
|
||||||
var stdout bytes.Buffer
|
out, err := exec.Command(d.PrlctlPath, "--version").Output()
|
||||||
|
if err != nil {
|
||||||
cmd := exec.Command(d.PrlctlPath, "--version")
|
|
||||||
cmd.Stdout = &stdout
|
|
||||||
if err := cmd.Run(); err != nil {
|
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
versionOutput := strings.TrimSpace(stdout.String())
|
versionRe := regexp.MustCompile(`prlctl version (\d+\.\d+.\d+)`)
|
||||||
re := regexp.MustCompile("prlctl version ([0-9\\.]+)")
|
matches := versionRe.FindStringSubmatch(string(out))
|
||||||
verMatch := re.FindAllStringSubmatch(versionOutput, 1)
|
if matches == nil {
|
||||||
|
return "", fmt.Errorf(
|
||||||
if len(verMatch) != 1 {
|
"Could not find Parallels Desktop version in output:\n%s", string(out))
|
||||||
return "", fmt.Errorf("prlctl version not found!\n")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
version := verMatch[0][1]
|
version := matches[1]
|
||||||
log.Printf("prlctl version: %s\n", version)
|
log.Printf("Parallels Desktop version: %s", version)
|
||||||
return version, nil
|
return version, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,6 @@ type config struct {
|
||||||
ParallelsToolsMode string `mapstructure:"parallels_tools_mode"`
|
ParallelsToolsMode string `mapstructure:"parallels_tools_mode"`
|
||||||
ParallelsToolsGuestPath string `mapstructure:"parallels_tools_guest_path"`
|
ParallelsToolsGuestPath string `mapstructure:"parallels_tools_guest_path"`
|
||||||
ParallelsToolsHostPath string `mapstructure:"parallels_tools_host_path"`
|
ParallelsToolsHostPath string `mapstructure:"parallels_tools_host_path"`
|
||||||
GuestOSType string `mapstructure:"guest_os_type"`
|
|
||||||
GuestOSDistribution string `mapstructure:"guest_os_distribution"`
|
GuestOSDistribution string `mapstructure:"guest_os_distribution"`
|
||||||
HardDriveInterface string `mapstructure:"hard_drive_interface"`
|
HardDriveInterface string `mapstructure:"hard_drive_interface"`
|
||||||
HostInterfaces []string `mapstructure:"host_interfaces"`
|
HostInterfaces []string `mapstructure:"host_interfaces"`
|
||||||
|
@ -47,6 +46,9 @@ type config struct {
|
||||||
|
|
||||||
RawSingleISOUrl string `mapstructure:"iso_url"`
|
RawSingleISOUrl string `mapstructure:"iso_url"`
|
||||||
|
|
||||||
|
// Deprecated parameters
|
||||||
|
GuestOSType string `mapstructure:"guest_os_type"`
|
||||||
|
|
||||||
tpl *packer.ConfigTemplate
|
tpl *packer.ConfigTemplate
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,10 +97,6 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
||||||
b.config.HardDriveInterface = "sata"
|
b.config.HardDriveInterface = "sata"
|
||||||
}
|
}
|
||||||
|
|
||||||
if b.config.GuestOSType == "" {
|
|
||||||
b.config.GuestOSType = "other"
|
|
||||||
}
|
|
||||||
|
|
||||||
if b.config.GuestOSDistribution == "" {
|
if b.config.GuestOSDistribution == "" {
|
||||||
b.config.GuestOSDistribution = "other"
|
b.config.GuestOSDistribution = "other"
|
||||||
}
|
}
|
||||||
|
@ -125,7 +123,6 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
||||||
"parallels_tools_mode": &b.config.ParallelsToolsMode,
|
"parallels_tools_mode": &b.config.ParallelsToolsMode,
|
||||||
"parallels_tools_host_path": &b.config.ParallelsToolsHostPath,
|
"parallels_tools_host_path": &b.config.ParallelsToolsHostPath,
|
||||||
"parallels_tools_guest_path": &b.config.ParallelsToolsGuestPath,
|
"parallels_tools_guest_path": &b.config.ParallelsToolsGuestPath,
|
||||||
"guest_os_type": &b.config.GuestOSType,
|
|
||||||
"guest_os_distribution": &b.config.GuestOSDistribution,
|
"guest_os_distribution": &b.config.GuestOSDistribution,
|
||||||
"hard_drive_interface": &b.config.HardDriveInterface,
|
"hard_drive_interface": &b.config.HardDriveInterface,
|
||||||
"http_directory": &b.config.HTTPDir,
|
"http_directory": &b.config.HTTPDir,
|
||||||
|
|
|
@ -42,8 +42,8 @@ func TestBuilderPrepare_Defaults(t *testing.T) {
|
||||||
t.Errorf("bad parallels tools mode: %s", b.config.ParallelsToolsMode)
|
t.Errorf("bad parallels tools mode: %s", b.config.ParallelsToolsMode)
|
||||||
}
|
}
|
||||||
|
|
||||||
if b.config.GuestOSType != "other" {
|
if b.config.GuestOSDistribution != "other" {
|
||||||
t.Errorf("bad guest OS type: %s", b.config.GuestOSType)
|
t.Errorf("bad guest OS distribution: %s", b.config.GuestOSDistribution)
|
||||||
}
|
}
|
||||||
|
|
||||||
if b.config.VMName != "packer-foo" {
|
if b.config.VMName != "packer-foo" {
|
||||||
|
|
|
@ -28,7 +28,6 @@ func (s *stepCreateVM) Run(state multistep.StateBag) multistep.StepAction {
|
||||||
commands := make([][]string, 8)
|
commands := make([][]string, 8)
|
||||||
commands[0] = []string{
|
commands[0] = []string{
|
||||||
"create", name,
|
"create", name,
|
||||||
"--ostype", config.GuestOSType,
|
|
||||||
"--distribution", config.GuestOSDistribution,
|
"--distribution", config.GuestOSDistribution,
|
||||||
"--dst", path,
|
"--dst", path,
|
||||||
"--vmtype", "vm",
|
"--vmtype", "vm",
|
||||||
|
|
Loading…
Reference in New Issue