From 73255f41b053caee361b46e7a8f00220f4ec4a57 Mon Sep 17 00:00:00 2001 From: Piotr Resztak Date: Wed, 27 Oct 2021 23:44:09 +0200 Subject: [PATCH] ability to set a mirror for downloading kubectl, kubelet, & kubeadm --- cmd/minikube/cmd/dashboard.go | 6 +++--- cmd/minikube/cmd/kubectl.go | 6 +++--- hack/preload-images/generate.go | 2 +- pkg/minikube/bootstrapper/bsutil/binaries.go | 4 ++-- pkg/minikube/bootstrapper/kubeadm/kubeadm.go | 2 +- pkg/minikube/download/binary.go | 17 +++++++++++++---- pkg/minikube/download/download_test.go | 2 +- pkg/minikube/machine/cache_binaries.go | 4 ++-- pkg/minikube/machine/cache_binaries_test.go | 4 ++-- pkg/minikube/node/cache.go | 14 ++++++++------ 10 files changed, 36 insertions(+), 25 deletions(-) diff --git a/cmd/minikube/cmd/dashboard.go b/cmd/minikube/cmd/dashboard.go index 141b3ab212e6..7b8d56298856 100644 --- a/cmd/minikube/cmd/dashboard.go +++ b/cmd/minikube/cmd/dashboard.go @@ -98,7 +98,7 @@ var dashboardCmd = &cobra.Command{ } out.ErrT(style.Launch, "Launching proxy ...") - p, hostPort, err := kubectlProxy(kubectlVersion, cname, dashboardExposedPort) + p, hostPort, err := kubectlProxy(kubectlVersion, co.Config.KubeBinariesMirror, cname, dashboardExposedPort) if err != nil { exit.Error(reason.HostKubectlProxy, "kubectl proxy", err) } @@ -132,7 +132,7 @@ var dashboardCmd = &cobra.Command{ } // kubectlProxy runs "kubectl proxy", returning host:port -func kubectlProxy(kubectlVersion string, contextName string, port int) (*exec.Cmd, string, error) { +func kubectlProxy(kubectlVersion string, binaryURL string, contextName string, port int) (*exec.Cmd, string, error) { // port=0 picks a random system port kubectlArgs := []string{"--context", contextName, "proxy", "--port", strconv.Itoa(port)} @@ -140,7 +140,7 @@ func kubectlProxy(kubectlVersion string, contextName string, port int) (*exec.Cm var cmd *exec.Cmd if kubectl, err := exec.LookPath("kubectl"); err == nil { cmd = exec.Command(kubectl, kubectlArgs...) - } else if cmd, err = KubectlCommand(kubectlVersion, kubectlArgs...); err != nil { + } else if cmd, err = KubectlCommand(kubectlVersion, binaryURL, kubectlArgs...); err != nil { return nil, "", err } diff --git a/cmd/minikube/cmd/kubectl.go b/cmd/minikube/cmd/kubectl.go index 35c776d0eba8..c74ef61f26ae 100644 --- a/cmd/minikube/cmd/kubectl.go +++ b/cmd/minikube/cmd/kubectl.go @@ -99,7 +99,7 @@ host. Please be aware that when using --ssh all paths will apply to the remote m args = append(cluster, args...) } - c, err := KubectlCommand(version, args...) + c, err := KubectlCommand(version, cc.KubeBinariesMirror, args...) if err != nil { out.ErrLn("Error caching kubectl: %v", err) os.Exit(1) @@ -134,12 +134,12 @@ func kubeconfigPath(cfg config.ClusterConfig) string { } // KubectlCommand will return kubectl command with a version matching the cluster -func KubectlCommand(version string, args ...string) (*exec.Cmd, error) { +func KubectlCommand(version, binaryURL string, args ...string) (*exec.Cmd, error) { if version == "" { version = constants.DefaultKubernetesVersion } - path, err := node.CacheKubectlBinary(version) + path, err := node.CacheKubectlBinary(version, binaryURL) if err != nil { return nil, err } diff --git a/hack/preload-images/generate.go b/hack/preload-images/generate.go index 25e98d2b7794..4eb70f32cbfe 100644 --- a/hack/preload-images/generate.go +++ b/hack/preload-images/generate.go @@ -122,7 +122,7 @@ func generateTarball(kubernetesVersion, containerRuntime, tarballFilename string sm := sysinit.New(runner) - if err := bsutil.TransferBinaries(kcfg, runner, sm); err != nil { + if err := bsutil.TransferBinaries(kcfg, runner, sm, ""); err != nil { return errors.Wrap(err, "transferring k8s binaries") } // Create image tarball diff --git a/pkg/minikube/bootstrapper/bsutil/binaries.go b/pkg/minikube/bootstrapper/bsutil/binaries.go index 278e00037ae1..52648af45759 100644 --- a/pkg/minikube/bootstrapper/bsutil/binaries.go +++ b/pkg/minikube/bootstrapper/bsutil/binaries.go @@ -38,7 +38,7 @@ import ( ) // TransferBinaries transfers all required Kubernetes binaries -func TransferBinaries(cfg config.KubernetesConfig, c command.Runner, sm sysinit.Manager) error { +func TransferBinaries(cfg config.KubernetesConfig, c command.Runner, sm sysinit.Manager, binariesURL string) error { ok, err := binariesExist(cfg, c) if err == nil && ok { klog.Info("Found k8s binaries, skipping transfer") @@ -56,7 +56,7 @@ func TransferBinaries(cfg config.KubernetesConfig, c command.Runner, sm sysinit. for _, name := range constants.KubernetesReleaseBinaries { name := name g.Go(func() error { - src, err := download.Binary(name, cfg.KubernetesVersion, "linux", runtime.GOARCH) + src, err := download.Binary(name, cfg.KubernetesVersion, "linux", runtime.GOARCH, binariesURL) if err != nil { return errors.Wrapf(err, "downloading %s", name) } diff --git a/pkg/minikube/bootstrapper/kubeadm/kubeadm.go b/pkg/minikube/bootstrapper/kubeadm/kubeadm.go index 1b38c0d15eae..cb76691a5531 100644 --- a/pkg/minikube/bootstrapper/kubeadm/kubeadm.go +++ b/pkg/minikube/bootstrapper/kubeadm/kubeadm.go @@ -910,7 +910,7 @@ func (k *Bootstrapper) UpdateNode(cfg config.ClusterConfig, n config.Node, r cru sm := sysinit.New(k.c) - if err := bsutil.TransferBinaries(cfg.KubernetesConfig, k.c, sm); err != nil { + if err := bsutil.TransferBinaries(cfg.KubernetesConfig, k.c, sm, cfg.KubeBinariesMirror); err != nil { return errors.Wrap(err, "downloading binaries") } diff --git a/pkg/minikube/download/binary.go b/pkg/minikube/download/binary.go index da7fd8603af0..62516027dd2d 100644 --- a/pkg/minikube/download/binary.go +++ b/pkg/minikube/download/binary.go @@ -30,9 +30,18 @@ import ( "k8s.io/minikube/pkg/minikube/localpath" ) +// DefaultKubeBinariesURL returns a URL to kube binaries +func DefaultKubeBinariesURL() string { + return fmt.Sprintf("https://%s/kubernetes-release/release", downloadHost) +} + // binaryWithChecksumURL gets the location of a Kubernetes binary -func binaryWithChecksumURL(binaryName, version, osName, archName string) (string, error) { - base := fmt.Sprintf("https://%s/kubernetes-release/release/%s/bin/%s/%s/%s", downloadHost, version, osName, archName, binaryName) +func binaryWithChecksumURL(binaryName, version, osName, archName, binaryURL string) (string, error) { + if binaryURL == "" { + binaryURL = DefaultKubeBinariesURL() + } + + base := fmt.Sprintf("%s/%s/bin/%s/%s/%s", binaryURL, version, osName, archName, binaryName) v, err := semver.Make(version[1:]) if err != nil { return "", err @@ -45,12 +54,12 @@ func binaryWithChecksumURL(binaryName, version, osName, archName string) (string } // Binary will download a binary onto the host -func Binary(binary, version, osName, archName string) (string, error) { +func Binary(binary, version, osName, archName, binaryURL string) (string, error) { targetDir := localpath.MakeMiniPath("cache", osName, version) targetFilepath := path.Join(targetDir, binary) targetLock := targetFilepath + ".lock" - url, err := binaryWithChecksumURL(binary, version, osName, archName) + url, err := binaryWithChecksumURL(binary, version, osName, archName, binaryURL) if err != nil { return "", err } diff --git a/pkg/minikube/download/download_test.go b/pkg/minikube/download/download_test.go index 03099dce7de1..e9b03a74f76f 100644 --- a/pkg/minikube/download/download_test.go +++ b/pkg/minikube/download/download_test.go @@ -61,7 +61,7 @@ func testBinaryDownloadPreventsMultipleDownload(t *testing.T) { var group sync.WaitGroup group.Add(2) dlCall := func() { - if _, err := Binary("kubectl", "v1.20.2", "linux", "amd64"); err != nil { + if _, err := Binary("kubectl", "v1.20.2", "linux", "amd64", ""); err != nil { t.Errorf("Failed to download binary: %+v", err) } group.Done() diff --git a/pkg/minikube/machine/cache_binaries.go b/pkg/minikube/machine/cache_binaries.go index 4356577e842c..acf3f544ccca 100644 --- a/pkg/minikube/machine/cache_binaries.go +++ b/pkg/minikube/machine/cache_binaries.go @@ -43,7 +43,7 @@ func isExcluded(binary string, excludedBinaries []string) bool { } // CacheBinariesForBootstrapper will cache binaries for a bootstrapper -func CacheBinariesForBootstrapper(version string, clusterBootstrapper string, excludeBinaries []string) error { +func CacheBinariesForBootstrapper(version string, clusterBootstrapper string, excludeBinaries []string, binariesURL string) error { binaries := bootstrapper.GetCachedBinaryList(clusterBootstrapper) var g errgroup.Group @@ -53,7 +53,7 @@ func CacheBinariesForBootstrapper(version string, clusterBootstrapper string, ex } bin := bin // https://golang.org/doc/faq#closures_and_goroutines g.Go(func() error { - if _, err := download.Binary(bin, version, "linux", detect.EffectiveArch()); err != nil { + if _, err := download.Binary(bin, version, "linux", detect.EffectiveArch(), binariesURL); err != nil { return errors.Wrapf(err, "caching binary %s", bin) } return nil diff --git a/pkg/minikube/machine/cache_binaries_test.go b/pkg/minikube/machine/cache_binaries_test.go index 8359fbf1fceb..a727a67cd8f1 100644 --- a/pkg/minikube/machine/cache_binaries_test.go +++ b/pkg/minikube/machine/cache_binaries_test.go @@ -121,7 +121,7 @@ func TestCacheBinariesForBootstrapper(t *testing.T) { for _, test := range tc { t.Run(test.version, func(t *testing.T) { os.Setenv("MINIKUBE_HOME", test.minikubeHome) - err := CacheBinariesForBootstrapper(test.version, test.clusterBootstrapper, nil) + err := CacheBinariesForBootstrapper(test.version, test.clusterBootstrapper, nil, "") if err != nil && !test.err { t.Fatalf("Got unexpected error %v", err) } @@ -160,7 +160,7 @@ func TestExcludedBinariesNotDownloaded(t *testing.T) { } }() - if err := CacheBinariesForBootstrapper("v1.16.0", clusterBootstrapper, []string{binaryToExclude}); err != nil { + if err := CacheBinariesForBootstrapper("v1.16.0", clusterBootstrapper, []string{binaryToExclude}, ""); err != nil { t.Errorf("Failed to cache binaries: %v", err) } } diff --git a/pkg/minikube/node/cache.go b/pkg/minikube/node/cache.go index 42a965412224..7b5e99fda2b4 100644 --- a/pkg/minikube/node/cache.go +++ b/pkg/minikube/node/cache.go @@ -78,10 +78,12 @@ func handleDownloadOnly(cacheGroup, kicGroup *errgroup.Group, k8sVersion, contai if !viper.GetBool("download-only") { return } - if err := doCacheBinaries(k8sVersion, containerRuntime, driverName); err != nil { + + binariesURL := viper.GetString("kube-binaries-mirror") + if err := doCacheBinaries(k8sVersion, containerRuntime, driverName, binariesURL); err != nil { exit.Error(reason.InetCacheBinaries, "Failed to cache binaries", err) } - if _, err := CacheKubectlBinary(k8sVersion); err != nil { + if _, err := CacheKubectlBinary(k8sVersion, binariesURL); err != nil { exit.Error(reason.InetCacheKubectl, "Failed to cache kubectl", err) } waitCacheRequiredImages(cacheGroup) @@ -94,22 +96,22 @@ func handleDownloadOnly(cacheGroup, kicGroup *errgroup.Group, k8sVersion, contai } // CacheKubectlBinary caches the kubectl binary -func CacheKubectlBinary(k8sVersion string) (string, error) { +func CacheKubectlBinary(k8sVersion, binaryURL string) (string, error) { binary := "kubectl" if runtime.GOOS == "windows" { binary = "kubectl.exe" } - return download.Binary(binary, k8sVersion, runtime.GOOS, detect.EffectiveArch()) + return download.Binary(binary, k8sVersion, runtime.GOOS, detect.EffectiveArch(), binaryURL) } // doCacheBinaries caches Kubernetes binaries in the foreground -func doCacheBinaries(k8sVersion, containerRuntime, driverName string) error { +func doCacheBinaries(k8sVersion, containerRuntime, driverName, binariesURL string) error { existingBinaries := constants.KubernetesReleaseBinaries if !download.PreloadExists(k8sVersion, containerRuntime, driverName) { existingBinaries = nil } - return machine.CacheBinariesForBootstrapper(k8sVersion, viper.GetString(cmdcfg.Bootstrapper), existingBinaries) + return machine.CacheBinariesForBootstrapper(k8sVersion, viper.GetString(cmdcfg.Bootstrapper), existingBinaries, binariesURL) } // beginDownloadKicBaseImage downloads the kic image