Rebased, resolved merge conflicts
commit
9d75c7c35a
|
@ -123,6 +123,7 @@ const (
|
|||
hostOnlyNicType = "host-only-nic-type"
|
||||
natNicType = "nat-nic-type"
|
||||
nodes = "nodes"
|
||||
preload = "preload"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -175,11 +176,12 @@ func initMinikubeFlags() {
|
|||
startCmd.Flags().Bool(autoUpdate, true, "If set, automatically updates drivers to the latest version. Defaults to true.")
|
||||
startCmd.Flags().Bool(installAddons, true, "If set, install addons. Defaults to true.")
|
||||
startCmd.Flags().IntP(nodes, "n", 1, "The number of nodes to spin up. Defaults to 1.")
|
||||
startCmd.Flags().Bool(preload, true, "If set, download tarball of preloaded images if available to improve start time. Defaults to true.")
|
||||
}
|
||||
|
||||
// initKubernetesFlags inits the commandline flags for kubernetes related options
|
||||
func initKubernetesFlags() {
|
||||
startCmd.Flags().String(kubernetesVersion, "", "The kubernetes version that the minikube VM will use (ex: v1.2.3)")
|
||||
startCmd.Flags().String(kubernetesVersion, "", fmt.Sprintf("The kubernetes version that the minikube VM will use (ex: v1.2.3, 'stable' for %s, 'latest' for %s). Defaults to 'stable'.", constants.DefaultKubernetesVersion, constants.NewestKubernetesVersion))
|
||||
startCmd.Flags().Var(&config.ExtraOptions, "extra-config",
|
||||
`A set of key=value pairs that describe configuration that may be passed to different components.
|
||||
The key should be '.' separated, and the first part before the dot is the component to apply the configuration to.
|
||||
|
@ -480,10 +482,10 @@ func selectDriver(existing *config.ClusterConfig) registry.DriverState {
|
|||
if vmd := viper.GetString("vm-driver"); vmd != "" {
|
||||
// Output a warning
|
||||
warning := `Both driver={{.driver}} and vm-driver={{.vmd}} have been set.
|
||||
|
||||
|
||||
Since vm-driver is deprecated, minikube will default to driver={{.driver}}.
|
||||
|
||||
If vm-driver is set in the global config, please run "minikube config unset vm-driver" to resolve this warning.
|
||||
If vm-driver is set in the global config, please run "minikube config unset vm-driver" to resolve this warning.
|
||||
`
|
||||
out.T(out.Warning, warning, out.V{"driver": d, "vmd": vmd})
|
||||
}
|
||||
|
@ -1065,13 +1067,15 @@ func autoSetDriverOptions(cmd *cobra.Command, drvName string) (err error) {
|
|||
func getKubernetesVersion(old *config.ClusterConfig) string {
|
||||
paramVersion := viper.GetString(kubernetesVersion)
|
||||
|
||||
if paramVersion == "" { // if the user did not specify any version then ...
|
||||
if old != nil { // .. use the old version from config (if any)
|
||||
paramVersion = old.KubernetesConfig.KubernetesVersion
|
||||
}
|
||||
if paramVersion == "" { // .. otherwise use the default version
|
||||
paramVersion = constants.DefaultKubernetesVersion
|
||||
}
|
||||
// try to load the old version first if the user didn't specify anything
|
||||
if paramVersion == "" && old != nil {
|
||||
paramVersion = old.KubernetesConfig.KubernetesVersion
|
||||
}
|
||||
|
||||
if paramVersion == "" || strings.EqualFold(paramVersion, "stable") {
|
||||
paramVersion = constants.DefaultKubernetesVersion
|
||||
} else if strings.EqualFold(paramVersion, "latest") {
|
||||
paramVersion = constants.NewestKubernetesVersion
|
||||
}
|
||||
|
||||
nvs, err := semver.Make(strings.TrimPrefix(paramVersion, version.VersionPrefix))
|
||||
|
|
|
@ -26,7 +26,7 @@ import (
|
|||
"k8s.io/minikube/pkg/minikube/constants"
|
||||
)
|
||||
|
||||
func TestGetKuberneterVersion(t *testing.T) {
|
||||
func TestGetKubernetesVersion(t *testing.T) {
|
||||
var tests = []struct {
|
||||
description string
|
||||
expectedVersion string
|
||||
|
@ -55,6 +55,16 @@ func TestGetKuberneterVersion(t *testing.T) {
|
|||
paramVersion: "v1.16.0",
|
||||
cfg: &cfg.ClusterConfig{KubernetesConfig: cfg.KubernetesConfig{KubernetesVersion: "v1.15.0"}},
|
||||
},
|
||||
{
|
||||
description: "kubernetes-version given as 'stable', no config",
|
||||
expectedVersion: constants.DefaultKubernetesVersion,
|
||||
paramVersion: "stable",
|
||||
},
|
||||
{
|
||||
description: "kubernetes-version given as 'latest', no config",
|
||||
expectedVersion: constants.NewestKubernetesVersion,
|
||||
paramVersion: "latest",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
|
|
|
@ -121,7 +121,7 @@ func (d *Driver) Create() error {
|
|||
return errors.Wrap(err, "prepare kic ssh")
|
||||
}
|
||||
|
||||
// return now if no preload is available
|
||||
// If preload doesn't exist, don't bother extracting tarball to volume
|
||||
if !download.PreloadExists(d.NodeConfig.KubernetesVersion, d.NodeConfig.ContainerRuntime) {
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -524,17 +524,22 @@ func (k *Bootstrapper) UpdateCluster(cfg config.ClusterConfig) error {
|
|||
return errors.Wrap(err, "kubeadm images")
|
||||
}
|
||||
|
||||
if cfg.KubernetesConfig.ShouldLoadCachedImages {
|
||||
if err := machine.LoadImages(&cfg, k.c, images, constants.ImageCacheDir); err != nil {
|
||||
out.FailureT("Unable to load cached images: {{.error}}", out.V{"error": err})
|
||||
}
|
||||
}
|
||||
r, err := cruntime.New(cruntime.Config{Type: cfg.KubernetesConfig.ContainerRuntime,
|
||||
Runner: k.c, Socket: cfg.KubernetesConfig.CRISocket})
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "runtime")
|
||||
}
|
||||
|
||||
if err := r.Preload(cfg.KubernetesConfig); err != nil {
|
||||
return errors.Wrap(err, "preloading")
|
||||
}
|
||||
|
||||
if cfg.KubernetesConfig.ShouldLoadCachedImages {
|
||||
if err := machine.LoadImages(&cfg, k.c, images, constants.ImageCacheDir); err != nil {
|
||||
out.FailureT("Unable to load cached images: {{.error}}", out.V{"error": err})
|
||||
}
|
||||
}
|
||||
|
||||
for _, n := range cfg.Nodes {
|
||||
err := k.UpdateNode(cfg, n, r)
|
||||
if err != nil {
|
||||
|
|
|
@ -30,6 +30,7 @@ import (
|
|||
"github.com/pkg/errors"
|
||||
"k8s.io/minikube/pkg/minikube/bootstrapper/images"
|
||||
"k8s.io/minikube/pkg/minikube/config"
|
||||
"k8s.io/minikube/pkg/minikube/download"
|
||||
"k8s.io/minikube/pkg/minikube/out"
|
||||
)
|
||||
|
||||
|
@ -313,5 +314,8 @@ func (r *Containerd) SystemLogCmd(len int) string {
|
|||
|
||||
// Preload preloads the container runtime with k8s images
|
||||
func (r *Containerd) Preload(cfg config.KubernetesConfig) error {
|
||||
if !download.PreloadExists(cfg.KubernetesVersion, cfg.ContainerRuntime) {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("not yet implemented for %s", r.Name())
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ import (
|
|||
"github.com/pkg/errors"
|
||||
"k8s.io/minikube/pkg/minikube/bootstrapper/images"
|
||||
"k8s.io/minikube/pkg/minikube/config"
|
||||
"k8s.io/minikube/pkg/minikube/download"
|
||||
"k8s.io/minikube/pkg/minikube/out"
|
||||
)
|
||||
|
||||
|
@ -230,5 +231,8 @@ func (r *CRIO) SystemLogCmd(len int) string {
|
|||
|
||||
// Preload preloads the container runtime with k8s images
|
||||
func (r *CRIO) Preload(cfg config.KubernetesConfig) error {
|
||||
if !download.PreloadExists(cfg.KubernetesVersion, cfg.ContainerRuntime) {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("not yet implemented for %s", r.Name())
|
||||
}
|
||||
|
|
|
@ -290,6 +290,9 @@ func (r *Docker) SystemLogCmd(len int) string {
|
|||
// 2. Extract the preloaded tarball to the correct directory
|
||||
// 3. Remove the tarball within the VM
|
||||
func (r *Docker) Preload(cfg config.KubernetesConfig) error {
|
||||
if !download.PreloadExists(cfg.KubernetesVersion, cfg.ContainerRuntime) {
|
||||
return nil
|
||||
}
|
||||
k8sVersion := cfg.KubernetesVersion
|
||||
cRuntime := cfg.ContainerRuntime
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ import (
|
|||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
|
||||
"cloud.google.com/go/storage"
|
||||
|
@ -32,6 +32,7 @@ import (
|
|||
"github.com/golang/glog"
|
||||
"github.com/hashicorp/go-getter"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/viper"
|
||||
"k8s.io/minikube/pkg/minikube/localpath"
|
||||
"k8s.io/minikube/pkg/minikube/out"
|
||||
)
|
||||
|
@ -60,14 +61,14 @@ func targetDir() string {
|
|||
return localpath.MakeMiniPath("cache", "preloaded-tarball")
|
||||
}
|
||||
|
||||
// PreloadChecksumPath returns path to checksum file
|
||||
// PreloadChecksumPath returns the local path to the cached checksum file
|
||||
func PreloadChecksumPath(k8sVersion, containerRuntime string) string {
|
||||
return path.Join(targetDir(), checksumName(k8sVersion, containerRuntime))
|
||||
return filepath.Join(targetDir(), checksumName(k8sVersion, containerRuntime))
|
||||
}
|
||||
|
||||
// TarballPath returns the path to the preloaded tarball
|
||||
// TarballPath returns the local path to the cached preload tarball
|
||||
func TarballPath(k8sVersion, containerRuntime string) string {
|
||||
return path.Join(targetDir(), TarballName(k8sVersion, containerRuntime))
|
||||
return filepath.Join(targetDir(), TarballName(k8sVersion, containerRuntime))
|
||||
}
|
||||
|
||||
// remoteTarballURL returns the URL for the remote tarball in GCS
|
||||
|
@ -77,6 +78,13 @@ func remoteTarballURL(k8sVersion, containerRuntime string) string {
|
|||
|
||||
// PreloadExists returns true if there is a preloaded tarball that can be used
|
||||
func PreloadExists(k8sVersion, containerRuntime string) bool {
|
||||
if !viper.GetBool("preload") {
|
||||
return false
|
||||
}
|
||||
|
||||
// See https://github.com/kubernetes/minikube/issues/6933
|
||||
// and https://github.com/kubernetes/minikube/issues/6934
|
||||
// to track status of adding containerd & crio
|
||||
if containerRuntime != "docker" {
|
||||
return false
|
||||
}
|
||||
|
@ -120,7 +128,7 @@ func Preload(k8sVersion, containerRuntime string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
out.T(out.FileDownload, "Downloading preloaded images tarball for k8s {{.version}} ...", out.V{"version": k8sVersion})
|
||||
out.T(out.FileDownload, "Downloading Kubernetes {{.version}} preload ...", out.V{"version": k8sVersion})
|
||||
url := remoteTarballURL(k8sVersion, containerRuntime)
|
||||
|
||||
tmpDst := targetPath + ".download"
|
||||
|
|
|
@ -100,6 +100,7 @@ func doCacheBinaries(k8sVersion string) error {
|
|||
|
||||
// BeginDownloadKicArtifacts downloads the kic image + preload tarball, returns true if preload is available
|
||||
func beginDownloadKicArtifacts(g *errgroup.Group) {
|
||||
out.T(out.Pulling, "Pulling base image ...")
|
||||
glog.Info("Beginning downloading kic artifacts")
|
||||
g.Go(func() error {
|
||||
glog.Infof("Downloading %s to local daemon", kic.BaseImage)
|
||||
|
|
|
@ -49,6 +49,7 @@ import (
|
|||
"k8s.io/minikube/pkg/minikube/localpath"
|
||||
"k8s.io/minikube/pkg/minikube/logs"
|
||||
"k8s.io/minikube/pkg/minikube/machine"
|
||||
"k8s.io/minikube/pkg/minikube/mustload"
|
||||
"k8s.io/minikube/pkg/minikube/out"
|
||||
"k8s.io/minikube/pkg/minikube/proxy"
|
||||
"k8s.io/minikube/pkg/util"
|
||||
|
@ -321,11 +322,34 @@ func startMachine(cfg *config.ClusterConfig, node *config.Node) (runner command.
|
|||
}
|
||||
|
||||
// startHost starts a new minikube host using a VM or None
|
||||
func startHost(api libmachine.API, mc config.ClusterConfig, n config.Node) (*host.Host, bool) {
|
||||
host, exists, err := machine.StartHost(api, mc, n)
|
||||
if err != nil {
|
||||
exit.WithError("Unable to start VM. Please investigate and run 'minikube delete' if possible", err)
|
||||
func startHost(api libmachine.API, cc config.ClusterConfig, n config.Node) (*host.Host, bool) {
|
||||
host, exists, err := machine.StartHost(api, cc, n)
|
||||
if err == nil {
|
||||
return host, exists
|
||||
}
|
||||
out.T(out.Embarrassed, "StartHost failed, but will try again: {{.error}}", out.V{"error": err})
|
||||
|
||||
// NOTE: People get very cranky if you delete their prexisting VM. Only delete new ones.
|
||||
if !exists {
|
||||
err := machine.DeleteHost(api, driver.MachineName(cc, n))
|
||||
if err != nil {
|
||||
glog.Warningf("delete host: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Try again, but just once to avoid making the logs overly confusing
|
||||
time.Sleep(5 * time.Second)
|
||||
|
||||
host, exists, err = machine.StartHost(api, cc, n)
|
||||
if err == nil {
|
||||
return host, exists
|
||||
}
|
||||
|
||||
out.T(out.FailureType, "StartHost failed again: {{.error}}", out.V{"error": err})
|
||||
out.T(out.Workaround, `Run: "{{.delete}}", then "{{.start}} --alsologtostderr -v=1" to try again with more logging`,
|
||||
out.V{"delete": mustload.ExampleCmd(cc.Name, "delete"), "start": mustload.ExampleCmd(cc.Name, "start")})
|
||||
|
||||
exit.WithError("Unable to start VM after repeated tries. Please try {{'minikube delete' if possible", err)
|
||||
return host, exists
|
||||
}
|
||||
|
||||
|
|
|
@ -68,6 +68,9 @@ func T(style StyleEnum, format string, a ...V) {
|
|||
|
||||
// String writes a basic formatted string to stdout
|
||||
func String(format string, a ...interface{}) {
|
||||
// Flush log buffer so that output order makes sense
|
||||
glog.Flush()
|
||||
|
||||
if outFile == nil {
|
||||
glog.Warningf("[unset outFile]: %s", fmt.Sprintf(format, a...))
|
||||
return
|
||||
|
|
|
@ -38,12 +38,13 @@ func CalculateSizeInMB(humanReadableSize string) (int, error) {
|
|||
if err == nil {
|
||||
humanReadableSize += "mb"
|
||||
}
|
||||
size, err := units.FromHumanSize(humanReadableSize)
|
||||
// parse the size suffix binary instead of decimal so that 1G -> 1024MB instead of 1000MB
|
||||
size, err := units.RAMInBytes(humanReadableSize)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("FromHumanSize: %v", err)
|
||||
}
|
||||
|
||||
return int(size / units.MB), nil
|
||||
return int(size / units.MiB), nil
|
||||
}
|
||||
|
||||
// GetBinaryDownloadURL returns a suitable URL for the platform
|
||||
|
|
|
@ -51,6 +51,7 @@ func TestCalculateSizeInMB(t *testing.T) {
|
|||
{"1024KB", 1},
|
||||
{"1024mb", 1024},
|
||||
{"1024b", 0},
|
||||
{"1g", 1024},
|
||||
}
|
||||
|
||||
for _, tt := range testData {
|
||||
|
@ -59,7 +60,7 @@ func TestCalculateSizeInMB(t *testing.T) {
|
|||
t.Fatalf("unexpected err: %v", err)
|
||||
}
|
||||
if number != tt.expectedNumber {
|
||||
t.Fatalf("Expected '%d'' but got '%d'", tt.expectedNumber, number)
|
||||
t.Fatalf("Expected '%d' but got '%d' from size '%s'", tt.expectedNumber, number, tt.size)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -175,7 +175,7 @@ func TestStartStopWithPreload(t *testing.T) {
|
|||
ctx, cancel := context.WithTimeout(context.Background(), Minutes(40))
|
||||
defer CleanupWithLogs(t, profile, cancel)
|
||||
|
||||
startArgs := []string{"start", "-p", profile, "--memory=2200", "--alsologtostderr", "-v=3", "--wait=true"}
|
||||
startArgs := []string{"start", "-p", profile, "--memory=2200", "--alsologtostderr", "-v=3", "--wait=true", "--preload=false"}
|
||||
startArgs = append(startArgs, StartArgs()...)
|
||||
k8sVersion := "v1.17.0"
|
||||
startArgs = append(startArgs, fmt.Sprintf("--kubernetes-version=%s", k8sVersion))
|
||||
|
@ -191,6 +191,7 @@ func TestStartStopWithPreload(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatalf("%s failed: %v", rr.Args, err)
|
||||
}
|
||||
|
||||
// Restart minikube with v1.17.3, which has a preloaded tarball
|
||||
startArgs = []string{"start", "-p", profile, "--memory=2200", "--alsologtostderr", "-v=3", "--wait=true"}
|
||||
startArgs = append(startArgs, StartArgs()...)
|
||||
|
@ -200,8 +201,6 @@ func TestStartStopWithPreload(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatalf("%s failed: %v", rr.Args, err)
|
||||
}
|
||||
|
||||
// Ensure that busybox still exists in the daemon
|
||||
rr, err = Run(t, exec.CommandContext(ctx, Target(), "ssh", "-p", profile, "--", "docker", "images"))
|
||||
if err != nil {
|
||||
t.Fatalf("%s failed: %v", rr.Args, err)
|
||||
|
|
Loading…
Reference in New Issue