github.com/sneal/packer@v0.5.2/builder/vmware/common/driver.go (about)

     1  package common
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"log"
     7  	"os/exec"
     8  	"runtime"
     9  	"strings"
    10  
    11  	"github.com/mitchellh/multistep"
    12  )
    13  
    14  // A driver is able to talk to VMware, control virtual machines, etc.
    15  type Driver interface {
    16  	// Clone clones the VMX and the disk to the destination path. The
    17  	// destination is a path to the VMX file. The disk will be copied
    18  	// to that same directory.
    19  	Clone(dst string, src string) error
    20  
    21  	// CompactDisk compacts a virtual disk.
    22  	CompactDisk(string) error
    23  
    24  	// CreateDisk creates a virtual disk with the given size.
    25  	CreateDisk(string, string, string) error
    26  
    27  	// Checks if the VMX file at the given path is running.
    28  	IsRunning(string) (bool, error)
    29  
    30  	// SSHAddress returns the SSH address for the VM that is being
    31  	// managed by this driver.
    32  	SSHAddress(multistep.StateBag) (string, error)
    33  
    34  	// Start starts a VM specified by the path to the VMX given.
    35  	Start(string, bool) error
    36  
    37  	// Stop stops a VM specified by the path to the VMX given.
    38  	Stop(string) error
    39  
    40  	// SuppressMessages modifies the VMX or surrounding directory so that
    41  	// VMware doesn't show any annoying messages.
    42  	SuppressMessages(string) error
    43  
    44  	// Get the path to the VMware ISO for the given flavor.
    45  	ToolsIsoPath(string) string
    46  
    47  	// Get the path to the DHCP leases file for the given device.
    48  	DhcpLeasesPath(string) string
    49  
    50  	// Verify checks to make sure that this driver should function
    51  	// properly. This should check that all the files it will use
    52  	// appear to exist and so on. If everything is okay, this doesn't
    53  	// return an error. Otherwise, this returns an error.
    54  	Verify() error
    55  }
    56  
    57  // NewDriver returns a new driver implementation for this operating
    58  // system, or an error if the driver couldn't be initialized.
    59  func NewDriver(dconfig *DriverConfig, config *SSHConfig) (Driver, error) {
    60  	drivers := []Driver{}
    61  
    62  	switch runtime.GOOS {
    63  	case "darwin":
    64  		drivers = []Driver{
    65  			&Fusion6Driver{
    66  				Fusion5Driver: Fusion5Driver{
    67  					AppPath:   dconfig.FusionAppPath,
    68  					SSHConfig: config,
    69  				},
    70  			},
    71  			&Fusion5Driver{
    72  				AppPath:   dconfig.FusionAppPath,
    73  				SSHConfig: config,
    74  			},
    75  		}
    76  	case "linux":
    77  		drivers = []Driver{
    78  			&Workstation9Driver{
    79  				SSHConfig: config,
    80  			},
    81  			&Player5LinuxDriver{
    82  				SSHConfig: config,
    83  			},
    84  		}
    85  	case "windows":
    86  		drivers = []Driver{
    87  			&Workstation9Driver{
    88  				SSHConfig: config,
    89  			},
    90  		}
    91  	default:
    92  		return nil, fmt.Errorf("can't find driver for OS: %s", runtime.GOOS)
    93  	}
    94  
    95  	errs := ""
    96  	for _, driver := range drivers {
    97  		err := driver.Verify()
    98  		if err == nil {
    99  			return driver, nil
   100  		}
   101  		errs += "* " + err.Error() + "\n"
   102  	}
   103  
   104  	return nil, fmt.Errorf(
   105  		"Unable to initialize any driver for this platform. The errors\n"+
   106  			"from each driver are shown below. Please fix at least one driver\n"+
   107  			"to continue:\n%s", errs)
   108  }
   109  
   110  func runAndLog(cmd *exec.Cmd) (string, string, error) {
   111  	var stdout, stderr bytes.Buffer
   112  
   113  	log.Printf("Executing: %s %v", cmd.Path, cmd.Args[1:])
   114  	cmd.Stdout = &stdout
   115  	cmd.Stderr = &stderr
   116  	err := cmd.Run()
   117  
   118  	stdoutString := strings.TrimSpace(stdout.String())
   119  	stderrString := strings.TrimSpace(stderr.String())
   120  
   121  	if _, ok := err.(*exec.ExitError); ok {
   122  		err = fmt.Errorf("VMware error: %s", stderrString)
   123  	}
   124  
   125  	log.Printf("stdout: %s", stdoutString)
   126  	log.Printf("stderr: %s", stderrString)
   127  
   128  	// Replace these for Windows, we only want to deal with Unix
   129  	// style line endings.
   130  	returnStdout := strings.Replace(stdout.String(), "\r\n", "\n", -1)
   131  	returnStderr := strings.Replace(stderr.String(), "\r\n", "\n", -1)
   132  
   133  	return returnStdout, returnStderr, err
   134  }