Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions cmd/minikube/cmd/start_flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ const (
ha = "ha"
nodes = "nodes"
preload = "preload"
preloadURL = "preload-url"
deleteOnFailure = "delete-on-failure"
forceSystemd = "force-systemd"
kicBaseImage = "base-image"
Expand Down Expand Up @@ -196,6 +197,13 @@ func initMinikubeFlags() {
startCmd.Flags().Bool(ha, false, "Create Highly Available Multi-Control Plane Cluster with a minimum of three control-plane nodes that will also be marked for work.")
startCmd.Flags().IntP(nodes, "n", 1, "The total 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.")
startCmd.Flags().String(preloadURL, "", "override preload download URL (testing only)")
if err := viper.BindPFlag("preload-url", startCmd.Flags().Lookup(preloadURL)); err != nil {
klog.Fatalf("Failed to bind flag: %v", err)
}
if err := startCmd.Flags().MarkHidden("preload-url"); err != nil {
klog.Warningf("Failed to hide %s flag: %v\n", "preload-url", err)
}
startCmd.Flags().Bool(noKubernetes, false, "If set, minikube VM/container will start without starting or configuring Kubernetes. (only works on new clusters)")
startCmd.Flags().Bool(deleteOnFailure, false, "If set, delete the current cluster if start fails and try again. Defaults to false.")
startCmd.Flags().Bool(forceSystemd, false, "If set, force the container runtime to use systemd as cgroup manager. Defaults to false.")
Expand Down
13 changes: 13 additions & 0 deletions pkg/minikube/download/preload.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,11 @@ func remoteTarballURLGitHub(k8sVersion, containerRuntime string) string {
}

func remoteTarballURL(k8sVersion, containerRuntime string, source preloadSource) string {
overrideURL := viper.GetString("preload-url")
if overrideURL != "" {
klog.V(2).Infof("Using override preload URL: %s", overrideURL)
return overrideURL
}
switch source {
case preloadSourceGitHub:
return remoteTarballURLGitHub(k8sVersion, containerRuntime)
Expand Down Expand Up @@ -246,7 +251,15 @@ func Preload(k8sVersion, containerRuntime, driverName string) error {
if ok && state.source != preloadSourceNone {
source = state.source
}

url := remoteTarballURL(k8sVersion, containerRuntime, source)
// override URL if flag is set
customURL := viper.GetString("preload-url")
if customURL != "" {
klog.Infof("Using custom preload tarball URL: %s", customURL)
url = customURL
}

var checksum []byte
var chksErr error
checksum, chksErr = getChecksum(source, k8sVersion, containerRuntime)
Expand Down
74 changes: 74 additions & 0 deletions test/integration/aaa_download_only_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ import (
"strings"
"testing"

"github.com/spf13/viper"
"k8s.io/klog/v2"
"k8s.io/minikube/pkg/minikube/bootstrapper/images"
"k8s.io/minikube/pkg/minikube/constants"
"k8s.io/minikube/pkg/minikube/download"
Expand Down Expand Up @@ -145,6 +147,78 @@ func TestDownloadOnly(t *testing.T) { // nolint:gocyclo
}
})

t.Run("preload-failed", func(t *testing.T) {
args := []string{"start", "-p", profile, "--download-only", "--alsologtostderr"}
rr, err := Run(t, exec.CommandContext(ctx, Target(), args...))
if err != nil {
t.Logf("start with invalid preload-url failed as expected %q : %v", rr.Command(), err)
} else {
t.Errorf("start with invalid preload-url expected to fail, but succeeded: %q", rr.Command())
}
viper.Set("preload-url", "http://invalid-url/preload.tar.gz")
klog.Infof("preload-url: %s", viper.GetString("preload-url"))

// checking binaries downloaded (kubelet,kubeadm)
for _, bin := range constants.KubernetesReleaseBinaries {
fp := filepath.Join(localpath.MiniPath(), "cache", "linux", runtime.GOARCH, v, bin)
_, err := os.Stat(fp)
if err != nil {
t.Errorf("expected the file for binary exist at %q but got error %v", fp, err)
}
}

imgs, err := images.Kubeadm("", v)
if err != nil {
t.Errorf("failed to get kubeadm images for %v: %+v", v, err)
}

for _, img := range imgs {
pathToImage := []string{localpath.MiniPath(), "cache", "images", runtime.GOARCH}
img = strings.Replace(img, ":", "_", 1) // for example kube-scheduler:v1.15.2 --> kube-scheduler_v1.15.2
imagePath := strings.Split(img, "/") // changes "gcr.io/k8s-minikube/storage-provisioner_v5" into ["gcr.io", "k8s-minikube", "storage-provisioner_v5"] to match cache folder structure
pathToImage = append(pathToImage, imagePath...)
fp := filepath.Join(pathToImage...)
_, err := os.Stat(fp)
if err != nil {
t.Errorf("expected image file exist at %q but got error: %v", fp, err)
}
}
})

t.Run("preload-false", func(t *testing.T) {
args := []string{"start", "-p", profile, "--alsologtostderr", "--preload=false"}
rr, err := Run(t, exec.CommandContext(ctx, Target(), args...))
if err != nil {
t.Errorf("start with preload=false failed %q : %v", rr.Command(), err)
}

// checking binaries downloaded (kubelet,kubeadm)
for _, bin := range constants.KubernetesReleaseBinaries {
fp := filepath.Join(localpath.MiniPath(), "cache", "linux", runtime.GOARCH, v, bin)
_, err := os.Stat(fp)
if err != nil {
t.Errorf("expected the file for binary exist at %q but got error %v", fp, err)
}
}

imgs, err := images.Kubeadm("", v)
if err != nil {
t.Errorf("failed to get kubeadm images for %v: %+v", v, err)
}

for _, img := range imgs {
pathToImage := []string{localpath.MiniPath(), "cache", "images", runtime.GOARCH}
img = strings.Replace(img, ":", "_", 1) // for example kube-scheduler:v1.15.2 --> kube-scheduler_v1.15.2
imagePath := strings.Split(img, "/") // changes "gcr.io/k8s-minikube/storage-provisioner_v5" into ["gcr.io", "k8s-minikube", "storage-provisioner_v5"] to match cache folder structure
pathToImage = append(pathToImage, imagePath...)
fp := filepath.Join(pathToImage...)
_, err := os.Stat(fp)
if err != nil {
t.Errorf("expected image file exist at %q but got error: %v", fp, err)
}
}
})

t.Run("binaries", func(t *testing.T) {
if preloadExists {
t.Skip("Preload exists, binaries are present within.")
Expand Down