/
exit.go
101 lines (86 loc) · 3.67 KB
/
exit.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
/*
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 exit contains functions useful for exiting gracefully.
package exit
import (
"fmt"
"os"
"strings"
"github.com/golang/glog"
"github.com/pkg/errors"
"k8s.io/minikube/pkg/minikube/console"
)
// Exit codes based on sysexits(3)
const (
Failure = 1 // Failure represents a general failure code
BadUsage = 64 // Usage represents an incorrect command line
Data = 65 // Data represents incorrect data supplied by the user
NoInput = 66 // NoInput represents that the input file did not exist or was not readable
Unavailable = 69 // Unavailable represents when a service was unavailable
Software = 70 // Software represents an internal software error.
IO = 74 // IO represents an I/O error
Config = 78 // Config represents an unconfigured or misconfigured state
Permissions = 77 // Permissions represents a permissions error
// MaxProblems controls the number of problems to show for each source
MaxProblems = 3
)
// Usage outputs a usage error and exits with error code 64
func Usage(format string, a ...interface{}) {
console.ErrStyle("usage", format, a...)
os.Exit(BadUsage)
}
// WithCode outputs a fatal error message and exits with a supplied error code.
func WithCode(code int, format string, a ...interface{}) {
// use Warning because Error will display a duplicate message to stderr
glog.Warningf(format, a...)
console.Fatal(format, a...)
os.Exit(code)
}
// WithError outputs an error and exits.
func WithError(msg string, err error) {
displayError(msg, err)
// Here is where we would insert code to optionally upload a stack trace.
// We can be smarter about guessing exit codes, but EX_SOFTWARE should suffice.
os.Exit(Software)
}
// WithProblems outputs an error along with any autodetected problems, and exits.
func WithProblems(msg string, err error, problems map[string][]string) {
displayError(msg, err)
for name, lines := range problems {
console.OutStyle("failure", "Problems detected in %q:", name)
if len(lines) > MaxProblems {
lines = lines[:MaxProblems]
}
for _, l := range lines {
console.OutStyle("log-entry", l)
}
}
os.Exit(Software)
}
func displayError(msg string, err error) {
// use Warning because Error will display a duplicate message to stderr
glog.Warningf(fmt.Sprintf("%s: %v", msg, err))
console.Fatal(msg+": %v", err)
console.Err("\n")
// unfortunately Cause only supports one level of actual error wrapping
cause := errors.Cause(err)
text := cause.Error()
if strings.Contains(text, "VBoxManage not found. Make sure VirtualBox is installed and VBoxManage is in the path") ||
strings.Contains(text, "Driver \"kvm2\" not found. Do you have the plugin binary \"docker-machine-driver-kvm2\" accessible in your PATH?") {
console.ErrStyle("usage", "Make sure to install all necessary requirements, according to the documentation:")
console.ErrStyle("url", "https://kubernetes.io/docs/tasks/tools/install-minikube/")
} else {
console.ErrStyle("sad", "Sorry that minikube crashed. If this was unexpected, we would love to hear from you:")
console.ErrStyle("url", "https://github.com/kubernetes/minikube/issues/new")
}
}