Add download package & support URL fallback

pull/6892/head
Thomas Stromberg 2020-03-04 17:07:49 -08:00
parent aa91f39ffb
commit 39670fc06f
24 changed files with 42 additions and 664 deletions

View File

@ -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: <number>[<unit>], 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),

3
go.mod
View File

@ -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

6
go.sum
View File

@ -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=

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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

View File

@ -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}

View File

@ -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

View File

@ -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 {

View File

@ -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)
}
})
}
}

View File

@ -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)

View File

@ -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

View File

@ -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,

View File

@ -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)

View File

@ -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"),

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
}

View File

@ -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)
}
}

View File

@ -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() }

View File

@ -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) {

View File

@ -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