From 071a6099c834c577a347bc3a6003d6be50cfef6e Mon Sep 17 00:00:00 2001 From: Ross Smith II Date: Sat, 27 Jul 2013 13:00:21 -0700 Subject: [PATCH 1/4] fixes #221 Add support for VMWare Workstation in Windows --- builder/vmware/driver.go | 3 +- builder/vmware/driver_workstation9.go | 32 +-- builder/vmware/driver_workstation9_windows.go | 254 ++++++++++++++++++ builder/vmware/guest_ip.go | 3 + builder/vmware/host_ip.go | 2 + builder/vmware/host_ip_windows.go | 109 ++++++++ scripts/dist.sh | 1 + 7 files changed, 388 insertions(+), 16 deletions(-) create mode 100644 builder/vmware/driver_workstation9_windows.go create mode 100644 builder/vmware/host_ip_windows.go mode change 100755 => 100644 scripts/dist.sh diff --git a/builder/vmware/driver.go b/builder/vmware/driver.go index 308365c7d..bb0eb6b24 100644 --- a/builder/vmware/driver.go +++ b/builder/vmware/driver.go @@ -46,7 +46,8 @@ func NewDriver() (Driver, error) { AppPath: "/Applications/VMware Fusion.app", } case "linux": - driver = &Workstation9LinuxDriver{} + case "windows": + driver = &Workstation9Driver{} default: return nil, fmt.Errorf("can't find driver for OS: %s", runtime.GOOS) } diff --git a/builder/vmware/driver_workstation9.go b/builder/vmware/driver_workstation9.go index 7d86d8d66..60b151eaf 100644 --- a/builder/vmware/driver_workstation9.go +++ b/builder/vmware/driver_workstation9.go @@ -1,3 +1,5 @@ +// +build darwin freebsd linux netbsd openbsd + package vmware import ( @@ -10,15 +12,15 @@ import ( "strings" ) -// Workstation9LinuxDriver is a driver that can run VMware Workstation 9 -// on Linux. -type Workstation9LinuxDriver struct { +// Workstation9Driver is a driver that can run VMware Workstation 9 +// on non-Windows platforms. +type Workstation9Driver struct { AppPath string VdiskManagerPath string VmrunPath string } -func (d *Workstation9LinuxDriver) CompactDisk(diskPath string) error { +func (d *Workstation9Driver) CompactDisk(diskPath string) error { defragCmd := exec.Command(d.VdiskManagerPath, "-d", diskPath) if _, _, err := d.runAndLog(defragCmd); err != nil { return err @@ -32,7 +34,7 @@ func (d *Workstation9LinuxDriver) CompactDisk(diskPath string) error { return nil } -func (d *Workstation9LinuxDriver) CreateDisk(output string, size string) error { +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 @@ -41,7 +43,7 @@ func (d *Workstation9LinuxDriver) CreateDisk(output string, size string) error { return nil } -func (d *Workstation9LinuxDriver) IsRunning(vmxPath string) (bool, error) { +func (d *Workstation9Driver) IsRunning(vmxPath string) (bool, error) { vmxPath, err := filepath.Abs(vmxPath) if err != nil { return false, err @@ -62,7 +64,7 @@ func (d *Workstation9LinuxDriver) IsRunning(vmxPath string) (bool, error) { return false, nil } -func (d *Workstation9LinuxDriver) Start(vmxPath string, headless bool) error { +func (d *Workstation9Driver) Start(vmxPath string, headless bool) error { guiArgument := "gui" if headless { guiArgument = "nogui" @@ -76,7 +78,7 @@ func (d *Workstation9LinuxDriver) Start(vmxPath string, headless bool) error { return nil } -func (d *Workstation9LinuxDriver) Stop(vmxPath string) error { +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 @@ -85,7 +87,7 @@ func (d *Workstation9LinuxDriver) Stop(vmxPath string) error { return nil } -func (d *Workstation9LinuxDriver) Verify() error { +func (d *Workstation9Driver) Verify() error { if err := d.findApp(); err != nil { return fmt.Errorf("VMware Workstation application ('vmware') not found in path.") } @@ -111,7 +113,7 @@ func (d *Workstation9LinuxDriver) Verify() error { return nil } -func (d *Workstation9LinuxDriver) findApp() error { +func (d *Workstation9Driver) findApp() error { path, err := exec.LookPath("vmware") if err != nil { return err @@ -120,7 +122,7 @@ func (d *Workstation9LinuxDriver) findApp() error { return nil } -func (d *Workstation9LinuxDriver) findVdiskManager() error { +func (d *Workstation9Driver) findVdiskManager() error { path, err := exec.LookPath("vmware-vdiskmanager") if err != nil { return err @@ -129,7 +131,7 @@ func (d *Workstation9LinuxDriver) findVdiskManager() error { return nil } -func (d *Workstation9LinuxDriver) findVmrun() error { +func (d *Workstation9Driver) findVmrun() error { path, err := exec.LookPath("vmrun") if err != nil { return err @@ -138,15 +140,15 @@ func (d *Workstation9LinuxDriver) findVmrun() error { return nil } -func (d *Workstation9LinuxDriver) ToolsIsoPath(flavor string) string { +func (d *Workstation9Driver) ToolsIsoPath(flavor string) string { return "/usr/lib/vmware/isoimages/" + flavor + ".iso" } -func (d *Workstation9LinuxDriver) DhcpLeasesPath(device string) string { +func (d *Workstation9Driver) DhcpLeasesPath(device string) string { return "/etc/vmware/" + device + "/dhcpd/dhcpd.leases" } -func (d *Workstation9LinuxDriver) runAndLog(cmd *exec.Cmd) (string, string, error) { +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:]) diff --git a/builder/vmware/driver_workstation9_windows.go b/builder/vmware/driver_workstation9_windows.go new file mode 100644 index 000000000..b88dfbc43 --- /dev/null +++ b/builder/vmware/driver_workstation9_windows.go @@ -0,0 +1,254 @@ +// +build windows +// Contributed by Ross Smith II (smithii.com) + +package vmware + +import ( + "bytes" + "fmt" + "log" + "os" + "os/exec" + "path/filepath" + "strings" + "unsafe" + "syscall" +) + +// 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 + } + + 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 + } + + cmd := exec.Command(d.VmrunPath, "-T", "ws", "list") + stdout, _, err := d.runAndLog(cmd) + if err != nil { + return false, err + } + + for _, line := range strings.Split(stdout, "\n") { + if line == vmxPath { + return true, nil + } + } + + return false, 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.") + } + + // 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") + if err != nil { + path, err := getVmwarePath() + if err != nil { + return err + } + path += "vmware.exe" + } + log.Printf("Using '%s' for vmware path", path) + d.AppPath = path + + return 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" + } + 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") + if err != nil { + path, err := getVmwarePath() + if err != nil { + return err + } + path += "vmrun.exe" + } + log.Printf("Using '%s' for vmrun path", path) + d.VmrunPath = path + return nil +} + +func (d *Workstation9Driver) ToolsIsoPath(flavor string) string { + path, err := getVmwarePath() + if err != nil { + return "" + } else { + return path + flavor + ".iso" + } +} + +func (d *Workstation9Driver) DhcpLeasesPath(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) + 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 +} + +// see http://blog.natefinch.com/2012/11/go-win-stuff.html + +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) + if err != nil { + return + } + defer syscall.RegCloseKey(h) + + var typ uint32 + var bufSize uint32 + + err = syscall.RegQueryValueEx( + h, + syscall.StringToUTF16Ptr(valueName), + nil, + &typ, + nil, + &bufSize) + if err != nil { + return + } + + data := make([]uint16, bufSize/2+1) + + err = syscall.RegQueryValueEx( + h, + syscall.StringToUTF16Ptr(valueName), + nil, + &typ, + (*byte)(unsafe.Pointer(&data[0])), + &bufSize) + if err != nil { + return + } + + return syscall.UTF16ToString(data), nil +} + +func getVmwarePath() (s string, e 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 + } + log.Printf("Found '%s' in registry key %s\\%s", s, key, subkey) + s = strings.Replace(s, "\\", "/", -1) + return s, nil +} diff --git a/builder/vmware/guest_ip.go b/builder/vmware/guest_ip.go index 2a79d52ff..ddf7506d5 100644 --- a/builder/vmware/guest_ip.go +++ b/builder/vmware/guest_ip.go @@ -50,6 +50,9 @@ func (f *DHCPLeaseGuestLookup) GuestIP() (string, error) { macLineRe := regexp.MustCompile(`^\s*hardware ethernet (.+?);$`) for _, line := range strings.Split(string(dhcpBytes), "\n") { + // Need to trim off CR character when running in windows + line = strings.TrimRight(line, "\r"); + matches := ipLineRe.FindStringSubmatch(line) if matches != nil { lastIp = matches[1] diff --git a/builder/vmware/host_ip.go b/builder/vmware/host_ip.go index 053e70432..44163b9c3 100644 --- a/builder/vmware/host_ip.go +++ b/builder/vmware/host_ip.go @@ -1,3 +1,5 @@ +// +build darwin freebsd linux netbsd openbsd + package vmware import ( diff --git a/builder/vmware/host_ip_windows.go b/builder/vmware/host_ip_windows.go new file mode 100644 index 000000000..6d4e06bf3 --- /dev/null +++ b/builder/vmware/host_ip_windows.go @@ -0,0 +1,109 @@ +// +build windows +// Contributed by Ross Smith II (smithii.com) + +package vmware + +import ( + "errors" + "regexp" + "log" + "strings" + "net" + "os" + "io/ioutil" +) + +// Interface to help find the host IP that is available from within +// the VMware virtual machines. +type HostIPFinder interface { + HostIP() (string, error) +} + +// IfconfigIPFinder finds the host IP based on the output of `ifconfig`. +type IfconfigIPFinder struct { + Device string +} + +func (f *IfconfigIPFinder) HostIP() (string, error) { + ift, err := net.Interfaces() + if err != nil { + return "", errors.New("No network interfaces found") + } + + vmwareMac, err := getVMWareMAC() + if err != nil { + log.Print(err) + } + + log.Printf("Searching for MAC %s", vmwareMac) + re := regexp.MustCompile("(?i)^" + vmwareMac) + + var rv string + + for _, ifi := range ift { + log.Printf("Found interface %s", ifi.HardwareAddr.String()) + + matches := re.FindStringSubmatch(ifi.HardwareAddr.String()) + + if matches == nil { + continue + } + + addrs, err := ifi.Addrs() + if err != nil { + log.Printf("No IP addresses found for %s", ifi.HardwareAddr.String()) + continue + } + + for _, address := range addrs { + rv = address.String() + log.Printf("Found VMWare IP address %s", address.String()) + } + + // continue looping as VMNet8 comes after VMNet1 (at least on my system) + } + + if rv > "" { + return rv, nil + } + + return "", errors.New("No VMWare MAC addresses found") +} + +func getVMWareMAC() (string, error) { + // return the first three tuples, if the actual MAC cannot be found + const defaultMacRe = "00:50:56" + + programData := os.Getenv("ProgramData") + vmnetnat := programData + "/VMware/vmnetnat.conf" + if _, err := os.Stat(vmnetnat); os.IsNotExist(err) { + log.Printf("File not found: '%s' (found '%s' in %%ProgramData%%)", vmnetnat, programData) + return defaultMacRe, err + } + + fh, err := os.Open(vmnetnat) + if err != nil { + return defaultMacRe, err + } + defer fh.Close() + + bytes, err := ioutil.ReadAll(fh) + if err != nil { + return defaultMacRe, err + } + + hostMacRe := regexp.MustCompile(`(?i)^\s*hostMAC\s*=\s*(.+)\s*$`) + + for _, line := range strings.Split(string(bytes), "\n") { + // Need to trim off CR character when running in windows + line = strings.TrimRight(line, "\r"); + + matches := hostMacRe.FindStringSubmatch(line) + if matches != nil { + return matches[1], nil + } + } + + return defaultMacRe, nil + +} diff --git a/scripts/dist.sh b/scripts/dist.sh old mode 100755 new mode 100644 index 058d82781..066992caf --- a/scripts/dist.sh +++ b/scripts/dist.sh @@ -36,6 +36,7 @@ xc() { -d="${DIR}/pkg" \ -pv="${VERSION}" \ -pr="${PREVERSION}" \ + $XC_OPTS \ go-install \ xc } From 56c383cf68ef133e8cb84ab5759286eb30e0dc4a Mon Sep 17 00:00:00 2001 From: Ross Smith II Date: Sat, 27 Jul 2013 14:59:23 -0700 Subject: [PATCH 2/4] gofmt fixes, improved/added log messages, fixes #221/#222 --- builder/vmware/driver_workstation9_windows.go | 83 ++++++++++--------- builder/vmware/guest_ip.go | 2 +- builder/vmware/host_ip_windows.go | 35 +++++--- 3 files changed, 66 insertions(+), 54 deletions(-) diff --git a/builder/vmware/driver_workstation9_windows.go b/builder/vmware/driver_workstation9_windows.go index b88dfbc43..67ccb8096 100644 --- a/builder/vmware/driver_workstation9_windows.go +++ b/builder/vmware/driver_workstation9_windows.go @@ -11,8 +11,8 @@ import ( "os/exec" "path/filepath" "strings" + "syscall" "unsafe" - "syscall" ) // Workstation9Driver is a driver that can run VMware Workstation 9 @@ -104,16 +104,16 @@ func (d *Workstation9Driver) Verify() error { } // 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) - } + /* + 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.") - } -*/ + if len(matches) == 0 { + return errors.New("Workstation does not appear to be licensed. Please license it.") + } + */ return nil } @@ -126,6 +126,7 @@ func (d *Workstation9Driver) findApp() error { } path += "vmware.exe" } + path = strings.Replace(path, "\\", "/", -1) log.Printf("Using '%s' for vmware path", path) d.AppPath = path @@ -141,6 +142,7 @@ func (d *Workstation9Driver) findVdiskManager() error { } path += "vmware-vdiskmanager.exe" } + path = strings.Replace(path, "\\", "/", -1) log.Printf("Using '%s' for vmware-vdiskmanager path", path) d.VdiskManagerPath = path return nil @@ -155,6 +157,7 @@ func (d *Workstation9Driver) findVmrun() error { } path += "vmrun.exe" } + path = strings.Replace(path, "\\", "/", -1) log.Printf("Using '%s' for vmrun path", path) d.VmrunPath = path return nil @@ -203,41 +206,41 @@ func (d *Workstation9Driver) runAndLog(cmd *exec.Cmd) (string, string, error) { // see http://blog.natefinch.com/2012/11/go-win-stuff.html 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) - if err != nil { - return - } - defer syscall.RegCloseKey(h) + var h syscall.Handle + err = syscall.RegOpenKeyEx(hive, syscall.StringToUTF16Ptr(subKeyPath), 0, syscall.KEY_READ, &h) + if err != nil { + return + } + defer syscall.RegCloseKey(h) - var typ uint32 - var bufSize uint32 + var typ uint32 + var bufSize uint32 - err = syscall.RegQueryValueEx( - h, - syscall.StringToUTF16Ptr(valueName), - nil, - &typ, - nil, - &bufSize) - if err != nil { - return - } + err = syscall.RegQueryValueEx( + h, + syscall.StringToUTF16Ptr(valueName), + nil, + &typ, + nil, + &bufSize) + if err != nil { + return + } - data := make([]uint16, bufSize/2+1) + data := make([]uint16, bufSize/2+1) - err = syscall.RegQueryValueEx( - h, - syscall.StringToUTF16Ptr(valueName), - nil, - &typ, - (*byte)(unsafe.Pointer(&data[0])), - &bufSize) - if err != nil { - return - } + err = syscall.RegQueryValueEx( + h, + syscall.StringToUTF16Ptr(valueName), + nil, + &typ, + (*byte)(unsafe.Pointer(&data[0])), + &bufSize) + if err != nil { + return + } - return syscall.UTF16ToString(data), nil + return syscall.UTF16ToString(data), nil } func getVmwarePath() (s string, e error) { diff --git a/builder/vmware/guest_ip.go b/builder/vmware/guest_ip.go index ddf7506d5..b7cc6eeef 100644 --- a/builder/vmware/guest_ip.go +++ b/builder/vmware/guest_ip.go @@ -51,7 +51,7 @@ func (f *DHCPLeaseGuestLookup) GuestIP() (string, error) { for _, line := range strings.Split(string(dhcpBytes), "\n") { // Need to trim off CR character when running in windows - line = strings.TrimRight(line, "\r"); + line = strings.TrimRight(line, "\r") matches := ipLineRe.FindStringSubmatch(line) if matches != nil { diff --git a/builder/vmware/host_ip_windows.go b/builder/vmware/host_ip_windows.go index 6d4e06bf3..a6613016d 100644 --- a/builder/vmware/host_ip_windows.go +++ b/builder/vmware/host_ip_windows.go @@ -5,12 +5,12 @@ package vmware import ( "errors" - "regexp" + "io/ioutil" "log" - "strings" "net" "os" - "io/ioutil" + "regexp" + "strings" ) // Interface to help find the host IP that is available from within @@ -38,12 +38,13 @@ func (f *IfconfigIPFinder) HostIP() (string, error) { log.Printf("Searching for MAC %s", vmwareMac) re := regexp.MustCompile("(?i)^" + vmwareMac) - var rv string + ip := "" for _, ifi := range ift { - log.Printf("Found interface %s", ifi.HardwareAddr.String()) + mac := ifi.HardwareAddr.String() + log.Printf("Found MAC %s", mac) - matches := re.FindStringSubmatch(ifi.HardwareAddr.String()) + matches := re.FindStringSubmatch(mac) if matches == nil { continue @@ -51,23 +52,25 @@ func (f *IfconfigIPFinder) HostIP() (string, error) { addrs, err := ifi.Addrs() if err != nil { - log.Printf("No IP addresses found for %s", ifi.HardwareAddr.String()) + log.Printf("No IP addresses found for MAC %s", mac) continue } for _, address := range addrs { - rv = address.String() - log.Printf("Found VMWare IP address %s", address.String()) + ip = address.String() + log.Printf("Found IP address %s for MAC %s", ip, mac) } // continue looping as VMNet8 comes after VMNet1 (at least on my system) } - if rv > "" { - return rv, nil + if ip == "" { + return "", errors.New("No MACs found matching " + vmwareMac) } - return "", errors.New("No VMWare MAC addresses found") + log.Printf("Returning IP address %s", ip) + + return ip, nil } func getVMWareMAC() (string, error) { @@ -75,12 +78,15 @@ func getVMWareMAC() (string, error) { const defaultMacRe = "00:50:56" programData := os.Getenv("ProgramData") + programData = strings.Replace(programData, "\\", "/", -1) vmnetnat := programData + "/VMware/vmnetnat.conf" if _, err := os.Stat(vmnetnat); os.IsNotExist(err) { log.Printf("File not found: '%s' (found '%s' in %%ProgramData%%)", vmnetnat, programData) return defaultMacRe, err } + log.Printf("Searching for key hostMAC in '%s'", vmnetnat) + fh, err := os.Open(vmnetnat) if err != nil { return defaultMacRe, err @@ -96,14 +102,17 @@ func getVMWareMAC() (string, error) { for _, line := range strings.Split(string(bytes), "\n") { // Need to trim off CR character when running in windows - line = strings.TrimRight(line, "\r"); + line = strings.TrimRight(line, "\r") matches := hostMacRe.FindStringSubmatch(line) if matches != nil { + log.Printf("Found MAC '%s' in '%s'", matches[1], vmnetnat) return matches[1], nil } } + log.Printf("Did not find key hostMAC in '%s', using %s instead", vmnetnat, defaultMacRe) + return defaultMacRe, nil } From cf46148300650212e2f355dd41d5986ce3963af3 Mon Sep 17 00:00:00 2001 From: Ross Smith II Date: Sun, 28 Jul 2013 20:41:09 -0700 Subject: [PATCH 3/4] added missing fallthru in case statement for linux option, fixes #221, #222 --- builder/vmware/driver.go | 1 + 1 file changed, 1 insertion(+) diff --git a/builder/vmware/driver.go b/builder/vmware/driver.go index bb0eb6b24..4df6089fd 100644 --- a/builder/vmware/driver.go +++ b/builder/vmware/driver.go @@ -46,6 +46,7 @@ func NewDriver() (Driver, error) { AppPath: "/Applications/VMware Fusion.app", } case "linux": + fallthrough case "windows": driver = &Workstation9Driver{} default: From e4086a0230102db6f3f6a1f5f7c69b7b3799911b Mon Sep 17 00:00:00 2001 From: Ross Smith II Date: Mon, 29 Jul 2013 08:20:48 -0700 Subject: [PATCH 4/4] Updated website for vmware workstation support, fixes #221/#222 --- website/source/docs/builders/vmware.html.markdown | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/website/source/docs/builders/vmware.html.markdown b/website/source/docs/builders/vmware.html.markdown index 1989e6539..23bf6896e 100644 --- a/website/source/docs/builders/vmware.html.markdown +++ b/website/source/docs/builders/vmware.html.markdown @@ -7,9 +7,10 @@ layout: "docs" Type: `vmware` The VMware builder is able to create VMware virtual machines. It currently -only supports building the virtual machines using -[VMware Fusion](http://www.vmware.com/products/fusion/overview.html), but -support for Windows and other VMware products is forthcoming. +supports building virtual machines on hosts running +[VMware Fusion](http://www.vmware.com/products/fusion/overview.html) for OS X, and +[VMware Workstation](http://www.vmware.com/products/workstation/overview.html) for Linux and Windows. +Support for VMWare ESXi/vSphere and VMWare Player is forthcoming. The builder builds a virtual machine by creating a new virtual machine from scratch, booting it, installing an OS, provisioning software within