Skip to content
Closed
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
45 changes: 21 additions & 24 deletions pkg/minikube/download/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import (
"github.com/cheggaaa/pb/v3"
"github.com/google/go-containerregistry/pkg/name"
v1 "github.com/google/go-containerregistry/pkg/v1"
"github.com/google/go-containerregistry/pkg/v1/daemon"
"github.com/google/go-containerregistry/pkg/v1/remote"
"github.com/google/go-containerregistry/pkg/v1/tarball"
"github.com/hashicorp/go-getter"
Expand Down Expand Up @@ -106,19 +105,15 @@ func ImageExistsInDaemon(img string) bool {
// arch. This is needed to resolve
// https://github.com/kubernetes/minikube/pull/19205
func isImageCorrectArch(img string) (bool, error) {
ref, err := name.ParseReference(img)
if err != nil {
return false, fmt.Errorf("failed to parse reference: %v", err)
}
dImg, err := daemon.Image(ref)
if err != nil {
return false, fmt.Errorf("failed to get image from daemon: %v", err)
}
cfg, err := dImg.ConfigFile()
// Use the docker CLI instead of directly accessing the Docker daemon
// socket so that users who access docker via sudo wrappers are supported.
cmd := exec.Command("docker", "image", "inspect", "--format", "{{.Architecture}}", img)
output, err := cmd.Output()
if err != nil {
Comment on lines +111 to 112

Copilot AI Apr 22, 2026

Copy link

Choose a reason for hiding this comment

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

cmd.Output() drops stderr, so failures from docker image inspect will return an unhelpful error (e.g. only exit status 1). Consider using CombinedOutput() and include the captured output in the returned error to make diagnosing inspect failures easier.

Suggested change
output, err := cmd.Output()
if err != nil {
output, err := cmd.CombinedOutput()
if err != nil {
inspectOutput := strings.TrimSpace(string(output))
if inspectOutput != "" {
return false, fmt.Errorf("failed to inspect image %s: %v: %s", img, err, inspectOutput)
}

Copilot uses AI. Check for mistakes.
return false, fmt.Errorf("failed to get config for %s: %v", img, err)
return false, fmt.Errorf("failed to inspect image %s: %v", img, err)
}
return cfg.Architecture == runtime.GOARCH, nil
arch := strings.TrimSpace(string(output))
return arch == runtime.GOARCH, nil
}

// ImageToCache downloads img (if not present in cache) and writes it to the local cache directory
Expand Down Expand Up @@ -285,30 +280,32 @@ func parseImage(img string) (*name.Tag, name.Reference, error) {
func CacheToDaemon(img string) (string, error) {
p := imagePathInCache(img)

tag, ref, err := parseImage(img)
_, ref, err := parseImage(img)
if err != nil {
Comment on lines +283 to 284

Copilot AI Apr 22, 2026

Copy link

Choose a reason for hiding this comment

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

parseImage now returns a tag that is immediately discarded (_, ref, err := parseImage(img)). Since this is the only call site, consider simplifying parseImage to return just what CacheToDaemon needs (or avoid computing/returning the unused tag) to reduce confusion and unnecessary work.

Copilot uses AI. Check for mistakes.
return "", err
}
// do not use cache if image is set in format <name>:latest
if _, ok := ref.(name.Tag); ok {
if tag.Name() == "latest" {
if t, ok := ref.(name.Tag); ok {
if t.TagStr() == "latest" {
return "", fmt.Errorf("can't cache 'latest' tag")
}
}

i, err := tarball.ImageFromPath(p, tag)
// Use the docker CLI to load the image so that users who access docker
// via sudo wrappers or similar privilege-escalation mechanisms are
// supported. The previous daemon.Write() call connected directly to
// the Docker socket, which fails with "permission denied" when the
// current user doesn't have socket access.
cmd := exec.Command("docker", "load", "-i", p)
klog.Infof("Loading image into docker daemon: %v", cmd.Args)
output, err := cmd.CombinedOutput()
klog.V(2).Infof("docker load output: %s", output)
if err != nil {
return "", fmt.Errorf("tarball: %w", err)
}

resp, err := daemon.Write(*tag, i)
klog.V(2).Infof("response: %s", resp)
if err != nil {
return "", err
return "", fmt.Errorf("error loading image: %w", err)

Copilot AI Apr 22, 2026

Copy link

Choose a reason for hiding this comment

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

On docker load failure, the returned error wraps only err (often just exit status 1) while the more useful details are in output and only logged at -v=2. Include the docker load output (and/or command) in the returned error so users get actionable diagnostics at default log levels.

Suggested change
return "", fmt.Errorf("error loading image: %w", err)
trimmedOutput := strings.TrimSpace(string(output))
if trimmedOutput != "" {
return "", fmt.Errorf("error loading image with %v: %s: %w", cmd.Args, trimmedOutput, err)
}
return "", fmt.Errorf("error loading image with %v: %w", cmd.Args, err)

Copilot uses AI. Check for mistakes.
}

platform := fmt.Sprintf("linux/%s", runtime.GOARCH)
cmd := exec.Command("docker", "pull", "--platform", platform, "--quiet", img)
cmd = exec.Command("docker", "pull", "--platform", platform, "--quiet", img)
if output, err := cmd.CombinedOutput(); err != nil {
klog.Warningf("failed to pull image digest (expected if offline): %s: %v", output, err)
img = image.Tag(img)
Expand Down