Download kvm2 driver

pull/5085/head
josedonizetti 2019-08-14 20:28:38 -04:00
parent f36c5d8ed1
commit 30e75c3c39
6 changed files with 155 additions and 30 deletions

View File

@ -21,6 +21,7 @@ import (
"fmt"
"io/ioutil"
"os"
"runtime"
"strings"
"github.com/docker/machine/libmachine"
@ -108,6 +109,12 @@ func Execute() {
flag.Usage = translate.T(flag.Usage)
})
if runtime.GOOS == "linux" {
// add minikube binaries to the path
targetDir := constants.MakeMiniPath("bin")
addToPath(targetDir)
}
if err := RootCmd.Execute(); err != nil {
// Cobra already outputs the error, typically because the user provided an unknown command.
os.Exit(exit.BadUsage)
@ -281,3 +288,8 @@ func getClusterBootstrapper(api libmachine.API, bootstrapperName string) (bootst
return b, nil
}
func addToPath(dir string) {
path := os.Getenv("PATH")
os.Setenv("PATH", fmt.Sprintf("%s:%s", dir, path))
}

View File

@ -24,7 +24,6 @@ import (
"os/exec"
"os/user"
"path/filepath"
"regexp"
"runtime"
"strconv"
"strings"
@ -46,6 +45,7 @@ import (
"github.com/spf13/viper"
"golang.org/x/sync/errgroup"
cmdcfg "k8s.io/minikube/cmd/minikube/cmd/config"
"k8s.io/minikube/pkg/drivers"
"k8s.io/minikube/pkg/minikube/bootstrapper"
"k8s.io/minikube/pkg/minikube/bootstrapper/kubeadm"
"k8s.io/minikube/pkg/minikube/cluster"
@ -278,7 +278,8 @@ func runStart(cmd *cobra.Command, args []string) {
registryMirror = viper.GetStringSlice("registry_mirror")
}
if err := cmdcfg.IsValidDriver(runtime.GOOS, viper.GetString(vmDriver)); err != nil {
driver := viper.GetString(vmDriver)
if err := cmdcfg.IsValidDriver(runtime.GOOS, driver); err != nil {
exit.WithCodeT(
exit.Failure,
"The driver '{{.driver}}' is not supported on {{.os}}",
@ -288,7 +289,7 @@ func runStart(cmd *cobra.Command, args []string) {
validateConfig()
validateUser()
validateDriverVersion(viper.GetString(vmDriver))
validateDriverVersion(driver)
k8sVersion, isUpgrade := getKubernetesVersion()
config, err := generateCfgFromFlags(cmd, k8sVersion)
@ -1027,9 +1028,21 @@ func validateDriverVersion(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.Download(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
@ -1046,7 +1059,7 @@ func validateDriverVersion(vmDriver string) {
return
}
v := extractVMDriverVersion(string(output))
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) {
@ -1063,12 +1076,6 @@ func validateDriverVersion(vmDriver string) {
return
}
minikubeVersion, err := version.GetSemverVersion()
if err != nil {
out.WarningT("Error parsing minikube 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}}",
@ -1076,20 +1083,3 @@ func validateDriverVersion(vmDriver string) {
)
}
}
// extractVMDriverVersion extracts the driver version.
// KVM and Hyperkit drivers support the 'version' command, that display the information as:
// version: vX.X.X
// commit: XXXX
// This method returns the version 'vX.X.X' or empty if the version isn't found.
func extractVMDriverVersion(s string) string {
versionRegex := regexp.MustCompile(`version:(.*)`)
matches := versionRegex.FindStringSubmatch(s)
if len(matches) != 2 {
return ""
}
v := strings.TrimSpace(matches[1])
return strings.TrimPrefix(v, version.VersionPrefix)
}

View File

@ -20,15 +20,29 @@ import (
"io"
"io/ioutil"
"os"
"os/exec"
"path"
"path/filepath"
"regexp"
"strings"
"syscall"
"github.com/blang/semver"
"github.com/docker/machine/libmachine/drivers"
"github.com/docker/machine/libmachine/mcnflag"
"github.com/docker/machine/libmachine/mcnutils"
"github.com/docker/machine/libmachine/ssh"
"github.com/golang/glog"
"github.com/hashicorp/go-getter"
"github.com/pkg/errors"
"k8s.io/minikube/pkg/version"
"k8s.io/minikube/pkg/minikube/out"
"k8s.io/minikube/pkg/util"
)
const (
driverKVMDownloadURL = "https://storage.googleapis.com/minikube/releases/latest/docker-machine-driver-kvm2"
)
// GetDiskPath returns the path of the machine disk image
@ -136,3 +150,88 @@ func fixPermissions(path string) error {
}
return nil
}
// Download downloads driver if it is not present, or if the version is old
func Download(driver, destination string, minikubeVersion semver.Version) error {
_, err := exec.LookPath(driver)
// if file driver doesn't exist, download it
if err != nil {
return download(driver, destination)
}
cmd := exec.Command(driver, "version")
output, err := cmd.Output()
// if driver doesnt support 'version', it is old, download it
if err != nil {
return download(driver, destination)
}
v := ExtractVMDriverVersion(string(output))
// if the driver doesn't return any version, download it
if len(v) == 0 {
return download(driver, destination)
}
vmDriverVersion, err := semver.Make(v)
if err != nil {
return errors.Wrap(err, "can't parse driver version")
}
// if the current driver version is older, download newer
if vmDriverVersion.LT(minikubeVersion) {
return download(driver, destination)
}
return nil
}
func download(driver, destination string) error {
// only support kvm2 for now
if driver != "docker-machine-driver-kvm2" {
return nil
}
out.T(out.Happy, "Downloading driver {{.driver}}:", out.V{"driver": driver})
targetFilepath := path.Join(destination, "docker-machine-driver-kvm2")
os.Remove(targetFilepath)
url := driverKVMDownloadURL
opts := []getter.ClientOption{getter.WithProgress(util.DefaultProgressBar)}
client := &getter.Client{
Src: url,
Dst: targetFilepath,
Mode: getter.ClientModeFile,
Options: opts,
}
if err := client.Get(); err != nil {
return errors.Wrapf(err, "can't download driver %s from: %s", driver, url)
}
err := os.Chmod(targetFilepath, 0777)
if err != nil {
return errors.Wrap(err, "chmod error")
}
return nil
}
// ExtractVMDriverVersion extracts the driver version.
// KVM and Hyperkit drivers support the 'version' command, that display the information as:
// version: vX.X.X
// commit: XXXX
// This method returns the version 'vX.X.X' or empty if the version isn't found.
func ExtractVMDriverVersion(s string) string {
versionRegex := regexp.MustCompile(`version:(.*)`)
matches := versionRegex.FindStringSubmatch(s)
if len(matches) != 2 {
return ""
}
v := strings.TrimSpace(matches[1])
return strings.TrimPrefix(v, version.VersionPrefix)
}

View File

@ -48,3 +48,27 @@ func Test_createDiskImage(t *testing.T) {
t.Errorf("Disk size is %v, want %v", fi.Size(), sizeInBytes)
}
}
func TestExtractVMDriverVersion(t *testing.T) {
v := ExtractVMDriverVersion("")
if len(v) != 0 {
t.Error("Expected empty string")
}
v = ExtractVMDriverVersion("random text")
if len(v) != 0 {
t.Error("Expected empty string")
}
expectedVersion := "1.2.3"
v = ExtractVMDriverVersion("version: v1.2.3")
if expectedVersion != v {
t.Errorf("Expected version: %s, got: %s", expectedVersion, v)
}
v = ExtractVMDriverVersion("version: 1.2.3")
if expectedVersion != v {
t.Errorf("Expected version: %s, got: %s", expectedVersion, v)
}
}

View File

@ -69,7 +69,7 @@ func (f DefaultDownloader) CacheMinikubeISOFromURL(url string) error {
// Predictable temp destination so that resume can function
tmpDst := dst + ".download"
opts := []getter.ClientOption{getter.WithProgress(defaultProgressBar)}
opts := []getter.ClientOption{getter.WithProgress(DefaultProgressBar)}
client := &getter.Client{
Src: urlWithChecksum,
Dst: tmpDst,

View File

@ -15,9 +15,9 @@ limitations under the License.
*/
// This file implements a go-getter wrapper for cheggaaa progress bar
// based on:
// https://github.com/hashicorp/go-getter/blob/master/cmd/go-getter/progress_tracking.go
package util
import (
@ -29,7 +29,7 @@ import (
"github.com/hashicorp/go-getter"
)
var defaultProgressBar getter.ProgressTracker = &progressBar{}
var DefaultProgressBar getter.ProgressTracker = &progressBar{}
type progressBar struct {
lock sync.Mutex