Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automatically install docker-machine-driver-hyperkit if missing or incompatible #5354

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmd/minikube/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ func Execute() {
flag.Usage = translate.T(flag.Usage)
})

if runtime.GOOS == "linux" {
if runtime.GOOS != "windows" {
// add minikube binaries to the path
targetDir := constants.MakeMiniPath("bin")
addToPath(targetDir)
Expand Down
52 changes: 8 additions & 44 deletions cmd/minikube/cmd/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ func runStart(cmd *cobra.Command, args []string) {

validateConfig()
validateUser()
validateDriverVersion(driver)
installOrUpdateDriver(driver)

k8sVersion, isUpgrade := getKubernetesVersion()
config, err := generateCfgFromFlags(cmd, k8sVersion)
Expand Down Expand Up @@ -1028,62 +1028,26 @@ func saveConfig(clusterCfg *cfg.Config) error {
return cfg.CreateProfile(viper.GetString(cfg.MachineProfile), clusterCfg)
}

func validateDriverVersion(vmDriver string) {
func installOrUpdateDriver(vmDriver string) {
var driverExecutable string
driverDocumentation := fmt.Sprintf("%s%s#driver-installation", constants.DriverDocumentation, vmDriver)

minikubeVersion, err := version.GetSemverVersion()
if err != nil {
out.WarningT("Error parsing minukube version: {{.error}}", out.V{"error": err})
return
}

switch vmDriver {
case constants.DriverKvm2:
driverExecutable = fmt.Sprintf("docker-machine-driver-%s", constants.DriverKvm2)
targetDir := constants.MakeMiniPath("bin")
err := drivers.InstallOrUpdate(driverExecutable, targetDir, minikubeVersion)
if err != nil {
out.WarningT("Error downloading driver: {{.error}}", out.V{"error": err})
}
return
case constants.DriverHyperkit:
driverExecutable = fmt.Sprintf("docker-machine-driver-%s", constants.DriverHyperkit)
default: // driver doesn't support version
default: // driver doesn't install or update
return
}

cmd := exec.Command(driverExecutable, "version")
output, err := cmd.Output()

// we don't want to fail if an error was returned,
// libmachine has a nice message for the user if the driver isn't present
minikubeVersion, err := version.GetSemverVersion()
if err != nil {
out.WarningT("Error checking driver version: {{.error}}", out.V{"error": err})
out.WarningT("Error parsing minikube version: {{.error}}", out.V{"error": err})
return
}

v := drivers.ExtractVMDriverVersion(string(output))

// if the driver doesn't have return any version, it is really old, we force a upgrade.
if len(v) == 0 && !viper.GetBool(force) {
exit.WithCodeT(
exit.Failure,
"The installed version of '{{.driver_executable}}' is obsolete. Upgrade: {{.documentation_url}}",
out.V{"driver_executable": driverExecutable, "documentation_url": driverDocumentation},
)
}

vmDriverVersion, err := semver.Make(v)
targetDir := constants.MakeMiniPath("bin")
err = drivers.InstallOrUpdate(driverExecutable, targetDir, minikubeVersion)
if err != nil {
out.WarningT("Error parsing vmDriver version: {{.error}}", out.V{"error": err})
return
}

if vmDriverVersion.LT(minikubeVersion) {
out.WarningT(
"The installed version of '{{.driver_executable}}' ({{.driver_version}}) is no longer current. Upgrade: {{.documentation_url}}",
out.V{"driver_executable": driverExecutable, "driver_version": vmDriverVersion, "documentation_url": driverDocumentation},
)
out.WarningT("Error downloading driver: {{.error}}", out.V{"error": err})
}
}
44 changes: 39 additions & 5 deletions pkg/drivers/drivers.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
package drivers

import (
"fmt"
"io"
"io/ioutil"
"os"
Expand All @@ -42,7 +43,8 @@ import (
)

const (
driverKVMDownloadURL = "https://storage.googleapis.com/minikube/releases/latest/docker-machine-driver-kvm2"
driverKVMDownloadURL = "https://storage.googleapis.com/minikube/releases/latest/docker-machine-driver-kvm2"
driverHyperKitDownloadURL = "https://storage.googleapis.com/minikube/releases/latest/docker-machine-driver-hyperkit"
)

// GetDiskPath returns the path of the machine disk image
Expand Down Expand Up @@ -187,17 +189,23 @@ func InstallOrUpdate(driver, destination string, minikubeVersion semver.Version)
}

func download(driver, destination string) error {
// only support kvm2 for now
if driver != "docker-machine-driver-kvm2" {
// supports kvm2 and hyperkit
if driver != "docker-machine-driver-kvm2" && driver != "docker-machine-driver-hyperkit" {
return nil
}

out.T(out.Happy, "Downloading driver {{.driver}}:", out.V{"driver": driver})

targetFilepath := path.Join(destination, "docker-machine-driver-kvm2")
targetFilepath := path.Join(destination, driver)
os.Remove(targetFilepath)

url := driverKVMDownloadURL
var url string
switch driver {
case "docker-machine-driver-kvm2":
url = driverKVMDownloadURL
case "docker-machine-driver-hyperkit":
url = driverHyperKitDownloadURL
}

opts := []getter.ClientOption{getter.WithProgress(util.DefaultProgressBar)}
client := &getter.Client{
Expand All @@ -216,6 +224,13 @@ func download(driver, destination string) error {
return errors.Wrap(err, "chmod error")
}

if driver == "docker-machine-driver-hyperkit" {
err := setHyperKitPermissions(targetFilepath)
if err != nil {
return errors.Wrap(err, "setting hyperkit permission")
}
}

return nil
}

Expand All @@ -235,3 +250,22 @@ func ExtractVMDriverVersion(s string) string {
v := strings.TrimSpace(matches[1])
return strings.TrimPrefix(v, version.VersionPrefix)
}

func setHyperKitPermissions(driverPath string) error {
msg := fmt.Sprintf("A new hyperkit driver was installed. It needs elevated permissions to run. The following commands will be executed\nsudo chown root:wheel %s\nsudo chmod u+s %s", driverPath, driverPath)
out.T(out.Happy, msg, out.V{})

cmd := exec.Command("sudo", "chown", "root:wheel", driverPath)
err := cmd.Run()
if err != nil {
return errors.Wrap(err, "chown root:wheel")
}

cmd = exec.Command("sudo", "chmod", "u+s", driverPath)
err = cmd.Run()
if err != nil {
return errors.Wrap(err, "chmod u+s")
}

return nil
}
5 changes: 0 additions & 5 deletions pkg/minikube/constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -374,8 +374,3 @@ const (
// GvisorURL is the url to download gvisor
GvisorURL = "https://storage.googleapis.com/gvisor/releases/nightly/2019-01-14/runsc"
)

const (
// DriverDocumentation the documentation of the KVM driver
DriverDocumentation = "https://minikube.sigs.k8s.io/docs/reference/drivers/"
)