提交 f3cce500 编写于 作者: T Thomas Stromberg

Improve error disambiguation, especially for non-running drivers

上级 7f5a06b6
......@@ -224,7 +224,7 @@ func postStartValidations(h *host.Host, drvName string) {
glog.Warningf("error getting percentage of /var that is free: %v", err)
}
if percentageFull >= 99 {
exit.Message(reason.RsrcInsufficientDockerStorage, `Docker is out of disk space! ({{.p}}% of capacity)`, out.V{"p": percentageFull})
exit.Message(reason.RsrcInsufficientDockerStorage, `Docker is out of disk space! (/var is at {{.p}}% of capacity)`, out.V{"p": percentageFull})
}
if percentageFull >= 85 {
......
......@@ -100,7 +100,11 @@ func displayText(k reason.Kind, format string, a ...V) {
}
issueURLs := k.IssueURLs()
if len(issueURLs) > 0 {
if len(issueURLs) == 1 {
ErrT(style.Issues, "Related issue: {{.url}}", V{"url": issueURLs[0]})
}
if len(issueURLs) > 1 {
ErrT(style.Issues, "Related issues:")
for _, i := range issueURLs {
ErrT(style.Issue, "{{.url}}", V{"url": i})
......
......@@ -34,6 +34,8 @@ package reason
import (
"regexp"
"k8s.io/minikube/pkg/minikube/style"
)
// links used by multiple known issues
......@@ -152,8 +154,9 @@ var hostIssues = []match{
Kind: Kind{
ID: "HOST_KUBECONFIG_PERMISSION",
ExitCode: ExHostPermission,
Advice: "Run: 'chmod 600 $HOME/.kube/config'",
Advice: "Run: 'sudo chown $USER $HOME/.kube/config && chmod 600 $HOME/.kube/config'",
Issues: []int{5714},
Style: style.NotAllowed,
},
Regexp: re(`.kube/config: permission denied`),
GOOS: []string{"darwin", "linux"},
......
......@@ -114,7 +114,7 @@ var (
InternalCredsNotFound = Kind{ID: "MK_CREDENTIALS_NOT_FOUND", ExitCode: ExProgramNotFound, Style: style.Shrug}
InternalSemverParse = Kind{ID: "MK_SEMVER_PARSE", ExitCode: ExProgramError}
RsrcInsufficientCores = Kind{ID: "RSRC_INSUFFICIENT_CORES", ExitCode: ExInsufficientCores, Style: style.NoEntry}
RsrcInsufficientCores = Kind{ID: "RSRC_INSUFFICIENT_CORES", ExitCode: ExInsufficientCores, Style: style.UnmetRequirement}
RsrcInsufficientDarwinDockerCores = Kind{
ID: "RSRC_DOCKER_CORES",
ExitCode: ExInsufficientCores,
......@@ -123,7 +123,7 @@ var (
3. Click "Resources"
4. Increase "CPUs" slider bar to 2 or higher
5. Click "Apply & Restart"`,
Style: style.NoEntry,
Style: style.UnmetRequirement,
URL: "https://docs.docker.com/docker-for-mac/#resources",
}
......@@ -136,12 +136,12 @@ var (
4. Increase "CPUs" slider bar to 2 or higher
5. Click "Apply & Restart"`,
URL: "https://docs.docker.com/docker-for-windows/#resources",
Style: style.NoEntry,
Style: style.UnmetRequirement,
}
RsrcInsufficientReqMemory = Kind{ID: "RSRC_INSUFFICIENT_REQ_MEMORY", ExitCode: ExInsufficientMemory, Style: style.NoEntry}
RsrcInsufficientSysMemory = Kind{ID: "RSRC_INSUFFICIENT_SYS_MEMORY", ExitCode: ExInsufficientMemory, Style: style.NoEntry}
RsrcInsufficientContainerMemory = Kind{ID: "RSRC_INSUFFICIENT_CONTAINER_MEMORY", ExitCode: ExInsufficientMemory, Style: style.NoEntry}
RsrcInsufficientReqMemory = Kind{ID: "RSRC_INSUFFICIENT_REQ_MEMORY", ExitCode: ExInsufficientMemory, Style: style.UnmetRequirement}
RsrcInsufficientSysMemory = Kind{ID: "RSRC_INSUFFICIENT_SYS_MEMORY", ExitCode: ExInsufficientMemory, Style: style.UnmetRequirement}
RsrcInsufficientContainerMemory = Kind{ID: "RSRC_INSUFFICIENT_CONTAINER_MEMORY", ExitCode: ExInsufficientMemory, Style: style.UnmetRequirement}
RsrcInsufficientWindowsDockerMemory = Kind{
ID: "RSRC_DOCKER_MEMORY",
ExitCode: ExInsufficientMemory,
......@@ -151,7 +151,7 @@ var (
4. Increase "Memory" slider bar to {{.recommend}} or higher
5. Click "Apply & Restart"`,
URL: "https://docs.docker.com/docker-for-windows/#resources",
Style: style.NoEntry,
Style: style.UnmetRequirement,
}
RsrcInsufficientDarwinDockerMemory = Kind{
ID: "RSRC_DOCKER_MEMORY",
......@@ -161,7 +161,7 @@ var (
3. Click "Resources"
4. Increase "Memory" slider bar to {{.recommend}} or higher
5. Click "Apply & Restart"`,
Style: style.NoEntry,
Style: style.UnmetRequirement,
URL: "https://docs.docker.com/docker-for-mac/#resources",
}
......@@ -177,7 +177,7 @@ var (
Issues: []int{9024},
}
RsrcInsufficientStorage = Kind{ID: "RSRC_INSUFFICIENT_STORAGE", ExitCode: ExInsufficientStorage, Style: style.NoEntry}
RsrcInsufficientStorage = Kind{ID: "RSRC_INSUFFICIENT_STORAGE", ExitCode: ExInsufficientStorage, Style: style.UnmetRequirement}
HostHomeMkdir = Kind{ID: "HOST_HOME_MKDIR", ExitCode: ExHostPermission}
HostHomeChown = Kind{ID: "HOST_HOME_CHOWN", ExitCode: ExHostPermission}
......
......@@ -150,17 +150,17 @@ func checkOverlayMod() registry.State {
// suggestFix matches a stderr with possible fix for the docker driver
func suggestFix(stderr string, err error) registry.State {
if strings.Contains(stderr, "permission denied") && runtime.GOOS == "linux" {
return registry.State{Error: err, Installed: true, Healthy: false, Fix: "Add your user to the 'docker' group: 'sudo usermod -aG docker $USER && newgrp docker'", Doc: "https://docs.docker.com/engine/install/linux-postinstall/"}
return registry.State{Error: err, Installed: true, Running: true, Healthy: false, Fix: "Add your user to the 'docker' group: 'sudo usermod -aG docker $USER && newgrp docker'", Doc: "https://docs.docker.com/engine/install/linux-postinstall/"}
}
if strings.Contains(stderr, "/pipe/docker_engine: The system cannot find the file specified.") && runtime.GOOS == "windows" {
return registry.State{Error: err, Installed: true, Healthy: false, Fix: "Start the Docker service. If Docker is already running, you may need to reset Docker to factory settings with: Settings > Reset.", Doc: "https://github.com/docker/for-win/issues/1825#issuecomment-450501157"}
return registry.State{Error: err, Installed: true, Running: false, Healthy: false, Fix: "Start the Docker service. If Docker is already running, you may need to reset Docker to factory settings with: Settings > Reset.", Doc: "https://github.com/docker/for-win/issues/1825#issuecomment-450501157"}
}
if strings.Contains(stderr, "Cannot connect") || strings.Contains(stderr, "refused") || strings.Contains(stderr, "Is the docker daemon running") || strings.Contains(stderr, "docker daemon is not running") {
return registry.State{Error: err, Installed: true, Healthy: false, Fix: "Start the Docker service", Doc: docURL}
return registry.State{Error: err, Installed: true, Running: false, Healthy: false, Fix: "Start the Docker service", Doc: docURL}
}
// We don't have good advice, but at least we can provide a good error message
return registry.State{Error: err, Installed: true, Healthy: false, Doc: docURL}
return registry.State{Error: err, Installed: true, Running: true, Healthy: false, Doc: docURL}
}
......@@ -96,7 +96,7 @@ func status() registry.State {
cmd := exec.CommandContext(ctx, path, "-v")
out, err := cmd.CombinedOutput()
if err != nil {
return registry.State{Installed: true, Error: fmt.Errorf("%s failed:\n%s", strings.Join(cmd.Args, " "), out), Fix: "Run 'brew install hyperkit'", Doc: docURL}
return registry.State{Installed: true, Running: false, Error: fmt.Errorf("%s failed:\n%s", strings.Join(cmd.Args, " "), out), Fix: "Run 'brew install hyperkit'", Doc: docURL}
}
// Split version from v0.YYYYMMDD-HH-xxxxxxx or 0.YYYYMMDD to YYYYMMDD
......@@ -105,13 +105,13 @@ func status() registry.State {
// If current hyperkit is not newer than minimumVersion, suggest upgrade information
isNew, err := isNewerVersion(currentVersion, specificVersion)
if err != nil {
return registry.State{Installed: true, Healthy: true, Error: fmt.Errorf("hyperkit version check failed:\n%v", err), Doc: docURL}
return registry.State{Installed: true, Running: true, Healthy: true, Error: fmt.Errorf("hyperkit version check failed:\n%v", err), Doc: docURL}
}
if !isNew {
return registry.State{Installed: true, Healthy: true, Error: fmt.Errorf("the installed hyperkit version (0.%s) is older than the minimum recommended version (%s)", currentVersion, minimumVersion), Fix: "Run 'brew upgrade hyperkit'", Doc: docURL}
return registry.State{Installed: true, Running: true, Healthy: true, Error: fmt.Errorf("the installed hyperkit version (0.%s) is older than the minimum recommended version (%s)", currentVersion, minimumVersion), Fix: "Run 'brew upgrade hyperkit'", Doc: docURL}
}
return registry.State{Installed: true, Healthy: true}
return registry.State{Installed: true, Running: true, Healthy: true}
}
// isNewerVersion checks whether current hyperkit is newer than specific version
......
......@@ -95,14 +95,14 @@ func status() registry.State {
if err != nil {
errorMessage := fmt.Errorf("%s failed:\n%s", strings.Join(cmd.Args, " "), out)
fixMessage := "Start PowerShell as an Administrator"
return registry.State{Installed: false, Error: errorMessage, Fix: fixMessage, Doc: docURL}
return registry.State{Installed: false, Running: true, Error: errorMessage, Fix: fixMessage, Doc: docURL}
}
// Get-Wmiobject does not return an error code for false
if strings.TrimSpace(string(out)) != "True" {
errorMessage := fmt.Errorf("%s returned %q", strings.Join(cmd.Args, " "), out)
fixMessage := "Enable Hyper-V: Start PowerShell as Administrator, and run: 'Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All'"
return registry.State{Installed: false, Error: errorMessage, Fix: fixMessage, Doc: docURL}
return registry.State{Installed: false, Running: false, Error: errorMessage, Fix: fixMessage, Doc: docURL}
}
return registry.State{Installed: true, Healthy: true}
......
......@@ -117,6 +117,7 @@ func status() registry.State {
if err != nil {
return registry.State{
Installed: true,
Running: true,
Error: fmt.Errorf("%s failed:\n%s", strings.Join(cmd.Args, " "), strings.TrimSpace(string(out))),
Fix: "Follow your Linux distribution instructions for configuring KVM",
Doc: docURL,
......@@ -129,6 +130,7 @@ func status() registry.State {
if err != nil {
return registry.State{
Installed: true,
Running: true,
Error: fmt.Errorf("%s failed:\n%s", strings.Join(cmd.Args, " "), strings.TrimSpace(string(out))),
Fix: "Check that libvirtd is properly installed and that you are a member of the appropriate libvirt group",
Doc: docURL,
......
......@@ -54,16 +54,16 @@ func configure(cc config.ClusterConfig, n config.Node) (interface{}, error) {
func status() registry.State {
_, err := exec.LookPath("iptables")
if err != nil {
return registry.State{Error: err, Fix: "iptables must be installed", Doc: "https://minikube.sigs.k8s.io/docs/reference/drivers/none/"}
return registry.State{Running: true, Error: err, Fix: "iptables must be installed", Doc: "https://minikube.sigs.k8s.io/docs/reference/drivers/none/"}
}
if _, err := exec.LookPath("docker"); err != nil {
return registry.State{Error: err, Installed: false, Fix: "Install docker", Doc: "https://minikube.sigs.k8s.io/docs/reference/drivers/none/"}
return registry.State{Running: true, Error: err, Installed: false, Fix: "Install docker", Doc: "https://minikube.sigs.k8s.io/docs/reference/drivers/none/"}
}
u, err := user.Current()
if err != nil {
return registry.State{Error: err, Healthy: false, Doc: "https://minikube.sigs.k8s.io/docs/reference/drivers/none/"}
return registry.State{Running: true, Error: err, Healthy: false, Doc: "https://minikube.sigs.k8s.io/docs/reference/drivers/none/"}
}
if u.Uid != "0" {
......
......@@ -59,5 +59,5 @@ func status() registry.State {
if err != nil {
return registry.State{Error: err, Fix: "Install docker-machine-driver-parallels", Doc: "https://minikube.sigs.k8s.io/docs/reference/drivers/parallels/"}
}
return registry.State{Installed: true, Healthy: true}
return registry.State{Installed: true, Healthy: true, Running: true}
}
......@@ -104,7 +104,7 @@ func status() registry.State {
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"}
return registry.State{Error: err, Installed: true, Running: 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) {
......@@ -122,7 +122,7 @@ func status() registry.State {
// Basic timeout
if ctx.Err() == context.DeadlineExceeded {
return registry.State{Error: err, Installed: true, Healthy: false, Fix: "Restart the Podman service", Doc: docURL}
return registry.State{Error: err, Installed: true, Running: false, Healthy: false, Fix: "Restart the Podman service", Doc: docURL}
}
username := "$USER"
......
......@@ -73,9 +73,10 @@ func status() registry.State {
path, err := exec.LookPath(tryPath)
if err != nil {
return registry.State{
Error: fmt.Errorf("unable to find VBoxManage in $PATH"),
Fix: "Install VirtualBox",
Doc: docURL,
Error: fmt.Errorf("unable to find VBoxManage in $PATH"),
Fix: "Install VirtualBox",
Installed: false,
Doc: docURL,
}
}
......@@ -89,7 +90,7 @@ func status() registry.State {
// Basic timeout
if ctx.Err() == context.DeadlineExceeded {
glog.Warningf("%q timed out. ", strings.Join(cmd.Args, " "))
return registry.State{Error: err, Installed: true, Healthy: false, Fix: "Restart VirtualBox", Doc: docURL}
return registry.State{Error: err, Installed: true, Running: false, Healthy: false, Fix: "Restart VirtualBox", Doc: docURL}
}
if exitErr, ok := err.(*exec.ExitError); ok {
......
......@@ -74,6 +74,7 @@ type StatusChecker func() State
type State struct {
Installed bool
Healthy bool
Running bool // the provider does not appear to be running
NeedsImprovement bool // driver is healthy but could be improved
Error error
Fix string
......
......@@ -55,7 +55,7 @@ var Config = map[Enum]Options{
Empty: {Prefix: "", LowPrefix: ""},
Happy: {Prefix: "😄 "},
Issue: {Prefix: " ▪ ", LowPrefix: LowIndent}, // Indented bullet
Issues: {Prefix: "⁉️ "},
Issues: {Prefix: "🍿 "},
Launch: {Prefix: "🚀 "},
LogEntry: {Prefix: " "}, // Indent
New: {Prefix: "🆕 "},
......@@ -80,17 +80,18 @@ var Config = map[Enum]Options{
Workaround: {Prefix: "👉 ", LowPrefix: LowIndent},
// Fail emoji's
Conflict: {Prefix: "💢 ", LowPrefix: LowWarning},
Failure: {Prefix: "❌ ", LowPrefix: LowError},
Fatal: {Prefix: "💣 ", LowPrefix: LowError},
Warning: {Prefix: "❗ ", LowPrefix: LowWarning},
KnownIssue: {Prefix: "🧯 ", LowPrefix: LowError},
NoEntry: {Prefix: "⛔ ", LowPrefix: LowError},
Embarrassed: {Prefix: "🤦 ", LowPrefix: LowWarning},
Sad: {Prefix: "😿 "},
Shrug: {Prefix: "🤷 "},
Improvement: {Prefix: "🏎️ ", LowPrefix: LowWarning},
SeeNoEvil: {Prefix: "🙈 ", LowPrefix: LowError},
Conflict: {Prefix: "💢 ", LowPrefix: LowWarning},
Failure: {Prefix: "❌ ", LowPrefix: LowError},
Fatal: {Prefix: "💣 ", LowPrefix: LowError},
Warning: {Prefix: "❗ ", LowPrefix: LowWarning},
KnownIssue: {Prefix: "🧯 ", LowPrefix: LowError},
UnmetRequirement: {Prefix: "⛔ ", LowPrefix: LowError},
NotAllowed: {Prefix: "🚫 ", LowPrefix: LowError},
Embarrassed: {Prefix: "🤦 ", LowPrefix: LowWarning},
Sad: {Prefix: "😿 "},
Shrug: {Prefix: "🤷 "},
Improvement: {Prefix: "💨 ", LowPrefix: LowWarning},
SeeNoEvil: {Prefix: "🙈 ", LowPrefix: LowError},
// Specialized purpose styles
AddonDisable: {Prefix: "🌑 "},
......
......@@ -64,7 +64,7 @@ const (
MountOptions
New
Notice
NoEntry
NotAllowed
Option
Pause
Permissions
......@@ -90,6 +90,7 @@ const (
Tip
Unmount
Unpause
UnmetRequirement
Unsupported
URL
Usage
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册