Skip to content

Conversation

@henry3260
Copy link
Contributor

@henry3260 henry3260 commented Sep 29, 2025

This PR addresses issue #21179 by reorganizing the cache folder structure for binaries.

Before

  • Binaries for Linux and Darwin were placed directly under:
    • ~/.minikube/cache/linux
    • ~/.minikube/cache/darwin

After

  • They are now moved into a dedicated binaries subfolder:
    • ~/.minikube/cache/bin/linux
    • ~/.minikube/cache/bin/darwin

Why

  • This improves organization of the cache directory.
  • Aligns binaries with how other cached items (e.g., images, ISO files) are stored.
  • No functional behavior is changed, only the storage path for binaries.

Fixes #21179

Screenshot (Before)

image

Screenshot (After)

image

@k8s-ci-robot k8s-ci-robot added the cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. label Sep 29, 2025
@k8s-ci-robot k8s-ci-robot requested review from nirs and prezha September 29, 2025 11:35
@k8s-ci-robot k8s-ci-robot added the needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. label Sep 29, 2025
@k8s-ci-robot
Copy link
Contributor

Hi @henry3260. Thanks for your PR.

I'm waiting for a kubernetes member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@k8s-ci-robot k8s-ci-robot added the size/S Denotes a PR that changes 10-29 lines, ignoring generated files. label Sep 29, 2025
@minikube-bot
Copy link
Collaborator

Can one of the admins verify this patch?

func Binary(binary, version, osName, archName, binaryURL string) (string, error) {
targetDir := localpath.MakeMiniPath("cache", osName, archName, version)
// targetDir := localpath.MakeMiniPath("cache", osName, archName, version)
targetDir := localpath.MakeMiniPath("cache", "binaries", osName, archName, version)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should use "bin", it is more consistent with ~/.minikube/bin and the rest of the world.

We are using "binaries" internally which would nice to change also to bin but it may be harder since we may code using it. Since this cache directory is new we don't have backward compatibility concerns.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should use "bin", it is more consistent with ~/.minikube/bin and the rest of the world.

We are using "binaries" internally which would nice to change also to bin but it may be harder since we may code using it. Since this cache directory is new we don't have backward compatibility concerns.

Thanks for the suggestion! That makes sense, I’ll update it to use bin for consistency.

@henry3260 henry3260 requested a review from nirs September 29, 2025 13:35
@nirs
Copy link
Contributor

nirs commented Sep 29, 2025

/lgtm

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Sep 29, 2025
@nirs
Copy link
Contributor

nirs commented Sep 29, 2025

/assign @medyagh


// check that the bin directory was created
targetDir := filepath.Join(
os.Getenv("HOME"), ".minikube", "cache", "bin", "linux", "amd64", "v1.31.0",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

~/.minikube is the default, but if MINIKUBE_HOME is defined it will be used. There is a helper function to return the right path (but I don't remember the function name). Check what other tests are doing.

@k8s-ci-robot k8s-ci-robot removed the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Oct 3, 2025
// check that the bin directory was created
targetDir := filepath.Join(
os.Getenv("HOME"), ".minikube", "cache", "bin", "linux", "amd64", "v1.31.0",
localpath.MiniPath(), "cache", "bin", "linux", "amd64", "v1.31.0",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, to make it even better squash this commit into the first one. Having this in git history is not helpful.

@nirs
Copy link
Contributor

nirs commented Oct 3, 2025

/lgtm

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Oct 3, 2025
@k8s-ci-robot k8s-ci-robot removed the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Oct 3, 2025
@nirs
Copy link
Contributor

nirs commented Oct 3, 2025

/lgtm

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Oct 3, 2025
@medyagh
Copy link
Member

medyagh commented Oct 17, 2025

/ok-to-test

@k8s-ci-robot k8s-ci-robot added ok-to-test Indicates a non-member PR verified by an org member that is safe to test. and removed needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. labels Oct 17, 2025
Copy link
Member

@medyagh medyagh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for the PR, please update the before/after (it seems to be outdated)

@minikube-pr-bot

This comment has been minimized.

@minikube-pr-bot

This comment has been minimized.

@henry3260
Copy link
Contributor Author

thanks for the PR, please update the before/after (it seems to be outdated)

updated!

@nirs
Copy link
Contributor

nirs commented Oct 23, 2025

thanks for the PR, please update the before/after (it seems to be outdated)

updated!

It is still outdated:

They are now moved into a dedicated binaries subfolder:
~/.minikube/cache/binaries/linux
~/.minikube/cache/binaries/darwin

@henry3260
Copy link
Contributor Author

thanks for the PR, please update the before/after (it seems to be outdated)

updated!

It is still outdated:

They are now moved into a dedicated binaries subfolder:
~/.minikube/cache/binaries/linux
~/.minikube/cache/binaries/darwin

Thanks for pointing that out! I've corrected it now.

@nirs
Copy link
Contributor

nirs commented Oct 23, 2025

@henry3260 this change broke few test:

=== RUN   TestDownloadOnly/v1.28.0/binaries
aaa_download_only_test.go:157: expected the file for binary exist at "/home/jenkins/minikube-integration/21664-14293/.minikube/cache/linux/amd64/v1.28.0/kubelet" but got error stat /home/jenkins/minikube-integration/21664-14293/.minikube/cache/linux/amd64/v1.28.0/kubelet: no such file or directory
aaa_download_only_test.go:157: expected the file for binary exist at "/home/jenkins/minikube-integration/21664-14293/.minikube/cache/linux/amd64/v1.28.0/kubeadm" but got error stat /home/jenkins/minikube-integration/21664-14293/.minikube/cache/linux/amd64/v1.28.0/kubeadm: no such file or directory
aaa_download_only_test.go:157: expected the file for binary exist at "/home/jenkins/minikube-integration/21664-14293/.minikube/cache/linux/amd64/v1.28.0/kubectl" but got error stat /home/jenkins/minikube-integration/21664-14293/.minikube/cache/linux/amd64/v1.28.0/kubectl: no such file or directory

Please run integration tests locally and fix the failing tests.
See https://minikube.sigs.k8s.io/docs/contrib/testing/

Copy link
Contributor

@nirs nirs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to fix the tests assuming the old location.

The issue is we compute the path manually in the test and in the code. We need a helper to locate the binaries that can be used by the code and the tests.

@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: henry3260
Once this PR has been reviewed and has the lgtm label, please ask for approval from medyagh. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@henry3260
Copy link
Contributor Author

@henry3260 this change broke few test:

=== RUN   TestDownloadOnly/v1.28.0/binaries
aaa_download_only_test.go:157: expected the file for binary exist at "/home/jenkins/minikube-integration/21664-14293/.minikube/cache/linux/amd64/v1.28.0/kubelet" but got error stat /home/jenkins/minikube-integration/21664-14293/.minikube/cache/linux/amd64/v1.28.0/kubelet: no such file or directory
aaa_download_only_test.go:157: expected the file for binary exist at "/home/jenkins/minikube-integration/21664-14293/.minikube/cache/linux/amd64/v1.28.0/kubeadm" but got error stat /home/jenkins/minikube-integration/21664-14293/.minikube/cache/linux/amd64/v1.28.0/kubeadm: no such file or directory
aaa_download_only_test.go:157: expected the file for binary exist at "/home/jenkins/minikube-integration/21664-14293/.minikube/cache/linux/amd64/v1.28.0/kubectl" but got error stat /home/jenkins/minikube-integration/21664-14293/.minikube/cache/linux/amd64/v1.28.0/kubectl: no such file or directory

Please run integration tests locally and fix the failing tests. See https://minikube.sigs.k8s.io/docs/contrib/testing/

It looks like the current logic no longer downloads all KubernetesReleaseBinaries locally. Before I made any changes, I ran the integration tests on main and saw similar errors:

aaa_download_only_test.go:157: expected the file for binary exist at "/home/jenkins/minikube-integration/.../kubeadm" but got error stat: no such file or directory
aaa_download_only_test.go:157: expected the file for binary exist at "/home/jenkins/minikube-integration/.../kubectl" but got error stat: no such file or directory

So the previous behavior already failed to download kubeadm and kubelet locally. Only kubectl seems to be downloaded on the host.

This means the test assumption that all binaries are always cached locally is outdated. I think we need to update the tests to only check for binaries that Minikube actually downloads on the host or to conditionally check depending on the runtime driver.

@k8s-ci-robot
Copy link
Contributor

New changes are detected. LGTM label has been removed.

@k8s-ci-robot k8s-ci-robot added size/M Denotes a PR that changes 30-99 lines, ignoring generated files. and removed lgtm "Looks good to me", indicates that a PR is ready to be merged. size/S Denotes a PR that changes 10-29 lines, ignoring generated files. labels Oct 26, 2025
@k8s-ci-robot
Copy link
Contributor

@henry3260: The following tests failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
pull-minikube-integration fca5789 link true /test pull-minikube-integration
integration-kvm-crio-linux-x86-64 0ce7767 link true /test integration-kvm-crio-linux-x86-64
integration-kvm-containerd-linux-x86-64 0ce7767 link true /test integration-kvm-containerd-linux-x86-64
integration-kvm-docker-linux-x86-64 0ce7767 link true /test integration-kvm-docker-linux-x86-64
integration-docker-docker-linux-x86-64 0ce7767 link true /test integration-docker-docker-linux-x86-64
integration-docker-crio-linux-x86-64 0ce7767 link true /test integration-docker-crio-linux-x86-64
integration-docker-containerd-linux-x86-64 0ce7767 link true /test integration-docker-containerd-linux-x86-64
integration-none-docker-linux-x86-64 0ce7767 link true /test integration-none-docker-linux-x86-64

Full PR test history. Your PR dashboard. Please help us cut down on flakes by linking to an open issue when you hit one in your PR.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

@henry3260
Copy link
Contributor Author

Do you think we should introduce a helper function like CachedBinaryPath inside t.Run("cached-images", ...) to keep things consistent?
If so, should we open a separate issue for that improvement, or would you prefer that we include it in this PR?

@nirs
Copy link
Contributor

nirs commented Oct 26, 2025

It is possible that the test was broken before this change. To be sure please share complete test command and output with master showing the failures.

We meed to fix the test before we change the code. Otherwise we may break things.

I think kubeadm is cached only when disabling preloads. By default preloads are enabled and kubeadm is onstalled from the preloaded tarball. Maybe the test does not use the right flags.

Let’s open another issue for this test and work on fixing it in another PR. This PR can wait until we fix the test.

@minikube-pr-bot
Copy link

kvm2 driver with docker runtime

┌────────────────┬──────────┬────────────────────────┐
│    COMMAND     │ MINIKUBE │ MINIKUBE  ( PR 21664 ) │
├────────────────┼──────────┼────────────────────────┤
│ minikube start │ 43.6s    │ 42.9s                  │
│ enable ingress │ 16.8s    │ 17.7s                  │
└────────────────┴──────────┴────────────────────────┘

Times for minikube start: 44.2s 45.0s 42.3s 42.5s 43.9s
Times for minikube (PR 21664) start: 44.0s 41.9s 40.8s 43.3s 44.7s

Times for minikube (PR 21664) ingress: 21.3s 16.8s 17.3s 15.8s 17.4s
Times for minikube ingress: 15.8s 15.8s 19.8s 15.8s 16.8s

docker driver with docker runtime

┌────────────────┬──────────┬────────────────────────┐
│    COMMAND     │ MINIKUBE │ MINIKUBE  ( PR 21664 ) │
├────────────────┼──────────┼────────────────────────┤
│ minikube start │ 22.8s    │ 22.0s                  │
│ enable ingress │ 12.3s    │ 11.7s                  │
└────────────────┴──────────┴────────────────────────┘

Times for minikube start: 22.7s 21.8s 22.6s 23.2s 23.8s
Times for minikube (PR 21664) start: 22.3s 21.8s 22.3s 22.3s 21.2s

Times for minikube ingress: 11.8s 12.7s 10.7s 12.7s 13.7s
Times for minikube (PR 21664) ingress: 11.7s 10.7s 10.7s 11.7s 13.7s

docker driver with containerd runtime

┌────────────────┬──────────┬────────────────────────┐
│    COMMAND     │ MINIKUBE │ MINIKUBE  ( PR 21664 ) │
├────────────────┼──────────┼────────────────────────┤
│ minikube start │ 22.3s    │ 20.8s                  │
│ enable ingress │ 21.0s    │ 22.0s                  │
└────────────────┴──────────┴────────────────────────┘

Times for minikube ingress: 20.2s 20.2s 22.2s 20.2s 22.2s
Times for minikube (PR 21664) ingress: 22.2s 22.1s 23.2s 20.2s 22.2s

Times for minikube start: 19.2s 25.1s 21.6s 24.2s 21.4s
Times for minikube (PR 21664) start: 21.0s 20.2s 22.8s 20.6s 19.5s

@nirs
Copy link
Contributor

nirs commented Oct 26, 2025

@henry3260 looking in the test is does not disable preloads, and it checks if reload exists after starting minikube. If the preload tarball exists it does check for binaries. If preload tarball does not exit, it fallback to checking the binaries.

This test has few problems:

  • it is too complicated
  • it does not test the same case in all runs, depending on external state. If the preload tarball exist in the external system it test one case, and if not another case.
			preloadExists := false
			t.Run("preload-exists", func(t *testing.T) {
				// skip for none, as none driver does not have preload feature.
				if NoneDriver() {
					t.Skip("None driver does not have preload")
				}
				// Driver does not matter here, since the only exception is none driver,
				// which cannot occur here.
				if !download.PreloadExists(v, containerRuntime, "docker", true) {
					t.Skip("No preload image")
				}
				// Just make sure the tarball path exists
				if _, err := os.Stat(download.TarballPath(v, containerRuntime)); err != nil {
					t.Errorf("failed to verify preloaded tarball file exists: %v", err)
				}
				preloadExists = true
			})

			t.Run("cached-images", func(t *testing.T) {
				// skip verify for cache images if --driver=none
				if NoneDriver() {
					t.Skip("None driver has no cache")
				}
				if preloadExists {
					t.Skip("Preload exists, images won't be cached")
				}
				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)
					}
				}
			})

We need is to test all cases in all runs:

  • Preload does not exist, falling back to downloaded images - change preload url/name so it cannot be downloaded from the system publishing the preloads. The best way to test it is to add a --preload-url flag. We can make this flag hidden if we don't think it is useful or users and we need it only for testing.
  • Preload exists, no fallback - must use a preload that always exists. Using latest release is a good bet. Since preloads are important minikube feature, we can assume that we always have a preload for the latest release. If it does not work it is likely to be fixed.
  • Preload disabled (--preload=false), fallback to downloading the binaries.

Note that we also have preload_test.go, which tests --preload=false. But it does not test downloaded binaries. It seem to be focused on something else, not sure how it is related to preloads.

@henry3260
Copy link
Contributor Author

@henry3260 looking in the test is does not disable preloads, and it checks if reload exists after starting minikube. If the preload tarball exists it does check for binaries. If preload tarball does not exit, it fallback to checking the binaries.

This test has few problems:

  • it is too complicated
  • it does not test the same case in all runs, depending on external state. If the preload tarball exist in the external system it test one case, and if not another case.
			preloadExists := false
			t.Run("preload-exists", func(t *testing.T) {
				// skip for none, as none driver does not have preload feature.
				if NoneDriver() {
					t.Skip("None driver does not have preload")
				}
				// Driver does not matter here, since the only exception is none driver,
				// which cannot occur here.
				if !download.PreloadExists(v, containerRuntime, "docker", true) {
					t.Skip("No preload image")
				}
				// Just make sure the tarball path exists
				if _, err := os.Stat(download.TarballPath(v, containerRuntime)); err != nil {
					t.Errorf("failed to verify preloaded tarball file exists: %v", err)
				}
				preloadExists = true
			})

			t.Run("cached-images", func(t *testing.T) {
				// skip verify for cache images if --driver=none
				if NoneDriver() {
					t.Skip("None driver has no cache")
				}
				if preloadExists {
					t.Skip("Preload exists, images won't be cached")
				}
				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)
					}
				}
			})

We need is to test all cases in all runs:

  • Preload does not exist, falling back to downloaded images - change preload url/name so it cannot be downloaded from the system publishing the preloads. The best way to test it is to add a --preload-url flag. We can make this flag hidden if we don't think it is useful or users and we need it only for testing.
  • Preload exists, no fallback - must use a preload that always exists. Using latest release is a good bet. Since preloads are important minikube feature, we can assume that we always have a preload for the latest release. If it does not work it is likely to be fixed.
  • Preload disabled (--preload=false), fallback to downloading the binaries.

Note that we also have preload_test.go, which tests --preload=false. But it does not test downloaded binaries. It seem to be focused on something else, not sure how it is related to preloads.

I opened the issue for this #21805

@minikube-pr-bot
Copy link

Here are the number of top 10 failed tests in each environments with lowest flake rate.

Environment Test Name Flake Rate
Docker_Windows (3 failed) TestDownloadOnly/v1.28.0/kubectl(gopogh) Unknown
Docker_Windows (3 failed) TestDownloadOnly/v1.34.1/kubectl(gopogh) Unknown
Docker_Windows (3 failed) TestErrorSpam/setup(gopogh) Unknown
KVM_Linux_crio (7 failed) TestStartStop/group/default-k8s-diff-port/serial/UserAppExistsAfterStop(gopogh) 9.09% (chart)
KVM_Linux_crio (7 failed) TestStartStop/group/default-k8s-diff-port/serial/AddonExistsAfterStop(gopogh) 9.09% (chart)
KVM_Linux_crio (7 failed) TestStartStop/group/embed-certs/serial/UserAppExistsAfterStop(gopogh) 12.50% (chart)
KVM_Linux_crio (7 failed) TestStartStop/group/embed-certs/serial/AddonExistsAfterStop(gopogh) 12.50% (chart)

Besides the following environments also have failed tests:

  • Docker_Linux_crio: 40 failed (gopogh)

  • Docker_Linux_crio_arm64: 36 failed (gopogh)

To see the flake rates of all tests by environment, click here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. ok-to-test Indicates a non-member PR verified by an org member that is safe to test. size/M Denotes a PR that changes 30-99 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

move binaries in cache folder under folder called "binaries"

6 participants