diff --git a/pkg/minikube/registry/drvs/podman/podman.go b/pkg/minikube/registry/drvs/podman/podman.go index 79815c0d2e..dd54e998d8 100644 --- a/pkg/minikube/registry/drvs/podman/podman.go +++ b/pkg/minikube/registry/drvs/podman/podman.go @@ -42,12 +42,18 @@ import ( var minReqPodmanVer = semver.Version{Major: 1, Minor: 7, Patch: 0} func init() { + priority := registry.Experimental + // Staged rollout for default: + // - Linux + // - macOS (podman-remote) + // - Windows (podman-remote) + if err := registry.Register(registry.DriverDef{ Name: driver.Podman, Config: configure, Init: func() drivers.Driver { return kic.NewDriver(kic.Config{OCIPrefix: oci.Sudo, OCIBinary: oci.Podman}) }, Status: status, - Priority: registry.Experimental, + Priority: priority, }); err != nil { panic(fmt.Sprintf("register failed: %v", err)) } @@ -56,14 +62,16 @@ func init() { func configure(cc config.ClusterConfig, n config.Node) (interface{}, error) { baseImage := viper.GetString("base-image") return kic.NewDriver(kic.Config{ - MachineName: driver.MachineName(cc, n), - StorePath: localpath.MiniPath(), - ImageDigest: strings.Split(baseImage, "@")[0], // for podman does not support docker images references with both a tag and digest. - CPU: cc.CPUs, - Memory: cc.Memory, - OCIPrefix: oci.Sudo, - OCIBinary: oci.Podman, - APIServerPort: cc.Nodes[0].Port, + MachineName: driver.MachineName(cc, n), + StorePath: localpath.MiniPath(), + ImageDigest: strings.Split(baseImage, "@")[0], // for podman does not support docker images references with both a tag and digest. + CPU: cc.CPUs, + Memory: cc.Memory, + OCIPrefix: oci.Sudo, + OCIBinary: oci.Podman, + APIServerPort: cc.Nodes[0].Port, + KubernetesVersion: cc.KubernetesConfig.KubernetesVersion, + ContainerRuntime: cc.KubernetesConfig.ContainerRuntime, }), nil } @@ -74,58 +82,59 @@ func status() registry.State { return registry.State{Error: err, Installed: false, Healthy: false, Fix: "Install Podman", Doc: docURL} } - // Allow no more than 2 seconds for version command - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) - defer cancel() - - cmd := exec.CommandContext(ctx, oci.Podman, "version", "-f", "{{.Version}}") - o, err := cmd.CombinedOutput() - output := string(o) - if err != nil { - glog.Warningf("podman version returned %s", output) - return registry.State{Error: err, Installed: true, Healthy: false, Fix: "Cant verify mininim required version for podman . See podman website for installation guide.", Doc: "https://podman.io/getting-started/installation.html"} - } - - v, err := semver.Make(output) - if err != nil { - return registry.State{Error: err, Installed: true, Healthy: false, Fix: "Cant verify mininim required version for podman . See podman website for installation guide.", Doc: "https://podman.io/getting-started/installation.html"} - } - - if v.LT(minReqPodmanVer) { - glog.Warningf("Warning ! mininim required version for podman is %s. your version is %q. minikube might not work. use at your own risk. To install latest version please see https://podman.io/getting-started/installation.html ", minReqPodmanVer.String(), v.String()) - } - - // Allow no more than 3 seconds for querying state - ctx, cancel = context.WithTimeout(context.Background(), 3*time.Second) + ctx, cancel := context.WithTimeout(context.Background(), 6*time.Second) defer cancel() + // Quickly returns an error code if service is not running + cmd := exec.CommandContext(ctx, oci.Podman, "version", "--format", "{{.Server.Version}}") // Run with sudo on linux (local), otherwise podman-remote (as podman) if runtime.GOOS == "linux" { - cmd = exec.CommandContext(ctx, oci.Sudo, "-n", oci.Podman, "info") + cmd = exec.CommandContext(ctx, oci.Sudo, "-n", oci.Podman, "version", "--format", "{{.Version}}") cmd.Env = append(os.Environ(), "LANG=C", "LC_ALL=C") // sudo is localized - } else { - cmd = exec.CommandContext(ctx, oci.Podman, "info") } - _, err = cmd.Output() + o, err := cmd.Output() + output := string(o) if err == nil { + v, err := semver.Make(output) + if err != nil { + return registry.State{Error: err, Installed: true, Healthy: false, Fix: "Cant verify minimum required version for podman . See podman website for installation guide.", Doc: "https://podman.io/getting-started/installation.html"} + } + + if v.LT(minReqPodmanVer) { + glog.Warningf("Warning ! minimum required version for podman is %s. your version is %q. minikube might not work. use at your own risk. To install latest version please see https://podman.io/getting-started/installation.html ", minReqPodmanVer.String(), v.String()) + } + return registry.State{Installed: true, Healthy: true} } glog.Warningf("podman returned error: %v", err) + // Basic timeout + if ctx.Err() == context.DeadlineExceeded { + return registry.State{Error: err, Installed: true, Healthy: false, Fix: "Restart the Podman service", Doc: docURL} + } + + username := "$USER" + if u, err := user.Current(); err == nil { + username = u.Username + } + if exitErr, ok := err.(*exec.ExitError); ok { stderr := strings.TrimSpace(string(exitErr.Stderr)) newErr := fmt.Errorf(`%q %v: %s`, strings.Join(cmd.Args, " "), exitErr, stderr) - username := "$USER" - if u, err := user.Current(); err == nil { - username = u.Username - } - if strings.Contains(stderr, "a password is required") && runtime.GOOS == "linux" { return registry.State{Error: newErr, Installed: true, Healthy: false, Fix: fmt.Sprintf("Add your user to the 'sudoers' file: '%s ALL=(ALL) NOPASSWD: %s'", username, podman), Doc: "https://podman.io"} } + // Typical low-level errors from running podman-remote: + // - local: "dial unix /run/podman/io.podman: connect: no such file or directory" + // - remote: "unexpected EOF" (ssh varlink isn't so great at handling rejections) + + if strings.Contains(stderr, "could not get runtime") || strings.Contains(stderr, "Unable to obtain server version information") { + return registry.State{Error: newErr, Installed: true, Healthy: false, Fix: "Start the Podman service", Doc: docURL} + } + // We don't have good advice, but at least we can provide a good error message return registry.State{Error: newErr, Installed: true, Healthy: false, Doc: docURL} }