diff --git a/drivers/virtualbox/vbm.go b/drivers/virtualbox/vbm.go index 6dffeff896..5f5bf82b7e 100644 --- a/drivers/virtualbox/vbm.go +++ b/drivers/virtualbox/vbm.go @@ -4,11 +4,8 @@ import ( "bytes" "errors" "fmt" - "os" "os/exec" - "path/filepath" "regexp" - "runtime" "strings" "github.com/docker/machine/libmachine/log" @@ -78,31 +75,3 @@ func (v *VBoxCmdManager) vbmOutErr(args ...string) (string, string, error) { return stdout.String(), stderrStr, err } - -// detectVBoxManageCmd detects the VBoxManage cmd's path if needed -func detectVBoxManageCmd() string { - cmd := "VBoxManage" - if path, err := exec.LookPath(cmd); err == nil { - return path - } - - if runtime.GOOS == "windows" { - if p := os.Getenv("VBOX_INSTALL_PATH"); p != "" { - if path, err := exec.LookPath(filepath.Join(p, cmd)); err == nil { - return path - } - } - if p := os.Getenv("VBOX_MSI_INSTALL_PATH"); p != "" { - if path, err := exec.LookPath(filepath.Join(p, cmd)); err == nil { - return path - } - } - // look at HKEY_LOCAL_MACHINE\SOFTWARE\Oracle\VirtualBox\InstallDir - p := "C:\\Program Files\\Oracle\\VirtualBox" - if path, err := exec.LookPath(filepath.Join(p, cmd)); err == nil { - return path - } - } - - return cmd -} diff --git a/drivers/virtualbox/virtualbox.go b/drivers/virtualbox/virtualbox.go index 948ba38991..ab7113589c 100644 --- a/drivers/virtualbox/virtualbox.go +++ b/drivers/virtualbox/virtualbox.go @@ -186,21 +186,6 @@ func (d *Driver) PreCreateCheck() error { return d.vbm() } -// cmdOutput runs a shell command and returns its output. -func cmdOutput(name string, args ...string) (string, error) { - cmd := exec.Command(name, args...) - log.Debugf("COMMAND: %v %v", name, strings.Join(args, " ")) - - stdout, err := cmd.Output() - if err != nil { - return "", err - } - - log.Debugf("STDOUT:\n{\n%v}", string(stdout)) - - return string(stdout), nil -} - // IsVTXDisabledInTheVM checks if VT-X is disabled in the started vm. func (d *Driver) IsVTXDisabledInTheVM() (bool, error) { logPath := filepath.Join(d.ResolveStorePath(d.MachineName), "Logs", "VBox.log") @@ -845,3 +830,11 @@ func getRandomIPinSubnet(baseIP net.IP) (net.IP, error) { return dhcpAddr, nil } + +func detectVBoxManageCmdInPath() string { + cmd := "VBoxManage" + if path, err := exec.LookPath(cmd); err == nil { + return path + } + return cmd +} diff --git a/drivers/virtualbox/virtualbox_darwin.go b/drivers/virtualbox/virtualbox_darwin.go index e044e1e7ef..a8379115c5 100644 --- a/drivers/virtualbox/virtualbox_darwin.go +++ b/drivers/virtualbox/virtualbox_darwin.go @@ -20,3 +20,7 @@ func (d *Driver) IsVTXDisabled() bool { disabled := !strings.Contains(features, "VMX") return disabled } + +func detectVBoxManageCmd() string { + return detectVBoxManageCmdInPath() +} diff --git a/drivers/virtualbox/virtualbox_linux.go b/drivers/virtualbox/virtualbox_linux.go index f5892d6fb4..6925d0e458 100644 --- a/drivers/virtualbox/virtualbox_linux.go +++ b/drivers/virtualbox/virtualbox_linux.go @@ -5,3 +5,7 @@ package virtualbox func (d *Driver) IsVTXDisabled() bool { return false } + +func detectVBoxManageCmd() string { + return detectVBoxManageCmdInPath() +} diff --git a/drivers/virtualbox/virtualbox_windows.go b/drivers/virtualbox/virtualbox_windows.go index 33da8b470d..476a27719e 100644 --- a/drivers/virtualbox/virtualbox_windows.go +++ b/drivers/virtualbox/virtualbox_windows.go @@ -3,7 +3,13 @@ package virtualbox import ( "strings" + "fmt" + "os" + "os/exec" + "path/filepath" + "github.com/docker/machine/libmachine/log" + "golang.org/x/sys/windows/registry" ) // IsVTXDisabled checks if VT-X is disabled in the BIOS. If it is, the vm will fail to start. @@ -19,3 +25,67 @@ func (d *Driver) IsVTXDisabled() bool { disabled := strings.Contains(output, "FALSE") return disabled } + +// cmdOutput runs a shell command and returns its output. +func cmdOutput(name string, args ...string) (string, error) { + cmd := exec.Command(name, args...) + log.Debugf("COMMAND: %v %v", name, strings.Join(args, " ")) + + stdout, err := cmd.Output() + if err != nil { + return "", err + } + + log.Debugf("STDOUT:\n{\n%v}", string(stdout)) + + return string(stdout), nil +} + +func detectVBoxManageCmd() string { + cmd := "VBoxManage" + if p := os.Getenv("VBOX_INSTALL_PATH"); p != "" { + if path, err := exec.LookPath(filepath.Join(p, cmd)); err == nil { + return path + } + } + + if p := os.Getenv("VBOX_MSI_INSTALL_PATH"); p != "" { + if path, err := exec.LookPath(filepath.Join(p, cmd)); err == nil { + return path + } + } + + // Look in default installation path for VirtualBox version > 5 + if path, err := exec.LookPath(filepath.Join("C:\\Program Files\\Oracle\\VirtualBox", cmd)); err == nil { + return path + } + + // Look in windows registry + if p, err := findVBoxInstallDirInRegistry(); err == nil { + if path, err := exec.LookPath(filepath.Join(p, cmd)); err == nil { + return path + } + } + + return detectVBoxManageCmdInPath() //fallback to path +} + +func findVBoxInstallDirInRegistry() (string, error) { + registryKey, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Oracle\VirtualBox`, registry.QUERY_VALUE) + if err != nil { + errorMessage := fmt.Sprintf("Can't find VirtualBox registry entries, is VirtualBox really installed properly? %s", err) + log.Debugf(errorMessage) + return nil, fmt.Errorf(errorMessage) + } + + defer registryKey.Close() + + installDir, _, err := registryKey.GetStringValue("InstallDir") + if err != nil { + errorMessage := fmt.Sprintf("Can't find InstallDir registry key within VirtualBox registries entries, is VirtualBox really installed properly? %s", err) + log.Debugf(errorMessage) + return nil, fmt.Errorf(errorMessage) + } + + return installDir, nil +}