diff --git a/README.md b/README.md index 7739333..f2ef867 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ Download the the binary that corresponds to your OS into a directory residing in ### From Homebrew -The driver is available for easy installation via Homebrew on macOS. +The driver is available for easy installation via Homebrew on macOS. ```shell $ brew install docker-machine-driver-vmware @@ -60,6 +60,7 @@ $ docker-machine create --driver=vmware default - `--vmware-no-share`: Disable the mount of your home directory - `--vmware-ssh-password`: SSH password - `--vmware-ssh-user`: SSH user +- `--vmware-wait-ip`: Time to wait for vmrun to get an ip (in milliseconds) #### Environment variables and default values @@ -73,6 +74,7 @@ $ docker-machine create --driver=vmware default | `--vmware-no-share` | VMWARE_NO_SHARE | - | | `--vmware-ssh-password` | VMWARE_SSH_PASSWORD | `tcuser` | | `--vmware-ssh-user` | VMWARE_SSH_USER | `docker` | +| `--vmware-wait-ip` | VMWARE_WAIT_IP | `30000` | ## License diff --git a/pkg/drivers/vmware/config/config.go b/pkg/drivers/vmware/config/config.go index d17a426..f1f9548 100644 --- a/pkg/drivers/vmware/config/config.go +++ b/pkg/drivers/vmware/config/config.go @@ -31,6 +31,7 @@ const ( defaultDiskSize = 20000 defaultCPU = 1 defaultMemory = 1024 + defaultWaitIP = 30000 ) // Config specifies the configuration of driver VMware @@ -47,6 +48,8 @@ type Config struct { ConfigDriveISO string ConfigDriveURL string NoShare bool + + WaitIP int } // NewConfig creates a new Config @@ -56,6 +59,7 @@ func NewConfig(hostname, storePath string) *Config { Memory: defaultMemory, DiskSize: defaultDiskSize, SSHPassword: defaultSSHPass, + WaitIP: defaultWaitIP, BaseDriver: &drivers.BaseDriver{ SSHUser: defaultSSHUser, MachineName: hostname, @@ -115,5 +119,11 @@ func (c *Config) GetCreateFlags() []mcnflag.Flag { Name: "vmware-no-share", Usage: "Disable the mount of your home directory", }, + mcnflag.IntFlag{ + EnvVar: "VMWARE_WAIT_IP", + Name: "vmware-wait-ip", + Usage: "time to wait for vmrun to get an ip (in milliseconds)", + Value: defaultWaitIP, + }, } } diff --git a/pkg/drivers/vmware/driver.go b/pkg/drivers/vmware/driver.go index f0a9580..3aea3e5 100644 --- a/pkg/drivers/vmware/driver.go +++ b/pkg/drivers/vmware/driver.go @@ -89,6 +89,7 @@ func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error { d.SSHPassword = flags.String("vmware-ssh-password") d.SSHPort = 22 d.NoShare = flags.Bool("vmware-no-share") + d.WaitIP = flags.Int("vmware-wait-ip") // We support a maximum of 16 cpu to be consistent with Virtual Hardware 10 // specs. @@ -123,6 +124,11 @@ func (d *Driver) GetIP() (ip string, err error) { return "", drivers.ErrHostIsNotRunning } + // attempt to find the address from vmrun + if ip, err := d.getIPfromVmrun(); err == nil { + return ip, err + } + // determine MAC address for VM macaddr, err := d.getMacAddressFromVmx() if err != nil { @@ -401,6 +407,18 @@ func (d *Driver) getMacAddressFromVmx() (string, error) { return macaddr, nil } +func (d *Driver) getIPfromVmrun() (string, error) { + vmx := d.vmxPath() + + ip := regexp.MustCompile(`\d+\.\d+\.\d+\.\d+`) + stdout, _, _ := vmrun_wait(time.Duration(d.WaitIP)*time.Millisecond, "getGuestIPAddress", vmx, "-wait") + if match := ip.FindString(stdout); match != "" { + return match, nil + } + + return "", fmt.Errorf("could not get IP from vmrun") +} + func (d *Driver) getIPfromVmnetConfiguration(macaddr string) (string, error) { // DHCP lease table for NAT vmnet interface diff --git a/pkg/drivers/vmware/vmrun.go b/pkg/drivers/vmware/vmrun.go index 1ce7364..a62ac00 100644 --- a/pkg/drivers/vmware/vmrun.go +++ b/pkg/drivers/vmware/vmrun.go @@ -22,12 +22,14 @@ package vmware import ( "bytes" + "context" "errors" "fmt" "io" "os" "os/exec" "strings" + "time" "github.com/docker/machine/libmachine/log" ) @@ -55,7 +57,18 @@ func isMachineDebugEnabled() bool { func vmrun(args ...string) (string, string, error) { cmd := exec.Command(vmrunbin, args...) + return vmrun_cmd(cmd) +} + +func vmrun_wait(timeout time.Duration, args ...string) (string, string, error) { + ctx, cancel := context.WithTimeout(context.Background(), timeout) + defer cancel() + + cmd := exec.CommandContext(ctx, vmrunbin, args...) + return vmrun_cmd(cmd) +} +func vmrun_cmd(cmd *exec.Cmd) (string, string, error) { var stdout bytes.Buffer var stderr bytes.Buffer cmd.Stdout, cmd.Stderr = &stdout, &stderr @@ -66,7 +79,7 @@ func vmrun(args ...string) (string, string, error) { cmd.Stderr = io.MultiWriter(os.Stderr, cmd.Stderr) } - log.Debugf("executing: %v %v", vmrunbin, strings.Join(args, " ")) + log.Debugf("executing: %v", strings.Join(cmd.Args, " ")) err := cmd.Run() if err != nil {