From 229011def42571cfa045ef1e9492d21584156870 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Tue, 16 Jul 2013 14:23:01 -0700 Subject: [PATCH] builder/vmware: split drivers out into individual files --- builder/vmware/builder.go | 36 +--- builder/vmware/driver.go | 285 ++------------------------ builder/vmware/driver_fusion5.go | 142 +++++++++++++ builder/vmware/driver_workstation9.go | 150 ++++++++++++++ 4 files changed, 309 insertions(+), 304 deletions(-) create mode 100644 builder/vmware/driver_fusion5.go create mode 100644 builder/vmware/driver_workstation9.go diff --git a/builder/vmware/builder.go b/builder/vmware/builder.go index 3ea85f39f..ff96b4b81 100644 --- a/builder/vmware/builder.go +++ b/builder/vmware/builder.go @@ -255,7 +255,7 @@ func (b *Builder) Prepare(raws ...interface{}) error { errs = append(errs, fmt.Errorf("vnc_port_min must be less than vnc_port_max")) } - b.driver, err = b.newDriver() + b.driver, err = NewDriver() if err != nil { errs = append(errs, fmt.Errorf("Failed creating VMware driver: %s", err)) } @@ -358,37 +358,3 @@ func (b *Builder) Cancel() { b.runner.Cancel() } } - -func (b *Builder) newFusionDriver() (Driver, error) { - fusionAppPath := "/Applications/VMware Fusion.app" - driver := &Fusion5Driver{fusionAppPath} - if err := driver.Verify(); err != nil { - return nil, err - } - - return driver, nil -} - -func (b *Builder) newWorkstationLinuxDriver() (Driver, error) { - driver := &WS9LnxDriver{} - if err := driver.Verify(); err != nil { - return nil, err - } - - return driver, nil -} - -func (b *Builder) newDriver() (Driver, error) { - fusion, fusionErr := b.newFusionDriver() - ws, wsErr := b.newWorkstationLinuxDriver() - - if fusionErr == nil { - return fusion, nil - } - - if wsErr == nil { - return ws, nil - } - - return nil, fmt.Errorf("Unable to initialise VMware driver:\nFusion 5: %s\nWorkstation 9: %s", fusionErr, wsErr) -} diff --git a/builder/vmware/driver.go b/builder/vmware/driver.go index d4ef6e3a3..308365c7d 100644 --- a/builder/vmware/driver.go +++ b/builder/vmware/driver.go @@ -1,13 +1,8 @@ package vmware import ( - "bytes" "fmt" - "log" - "os" - "os/exec" - "path/filepath" - "strings" + "runtime" ) // A driver is able to talk to VMware, control virtual machines, etc. @@ -40,273 +35,25 @@ type Driver interface { Verify() error } -// Fusion5Driver is a driver that can run VMWare Fusion 5. -type Fusion5Driver struct { - // This is the path to the "VMware Fusion.app" - AppPath string -} +// NewDriver returns a new driver implementation for this operating +// system, or an error if the driver couldn't be initialized. +func NewDriver() (Driver, error) { + var driver Driver -func (d *Fusion5Driver) 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 *Fusion5Driver) 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 *Fusion5Driver) IsRunning(vmxPath string) (bool, error) { - vmxPath, err := filepath.Abs(vmxPath) - if err != nil { - return false, err - } - - cmd := exec.Command(d.vmrunPath(), "-T", "fusion", "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 + switch runtime.GOOS { + case "darwin": + driver = &Fusion5Driver{ + AppPath: "/Applications/VMware Fusion.app", } + case "linux": + driver = &Workstation9LinuxDriver{} + default: + return nil, fmt.Errorf("can't find driver for OS: %s", runtime.GOOS) } - return false, nil -} - -func (d *Fusion5Driver) Start(vmxPath string, headless bool) error { - guiArgument := "gui" - if headless == true { - guiArgument = "nogui" + if err := driver.Verify(); err != nil { + return nil, err } - cmd := exec.Command(d.vmrunPath(), "-T", "fusion", "start", vmxPath, guiArgument) - if _, _, err := d.runAndLog(cmd); err != nil { - return err - } - - return nil -} - -func (d *Fusion5Driver) Stop(vmxPath string) error { - cmd := exec.Command(d.vmrunPath(), "-T", "fusion", "stop", vmxPath, "hard") - if _, _, err := d.runAndLog(cmd); err != nil { - return err - } - - return nil -} - -func (d *Fusion5Driver) Verify() error { - if _, err := os.Stat(d.AppPath); err != nil { - if os.IsNotExist(err) { - return fmt.Errorf("Fusion application not found at path: %s", d.AppPath) - } - - return err - } - - if _, err := os.Stat(d.vmrunPath()); err != nil { - if os.IsNotExist(err) { - return fmt.Errorf("Critical application 'vmrun' not found at path: %s", d.vmrunPath()) - } - - return err - } - - if _, err := os.Stat(d.vdiskManagerPath()); err != nil { - if os.IsNotExist(err) { - return fmt.Errorf("Critical application vdisk manager not found at path: %s", d.vdiskManagerPath()) - } - - return err - } - - return nil -} - -func (d *Fusion5Driver) vdiskManagerPath() string { - return filepath.Join(d.AppPath, "Contents", "Library", "vmware-vdiskmanager") -} - -func (d *Fusion5Driver) vmrunPath() string { - return filepath.Join(d.AppPath, "Contents", "Library", "vmrun") -} - -func (d *Fusion5Driver) ToolsIsoPath(k string) string { - return filepath.Join(d.AppPath, "Contents", "Library", "isoimages", k+".iso") -} - -func (d *Fusion5Driver) DhcpLeasesPath(device string) string { - return "/etc/vmware/vmnet-dhcpd-" + device + ".leases" -} - -func (d *Fusion5Driver) 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() - - log.Printf("stdout: %s", strings.TrimSpace(stdout.String())) - log.Printf("stderr: %s", strings.TrimSpace(stderr.String())) - - return stdout.String(), stderr.String(), err -} - -// WS9LnxDriver is a driver that can run VMware Workstation 9 on Linux. -type WS9LnxDriver struct { - // These are paths to useful VMware Workstation binaries - AppPath string - VdiskManagerPath string - VmrunPath string -} - -func (d *WS9LnxDriver) 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 *WS9LnxDriver) 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 *WS9LnxDriver) 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 *WS9LnxDriver) 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 *WS9LnxDriver) 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 *WS9LnxDriver) 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("Critical application 'vmrun' not found in path.") - } - - if err := d.findVdiskManager(); err != nil { - return fmt.Errorf("Critical application 'vmware-vdiskmanager' not found in path.") - } - - return nil -} - -func (d *WS9LnxDriver) findApp() error { - path, err := exec.LookPath("vmware") - if err != nil { - return err - } - d.AppPath = path - return nil -} - -func (d *WS9LnxDriver) findVdiskManager() error { - path, err := exec.LookPath("vmware-vdiskmanager") - if err != nil { - return err - } - d.VdiskManagerPath = path - return nil -} - -func (d *WS9LnxDriver) findVmrun() error { - path, err := exec.LookPath("vmrun") - if err != nil { - return err - } - d.VmrunPath = path - return nil -} - -func (d *WS9LnxDriver) ToolsIsoPath(flavor string) string { - return "/usr/lib/vmware/isoimages/" + flavor + ".iso" -} - -func (d *WS9LnxDriver) DhcpLeasesPath(device string) string { - return "/etc/vmware/" + device + "/dhcpd/dhcpd.leases" -} - -func (d *WS9LnxDriver) 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() - - log.Printf("stdout: %s", strings.TrimSpace(stdout.String())) - log.Printf("stderr: %s", strings.TrimSpace(stderr.String())) - - return stdout.String(), stderr.String(), err + return driver, nil } diff --git a/builder/vmware/driver_fusion5.go b/builder/vmware/driver_fusion5.go new file mode 100644 index 000000000..afde64899 --- /dev/null +++ b/builder/vmware/driver_fusion5.go @@ -0,0 +1,142 @@ +package vmware + +import ( + "bytes" + "fmt" + "log" + "os" + "os/exec" + "path/filepath" + "strings" +) + +// Fusion5Driver is a driver that can run VMWare Fusion 5. +type Fusion5Driver struct { + // This is the path to the "VMware Fusion.app" + AppPath string +} + +func (d *Fusion5Driver) 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 *Fusion5Driver) 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 *Fusion5Driver) IsRunning(vmxPath string) (bool, error) { + vmxPath, err := filepath.Abs(vmxPath) + if err != nil { + return false, err + } + + cmd := exec.Command(d.vmrunPath(), "-T", "fusion", "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 *Fusion5Driver) Start(vmxPath string, headless bool) error { + guiArgument := "gui" + if headless == true { + guiArgument = "nogui" + } + + cmd := exec.Command(d.vmrunPath(), "-T", "fusion", "start", vmxPath, guiArgument) + if _, _, err := d.runAndLog(cmd); err != nil { + return err + } + + return nil +} + +func (d *Fusion5Driver) Stop(vmxPath string) error { + cmd := exec.Command(d.vmrunPath(), "-T", "fusion", "stop", vmxPath, "hard") + if _, _, err := d.runAndLog(cmd); err != nil { + return err + } + + return nil +} + +func (d *Fusion5Driver) Verify() error { + if _, err := os.Stat(d.AppPath); err != nil { + if os.IsNotExist(err) { + return fmt.Errorf("Fusion application not found at path: %s", d.AppPath) + } + + return err + } + + if _, err := os.Stat(d.vmrunPath()); err != nil { + if os.IsNotExist(err) { + return fmt.Errorf("Critical application 'vmrun' not found at path: %s", d.vmrunPath()) + } + + return err + } + + if _, err := os.Stat(d.vdiskManagerPath()); err != nil { + if os.IsNotExist(err) { + return fmt.Errorf("Critical application vdisk manager not found at path: %s", d.vdiskManagerPath()) + } + + return err + } + + return nil +} + +func (d *Fusion5Driver) vdiskManagerPath() string { + return filepath.Join(d.AppPath, "Contents", "Library", "vmware-vdiskmanager") +} + +func (d *Fusion5Driver) vmrunPath() string { + return filepath.Join(d.AppPath, "Contents", "Library", "vmrun") +} + +func (d *Fusion5Driver) ToolsIsoPath(k string) string { + return filepath.Join(d.AppPath, "Contents", "Library", "isoimages", k+".iso") +} + +func (d *Fusion5Driver) DhcpLeasesPath(device string) string { + return "/etc/vmware/vmnet-dhcpd-" + device + ".leases" +} + +func (d *Fusion5Driver) 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() + + log.Printf("stdout: %s", strings.TrimSpace(stdout.String())) + log.Printf("stderr: %s", strings.TrimSpace(stderr.String())) + + return stdout.String(), stderr.String(), err +} diff --git a/builder/vmware/driver_workstation9.go b/builder/vmware/driver_workstation9.go new file mode 100644 index 000000000..e27cafa25 --- /dev/null +++ b/builder/vmware/driver_workstation9.go @@ -0,0 +1,150 @@ +package vmware + +import ( + "bytes" + "fmt" + "log" + "os/exec" + "path/filepath" + "strings" +) + +// Workstation9LinuxDriver is a driver that can run VMware Workstation 9 +// on Linux. +type Workstation9LinuxDriver struct { + AppPath string + VdiskManagerPath string + VmrunPath string +} + +func (d *Workstation9LinuxDriver) 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 *Workstation9LinuxDriver) 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 *Workstation9LinuxDriver) 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 *Workstation9LinuxDriver) 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 *Workstation9LinuxDriver) 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 *Workstation9LinuxDriver) 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("Critical application 'vmrun' not found in path.") + } + + if err := d.findVdiskManager(); err != nil { + return fmt.Errorf("Critical application 'vmware-vdiskmanager' not found in path.") + } + + return nil +} + +func (d *Workstation9LinuxDriver) findApp() error { + path, err := exec.LookPath("vmware") + if err != nil { + return err + } + d.AppPath = path + return nil +} + +func (d *Workstation9LinuxDriver) findVdiskManager() error { + path, err := exec.LookPath("vmware-vdiskmanager") + if err != nil { + return err + } + d.VdiskManagerPath = path + return nil +} + +func (d *Workstation9LinuxDriver) findVmrun() error { + path, err := exec.LookPath("vmrun") + if err != nil { + return err + } + d.VmrunPath = path + return nil +} + +func (d *Workstation9LinuxDriver) ToolsIsoPath(flavor string) string { + return "/usr/lib/vmware/isoimages/" + flavor + ".iso" +} + +func (d *Workstation9LinuxDriver) DhcpLeasesPath(device string) string { + return "/etc/vmware/" + device + "/dhcpd/dhcpd.leases" +} + +func (d *Workstation9LinuxDriver) 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() + + log.Printf("stdout: %s", strings.TrimSpace(stdout.String())) + log.Printf("stderr: %s", strings.TrimSpace(stderr.String())) + + return stdout.String(), stderr.String(), err +}