diff --git a/builder/vmware/driver_workstation9.go b/builder/vmware/driver_workstation9.go index 60b151eaf..f931050ba 100644 --- a/builder/vmware/driver_workstation9.go +++ b/builder/vmware/driver_workstation9.go @@ -1,10 +1,7 @@ -// +build darwin freebsd linux netbsd openbsd - package vmware import ( "bytes" - "errors" "fmt" "log" "os/exec" @@ -88,64 +85,39 @@ func (d *Workstation9Driver) Stop(vmxPath string) error { } func (d *Workstation9Driver) Verify() error { - if err := d.findApp(); err != nil { - return fmt.Errorf("VMware Workstation application ('vmware') not found in path.") + var err error + if d.AppPath == "" { + if d.AppPath, err = workstationFindVMware(); err != nil { + return err + } } - if err := d.findVmrun(); err != nil { - return fmt.Errorf("Required application 'vmrun' not found in path.") + if d.VmrunPath == "" { + if d.VmrunPath, err = workstationFindVmrun(); err != nil { + return err + } } - if err := d.findVdiskManager(); err != nil { - return fmt.Errorf("Required application 'vmware-vdiskmanager' not found in path.") + if d.VdiskManagerPath == "" { + if d.VdiskManagerPath, err = workstationFindVdiskManager(); err != nil { + return err + } } // Check to see if it APPEARS to be licensed. - matches, err := filepath.Glob("/etc/vmware/license-*") - if err != nil { - return fmt.Errorf("Error looking for VMware license: %s", err) - } - - if len(matches) == 0 { - return errors.New("Workstation does not appear to be licensed. Please license it.") - } - - return nil -} - -func (d *Workstation9Driver) findApp() error { - path, err := exec.LookPath("vmware") - if err != nil { - return err - } - d.AppPath = path - return nil -} - -func (d *Workstation9Driver) findVdiskManager() error { - path, err := exec.LookPath("vmware-vdiskmanager") - if err != nil { + if err := workstationCheckLicense(); err != nil { return err } - d.VdiskManagerPath = path - return nil -} -func (d *Workstation9Driver) findVmrun() error { - path, err := exec.LookPath("vmrun") - if err != nil { - return err - } - d.VmrunPath = path return nil } func (d *Workstation9Driver) ToolsIsoPath(flavor string) string { - return "/usr/lib/vmware/isoimages/" + flavor + ".iso" + return workstationToolsIsoPath(flavor) } func (d *Workstation9Driver) DhcpLeasesPath(device string) string { - return "/etc/vmware/" + device + "/dhcpd/dhcpd.leases" + return workstationDhcpLeasesPath(device) } func (d *Workstation9Driver) runAndLog(cmd *exec.Cmd) (string, string, error) { diff --git a/builder/vmware/driver_workstation9_unix.go b/builder/vmware/driver_workstation9_unix.go new file mode 100644 index 000000000..8c96e7219 --- /dev/null +++ b/builder/vmware/driver_workstation9_unix.go @@ -0,0 +1,43 @@ +// +build !windows + +package vmware + +import ( + "errors" + "fmt" + "os/exec" + "path/filepath" +) + +func workstationCheckLicense() error { + matches, err := filepath.Glob("/etc/vmware/license-*") + if err != nil { + return fmt.Errorf("Error looking for VMware license: %s", err) + } + + if len(matches) == 0 { + return errors.New("Workstation does not appear to be licensed. Please license it.") + } + + return nil +} + +func workstationFindVdiskManager() (string, error) { + return exec.LookPath("vmware-vdiskmanager") +} + +func workstationFindVMware() (string, error) { + return exec.LookPath("vmware") +} + +func workstationFindVmrun() (string, error) { + return exec.LookPath("vmrun") +} + +func workstationDhcpLeasesPath(device string) string { + return "/etc/vmware/" + device + "/dhcpd/dhcpd.leases" +} + +func workstationToolsIsoPath(flavor string) string { + return "/usr/lib/vmware/isoimages/" + flavor + ".iso" +} diff --git a/builder/vmware/driver_workstation9_windows.go b/builder/vmware/driver_workstation9_windows.go index 67ccb8096..69c0ad483 100644 --- a/builder/vmware/driver_workstation9_windows.go +++ b/builder/vmware/driver_workstation9_windows.go @@ -1,11 +1,8 @@ // +build windows -// Contributed by Ross Smith II (smithii.com) package vmware import ( - "bytes" - "fmt" "log" "os" "os/exec" @@ -15,196 +12,74 @@ import ( "unsafe" ) -// Workstation9Driver is a driver that can run VMware Workstation 9 -// on Windows. -type Workstation9Driver struct { - AppPath string - VdiskManagerPath string - VmrunPath string -} - -func (d *Workstation9Driver) CompactDisk(diskPath string) error { - defragCmd := exec.Command(d.VdiskManagerPath, "-d", diskPath) - if _, _, err := d.runAndLog(defragCmd); err != nil { - return err - } - - shrinkCmd := exec.Command(d.VdiskManagerPath, "-k", diskPath) - if _, _, err := d.runAndLog(shrinkCmd); err != nil { - return err - } - +func workstationCheckLicense() error { + // Not implemented on Windows return nil } -func (d *Workstation9Driver) CreateDisk(output string, size string) error { - cmd := exec.Command(d.VdiskManagerPath, "-c", "-s", size, "-a", "lsilogic", "-t", "1", output) - if _, _, err := d.runAndLog(cmd); err != nil { - return err - } - - return nil -} - -func (d *Workstation9Driver) IsRunning(vmxPath string) (bool, error) { - vmxPath, err := filepath.Abs(vmxPath) - if err != nil { - return false, err +func workstationFindVdiskManager() (string, error) { + path, err := exec.LookPath("vmware-vdiskmanager.exe") + if err == nil { + return path, nil } - cmd := exec.Command(d.VmrunPath, "-T", "ws", "list") - stdout, _, err := d.runAndLog(cmd) + path, err = workstationVMwareRoot() if err != nil { - return false, err - } - - for _, line := range strings.Split(stdout, "\n") { - if line == vmxPath { - return true, nil - } + return "", err } - return false, nil + return filepath.Join(path, "vmware-vdiskmanager.exe"), nil } -func (d *Workstation9Driver) Start(vmxPath string, headless bool) error { - guiArgument := "gui" - if headless { - guiArgument = "nogui" - } - - cmd := exec.Command(d.VmrunPath, "-T", "ws", "start", vmxPath, guiArgument) - if _, _, err := d.runAndLog(cmd); err != nil { - return err - } - - return nil -} - -func (d *Workstation9Driver) Stop(vmxPath string) error { - cmd := exec.Command(d.VmrunPath, "-T", "ws", "stop", vmxPath, "hard") - if _, _, err := d.runAndLog(cmd); err != nil { - return err - } - - return nil -} - -func (d *Workstation9Driver) Verify() error { - if err := d.findApp(); err != nil { - return fmt.Errorf("VMware Workstation application ('vmware') not found in path.") - } - - if err := d.findVmrun(); err != nil { - return fmt.Errorf("Required application 'vmrun' not found in path.") - } - - if err := d.findVdiskManager(); err != nil { - return fmt.Errorf("Required application 'vmware-vdiskmanager' not found in path.") +func workstationFindVMware() (string, error) { + path, err := exec.LookPath("vmware.exe") + if err == nil { + return path, nil } - // Check to see if it APPEARS to be licensed. - /* - matches, err := filepath.Glob("/etc/vmware/license-*") - if err != nil { - return fmt.Errorf("Error looking for VMware license: %s", err) - } - - if len(matches) == 0 { - return errors.New("Workstation does not appear to be licensed. Please license it.") - } - */ - return nil -} - -func (d *Workstation9Driver) findApp() error { - path, err := exec.LookPath("vmware.exe") + path, err = workstationVMwareRoot() if err != nil { - path, err := getVmwarePath() - if err != nil { - return err - } - path += "vmware.exe" + return "", err } - path = strings.Replace(path, "\\", "/", -1) - log.Printf("Using '%s' for vmware path", path) - d.AppPath = path - return nil + return filepath.Join(path, "vmware.exe"), nil } -func (d *Workstation9Driver) findVdiskManager() error { - path, err := exec.LookPath("vmware-vdiskmanager.exe") - if err != nil { - path, err := getVmwarePath() - if err != nil { - return err - } - path += "vmware-vdiskmanager.exe" +func workstationFindVmrun() (string, error) { + path, err := exec.LookPath("vmrun.exe") + if err == nil { + return path, nil } - path = strings.Replace(path, "\\", "/", -1) - log.Printf("Using '%s' for vmware-vdiskmanager path", path) - d.VdiskManagerPath = path - return nil -} -func (d *Workstation9Driver) findVmrun() error { - path, err := exec.LookPath("vmrun.exe") + path, err = workstationVMwareRoot() if err != nil { - path, err := getVmwarePath() - if err != nil { - return err - } - path += "vmrun.exe" + return "", err } - path = strings.Replace(path, "\\", "/", -1) - log.Printf("Using '%s' for vmrun path", path) - d.VmrunPath = path - return nil + + return filepath.Join(path, "vmrun.exe"), nil } -func (d *Workstation9Driver) ToolsIsoPath(flavor string) string { - path, err := getVmwarePath() +func workstationToolsIsoPath(flavor string) string { + path, err := workstationVMwareRoot() if err != nil { return "" - } else { - return path + flavor + ".iso" } + + return filepath.Join(path, flavor+".iso") } -func (d *Workstation9Driver) DhcpLeasesPath(device string) string { +func workstationDhcpLeasesPath(device string) string { programData := os.Getenv("ProgramData") - rv := programData + "/VMware/vmnetdhcp.leases" - if _, err := os.Stat(rv); os.IsNotExist(err) { - log.Printf("File not found: '%s' (found '%s' in %%ProgramData%%)", rv, programData) + if programData == "" { return "" } - return rv -} - -func (d *Workstation9Driver) runAndLog(cmd *exec.Cmd) (string, string, error) { - var stdout, stderr bytes.Buffer - - log.Printf("Executing: %s %v", cmd.Path, cmd.Args[1:]) - cmd.Stdout = &stdout - cmd.Stderr = &stderr - err := cmd.Run() - - stdoutString := strings.TrimSpace(stdout.String()) - stderrString := strings.TrimSpace(stderr.String()) - - if _, ok := err.(*exec.ExitError); ok { - err = fmt.Errorf("VMware error: %s", stderrString) - } - log.Printf("stdout: %s", stdoutString) - log.Printf("stderr: %s", stderrString) - - return stdout.String(), stderr.String(), err + return filepath.Join(programData, "/VMware/vmnetdhcp.leases") } -// see http://blog.natefinch.com/2012/11/go-win-stuff.html - +// See http://blog.natefinch.com/2012/11/go-win-stuff.html +// +// This is used by workstationVMwareRoot in order to read some registry data. func readRegString(hive syscall.Handle, subKeyPath, valueName string) (value string, err error) { var h syscall.Handle err = syscall.RegOpenKeyEx(hive, syscall.StringToUTF16Ptr(subKeyPath), 0, syscall.KEY_READ, &h) @@ -215,7 +90,6 @@ func readRegString(hive syscall.Handle, subKeyPath, valueName string) (value str var typ uint32 var bufSize uint32 - err = syscall.RegQueryValueEx( h, syscall.StringToUTF16Ptr(valueName), @@ -228,7 +102,6 @@ func readRegString(hive syscall.Handle, subKeyPath, valueName string) (value str } data := make([]uint16, bufSize/2+1) - err = syscall.RegQueryValueEx( h, syscall.StringToUTF16Ptr(valueName), @@ -243,15 +116,16 @@ func readRegString(hive syscall.Handle, subKeyPath, valueName string) (value str return syscall.UTF16ToString(data), nil } -func getVmwarePath() (s string, e error) { - key := "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\vmware.exe" +// This reads the VMware installation path from the Windows registry. +func workstationVMwareRoot() (s string, err error) { + key := `SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\vmware.exe` subkey := "Path" - s, e = readRegString(syscall.HKEY_LOCAL_MACHINE, key, subkey) - if e != nil { - log.Printf("Unable to read registry key %s\\%s", key, subkey) - return "", e + s, err = readRegString(syscall.HKEY_LOCAL_MACHINE, key, subkey) + if err != nil { + log.Printf(`Unable to read registry key %s\%s`, key, subkey) + return } - log.Printf("Found '%s' in registry key %s\\%s", s, key, subkey) + s = strings.Replace(s, "\\", "/", -1) - return s, nil + return }