diff --git a/cmd/minikube/cmd/start.go b/cmd/minikube/cmd/start.go index c05d715ec4..e29b5f0418 100644 --- a/cmd/minikube/cmd/start.go +++ b/cmd/minikube/cmd/start.go @@ -43,10 +43,10 @@ import ( cmdcfg "k8s.io/minikube/cmd/minikube/cmd/config" "k8s.io/minikube/pkg/minikube/bootstrapper/bsutil" "k8s.io/minikube/pkg/minikube/bootstrapper/images" - "k8s.io/minikube/pkg/minikube/cluster" "k8s.io/minikube/pkg/minikube/config" "k8s.io/minikube/pkg/minikube/constants" "k8s.io/minikube/pkg/minikube/cruntime" + "k8s.io/minikube/pkg/minikube/download" "k8s.io/minikube/pkg/minikube/driver" "k8s.io/minikube/pkg/minikube/exit" "k8s.io/minikube/pkg/minikube/kubeconfig" @@ -154,7 +154,7 @@ func initMinikubeFlags() { startCmd.Flags().String(humanReadableDiskSize, defaultDiskSize, "Disk size allocated to the minikube VM (format: [], where unit = b, k, m or g).") startCmd.Flags().Bool(downloadOnly, false, "If true, only download and cache files for later use - don't install or start anything.") startCmd.Flags().Bool(cacheImages, true, "If true, cache docker images for the current bootstrapper and load them into the machine. Always false with --vm-driver=none.") - startCmd.Flags().String(isoURL, constants.DefaultISOURL, "Location of the minikube iso.") + startCmd.Flags().StringSlice(isoURL, download.DefaultISOURLs(), "Locations to fetch the minikube ISO from.") startCmd.Flags().Bool(keepContext, false, "This will keep the existing kubectl context and will create a minikube context.") startCmd.Flags().Bool(embedCerts, false, "if true, will embed the certs in kubeconfig.") startCmd.Flags().String(containerRuntime, "docker", "The container runtime to be used (docker, crio, containerd).") @@ -320,7 +320,13 @@ func runStart(cmd *cobra.Command, args []string) { return } - cacheISO(&mc, driverName) + if !driver.BareMetal(driverName) && !driver.IsKIC(driverName) { + url, err := download.ISO(viper.GetStringSlice(isoURL)) + if err != nil { + exit.WithError("Failed to cache ISO", err) + } + mc.MinikubeISO = url + } if viper.GetBool(nativeSSH) { ssh.SetDefaultClient(ssh.Native) @@ -354,14 +360,6 @@ func updateDriver(driverName string) { } } -func cacheISO(cfg *config.MachineConfig, driverName string) { - if !driver.BareMetal(driverName) && !driver.IsKIC(driverName) { - if err := cluster.CacheISO(*cfg); err != nil { - exit.WithError("Failed to cache ISO", err) - } - } -} - func displayVersion(version string) { prefix := "" if viper.GetString(config.MachineProfile) != constants.DefaultMachineName { @@ -782,7 +780,6 @@ func generateCfgFromFlags(cmd *cobra.Command, k8sVersion string, drvName string) Name: viper.GetString(config.MachineProfile), KeepContext: viper.GetBool(keepContext), EmbedCerts: viper.GetBool(embedCerts), - MinikubeISO: viper.GetString(isoURL), Memory: pkgutil.CalculateSizeInMB(viper.GetString(memory)), CPUs: viper.GetInt(cpus), DiskSize: pkgutil.CalculateSizeInMB(viper.GetString(humanReadableDiskSize)), @@ -803,7 +800,6 @@ func generateCfgFromFlags(cmd *cobra.Command, k8sVersion string, drvName string) KVMQemuURI: viper.GetString(kvmQemuURI), KVMGPU: viper.GetBool(kvmGPU), KVMHidden: viper.GetBool(kvmHidden), - Downloader: pkgutil.DefaultDownloader{}, DisableDriverMounts: viper.GetBool(disableDriverMounts), UUID: viper.GetString(uuid), NoVTXCheck: viper.GetBool(noVTXCheck), diff --git a/go.mod b/go.mod index e4798d896c..3618988a2a 100644 --- a/go.mod +++ b/go.mod @@ -23,15 +23,12 @@ require ( github.com/google/go-cmp v0.3.0 github.com/google/go-containerregistry v0.0.0-20200131185320-aec8da010de2 github.com/googleapis/gnostic v0.3.0 // indirect - github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce // indirect github.com/hashicorp/go-getter v1.4.0 - github.com/hashicorp/go-multierror v0.0.0-20160811015721-8c5f0ad93604 // indirect github.com/hashicorp/go-retryablehttp v0.5.4 github.com/hooklift/assert v0.0.0-20170704181755-9d1defd6d214 // indirect github.com/hooklift/iso9660 v0.0.0-20170318115843-1cf07e5970d8 github.com/imdario/mergo v0.3.8 // indirect github.com/intel-go/cpuid v0.0.0-20181003105527-1a4a6f06a1c6 // indirect - github.com/jimmidyson/go-download v0.0.0-20161028105827-7f9a90c8c95b github.com/johanneswuerbach/nfsexports v0.0.0-20181204082207-1aa528dcb345 github.com/juju/clock v0.0.0-20190205081909-9c5c9712527c github.com/juju/errors v0.0.0-20190806202954-0232dcc7464d // indirect diff --git a/go.sum b/go.sum index a5032159c7..42c9980d01 100644 --- a/go.sum +++ b/go.sum @@ -346,12 +346,8 @@ github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:Fecb github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce h1:prjrVgOk2Yg6w+PflHoszQNLTUh4kaByUcEWM/9uin4= -github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.0 h1:wvCrVc9TjDls6+YGAF2hAifE1E5U1+b4tH6KdvN3Gig= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-multierror v0.0.0-20160811015721-8c5f0ad93604 h1:VIq8E7fMiC4h3agg0ya56L0jHn7QisZZcWZXVKJb9jQ= -github.com/hashicorp/go-multierror v0.0.0-20160811015721-8c5f0ad93604/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I= github.com/hashicorp/go-retryablehttp v0.5.4 h1:1BZvpawXoJCWX6pNtow9+rpEj+3itIlutiqnntI6jOE= github.com/hashicorp/go-retryablehttp v0.5.4/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= github.com/hashicorp/go-safetemp v1.0.0 h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhEyExpmo= @@ -386,8 +382,6 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt github.com/intel-go/cpuid v0.0.0-20181003105527-1a4a6f06a1c6 h1:XboatR7lasl05yel5hNXF7kQBw2oFUGdMztcgisfhNU= github.com/intel-go/cpuid v0.0.0-20181003105527-1a4a6f06a1c6/go.mod h1:RmeVYf9XrPRbRc3XIx0gLYA8qOFvNoPOfaEZduRlEp4= github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= -github.com/jimmidyson/go-download v0.0.0-20161028105827-7f9a90c8c95b h1:3TknJxYSK1eDe21QorC3C2Yz8jylk6vlJG9YABnFzkU= -github.com/jimmidyson/go-download v0.0.0-20161028105827-7f9a90c8c95b/go.mod h1:I3WsAhNNoG7a/d8HMlYUywJJlfOs/+/83NEUjuDp4lc= github.com/jimstudt/http-authentication v0.0.0-20140401203705-3eca13d6893a/go.mod h1:wK6yTYYcgjHE1Z1QtXACPDjcFJyBskHEdagmnq3vsP8= github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8 h1:12VvqtR6Aowv3l/EQUlocDHW2Cp4G9WJVH7uyH8QFJE= github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= diff --git a/pkg/minikube/bootstrapper/bsutil/binaries.go b/pkg/minikube/bootstrapper/bsutil/binaries.go index 532be8a7ad..6778599db7 100644 --- a/pkg/minikube/bootstrapper/bsutil/binaries.go +++ b/pkg/minikube/bootstrapper/bsutil/binaries.go @@ -27,6 +27,7 @@ import ( "k8s.io/minikube/pkg/minikube/command" "k8s.io/minikube/pkg/minikube/config" "k8s.io/minikube/pkg/minikube/constants" + "k8s.io/minikube/pkg/minikube/download" "k8s.io/minikube/pkg/minikube/machine" "k8s.io/minikube/pkg/minikube/vmpath" ) @@ -43,7 +44,7 @@ func TransferBinaries(cfg config.KubernetesConfig, c command.Runner) error { for _, name := range constants.KubernetesReleaseBinaries { name := name g.Go(func() error { - src, err := machine.CacheBinary(name, cfg.KubernetesVersion, "linux", runtime.GOARCH) + src, err := download.Binary(name, cfg.KubernetesVersion, "linux", runtime.GOARCH) if err != nil { return errors.Wrapf(err, "downloading %s", name) } diff --git a/pkg/minikube/cluster/iso.go b/pkg/minikube/cluster/iso.go deleted file mode 100644 index 253acbd370..0000000000 --- a/pkg/minikube/cluster/iso.go +++ /dev/null @@ -1,30 +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 cluster - -import ( - "k8s.io/minikube/pkg/minikube/config" - "k8s.io/minikube/pkg/minikube/driver" -) - -// CacheISO downloads and caches ISO. -func CacheISO(cfg config.MachineConfig) error { - if driver.BareMetal(cfg.Driver) { - return nil - } - return cfg.Downloader.CacheMinikubeISOFromURL(cfg.MinikubeISO) -} diff --git a/pkg/minikube/config/types.go b/pkg/minikube/config/types.go index 6513efd2d9..b953c514c1 100644 --- a/pkg/minikube/config/types.go +++ b/pkg/minikube/config/types.go @@ -20,7 +20,6 @@ import ( "net" "github.com/blang/semver" - "k8s.io/minikube/pkg/util" ) // Profile represents a minikube profile @@ -49,13 +48,12 @@ type MachineConfig struct { HypervVirtualSwitch string HypervUseExternalSwitch bool HypervExternalAdapter string - KVMNetwork string // Only used by the KVM driver - KVMQemuURI string // Only used by kvm2 - KVMGPU bool // Only used by kvm2 - KVMHidden bool // Only used by kvm2 - Downloader util.ISODownloader `json:"-"` - DockerOpt []string // Each entry is formatted as KEY=VALUE. - DisableDriverMounts bool // Only used by virtualbox + KVMNetwork string // Only used by the KVM driver + KVMQemuURI string // Only used by kvm2 + KVMGPU bool // Only used by kvm2 + KVMHidden bool // Only used by kvm2 + DockerOpt []string // Each entry is formatted as KEY=VALUE. + DisableDriverMounts bool // Only used by virtualbox NFSShare []string NFSSharesRoot string UUID string // Only used by hyperkit to restore the mac address diff --git a/pkg/minikube/constants/constants.go b/pkg/minikube/constants/constants.go index dbf74c4747..0bc95661f9 100644 --- a/pkg/minikube/constants/constants.go +++ b/pkg/minikube/constants/constants.go @@ -17,13 +17,11 @@ limitations under the License. package constants import ( - "fmt" "path/filepath" "k8s.io/client-go/tools/clientcmd" "k8s.io/client-go/util/homedir" "k8s.io/minikube/pkg/minikube/localpath" - minikubeVersion "k8s.io/minikube/pkg/version" ) const ( @@ -78,10 +76,6 @@ var ( var ( SHASuffix = ".sha256" - // DefaultISOURL is the default location of the minikube.iso file - DefaultISOURL = fmt.Sprintf("https://storage.googleapis.com/%s/minikube-%s.iso", minikubeVersion.GetISOPath(), minikubeVersion.GetISOVersion()) - // DefaultISOSHAURL is the default location of the minikube.iso.sha256 file - DefaultISOSHAURL = DefaultISOURL + SHASuffix // DockerDaemonEnvs is list of docker-daemon related environment variables. DockerDaemonEnvs = [3]string{DockerHostEnv, DockerTLSVerifyEnv, DockerCertPathEnv} diff --git a/pkg/minikube/driver/install.go b/pkg/minikube/driver/install.go index 8a49e833fa..ae17a917cd 100644 --- a/pkg/minikube/driver/install.go +++ b/pkg/minikube/driver/install.go @@ -27,12 +27,11 @@ import ( "github.com/blang/semver" "github.com/golang/glog" - "github.com/hashicorp/go-getter" "github.com/juju/mutex" "github.com/pkg/errors" + "k8s.io/minikube/pkg/minikube/download" "k8s.io/minikube/pkg/minikube/out" - "k8s.io/minikube/pkg/util" "k8s.io/minikube/pkg/util/lock" ) @@ -59,7 +58,7 @@ func InstallOrUpdate(name string, directory string, v semver.Version, interactiv if !exists || (err != nil && autoUpdate) { glog.Warningf("%s: %v", executable, err) path = filepath.Join(directory, executable) - derr := download(executable, path, v) + derr := download.Driver(executable, path, v) if derr != nil { return derr } @@ -139,31 +138,6 @@ func validateDriver(executable string, v semver.Version) (string, error) { return path, nil } -func driverWithChecksumURL(name string, v semver.Version) string { - base := fmt.Sprintf("https://github.com/kubernetes/minikube/releases/download/v%s/%s", v, name) - return fmt.Sprintf("%s?checksum=file:%s.sha256", base, base) -} - -// download an arbitrary driver -func download(name string, destination string, v semver.Version) error { - out.T(out.FileDownload, "Downloading driver {{.driver}}:", out.V{"driver": name}) - os.Remove(destination) - url := driverWithChecksumURL(name, v) - client := &getter.Client{ - Src: url, - Dst: destination, - Mode: getter.ClientModeFile, - Options: []getter.ClientOption{getter.WithProgress(util.DefaultProgressBar)}, - } - - glog.Infof("Downloading: %+v", client) - if err := client.Get(); err != nil { - return errors.Wrapf(err, "download failed: %s", url) - } - // Give downloaded drivers a baseline decent file permission - return os.Chmod(destination, 0755) -} - // extractDriverVersion extracts the driver version. // KVM and Hyperkit drivers support the 'version' command, that display the information as: // version: vX.X.X diff --git a/pkg/minikube/machine/cache_binaries.go b/pkg/minikube/machine/cache_binaries.go index 898540eab3..f702ee950c 100644 --- a/pkg/minikube/machine/cache_binaries.go +++ b/pkg/minikube/machine/cache_binaries.go @@ -17,22 +17,15 @@ limitations under the License. package machine import ( - "crypto" - "fmt" - "os" "path" "runtime" - "github.com/blang/semver" - "github.com/golang/glog" - "github.com/jimmidyson/go-download" "github.com/pkg/errors" "golang.org/x/sync/errgroup" "k8s.io/minikube/pkg/minikube/assets" "k8s.io/minikube/pkg/minikube/bootstrapper" "k8s.io/minikube/pkg/minikube/command" - "k8s.io/minikube/pkg/minikube/localpath" - "k8s.io/minikube/pkg/minikube/out" + "k8s.io/minikube/pkg/minikube/download" ) // CacheBinariesForBootstrapper will cache binaries for a bootstrapper @@ -43,7 +36,7 @@ func CacheBinariesForBootstrapper(version string, clusterBootstrapper string) er for _, bin := range binaries { bin := bin // https://golang.org/doc/faq#closures_and_goroutines g.Go(func() error { - if _, err := CacheBinary(bin, version, "linux", runtime.GOARCH); err != nil { + if _, err := download.Binary(bin, version, "linux", runtime.GOARCH); err != nil { return errors.Wrapf(err, "caching binary %s", bin) } return nil @@ -52,72 +45,6 @@ func CacheBinariesForBootstrapper(version string, clusterBootstrapper string) er return g.Wait() } -// releaseURL gets the location of a Kubernetes binary -func releaseURL(binaryName, version, osName, archName string) string { - return fmt.Sprintf("https://storage.googleapis.com/kubernetes-release/release/%s/bin/%s/%s/%s", version, osName, archName, binaryName) -} - -// downloadOptions returns appropriate download options for a -func downloadOptions(url string, version string) (download.FileOptions, error) { - fo := download.FileOptions{ - Mkdirs: download.MkdirAll, - Options: download.Options{ - ChecksumHash: crypto.SHA1, - Checksum: url + ".sha1", - }, - } - - v, err := semver.Make(version[1:]) - if err != nil { - return fo, err - } - - if v.GTE(semver.MustParse("1.17.0")) { - fo.ChecksumHash = crypto.SHA256 - fo.Checksum = url + ".sha256" - } - return fo, nil -} - -// CacheBinary will cache a binary on the host -func CacheBinary(binary, version, osName, archName string) (string, error) { - - targetDir := localpath.MakeMiniPath("cache", osName, version) - targetFilepath := path.Join(targetDir, binary) - - url := releaseURL(binary, version, osName, archName) - - _, err := os.Stat(targetFilepath) - // If it exists, do no verification and continue - if err == nil { - glog.Infof("Not caching binary, using %s", url) - return targetFilepath, nil - } - if !os.IsNotExist(err) { - return "", errors.Wrapf(err, "stat %s version %s at %s", binary, version, targetDir) - } - - if err = os.MkdirAll(targetDir, 0777); err != nil { - return "", errors.Wrapf(err, "mkdir %s", targetDir) - } - - options, err := downloadOptions(url, version) - if err != nil { - return "", errors.Wrap(err, "options") - } - glog.Infof("Downloading %s: options: %+v", url, options) - - out.T(out.FileDownload, "Downloading {{.name}} {{.version}}", out.V{"name": binary, "version": version}) - if err := download.ToFile(url, targetFilepath, options); err != nil { - return "", errors.Wrapf(err, url) - } - if osName == runtime.GOOS && archName == runtime.GOARCH { - if err = os.Chmod(targetFilepath, 0755); err != nil { - return "", errors.Wrapf(err, "chmod +x %s", targetFilepath) - } - } - return targetFilepath, nil -} // CopyBinary copies a locally cached binary to the guest VM func CopyBinary(cr command.Runner, src string, dest string) error { diff --git a/pkg/minikube/machine/cache_binaries_test.go b/pkg/minikube/machine/cache_binaries_test.go index b490974eac..500c0ea74d 100644 --- a/pkg/minikube/machine/cache_binaries_test.go +++ b/pkg/minikube/machine/cache_binaries_test.go @@ -17,15 +17,11 @@ limitations under the License. package machine import ( - "crypto" "fmt" "io/ioutil" "os" - "runtime" "testing" - "github.com/google/go-cmp/cmp" - "github.com/jimmidyson/go-download" "k8s.io/minikube/pkg/minikube/assets" "k8s.io/minikube/pkg/minikube/bootstrapper" "k8s.io/minikube/pkg/minikube/command" @@ -126,149 +122,3 @@ func TestCacheBinariesForBootstrapper(t *testing.T) { }) } } -func TestCacheBinary(t *testing.T) { - oldMinikubeHome := os.Getenv("MINIKUBE_HOME") - defer os.Setenv("MINIKUBE_HOME", oldMinikubeHome) - - minikubeHome, err := ioutil.TempDir("/tmp", "") - if err != nil { - t.Fatalf("error during creating tmp dir: %v", err) - } - defer os.RemoveAll(minikubeHome) - noWritePermDir, err := ioutil.TempDir("/tmp", "") - if err != nil { - t.Fatalf("error during creating tmp dir: %v", err) - } - defer os.RemoveAll(noWritePermDir) - err = os.Chmod(noWritePermDir, 0000) - if err != nil { - t.Fatalf("error (%v) during changing permissions of dir %v", err, noWritePermDir) - } - - var tc = []struct { - desc, version, osName, archName string - minikubeHome, binary, description string - err bool - }{ - { - desc: "ok kubeadm", - version: "v1.16.0", - osName: "linux", - archName: runtime.GOARCH, - binary: "kubeadm", - err: false, - minikubeHome: minikubeHome, - }, - { - desc: "minikube home in dir without perms and arm runtime", - version: "v1.16.0", - osName: runtime.GOOS, - archName: "arm", - binary: "kubectl", - err: true, - minikubeHome: noWritePermDir, - }, - { - desc: "minikube home in dir without perms", - version: "v1.16.0", - osName: runtime.GOOS, - archName: runtime.GOARCH, - binary: "kubectl", - err: true, - minikubeHome: noWritePermDir, - }, - { - desc: "binary foo", - version: "v1.16.0", - osName: runtime.GOOS, - archName: runtime.GOARCH, - binary: "foo", - err: true, - minikubeHome: minikubeHome, - }, - { - desc: "version 9000", - version: "v9000", - osName: runtime.GOOS, - archName: runtime.GOARCH, - binary: "foo", - err: true, - minikubeHome: minikubeHome, - }, - { - desc: "bad os", - version: "v1.16.0", - osName: "no-such-os", - archName: runtime.GOARCH, - binary: "kubectl", - err: true, - minikubeHome: minikubeHome, - }, - } - for _, test := range tc { - t.Run(test.desc, func(t *testing.T) { - os.Setenv("MINIKUBE_HOME", test.minikubeHome) - _, err := CacheBinary(test.binary, test.version, test.osName, test.archName) - if err != nil && !test.err { - t.Fatalf("Got unexpected error %v", err) - } - if err == nil && test.err { - t.Fatalf("Expected error but got %v", err) - } - }) - } -} - -func TestDownloadOptions(t *testing.T) { - var tc = []struct { - url string - version string - want download.FileOptions - }{ - { - url: "https://s/kubernetes-release/release/v1.16.0/bin/amd64/kubectl", - version: "v1.16.0", - want: download.FileOptions{ - Options: download.Options{ - Checksum: "https://s/kubernetes-release/release/v1.16.0/bin/amd64/kubectl.sha1", - ChecksumHash: crypto.SHA1, - }, - Mkdirs: download.MkdirAll, - }, - }, - { - url: "https://s/kubernetes-release/release/v1.10.0/bin/hp9k/kubeadm", - version: "v1.10.0", - want: download.FileOptions{ - Options: download.Options{ - Checksum: "https://s/kubernetes-release/release/v1.10.0/bin/hp9k/kubeadm.sha1", - ChecksumHash: crypto.SHA1, - }, - Mkdirs: download.MkdirAll, - }, - }, - { - url: "https://s/kubernetes-release/release/v1.18.0/bin/arm64/kubelet", - version: "v1.18.0", - want: download.FileOptions{ - Options: download.Options{ - Checksum: "https://s/kubernetes-release/release/v1.18.0/bin/arm64/kubelet.sha256", - ChecksumHash: crypto.SHA256, - }, - Mkdirs: download.MkdirAll, - }, - }, - } - for _, test := range tc { - t.Run(test.version, func(t *testing.T) { - got, err := downloadOptions(test.url, test.version) - if err != nil { - t.Fatalf("unexpected error %v", err) - } - - if diff := cmp.Diff(test.want, got); diff != "" { - t.Errorf("unexpected options(-want +got):\n%s", diff) - } - }) - } -} diff --git a/pkg/minikube/machine/cluster_test.go b/pkg/minikube/machine/cluster_test.go index bf38656062..84c23ae889 100644 --- a/pkg/minikube/machine/cluster_test.go +++ b/pkg/minikube/machine/cluster_test.go @@ -30,7 +30,6 @@ import ( "github.com/docker/machine/libmachine/state" "github.com/spf13/viper" "k8s.io/minikube/pkg/minikube/config" - "k8s.io/minikube/pkg/minikube/constants" "k8s.io/minikube/pkg/minikube/driver" "k8s.io/minikube/pkg/minikube/registry" "k8s.io/minikube/pkg/minikube/tests" @@ -61,10 +60,8 @@ func RegisterMockDriver(t *testing.T) { } var defaultMachineConfig = config.MachineConfig{ - Driver: driver.Mock, - MinikubeISO: constants.DefaultISOURL, - Downloader: MockDownloader{}, - DockerEnv: []string{"MOCK_MAKE_IT_PROVISION=true"}, + Driver: driver.Mock, + DockerEnv: []string{"MOCK_MAKE_IT_PROVISION=true"}, } func TestCreateHost(t *testing.T) { @@ -262,10 +259,9 @@ func TestStartHostConfig(t *testing.T) { provision.SetDetector(md) config := config.MachineConfig{ - Driver: driver.Mock, - DockerEnv: []string{"FOO=BAR"}, - DockerOpt: []string{"param=value"}, - Downloader: MockDownloader{}, + Driver: driver.Mock, + DockerEnv: []string{"FOO=BAR"}, + DockerOpt: []string{"param=value"}, } h, err := StartHost(api, config) diff --git a/pkg/minikube/node/cache.go b/pkg/minikube/node/cache.go index b1d5ad8d12..e030b9942e 100644 --- a/pkg/minikube/node/cache.go +++ b/pkg/minikube/node/cache.go @@ -26,6 +26,7 @@ import ( cmdcfg "k8s.io/minikube/cmd/minikube/cmd/config" "k8s.io/minikube/pkg/minikube/config" "k8s.io/minikube/pkg/minikube/constants" + "k8s.io/minikube/pkg/minikube/download" "k8s.io/minikube/pkg/minikube/exit" "k8s.io/minikube/pkg/minikube/image" "k8s.io/minikube/pkg/minikube/localpath" @@ -71,7 +72,7 @@ func CacheKubectlBinary(k8sVerison string) (string, error) { binary = "kubectl.exe" } - return machine.CacheBinary(binary, k8sVerison, runtime.GOOS, runtime.GOARCH) + return download.Binary(binary, k8sVerison, runtime.GOOS, runtime.GOARCH) } // doCacheBinaries caches Kubernetes binaries in the foreground diff --git a/pkg/minikube/registry/drvs/hyperkit/hyperkit.go b/pkg/minikube/registry/drvs/hyperkit/hyperkit.go index 50a4e5a408..edde1da359 100644 --- a/pkg/minikube/registry/drvs/hyperkit/hyperkit.go +++ b/pkg/minikube/registry/drvs/hyperkit/hyperkit.go @@ -32,6 +32,7 @@ import ( "k8s.io/minikube/pkg/drivers/hyperkit" cfg "k8s.io/minikube/pkg/minikube/config" + "k8s.io/minikube/pkg/minikube/download" "k8s.io/minikube/pkg/minikube/driver" "k8s.io/minikube/pkg/minikube/localpath" "k8s.io/minikube/pkg/minikube/registry" @@ -69,7 +70,7 @@ func configure(config cfg.MachineConfig) (interface{}, error) { StorePath: localpath.MiniPath(), SSHUser: "docker", }, - Boot2DockerURL: config.Downloader.GetISOFileURI(config.MinikubeISO), + Boot2DockerURL: download.LocalISOResource(config.MinikubeISO), DiskSize: config.DiskSize, Memory: config.Memory, CPU: config.CPUs, diff --git a/pkg/minikube/registry/drvs/hyperv/hyperv.go b/pkg/minikube/registry/drvs/hyperv/hyperv.go index 9f15d0c470..db2f3c0144 100644 --- a/pkg/minikube/registry/drvs/hyperv/hyperv.go +++ b/pkg/minikube/registry/drvs/hyperv/hyperv.go @@ -54,7 +54,7 @@ func init() { func configure(config cfg.MachineConfig) (interface{}, error) { d := hyperv.NewDriver(config.Name, localpath.MiniPath()) - d.Boot2DockerURL = config.Downloader.GetISOFileURI(config.MinikubeISO) + d.Boot2DockerURL = download.LocalISOResource(config.MinikubeISO) d.VSwitch = config.HypervVirtualSwitch if d.VSwitch == "" && config.HypervUseExternalSwitch { switchName, adapter, err := chooseSwitch(config.HypervExternalAdapter) diff --git a/pkg/minikube/registry/drvs/kvm2/kvm2.go b/pkg/minikube/registry/drvs/kvm2/kvm2.go index dedad73bfb..0ae7d89754 100644 --- a/pkg/minikube/registry/drvs/kvm2/kvm2.go +++ b/pkg/minikube/registry/drvs/kvm2/kvm2.go @@ -30,6 +30,7 @@ import ( "github.com/docker/machine/libmachine/drivers" "k8s.io/minikube/pkg/minikube/config" + "k8s.io/minikube/pkg/minikube/download" "k8s.io/minikube/pkg/minikube/driver" "k8s.io/minikube/pkg/minikube/localpath" "k8s.io/minikube/pkg/minikube/registry" @@ -79,7 +80,7 @@ func configure(mc config.MachineConfig) (interface{}, error) { CPU: mc.CPUs, Network: mc.KVMNetwork, PrivateNetwork: "minikube-net", - Boot2DockerURL: mc.Downloader.GetISOFileURI(mc.MinikubeISO), + Boot2DockerURL: download.LocalISOResource(mc.MinikubeISO), DiskSize: mc.DiskSize, DiskPath: filepath.Join(localpath.MiniPath(), "machines", name, fmt.Sprintf("%s.rawdisk", name)), ISO: filepath.Join(localpath.MiniPath(), "machines", name, "boot2docker.iso"), diff --git a/pkg/minikube/registry/drvs/parallels/parallels.go b/pkg/minikube/registry/drvs/parallels/parallels.go index de319ec8fb..d5a6ef7169 100644 --- a/pkg/minikube/registry/drvs/parallels/parallels.go +++ b/pkg/minikube/registry/drvs/parallels/parallels.go @@ -25,6 +25,7 @@ import ( parallels "github.com/Parallels/docker-machine-parallels" "github.com/docker/machine/libmachine/drivers" cfg "k8s.io/minikube/pkg/minikube/config" + "k8s.io/minikube/pkg/minikube/download" "k8s.io/minikube/pkg/minikube/driver" "k8s.io/minikube/pkg/minikube/localpath" "k8s.io/minikube/pkg/minikube/registry" @@ -46,7 +47,7 @@ func init() { func configure(config cfg.MachineConfig) (interface{}, error) { d := parallels.NewDriver(config.Name, localpath.MiniPath()).(*parallels.Driver) - d.Boot2DockerURL = config.Downloader.GetISOFileURI(config.MinikubeISO) + d.Boot2DockerURL = download.LocalISOResource(config.MinikubeISO) d.Memory = config.Memory d.CPU = config.CPUs d.DiskSize = config.DiskSize diff --git a/pkg/minikube/registry/drvs/virtualbox/virtualbox.go b/pkg/minikube/registry/drvs/virtualbox/virtualbox.go index bfba0e42db..9fb264b8f6 100644 --- a/pkg/minikube/registry/drvs/virtualbox/virtualbox.go +++ b/pkg/minikube/registry/drvs/virtualbox/virtualbox.go @@ -27,6 +27,7 @@ import ( "github.com/docker/machine/libmachine/drivers" "k8s.io/minikube/pkg/minikube/config" + "k8s.io/minikube/pkg/minikube/download" "k8s.io/minikube/pkg/minikube/driver" "k8s.io/minikube/pkg/minikube/localpath" "k8s.io/minikube/pkg/minikube/registry" @@ -51,7 +52,7 @@ func init() { func configure(mc config.MachineConfig) (interface{}, error) { d := virtualbox.NewDriver(mc.Name, localpath.MiniPath()) - d.Boot2DockerURL = mc.Downloader.GetISOFileURI(mc.MinikubeISO) + d.Boot2DockerURL = download.LocalISOResource(mc.MinikubeISO) d.Memory = mc.Memory d.CPU = mc.CPUs d.DiskSize = mc.DiskSize diff --git a/pkg/minikube/registry/drvs/vmware/vmware.go b/pkg/minikube/registry/drvs/vmware/vmware.go index 885063cde2..f432916211 100644 --- a/pkg/minikube/registry/drvs/vmware/vmware.go +++ b/pkg/minikube/registry/drvs/vmware/vmware.go @@ -22,6 +22,7 @@ import ( vmwcfg "github.com/machine-drivers/docker-machine-driver-vmware/pkg/drivers/vmware/config" "k8s.io/minikube/pkg/minikube/config" + "k8s.io/minikube/pkg/minikube/download" "k8s.io/minikube/pkg/minikube/driver" "k8s.io/minikube/pkg/minikube/localpath" "k8s.io/minikube/pkg/minikube/registry" @@ -41,7 +42,7 @@ func init() { func configure(mc config.MachineConfig) (interface{}, error) { d := vmwcfg.NewConfig(mc.Name, localpath.MiniPath()) - d.Boot2DockerURL = mc.Downloader.GetISOFileURI(mc.MinikubeISO) + d.Boot2DockerURL = download.LocalISOResource(mc.MinikubeISO) d.Memory = mc.Memory d.CPU = mc.CPUs d.DiskSize = mc.DiskSize diff --git a/pkg/minikube/registry/drvs/vmwarefusion/vmwarefusion.go b/pkg/minikube/registry/drvs/vmwarefusion/vmwarefusion.go index bb5ed4196b..5c371d0dad 100644 --- a/pkg/minikube/registry/drvs/vmwarefusion/vmwarefusion.go +++ b/pkg/minikube/registry/drvs/vmwarefusion/vmwarefusion.go @@ -27,6 +27,7 @@ import ( "github.com/pkg/errors" cfg "k8s.io/minikube/pkg/minikube/config" + "k8s.io/minikube/pkg/minikube/download" "k8s.io/minikube/pkg/minikube/driver" "k8s.io/minikube/pkg/minikube/localpath" "k8s.io/minikube/pkg/minikube/registry" @@ -46,7 +47,7 @@ func init() { func configure(config cfg.MachineConfig) (interface{}, error) { d := vmwarefusion.NewDriver(config.Name, localpath.MiniPath()).(*vmwarefusion.Driver) - d.Boot2DockerURL = config.Downloader.GetISOFileURI(config.MinikubeISO) + d.Boot2DockerURL = download.LocalISOResource(config.MinikubeISO) d.Memory = config.Memory d.CPU = config.CPUs d.DiskSize = config.DiskSize diff --git a/pkg/util/downloader.go b/pkg/util/downloader.go deleted file mode 100644 index 72b4782565..0000000000 --- a/pkg/util/downloader.go +++ /dev/null @@ -1,131 +0,0 @@ -/* -Copyright 2016 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 util - -import ( - "net/url" - "os" - "path/filepath" - "time" - - "github.com/golang/glog" - "github.com/hashicorp/go-getter" - "github.com/juju/mutex" - "github.com/pkg/errors" - "k8s.io/minikube/pkg/minikube/constants" - "k8s.io/minikube/pkg/minikube/localpath" - "k8s.io/minikube/pkg/minikube/out" - "k8s.io/minikube/pkg/util/lock" -) - -const fileScheme = "file" - -// ISODownloader downloads an ISO -type ISODownloader interface { - GetISOFileURI(isoURL string) string - CacheMinikubeISOFromURL(isoURL string) error -} - -// DefaultDownloader is the default ISODownloader -type DefaultDownloader struct{} - -// GetISOFileURI gets the local destination for a remote source -func (f DefaultDownloader) GetISOFileURI(isoURL string) string { - urlObj, err := url.Parse(isoURL) - if err != nil { - return isoURL - } - if urlObj.Scheme == fileScheme { - return isoURL - } - isoPath := filepath.Join(localpath.MiniPath(), "cache", "iso", filepath.Base(isoURL)) - // As this is a file URL there should be no backslashes regardless of platform running on. - return "file://" + filepath.ToSlash(isoPath) -} - -// CacheMinikubeISOFromURL downloads the ISO, if it doesn't exist in cache -func (f DefaultDownloader) CacheMinikubeISOFromURL(url string) error { - dst := f.GetISOCacheFilepath(url) - - // Lock before we check for existence to avoid thundering herd issues - spec := lock.PathMutexSpec(dst) - spec.Timeout = 10 * time.Minute - glog.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() - - if !f.ShouldCacheMinikubeISO(url) { - glog.Infof("Not caching ISO, using %s", url) - return nil - } - - urlWithChecksum := url - if url == constants.DefaultISOURL { - urlWithChecksum = url + "?checksum=file:" + constants.DefaultISOSHAURL - } - - // Predictable temp destination so that resume can function - tmpDst := dst + ".download" - - opts := []getter.ClientOption{getter.WithProgress(DefaultProgressBar)} - client := &getter.Client{ - Src: urlWithChecksum, - Dst: tmpDst, - Mode: getter.ClientModeFile, - Options: opts, - } - - glog.Infof("full url: %s", urlWithChecksum) - out.T(out.ISODownload, "Downloading VM boot image ...") - if err := client.Get(); err != nil { - return errors.Wrap(err, url) - } - return os.Rename(tmpDst, dst) -} - -// ShouldCacheMinikubeISO returns if we need to download the ISO -func (f DefaultDownloader) ShouldCacheMinikubeISO(isoURL string) bool { - // store the minikube-iso inside the .minikube dir - - urlObj, err := url.Parse(isoURL) - if err != nil { - return false - } - if urlObj.Scheme == fileScheme { - return false - } - if f.IsMinikubeISOCached(isoURL) { - return false - } - return true -} - -// GetISOCacheFilepath returns the path of an ISO in the local cache -func (f DefaultDownloader) GetISOCacheFilepath(isoURL string) string { - return filepath.Join(localpath.MiniPath(), "cache", "iso", filepath.Base(isoURL)) -} - -// IsMinikubeISOCached returns if an ISO exists in the local cache -func (f DefaultDownloader) IsMinikubeISOCached(isoURL string) bool { - if _, err := os.Stat(f.GetISOCacheFilepath(isoURL)); os.IsNotExist(err) { - return false - } - return true -} diff --git a/pkg/util/downloader_test.go b/pkg/util/downloader_test.go deleted file mode 100644 index 3db8593296..0000000000 --- a/pkg/util/downloader_test.go +++ /dev/null @@ -1,117 +0,0 @@ -/* -Copyright 2016 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 util - -import ( - "bytes" - "io" - "io/ioutil" - "net/http" - "net/http/httptest" - "os" - "path/filepath" - "testing" - - "k8s.io/minikube/pkg/minikube/localpath" - "k8s.io/minikube/pkg/minikube/tests" -) - -func TestGetISOFileURI(t *testing.T) { - dler := DefaultDownloader{} - - tests := map[string]string{ - "file:///test/path/minikube-test.iso": "file:///test/path/minikube-test.iso", - "https://storage.googleapis.com/minikube/iso/minikube-test.iso": "file://" + filepath.ToSlash(filepath.Join(localpath.MiniPath(), "cache", "iso", "minikube-test.iso")), - } - - for input, expected := range tests { - if isoFileURI := dler.GetISOFileURI(input); isoFileURI != expected { - t.Fatalf("Expected GetISOFileURI with input %s to return %s but instead got: %s", input, expected, isoFileURI) - } - } - -} - -var testISOString = "hello" - -func TestCacheMinikubeISOFromURL(t *testing.T) { - tempDir := tests.MakeTempDir() - defer os.RemoveAll(tempDir) - dler := DefaultDownloader{} - isoPath := filepath.Join(localpath.MiniPath(), "cache", "iso", "minikube-test.iso") - - server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if _, err := io.WriteString(w, testISOString); err != nil { - t.Fatalf("WriteString: %v", err) - } - })) - isoURL := server.URL + "/minikube-test.iso" - if err := dler.CacheMinikubeISOFromURL(isoURL); err != nil { - t.Fatalf("Unexpected error from CacheMinikubeISOFromURL: %v", err) - } - - transferred, err := ioutil.ReadFile(filepath.Join(isoPath)) - if err != nil { - t.Fatalf("File not copied. Could not open file at path: %s", isoPath) - } - - // test that the ISO is transferred properly - contents := []byte(testISOString) - if !bytes.Contains(transferred, contents) { - t.Fatalf("Expected transfers to contain: %s. It was: %s", contents, transferred) - } - -} - -func TestShouldCacheMinikubeISO(t *testing.T) { - dler := DefaultDownloader{} - - tests := map[string]bool{ - "file:///test/path/minikube-test.iso": false, - "https://storage.googleapis.com/minikube/iso/minikube-test.iso": true, - } - - for input, expected := range tests { - if out := dler.ShouldCacheMinikubeISO(input); out != expected { - t.Fatalf("Expected ShouldCacheMinikubeISO with input %s to return %t but instead got: %t", input, expected, out) - } - } -} - -func TestIsMinikubeISOCached(t *testing.T) { - tempDir := tests.MakeTempDir() - defer os.RemoveAll(tempDir) - - dler := DefaultDownloader{} - - testFileURI := "file:///test/path/minikube-test.iso" - expected := false - - if out := dler.IsMinikubeISOCached(testFileURI); out != expected { - t.Fatalf("Expected IsMinikubeISOCached with input %s to return %t but instead got: %t", testFileURI, expected, out) - } - - if err := ioutil.WriteFile(filepath.Join(localpath.MiniPath(), "cache", "iso", "minikube-test.iso"), []byte(testISOString), os.FileMode(int(0644))); err != nil { - t.Fatalf("WriteFile: %v", err) - } - - expected = true - if out := dler.IsMinikubeISOCached(testFileURI); out != expected { - t.Fatalf("Expected IsMinikubeISOCached with input %s to return %t but instead got: %t", testFileURI, expected, out) - } - -} diff --git a/pkg/util/progressbar.go b/pkg/util/progressbar.go deleted file mode 100644 index fb16f6773c..0000000000 --- a/pkg/util/progressbar.go +++ /dev/null @@ -1,74 +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. -*/ - -// 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 ( - "io" - "path/filepath" - "sync" - - "github.com/cheggaaa/pb/v3" - "github.com/hashicorp/go-getter" -) - -// DefaultProgressBar is the default cheggaaa progress bar -var DefaultProgressBar getter.ProgressTracker = &progressBar{} - -type progressBar struct { - lock sync.Mutex - progress *pb.ProgressBar -} - -// TrackProgress instantiates a new progress bar that will -// display the progress of stream until closed. -// total can be 0. -func (cpb *progressBar) TrackProgress(src string, currentSize, totalSize int64, stream io.ReadCloser) io.ReadCloser { - cpb.lock.Lock() - defer cpb.lock.Unlock() - if cpb.progress == nil { - cpb.progress = pb.New64(totalSize) - } - p := pb.Full.Start64(totalSize) - p.Set("prefix", " > "+filepath.Base(src+": ")) - p.SetCurrent(currentSize) - p.Set(pb.Bytes, true) - - // Just a hair less than 80 (standard terminal width) for aesthetics & pasting into docs - p.SetWidth(79) - barReader := p.NewProxyReader(stream) - - return &readCloser{ - Reader: barReader, - close: func() error { - cpb.lock.Lock() - defer cpb.lock.Unlock() - p.Finish() - return nil - }, - } -} - -type readCloser struct { - io.Reader - close func() error -} - -func (c *readCloser) Close() error { return c.close() } diff --git a/pkg/version/version.go b/pkg/version/version.go index 727035115b..6587f3f722 100644 --- a/pkg/version/version.go +++ b/pkg/version/version.go @@ -53,10 +53,6 @@ func GetISOVersion() string { return isoVersion } -// GetISOPath returns the remote path to the minikube.iso -func GetISOPath() string { - return isoPath -} // GetSemverVersion returns the current minikube semantic version (semver) func GetSemverVersion() (semver.Version, error) { diff --git a/site/content/en/docs/Contributing/drivers.en.md b/site/content/en/docs/Contributing/drivers.en.md index aecd0e1179..3641e6b766 100644 --- a/site/content/en/docs/Contributing/drivers.en.md +++ b/site/content/en/docs/Contributing/drivers.en.md @@ -87,7 +87,7 @@ func init() { func createVMwareFusionHost(config cfg.MachineConfig) interface{} { d := vmwarefusion.NewDriver(config.Name, localpath.MiniPath()).(*vmwarefusion.Driver) - d.Boot2DockerURL = config.Downloader.GetISOFileURI(config.MinikubeISO) + d.Boot2DockerURL = download.LocalISOResource(config.MinikubeISO) d.Memory = config.Memory d.CPU = config.CPUs d.DiskSize = config.DiskSize