Pass driverName into Preload and PreloadExists to report no preload for BareMetal.

pull/11528/head
Andriy Dzikh 2021-05-27 14:25:26 -07:00
parent a8136ec322
commit f9f3ef9a09
16 changed files with 46 additions and 353 deletions

View File

@ -86,7 +86,8 @@ out:
if *limit > 0 && i >= *limit { if *limit > 0 && i >= *limit {
break out break out
} }
if !download.PreloadExists(kv, cr) { // Since none/mock are the only exceptions, it does not matter what driver we choose.
if !download.PreloadExists(kv, cr, "docker") {
toGenerate = append(toGenerate, preloadCfg{kv, cr}) toGenerate = append(toGenerate, preloadCfg{kv, cr})
i++ i++
fmt.Printf("[%d] A preloaded tarball for k8s version %s - runtime %q does not exist.\n", i, kv, cr) fmt.Printf("[%d] A preloaded tarball for k8s version %s - runtime %q does not exist.\n", i, kv, cr)

View File

@ -172,7 +172,7 @@ func (d *Driver) Create() error {
go func() { go func() {
defer waitForPreload.Done() defer waitForPreload.Done()
// If preload doesn't exist, don't bother extracting tarball to volume // If preload doesn't exist, don't bother extracting tarball to volume
if !download.PreloadExists(d.NodeConfig.KubernetesVersion, d.NodeConfig.ContainerRuntime) { if !download.PreloadExists(d.NodeConfig.KubernetesVersion, d.NodeConfig.ContainerRuntime, d.DriverName()) {
return return
} }
t := time.Now() t := time.Now()

View File

@ -866,7 +866,7 @@ func (k *Bootstrapper) UpdateCluster(cfg config.ClusterConfig) error {
return errors.Wrap(err, "runtime") return errors.Wrap(err, "runtime")
} }
if err := r.Preload(cfg.KubernetesConfig); err != nil { if err := r.Preload(cfg); err != nil {
klog.Infof("preload failed, will try to load cached images: %v", err) klog.Infof("preload failed, will try to load cached images: %v", err)
} }

View File

@ -464,16 +464,16 @@ func (r *Containerd) SystemLogCmd(len int) string {
} }
// Preload preloads the container runtime with k8s images // Preload preloads the container runtime with k8s images
func (r *Containerd) Preload(cfg config.KubernetesConfig) error { func (r *Containerd) Preload(cc config.ClusterConfig) error {
if !download.PreloadExists(cfg.KubernetesVersion, cfg.ContainerRuntime) { if !download.PreloadExists(cc.KubernetesConfig.KubernetesVersion, cc.KubernetesConfig.ContainerRuntime, cc.Driver) {
return nil return nil
} }
k8sVersion := cfg.KubernetesVersion k8sVersion := cc.KubernetesConfig.KubernetesVersion
cRuntime := cfg.ContainerRuntime cRuntime := cc.KubernetesConfig.ContainerRuntime
// If images already exist, return // If images already exist, return
images, err := images.Kubeadm(cfg.ImageRepository, k8sVersion) images, err := images.Kubeadm(cc.KubernetesConfig.ImageRepository, k8sVersion)
if err != nil { if err != nil {
return errors.Wrap(err, "getting images") return errors.Wrap(err, "getting images")
} }

View File

@ -316,16 +316,16 @@ func (r *CRIO) SystemLogCmd(len int) string {
} }
// Preload preloads the container runtime with k8s images // Preload preloads the container runtime with k8s images
func (r *CRIO) Preload(cfg config.KubernetesConfig) error { func (r *CRIO) Preload(cc config.ClusterConfig) error {
if !download.PreloadExists(cfg.KubernetesVersion, cfg.ContainerRuntime) { if !download.PreloadExists(cc.KubernetesConfig.KubernetesVersion, cc.KubernetesConfig.ContainerRuntime, cc.Driver) {
return nil return nil
} }
k8sVersion := cfg.KubernetesVersion k8sVersion := cc.KubernetesConfig.KubernetesVersion
cRuntime := cfg.ContainerRuntime cRuntime := cc.KubernetesConfig.ContainerRuntime
// If images already exist, return // If images already exist, return
images, err := images.Kubeadm(cfg.ImageRepository, k8sVersion) images, err := images.Kubeadm(cc.KubernetesConfig.ImageRepository, k8sVersion)
if err != nil { if err != nil {
return errors.Wrap(err, "getting images") return errors.Wrap(err, "getting images")
} }

View File

@ -125,7 +125,7 @@ type Manager interface {
// SystemLogCmd returns the command to return the system logs // SystemLogCmd returns the command to return the system logs
SystemLogCmd(int) string SystemLogCmd(int) string
// Preload preloads the container runtime with k8s images // Preload preloads the container runtime with k8s images
Preload(config.KubernetesConfig) error Preload(config.ClusterConfig) error
// ImagesPreloaded returns true if all images have been preloaded // ImagesPreloaded returns true if all images have been preloaded
ImagesPreloaded([]string) bool ImagesPreloaded([]string) bool
} }

View File

@ -449,15 +449,15 @@ func (r *Docker) forceSystemd() error {
// 1. Copy over the preloaded tarball into the VM // 1. Copy over the preloaded tarball into the VM
// 2. Extract the preloaded tarball to the correct directory // 2. Extract the preloaded tarball to the correct directory
// 3. Remove the tarball within the VM // 3. Remove the tarball within the VM
func (r *Docker) Preload(cfg config.KubernetesConfig) error { func (r *Docker) Preload(cc config.ClusterConfig) error {
if !download.PreloadExists(cfg.KubernetesVersion, cfg.ContainerRuntime) { if !download.PreloadExists(cc.KubernetesConfig.KubernetesVersion, cc.KubernetesConfig.ContainerRuntime, cc.Driver) {
return nil return nil
} }
k8sVersion := cfg.KubernetesVersion k8sVersion := cc.KubernetesConfig.KubernetesVersion
cRuntime := cfg.ContainerRuntime cRuntime := cc.KubernetesConfig.ContainerRuntime
// If images already exist, return // If images already exist, return
images, err := images.Kubeadm(cfg.ImageRepository, k8sVersion) images, err := images.Kubeadm(cc.KubernetesConfig.ImageRepository, k8sVersion)
if err != nil { if err != nil {
return errors.Wrap(err, "getting images") return errors.Wrap(err, "getting images")
} }

View File

@ -86,14 +86,14 @@ func testPreloadDownloadPreventsMultipleDownload(t *testing.T) {
} }
return nil, nil return nil, nil
} }
checkPreloadExists = func(k8sVersion, containerRuntime string, forcePreload ...bool) bool { return true } checkPreloadExists = func(k8sVersion, containerRuntime, driverName string, forcePreload ...bool) bool { return true }
getChecksum = func(k8sVersion, containerRuntime string) ([]byte, error) { return []byte("check"), nil } getChecksum = func(k8sVersion, containerRuntime string) ([]byte, error) { return []byte("check"), nil }
ensureChecksumValid = func(k8sVersion, containerRuntime, path string, checksum []byte) error { return nil } ensureChecksumValid = func(k8sVersion, containerRuntime, path string, checksum []byte) error { return nil }
var group sync.WaitGroup var group sync.WaitGroup
group.Add(2) group.Add(2)
dlCall := func() { dlCall := func() {
if err := Preload(constants.DefaultKubernetesVersion, constants.DefaultContainerRuntime); err != nil { if err := Preload(constants.DefaultKubernetesVersion, constants.DefaultContainerRuntime, "docker"); err != nil {
t.Logf("Failed to download preload: %+v (may be ok)", err) t.Logf("Failed to download preload: %+v (may be ok)", err)
} }
group.Done() group.Done()
@ -114,11 +114,11 @@ func testPreloadNotExists(t *testing.T) {
DownloadMock = mockSleepDownload(&downloadNum) DownloadMock = mockSleepDownload(&downloadNum)
checkCache = func(file string) (fs.FileInfo, error) { return nil, fmt.Errorf("cache not found") } checkCache = func(file string) (fs.FileInfo, error) { return nil, fmt.Errorf("cache not found") }
checkPreloadExists = func(k8sVersion, containerRuntime string, forcePreload ...bool) bool { return false } checkPreloadExists = func(k8sVersion, containerRuntime, driverName string, forcePreload ...bool) bool { return false }
getChecksum = func(k8sVersion, containerRuntime string) ([]byte, error) { return []byte("check"), nil } getChecksum = func(k8sVersion, containerRuntime string) ([]byte, error) { return []byte("check"), nil }
ensureChecksumValid = func(k8sVersion, containerRuntime, path string, checksum []byte) error { return nil } ensureChecksumValid = func(k8sVersion, containerRuntime, path string, checksum []byte) error { return nil }
err := Preload(constants.DefaultKubernetesVersion, constants.DefaultContainerRuntime) err := Preload(constants.DefaultKubernetesVersion, constants.DefaultContainerRuntime, "docker")
if err != nil { if err != nil {
t.Errorf("Expected no error when preload exists") t.Errorf("Expected no error when preload exists")
} }
@ -133,13 +133,13 @@ func testPreloadChecksumMismatch(t *testing.T) {
DownloadMock = mockSleepDownload(&downloadNum) DownloadMock = mockSleepDownload(&downloadNum)
checkCache = func(file string) (fs.FileInfo, error) { return nil, fmt.Errorf("cache not found") } checkCache = func(file string) (fs.FileInfo, error) { return nil, fmt.Errorf("cache not found") }
checkPreloadExists = func(k8sVersion, containerRuntime string, forcePreload ...bool) bool { return true } checkPreloadExists = func(k8sVersion, containerRuntime, driverName string, forcePreload ...bool) bool { return true }
getChecksum = func(k8sVersion, containerRuntime string) ([]byte, error) { return []byte("check"), nil } getChecksum = func(k8sVersion, containerRuntime string) ([]byte, error) { return []byte("check"), nil }
ensureChecksumValid = func(k8sVersion, containerRuntime, path string, checksum []byte) error { ensureChecksumValid = func(k8sVersion, containerRuntime, path string, checksum []byte) error {
return fmt.Errorf("checksum mismatch") return fmt.Errorf("checksum mismatch")
} }
err := Preload(constants.DefaultKubernetesVersion, constants.DefaultContainerRuntime) err := Preload(constants.DefaultKubernetesVersion, constants.DefaultContainerRuntime, "docker")
expectedErrMsg := "checksum mismatch" expectedErrMsg := "checksum mismatch"
if err == nil { if err == nil {
t.Errorf("Expected error when checksum mismatches") t.Errorf("Expected error when checksum mismatches")

View File

@ -33,6 +33,7 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/spf13/viper" "github.com/spf13/viper"
"k8s.io/klog/v2" "k8s.io/klog/v2"
"k8s.io/minikube/pkg/minikube/driver"
"k8s.io/minikube/pkg/minikube/localpath" "k8s.io/minikube/pkg/minikube/localpath"
"k8s.io/minikube/pkg/minikube/out" "k8s.io/minikube/pkg/minikube/out"
"k8s.io/minikube/pkg/minikube/style" "k8s.io/minikube/pkg/minikube/style"
@ -98,7 +99,7 @@ func remoteTarballURL(k8sVersion, containerRuntime string) string {
} }
// PreloadExists returns true if there is a preloaded tarball that can be used // PreloadExists returns true if there is a preloaded tarball that can be used
func PreloadExists(k8sVersion, containerRuntime string, forcePreload ...bool) bool { func PreloadExists(k8sVersion, containerRuntime, driverName string, forcePreload ...bool) bool {
// TODO (#8166): Get rid of the need for this and viper at all // TODO (#8166): Get rid of the need for this and viper at all
force := false force := false
if len(forcePreload) > 0 { if len(forcePreload) > 0 {
@ -107,7 +108,9 @@ func PreloadExists(k8sVersion, containerRuntime string, forcePreload ...bool) bo
// TODO: debug why this func is being called two times // TODO: debug why this func is being called two times
klog.Infof("Checking if preload exists for k8s version %s and runtime %s", k8sVersion, containerRuntime) klog.Infof("Checking if preload exists for k8s version %s and runtime %s", k8sVersion, containerRuntime)
if !viper.GetBool("preload") && !force { // If `driverName` is BareMetal, there is no preload. Note: some uses of
// `PreloadExists` assume that the driver is irrelevant unless BareMetal.
if driver.BareMetal(driverName) || !viper.GetBool("preload") && !force {
return false return false
} }
@ -147,7 +150,7 @@ func PreloadExists(k8sVersion, containerRuntime string, forcePreload ...bool) bo
var checkPreloadExists = PreloadExists var checkPreloadExists = PreloadExists
// Preload caches the preloaded images tarball on the host machine // Preload caches the preloaded images tarball on the host machine
func Preload(k8sVersion, containerRuntime string) error { func Preload(k8sVersion, containerRuntime, driverName string) error {
targetPath := TarballPath(k8sVersion, containerRuntime) targetPath := TarballPath(k8sVersion, containerRuntime)
targetLock := targetPath + ".lock" targetLock := targetPath + ".lock"
@ -165,7 +168,7 @@ func Preload(k8sVersion, containerRuntime string) error {
} }
// Make sure we support this k8s version // Make sure we support this k8s version
if !checkPreloadExists(k8sVersion, containerRuntime) { if !checkPreloadExists(k8sVersion, containerRuntime, driverName) {
klog.Infof("Preloaded tarball for k8s version %s does not exist", k8sVersion) klog.Infof("Preloaded tarball for k8s version %s does not exist", k8sVersion)
return nil return nil
} }

View File

@ -1,164 +0,0 @@
/*
Copyright 2019 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package driver
import (
"fmt"
"os"
"os/exec"
"path/filepath"
"regexp"
"strings"
"time"
"github.com/blang/semver"
"github.com/juju/mutex"
"github.com/pkg/errors"
"k8s.io/klog/v2"
"k8s.io/minikube/pkg/minikube/download"
"k8s.io/minikube/pkg/minikube/out"
"k8s.io/minikube/pkg/minikube/style"
"k8s.io/minikube/pkg/util/lock"
)
// InstallOrUpdate downloads driver if it is not present, or updates it if there's a newer version
func InstallOrUpdate(name string, directory string, v semver.Version, interactive bool, autoUpdate bool) error {
if name != KVM2 && name != HyperKit {
return nil
}
executable := fmt.Sprintf("docker-machine-driver-%s", name)
// Lock before we check for existence to avoid thundering herd issues
spec := lock.PathMutexSpec(executable)
spec.Timeout = 10 * time.Minute
klog.Infof("acquiring lock: %+v", spec)
releaser, err := mutex.Acquire(spec)
if err != nil {
return errors.Wrapf(err, "unable to acquire lock for %+v", spec)
}
defer releaser.Release()
exists := driverExists(executable)
path, err := validateDriver(executable, minAcceptableDriverVersion(name, v))
if !exists || (err != nil && autoUpdate) {
klog.Warningf("%s: %v", executable, err)
path = filepath.Join(directory, executable)
if err := download.Driver(executable, path, v); err != nil {
return err
}
}
return fixDriverPermissions(name, path, interactive)
}
// fixDriverPermissions fixes the permissions on a driver
func fixDriverPermissions(name string, path string, interactive bool) error {
if name != HyperKit {
return nil
}
// Using the find command for hyperkit is far easier than cross-platform uid checks in Go.
stdout, err := exec.Command("find", path, "-uid", "0", "-perm", "4755").Output()
klog.Infof("stdout: %s", stdout)
if err == nil && strings.TrimSpace(string(stdout)) == path {
klog.Infof("%s looks good", path)
return nil
}
cmds := []*exec.Cmd{
exec.Command("sudo", "chown", "root:wheel", path),
exec.Command("sudo", "chmod", "u+s", path),
}
var example strings.Builder
for _, c := range cmds {
example.WriteString(fmt.Sprintf(" $ %s \n", strings.Join(c.Args, " ")))
}
out.Styled(style.Permissions, "The '{{.driver}}' driver requires elevated permissions. The following commands will be executed:\n\n{{ .example }}\n", out.V{"driver": name, "example": example.String()})
for _, c := range cmds {
testArgs := append([]string{"-n"}, c.Args[1:]...)
test := exec.Command("sudo", testArgs...)
klog.Infof("testing: %v", test.Args)
if err := test.Run(); err != nil {
klog.Infof("%v may require a password: %v", c.Args, err)
if !interactive {
return fmt.Errorf("%v requires a password, and --interactive=false", c.Args)
}
}
klog.Infof("running: %v", c.Args)
err := c.Run()
if err != nil {
return errors.Wrapf(err, "%v", c.Args)
}
}
return nil
}
// validateDriver validates if a driver appears to be up-to-date and installed properly
func validateDriver(executable string, v semver.Version) (string, error) {
klog.Infof("Validating %s, PATH=%s", executable, os.Getenv("PATH"))
path, err := exec.LookPath(executable)
if err != nil {
return path, err
}
output, err := exec.Command(path, "version").Output()
if err != nil {
return path, err
}
ev := extractDriverVersion(string(output))
if len(ev) == 0 {
return path, fmt.Errorf("%s: unable to extract version from %q", executable, output)
}
driverVersion, err := semver.Make(ev)
if err != nil {
return path, errors.Wrap(err, "can't parse driver version")
}
klog.Infof("%s version is %s", path, driverVersion)
if driverVersion.LT(v) {
return path, fmt.Errorf("%s is version %s, want %s", executable, driverVersion, v)
}
return path, nil
}
// extractDriverVersion 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 extractDriverVersion(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, "v")
}
func driverExists(driver string) bool {
_, err := exec.LookPath(driver)
return err == nil
}

View File

@ -1,45 +0,0 @@
/*
Copyright 2019 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package driver
import (
"testing"
)
func TestExtractDriverVersion(t *testing.T) {
v := extractDriverVersion("")
if len(v) != 0 {
t.Error("Expected empty string")
}
v = extractDriverVersion("random text")
if len(v) != 0 {
t.Error("Expected empty string")
}
expectedVersion := "1.2.3"
v = extractDriverVersion("version: v1.2.3")
if expectedVersion != v {
t.Errorf("Expected version: %s, got: %s", expectedVersion, v)
}
v = extractDriverVersion("version: 1.2.3")
if expectedVersion != v {
t.Errorf("Expected version: %s, got: %s", expectedVersion, v)
}
}

View File

@ -1,52 +0,0 @@
/*
Copyright 2020 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package driver
import (
"github.com/blang/semver"
"k8s.io/klog/v2"
)
// minHyperkitVersion is the minimum version of the minikube hyperkit driver compatible with the current minikube code
var minHyperkitVersion *semver.Version
const minHyperkitVersionStr = "1.11.0"
func init() {
v, err := semver.New(minHyperkitVersionStr)
if err != nil {
klog.Errorf("Failed to parse the hyperkit driver version: %v", err)
} else {
minHyperkitVersion = v
}
}
// minAcceptableDriverVersion is the minimum version of driver supported by current version of minikube
func minAcceptableDriverVersion(driver string, mkVer semver.Version) semver.Version {
switch driver {
case HyperKit:
if minHyperkitVersion != nil {
return *minHyperkitVersion
}
return mkVer
case KVM2:
return mkVer
default:
klog.Warningf("Unexpected driver: %v", driver)
return mkVer
}
}

View File

@ -1,52 +0,0 @@
/*
Copyright 2020 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package driver
import (
"testing"
"github.com/blang/semver"
)
func Test_minDriverVersion(t *testing.T) {
tests := []struct {
desc string
driver string
mkV string
want semver.Version
}{
{"Hyperkit", HyperKit, "1.1.1", *minHyperkitVersion},
{"Invalid", "_invalid_", "1.1.1", v("1.1.1")},
{"KVM2", KVM2, "1.1.1", v("1.1.1")},
}
for _, tt := range tests {
t.Run(tt.desc, func(t *testing.T) {
if got := minAcceptableDriverVersion(tt.driver, v(tt.mkV)); !got.EQ(tt.want) {
t.Errorf("Invalid min supported version, got: %v, want: %v", got, tt.want)
}
})
}
}
func v(s string) semver.Version {
r, err := semver.New(s)
if err != nil {
panic(err)
}
return *r
}

View File

@ -48,11 +48,11 @@ const (
) )
// BeginCacheKubernetesImages caches images required for Kubernetes version in the background // BeginCacheKubernetesImages caches images required for Kubernetes version in the background
func beginCacheKubernetesImages(g *errgroup.Group, imageRepository string, k8sVersion string, cRuntime string) { func beginCacheKubernetesImages(g *errgroup.Group, imageRepository string, k8sVersion string, cRuntime string, driverName string) {
// TODO: remove imageRepository check once #7695 is fixed // TODO: remove imageRepository check once #7695 is fixed
if imageRepository == "" && download.PreloadExists(k8sVersion, cRuntime) { if imageRepository == "" && download.PreloadExists(k8sVersion, cRuntime, driverName) {
klog.Info("Caching tarball of preloaded images") klog.Info("Caching tarball of preloaded images")
err := download.Preload(k8sVersion, cRuntime) err := download.Preload(k8sVersion, cRuntime, driverName)
if err == nil { if err == nil {
klog.Infof("Finished verifying existence of preloaded tar for %s on %s", k8sVersion, cRuntime) klog.Infof("Finished verifying existence of preloaded tar for %s on %s", k8sVersion, cRuntime)
return // don't cache individual images if preload is successful. return // don't cache individual images if preload is successful.
@ -70,12 +70,12 @@ func beginCacheKubernetesImages(g *errgroup.Group, imageRepository string, k8sVe
} }
// handleDownloadOnly caches appropariate binaries and images // handleDownloadOnly caches appropariate binaries and images
func handleDownloadOnly(cacheGroup, kicGroup *errgroup.Group, k8sVersion, containerRuntime string) { func handleDownloadOnly(cacheGroup, kicGroup *errgroup.Group, k8sVersion, containerRuntime, driverName string) {
// If --download-only, complete the remaining downloads and exit. // If --download-only, complete the remaining downloads and exit.
if !viper.GetBool("download-only") { if !viper.GetBool("download-only") {
return return
} }
if err := doCacheBinaries(k8sVersion, containerRuntime); err != nil { if err := doCacheBinaries(k8sVersion, containerRuntime, driverName); err != nil {
exit.Error(reason.InetCacheBinaries, "Failed to cache binaries", err) exit.Error(reason.InetCacheBinaries, "Failed to cache binaries", err)
} }
if _, err := CacheKubectlBinary(k8sVersion); err != nil { if _, err := CacheKubectlBinary(k8sVersion); err != nil {
@ -101,9 +101,9 @@ func CacheKubectlBinary(k8sVersion string) (string, error) {
} }
// doCacheBinaries caches Kubernetes binaries in the foreground // doCacheBinaries caches Kubernetes binaries in the foreground
func doCacheBinaries(k8sVersion, containerRuntime string) error { func doCacheBinaries(k8sVersion, containerRuntime, driverName string) error {
existingBinaries := constants.KubernetesReleaseBinaries existingBinaries := constants.KubernetesReleaseBinaries
if !download.PreloadExists(k8sVersion, containerRuntime) { if !download.PreloadExists(k8sVersion, containerRuntime, driverName) {
existingBinaries = nil existingBinaries = nil
} }
return machine.CacheBinariesForBootstrapper(k8sVersion, viper.GetString(cmdcfg.Bootstrapper), existingBinaries) return machine.CacheBinariesForBootstrapper(k8sVersion, viper.GetString(cmdcfg.Bootstrapper), existingBinaries)

View File

@ -280,7 +280,7 @@ func Provision(cc *config.ClusterConfig, n *config.Node, apiServer bool, delOnFa
} }
if !driver.BareMetal(cc.Driver) { if !driver.BareMetal(cc.Driver) {
beginCacheKubernetesImages(&cacheGroup, cc.KubernetesConfig.ImageRepository, n.KubernetesVersion, cc.KubernetesConfig.ContainerRuntime) beginCacheKubernetesImages(&cacheGroup, cc.KubernetesConfig.ImageRepository, n.KubernetesVersion, cc.KubernetesConfig.ContainerRuntime, cc.Driver)
} }
// Abstraction leakage alert: startHost requires the config to be saved, to satistfy pkg/provision/buildroot. // Abstraction leakage alert: startHost requires the config to be saved, to satistfy pkg/provision/buildroot.
@ -289,7 +289,7 @@ func Provision(cc *config.ClusterConfig, n *config.Node, apiServer bool, delOnFa
return nil, false, nil, nil, errors.Wrap(err, "Failed to save config") return nil, false, nil, nil, errors.Wrap(err, "Failed to save config")
} }
handleDownloadOnly(&cacheGroup, &kicGroup, n.KubernetesVersion, cc.KubernetesConfig.ContainerRuntime) handleDownloadOnly(&cacheGroup, &kicGroup, n.KubernetesVersion, cc.KubernetesConfig.ContainerRuntime, cc.Driver)
waitDownloadKicBaseImage(&kicGroup) waitDownloadKicBaseImage(&kicGroup)
return startMachine(cc, n, delOnFail) return startMachine(cc, n, delOnFail)
@ -318,7 +318,7 @@ func configureRuntimes(runner cruntime.CommandRunner, cc config.ClusterConfig, k
// Preload is overly invasive for bare metal, and caching is not meaningful. // Preload is overly invasive for bare metal, and caching is not meaningful.
// KIC handles preload elsewhere. // KIC handles preload elsewhere.
if driver.IsVM(cc.Driver) { if driver.IsVM(cc.Driver) {
if err := cr.Preload(cc.KubernetesConfig); err != nil { if err := cr.Preload(cc); err != nil {
switch err.(type) { switch err.(type) {
case *cruntime.ErrISOFeature: case *cruntime.ErrISOFeature:
out.ErrT(style.Tip, "Existing disk is missing new features ({{.error}}). To upgrade, run 'minikube delete'", out.V{"error": err}) out.ErrT(style.Tip, "Existing disk is missing new features ({{.error}}). To upgrade, run 'minikube delete'", out.V{"error": err})

View File

@ -97,7 +97,9 @@ func TestDownloadOnly(t *testing.T) {
if NoneDriver() { if NoneDriver() {
t.Skip("None driver does not have preload") t.Skip("None driver does not have preload")
} }
if download.PreloadExists(v, containerRuntime, true) { // Driver does not matter here, since the only exception is none driver,
// which cannot occur here.
if download.PreloadExists(v, containerRuntime, "docker", true) {
// Just make sure the tarball path exists // Just make sure the tarball path exists
if _, err := os.Stat(download.TarballPath(v, containerRuntime)); err != nil { if _, err := os.Stat(download.TarballPath(v, containerRuntime)); err != nil {
t.Errorf("failed to verify preloaded tarball file exists: %v", err) t.Errorf("failed to verify preloaded tarball file exists: %v", err)