diff --git a/pkg/minikube/exit/exit.go b/pkg/minikube/exit/exit.go index b0908fbf5bd0..bb18b02ca40a 100644 --- a/pkg/minikube/exit/exit.go +++ b/pkg/minikube/exit/exit.go @@ -20,6 +20,7 @@ package exit import ( "fmt" "os" + "runtime" "github.com/golang/glog" "k8s.io/minikube/pkg/minikube/console" @@ -59,7 +60,7 @@ func WithCode(code int, format string, a ...interface{}) { // WithError outputs an error and exits. func WithError(msg string, err error) { - p := problem.FromError(err) + p := problem.FromError(err, runtime.GOOS) if p != nil { WithProblem(msg, p) } diff --git a/pkg/minikube/problem/err_map.go b/pkg/minikube/problem/err_map.go index a595a93009f2..bf0caf58d01c 100644 --- a/pkg/minikube/problem/err_map.go +++ b/pkg/minikube/problem/err_map.go @@ -36,10 +36,49 @@ var vmProblems = map[string]match{ Advice: "In some environments, this message is incorrect. Try 'minikube start --no-vtx-check'", Issues: []int{3900}, }, - "VBOX_THIRD_PARTY": { - Regexp: re(`The virtual machine * has terminated unexpectedly during startup with exit code 1`), - Advice: "A third-party program may be interfering with VirtualBox. Try disabling any real-time antivirus software, reinstalling VirtualBox and rebooting.", - Issues: []int{3910}, + "VBOX_VERR_VMX_NO_VMX": { + Regexp: re(`VT-x is not available.*VERR_VMX_NO_VMX`), + Advice: "Please check your BIOS, and ensure that you are running without HyperV or other nested virtualization that may interfere", + Issues: []int{1994}, + }, + "VBOX_BLOCKED": { + Regexp: re(`NS_ERROR_FAILURE.*0x80004005`), + Advice: "Reinstall VirtualBox and verify that it is not blocked: System Preferences -> Security & Privacy -> General -> Some system software was blocked from loading", + Issues: []int{4107}, + GOOS: "darwin", + }, + "VBOX_DRV_NOT_LOADED": { + Regexp: re(`The vboxdrv kernel module is not loaded`), + Advice: "Run 'sudo modprobe vboxdrv' and reinstall VirtualBox if it fails.", + Issues: []int{4043}, + }, + "VBOX_DEVICE_MISSING": { + Regexp: re(`/dev/vboxdrv does not exist`), + Advice: "Run 'sudo modprobe vboxdrv' and reinstall VirtualBox if it fails.", + Issues: []int{3974}, + }, + "VBOX_HARDENING": { + Regexp: re(`terminated unexpectedly.*VBoxHardening`), + Advice: "Disable real-time anti-virus software, reboot, and reinstall VirtualBox if the problem continues.", + Issues: []int{3859, 3910}, + URL: "https://forums.virtualbox.org/viewtopic.php?f=25&t=82106", + GOOS: "windows", + }, + "VBOX_HOST_ADAPTER": { + Regexp: re(`The host-only adapter we just created is not visible`), + Advice: "Reboot to complete VirtualBox installation, and verify that VirtualBox is not blocked by your system", + Issues: []int{3614}, + URL: "https://stackoverflow.com/questions/52277019/how-to-fix-vm-issue-with-minikube-start", + }, + "VBOX_BLOCKED_LOADING": { + Regexp: re(`NS_ERROR_FAILURE.*0x80004005`), + Advice: "Reinstall VirtualBox and verify that it is not blocked: System Preferences -> Security & Privacy -> General -> Some system software was blocked from loading", + Issues: []int{4107}, + }, + "VBOX_KERNEL_MODULE_NOT_LOADED": { + Regexp: re(`The vboxdrv kernel module is not loaded`), + Advice: "Run 'sudo modprobe vboxdrv' and reinstall VirtualBox if it fails.", + Issues: []int{4043}, }, "KVM2_NOT_FOUND": { Regexp: re(`Driver "kvm2" not found. Do you have the plugin binary .* accessible in your PATH`), @@ -51,16 +90,17 @@ var vmProblems = map[string]match{ Advice: "The KVM driver is unable to resurrect this old VM. Please run `minikube delete` to delete it and try again.", Issues: []int{3901, 3566, 3434}, }, + "KVM2_NETWORK_DEFINE_XML": { + Regexp: re(`not supported by the connection driver: virNetworkDefineXML`), + Advice: "Rebuild libvirt with virt-network support", + URL: "https://forums.gentoo.org/viewtopic-t-981692-start-0.html", + Issues: []int{4195}, + }, "VM_DOES_NOT_EXIST": { Regexp: re(`Error getting state for host: machine does not exist`), Advice: "Your system no longer knows about the VM previously created by minikube. Run 'minikube delete' to reset your local state.", Issues: []int{3864}, }, - "VM_IP_NOT_FOUND": { - Regexp: re(`Error getting ssh host name for driver: IP not found`), - Advice: "The minikube VM is offline. Please run 'minikube start' to start it again.", - Issues: []int{3849, 3648}, - }, "VM_BOOT_FAILED_HYPERV_ENABLED": { Regexp: re(`VirtualBox won't boot a 64bits VM when Hyper-V is activated`), Advice: "Disable Hyper-V when you want to run VirtualBox to boot the VM", @@ -156,3 +196,17 @@ var osProblems = map[string]match{ Issues: []int{1574}, }, } + +// stateProblems are issues relating to local state +var stateProblems = map[string]match{ + "MACHINE_DOES_NOT_EXST": { + Regexp: re(`Error getting state for host: machine does not exist`), + Advice: "Run 'minikube delete' to delete the stale VM", + Issues: []int{3864}, + }, + "IP_NOT_FOUND": { + Regexp: re(`Error getting ssh host name for driver: IP not found`), + Advice: "The minikube VM is offline. Please run 'minikube start' to start it again.", + Issues: []int{3849, 3648}, + }, +} diff --git a/pkg/minikube/problem/problem.go b/pkg/minikube/problem/problem.go index e5184341f8ab..446e16e940f5 100644 --- a/pkg/minikube/problem/problem.go +++ b/pkg/minikube/problem/problem.go @@ -27,10 +27,15 @@ const issueBase = "https://github.com/kubernetes/minikube/issues" // Problem represents a known problem in minikube. type Problem struct { - ID string - Err error + // ID is an arbitrary unique and stable string describing this issue + ID string + // Err is the original error + Err error + // Advice is actionable text that the user should follow Advice string - URL string + // URL is a reference URL for more information + URL string + // Issues are a list of related issues to this problem Issues []int } @@ -40,6 +45,8 @@ type match struct { Advice string URL string Issues []int + // GOOS is what platforms this problem may be specific to, when disambiguation is necessary. + GOOS string } // Display problem metadata to the console @@ -62,16 +69,20 @@ func (p *Problem) Display() { } } -// FromError returns a known problem from an error. -func FromError(err error) *Problem { +// FromError returns a known problem from an error on an OS +func FromError(err error, os string) *Problem { maps := []map[string]match{ osProblems, vmProblems, netProblems, deployProblems, + stateProblems, } for _, m := range maps { for k, v := range m { + if v.GOOS != "" && v.GOOS != os { + continue + } if v.Regexp.MatchString(err.Error()) { return &Problem{ Err: err, diff --git a/pkg/minikube/problem/problem_test.go b/pkg/minikube/problem/problem_test.go new file mode 100644 index 000000000000..85738ffbdb5f --- /dev/null +++ b/pkg/minikube/problem/problem_test.go @@ -0,0 +1,66 @@ +/* +Copyright 2019 The Kubernetes Authors All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package problem + +import ( + "fmt" + "testing" +) + +func TestFromError(t *testing.T) { + var tests = []struct { + issue int + os string + want string + err string + }{ + {0, "", "", "this is just a lame error message with no matches."}, + {3614, "", "VBOX_HOST_ADAPTER", "Error starting host: Error starting stopped host: Error setting up host only network on machine start: The host-only adapter we just created is not visible. This is a well known VirtualBox bug. You might want to uninstall it and reinstall at least version 5.0.12 that is is supposed to fix this issue"}, + {3784, "", "VBOX_NOT_FOUND", "create: precreate: VBoxManage not found. Make sure VirtualBox is installed and VBoxManage is in the path"}, + {3849, "", "IP_NOT_FOUND", "bootstrapper: Error creating new ssh host from driver: Error getting ssh host name for driver: IP not found"}, + {3859, "windows", "VBOX_HARDENING", `Unable to start VM: create: creating: Unable to start the VM: C:\Program Files\Oracle\VirtualBox\VBoxManage.exe startvm minikube --type headless failed: +VBoxManage.exe: error: The virtual machine 'minikube' has terminated unexpectedly during startup with exit code -1073741819 (0xc0000005). More details may be available in 'C:\Users\pabitra_b.minikube\machines\minikube\minikube\Logs\VBoxHardening.log' +VBoxManage.exe: error: Details: code E_FAIL (0x80004005), component MachineWrap, interface IMachine`}, + {3922, "", "ISO_DOWNLOAD_FAILED", `unable to cache ISO: https://storage.googleapis.com/minikube/iso/minikube-v0.35.0.iso: failed to download: failed to download to temp file: download failed: 5 error(s) occurred: +* Temporary download error: Get https://storage.googleapis.com/minikube/iso/minikube-v0.35.0.iso: dial tcp 216.58.207.144:443: connectex: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.`}, + {4107, "darwin", "VBOX_BLOCKED", "Result Code: NS_ERROR_FAILURE (0x80004005)"}, + } + for _, tc := range tests { + t.Run(tc.want, func(t *testing.T) { + got := FromError(fmt.Errorf(tc.err), tc.os) + if got == nil { + if tc.want != "" { + t.Errorf("FromError(%q)=nil, want %s", tc.err, tc.want) + } + return + } + if got.ID != tc.want { + t.Errorf("FromError(%q)=%s, want %s", tc.err, got.ID, tc.want) + } + + found := false + for _, i := range got.Issues { + if i == tc.issue { + found = true + } + } + if !found { + t.Errorf("Issue %d is not listed in %+v", tc.issue, got.Issues) + } + }) + } +}