diff --git a/pkg/minikube/bootstrapper/bsutil/binaries.go b/pkg/minikube/bootstrapper/bsutil/binaries.go index 0a462ca538b3..f43c4ee80a1a 100644 --- a/pkg/minikube/bootstrapper/bsutil/binaries.go +++ b/pkg/minikube/bootstrapper/bsutil/binaries.go @@ -25,6 +25,7 @@ import ( "strings" "github.com/pkg/errors" + "github.com/spf13/viper" "golang.org/x/sync/errgroup" "k8s.io/klog/v2" @@ -39,6 +40,12 @@ import ( // TransferBinaries transfers all required Kubernetes binaries func TransferBinaries(cfg config.KubernetesConfig, c command.Runner, sm sysinit.Manager, binariesURL string) error { + // Skip binary transfer in --no-kubernetes mode + if viper.GetBool("no-kubernetes") { + klog.Info("Skipping Kubernetes binary transfer due to --no-kubernetes flag") + return nil + } + ok, err := binariesExist(cfg, c) if err == nil && ok { klog.Info("Found k8s binaries, skipping transfer") diff --git a/pkg/minikube/download/binary.go b/pkg/minikube/download/binary.go index 6de9d9c42814..e67c0b0e60d8 100644 --- a/pkg/minikube/download/binary.go +++ b/pkg/minikube/download/binary.go @@ -24,6 +24,7 @@ import ( "github.com/blang/semver/v4" "github.com/pkg/errors" + "github.com/spf13/viper" "k8s.io/klog/v2" "k8s.io/minikube/pkg/minikube/localpath" ) @@ -53,6 +54,11 @@ func binaryWithChecksumURL(binaryName, version, osName, archName, binaryURL stri // Binary will download a binary onto the host func Binary(binary, version, osName, archName, binaryURL string) (string, error) { + // Prevent Kubernetes binary downloads in --no-kubernetes mode + if viper.GetBool("no-kubernetes") { + klog.Infof("Skipping Kubernetes binary download due to --no-kubernetes flag") + return "", nil + } targetDir := localpath.MakeMiniPath("cache", osName, archName, version) targetFilepath := path.Join(targetDir, binary) targetLock := targetFilepath + ".lock" diff --git a/pkg/minikube/download/preload.go b/pkg/minikube/download/preload.go index 3f8f7abdadd3..f32510b47dac 100644 --- a/pkg/minikube/download/preload.go +++ b/pkg/minikube/download/preload.go @@ -173,6 +173,11 @@ func PreloadExistsGH(k8sVersion, containerRuntime string) bool { // PreloadExists returns true if there is a preloaded tarball that can be used func PreloadExists(k8sVersion, containerRuntime, driverName string, forcePreload ...bool) bool { + // Prevent preload logic in --no-kubernetes mode + if viper.GetBool("no-kubernetes") { + klog.Infof("Skipping preload logic due to --no-kubernetes flag") + return false + } // TODO (#8166): Get rid of the need for this and viper at all force := false if len(forcePreload) > 0 { diff --git a/pkg/minikube/node/cache.go b/pkg/minikube/node/cache.go index 8fbf3e03ed3e..6b4d3f55cec1 100644 --- a/pkg/minikube/node/cache.go +++ b/pkg/minikube/node/cache.go @@ -54,6 +54,12 @@ const ( // BeginCacheKubernetesImages caches images required for Kubernetes version in the background func beginCacheKubernetesImages(g *errgroup.Group, imageRepository string, k8sVersion string, cRuntime string, driverName string) { + // Skip all caching operations in --no-kubernetes mode + if viper.GetBool("no-kubernetes") { + klog.Infof("Skipping Kubernetes image caching due to --no-kubernetes flag") + return + } + // TODO: remove imageRepository check once #7695 is fixed if imageRepository == "" && download.PreloadExists(k8sVersion, cRuntime, driverName) { klog.Info("Caching tarball of preloaded images") @@ -82,11 +88,15 @@ func handleDownloadOnly(cacheGroup, kicGroup *errgroup.Group, k8sVersion, contai } binariesURL := viper.GetString("binary-mirror") - if err := doCacheBinaries(k8sVersion, containerRuntime, driverName, binariesURL); err != nil { - exit.Error(reason.InetCacheBinaries, "Failed to cache binaries", err) - } - if _, err := CacheKubectlBinary(k8sVersion, binariesURL); err != nil { - exit.Error(reason.InetCacheKubectl, "Failed to cache kubectl", err) + + // Skip binary downloads in --no-kubernetes mode + if !viper.GetBool("no-kubernetes") { + if err := doCacheBinaries(k8sVersion, containerRuntime, driverName, binariesURL); err != nil { + exit.Error(reason.InetCacheBinaries, "Failed to cache binaries", err) + } + if _, err := CacheKubectlBinary(k8sVersion, binariesURL); err != nil { + exit.Error(reason.InetCacheKubectl, "Failed to cache kubectl", err) + } } waitCacheRequiredImages(cacheGroup) if driver.IsKIC(driverName) { diff --git a/test/integration/no_kubernetes_test.go b/test/integration/no_kubernetes_test.go index 71fbd8fbff03..096879cd5a1d 100644 --- a/test/integration/no_kubernetes_test.go +++ b/test/integration/no_kubernetes_test.go @@ -23,10 +23,13 @@ import ( "encoding/json" "fmt" "os/exec" + "path/filepath" + "runtime" "strings" "testing" "k8s.io/minikube/pkg/minikube/constants" + "k8s.io/minikube/pkg/minikube/localpath" ) // TestNoKubernetes tests starting minikube without Kubernetes, @@ -52,6 +55,7 @@ func TestNoKubernetes(t *testing.T) { {"StartWithK8s", validateStartWithK8S}, {"StartWithStopK8s", validateStartWithStopK8s}, {"Start", validateStartNoK8S}, + {"VerifyNok8sNoK8sDownloads", VerifyNoK8sDownloadCache}, {"VerifyK8sNotRunning", validateK8SNotRunning}, {"ProfileList", validateProfileListNoK8S}, {"Stop", validateStopNoK8S}, @@ -76,6 +80,25 @@ func TestNoKubernetes(t *testing.T) { }) } +// VerifyNoK8sDownloadCache verifies that starting minikube with --no-kubernetes does not create a download cache. +func VerifyNoK8sDownloadCache(ctx context.Context, t *testing.T, profile string) { + defer PostMortemLogs(t, profile) + + cachePath := filepath.Join(localpath.MiniPath(), "cache", runtime.GOOS, runtime.GOARCH, constants.NoKubernetesVersion) + + t.Logf("Checking cache directory: %s", cachePath) + files, err := filepath.Glob(filepath.Join(cachePath, "*")) + if err != nil { + t.Errorf("Error reading cache directory: %v", err) + return + } + + if len(files) > 0 { + t.Logf("Files found in cache directory: %v", files) + t.Errorf("Cache directory should not contain files when using --no-kubernetes") + } +} + // validateStartNoK8sWithVersion expect an error when starting a minikube cluster without kubernetes and with a kubernetes version. func validateStartNoK8sWithVersion(ctx context.Context, t *testing.T, profile string) { defer PostMortemLogs(t, profile)