129 lines
3.2 KiB
Go
129 lines
3.2 KiB
Go
package common
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"regexp"
|
|
"strings"
|
|
)
|
|
|
|
const VMWARE_FUSION_VERSION = "6"
|
|
|
|
// Fusion6Driver is a driver that can run VMware Fusion 6.
|
|
type Fusion6Driver struct {
|
|
Fusion5Driver
|
|
}
|
|
|
|
func NewFusion6Driver(dconfig *DriverConfig, config *SSHConfig) Driver {
|
|
return &Fusion6Driver{
|
|
Fusion5Driver: Fusion5Driver{
|
|
AppPath: dconfig.FusionAppPath,
|
|
SSHConfig: config,
|
|
},
|
|
}
|
|
}
|
|
|
|
func (d *Fusion6Driver) Clone(dst, src string, linked bool) error {
|
|
|
|
var cloneType string
|
|
if linked {
|
|
cloneType = "linked"
|
|
} else {
|
|
cloneType = "full"
|
|
}
|
|
|
|
cmd := exec.Command(d.vmrunPath(),
|
|
"-T", "fusion",
|
|
"clone", src, dst,
|
|
cloneType)
|
|
if _, _, err := runAndLog(cmd); err != nil {
|
|
if strings.Contains(err.Error(), "parameters was invalid") {
|
|
return fmt.Errorf(
|
|
"Clone is not supported with your version of Fusion. Packer "+
|
|
"only works with Fusion %s Professional or above. Please verify your version.", VMWARE_FUSION_VERSION)
|
|
}
|
|
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (d *Fusion6Driver) Verify() error {
|
|
if err := d.Fusion5Driver.Verify(); err != nil {
|
|
return err
|
|
}
|
|
|
|
vmxpath := filepath.Join(d.AppPath, "Contents", "Library", "vmware-vmx")
|
|
if _, err := os.Stat(vmxpath); err != nil {
|
|
if os.IsNotExist(err) {
|
|
return fmt.Errorf("vmware-vmx could not be found at path: %s",
|
|
vmxpath)
|
|
}
|
|
|
|
return err
|
|
}
|
|
|
|
var stderr bytes.Buffer
|
|
cmd := exec.Command(vmxpath, "-v")
|
|
cmd.Stderr = &stderr
|
|
if err := cmd.Run(); err != nil {
|
|
return err
|
|
}
|
|
|
|
// Example: VMware Fusion e.x.p build-6048684 Release
|
|
techPreviewRe := regexp.MustCompile(`(?i)VMware [a-z0-9-]+ e\.x\.p `)
|
|
matches := techPreviewRe.FindStringSubmatch(stderr.String())
|
|
if matches != nil {
|
|
log.Printf("Detected VMware version: e.x.p (Tech Preview)")
|
|
return nil
|
|
}
|
|
|
|
// Example: VMware Fusion 7.1.3 build-3204469 Release
|
|
versionRe := regexp.MustCompile(`(?i)VMware [a-z0-9-]+ (\d+)\.`)
|
|
matches = versionRe.FindStringSubmatch(stderr.String())
|
|
if matches == nil {
|
|
return fmt.Errorf(
|
|
"Couldn't find VMware version in output: %s", stderr.String())
|
|
}
|
|
log.Printf("Detected VMware version: %s", matches[1])
|
|
|
|
libpath := filepath.Join("/", "Library", "Preferences", "VMware Fusion")
|
|
|
|
d.VmwareDriver.DhcpLeasesPath = func(device string) string {
|
|
return "/var/db/vmware/vmnet-dhcpd-" + device + ".leases"
|
|
}
|
|
d.VmwareDriver.DhcpConfPath = func(device string) string {
|
|
return filepath.Join(libpath, device, "dhcpd.conf")
|
|
}
|
|
|
|
d.VmwareDriver.VmnetnatConfPath = func(device string) string {
|
|
return filepath.Join(libpath, device, "nat.conf")
|
|
}
|
|
d.VmwareDriver.NetworkMapper = func() (NetworkNameMapper, error) {
|
|
pathNetworking := filepath.Join(libpath, "networking")
|
|
if _, err := os.Stat(pathNetworking); err != nil {
|
|
return nil, fmt.Errorf("Could not find networking conf file: %s", pathNetworking)
|
|
}
|
|
log.Printf("Located networkmapper configuration file using Fusion6: %s", pathNetworking)
|
|
|
|
fd, err := os.Open(pathNetworking)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer fd.Close()
|
|
|
|
return ReadNetworkingConfig(fd)
|
|
}
|
|
|
|
return compareVersions(matches[1], VMWARE_FUSION_VERSION, "Fusion Professional")
|
|
}
|
|
|
|
func (d *Fusion6Driver) GetVmwareDriver() VmwareDriver {
|
|
return d.Fusion5Driver.VmwareDriver
|
|
}
|