Download kvm2 driver
parent
f36c5d8ed1
commit
30e75c3c39
|
@ -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))
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue