Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weโ€™ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UI: Add log file to GitHub issue output #11158

Merged
merged 12 commits into from
Apr 24, 2021
2 changes: 1 addition & 1 deletion pkg/addons/addons.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ https://github.com/kubernetes/minikube/issues/7332`, out.V{"driver_name": cc.Dri
return errors.Wrap(err, "registry port")
}
if enable {
out.Boxed(style.Tip, `Registry addon with {{.driver}} driver uses port {{.port}} please use that instead of default port 5000`, out.V{"driver": cc.Driver, "port": port})
out.Boxed(`Registry addon with {{.driver}} driver uses port {{.port}} please use that instead of default port 5000`, out.V{"driver": cc.Driver, "port": port})
}
out.Styled(style.Documentation, `For more information see: https://minikube.sigs.k8s.io/docs/drivers/{{.driver}}`, out.V{"driver": cc.Driver})
}
Expand Down
68 changes: 57 additions & 11 deletions pkg/minikube/out/out.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ import (
"html"
"html/template"
"io"
"io/ioutil"
"os"
"path/filepath"
"strconv"
"strings"
"time"
Expand All @@ -33,6 +35,7 @@ import (
isatty "github.com/mattn/go-isatty"

"k8s.io/klog/v2"
"k8s.io/minikube/pkg/minikube/localpath"
"k8s.io/minikube/pkg/minikube/out/register"
"k8s.io/minikube/pkg/minikube/style"
"k8s.io/minikube/pkg/minikube/translate"
Expand Down Expand Up @@ -111,17 +114,14 @@ func Styled(st style.Enum, format string, a ...V) {
}

// Boxed writes a stylized and templated message in a box to stdout
func Boxed(st style.Enum, format string, a ...V) {
func Boxed(format string, a ...V) {
str := Sprintf(style.None, format, a...)
str = strings.TrimSpace(str)
box := box.New(box.Config{Type: "Round"})
box := box.New(box.Config{Py: 1, Px: 4, Type: "Round"})
if useColor {
box.Config.Color = "Red"
}
txt := strings.Split(box.String("", str), "\n")
Styled(style.Indent, txt[0])
Styled(st, txt[1])
Styled(style.Indent, txt[2])
box.Println("", str)
}

// Sprintf is used for returning the string (doesn't write anything)
Expand Down Expand Up @@ -333,7 +333,7 @@ func wantsColor(w fdWriter) bool {

// LogEntries outputs an error along with any important log entries.
func LogEntries(msg string, err error, entries map[string][]string) {
DisplayError(msg, err)
displayError(msg, err)

for name, lines := range entries {
Step(style.Failure, "Problems detected in {{.entry}}:", V{"entry": name})
Expand All @@ -346,8 +346,8 @@ func LogEntries(msg string, err error, entries map[string][]string) {
}
}

// DisplayError prints the error and displays the standard minikube error messaging
func DisplayError(msg string, err error) {
// displayError prints the error and displays the standard minikube error messaging
func displayError(msg string, err error) {
klog.Warningf(fmt.Sprintf("%s: %v", msg, err))
if JSON {
FatalT("{{.msg}}: {{.err}}", V{"msg": translate.T(msg), "err": err})
Expand All @@ -357,8 +357,54 @@ func DisplayError(msg string, err error) {
ErrT(style.Empty, "")
FatalT("{{.msg}}: {{.err}}", V{"msg": translate.T(msg), "err": err})
ErrT(style.Empty, "")
ErrT(style.Sad, "minikube is exiting due to an error. If the above message is not useful, open an issue:")
ErrT(style.URL, "https://github.com/kubernetes/minikube/issues/new/choose")
displayGitHubIssueMessage()
}

func latestLogFilePath() (string, error) {
if len(os.Args) < 2 {
return "", fmt.Errorf("unable to detect command")
}
cmd := os.Args[1]
if cmd == "start" {
return localpath.LastStartLog(), nil
}

tmpdir := os.TempDir()
files, err := ioutil.ReadDir(tmpdir)
if err != nil {
return "", fmt.Errorf("failed to get list of files in tempdir: %v", err)
}
var lastModName string
var lastModTime time.Time
for _, file := range files {
if !strings.Contains(file.Name(), "minikube_") {
continue
}
if !lastModTime.IsZero() && lastModTime.After(file.ModTime()) {
continue
}
lastModName = file.Name()
lastModTime = file.ModTime()
}
fullPath := filepath.Join(tmpdir, lastModName)

return fullPath, nil
}

func displayGitHubIssueMessage() {
logPath, err := latestLogFilePath()
if err != nil {
klog.Warningf("failed to diplay GitHub issue message: %v", err)
}

msg := `If the above advice does not help, please let us know:
https://github.com/kubernetes/minikube/issues/new/choose

Please attach the following file to the GitHub issue:
- `
msg += logPath

Boxed(msg)
}

// applyTmpl applies formatting
Expand Down
3 changes: 1 addition & 2 deletions pkg/minikube/out/out_reason.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,7 @@ func displayText(k reason.Kind, format string, a ...V) {

if k.NewIssueLink {
ErrT(style.Empty, "")
ErrT(style.Sad, "If the above advice does not help, please let us know: ")
ErrT(style.URL, "https://github.com/kubernetes/minikube/issues/new/choose")
displayGitHubIssueMessage()
}
Ln("")
}
48 changes: 48 additions & 0 deletions pkg/minikube/out/out_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@ package out
import (
"fmt"
"os"
"path/filepath"
"strconv"
"testing"

"k8s.io/minikube/pkg/minikube/localpath"
"k8s.io/minikube/pkg/minikube/style"
"k8s.io/minikube/pkg/minikube/tests"
"k8s.io/minikube/pkg/minikube/translate"
Expand Down Expand Up @@ -114,3 +116,49 @@ func TestErr(t *testing.T) {
t.Errorf("Err() = %q, want %q", got, want)
}
}

func createLogFile() (string, error) {
td := os.TempDir()
name := filepath.Join(td, "minikube_test_test_test.log")
f, err := os.Create(name)
if err != nil {
return "", fmt.Errorf("failed to create log file: %v", err)
}

return f.Name(), nil
}

func TestLatestLogPath(t *testing.T) {
filename, err := createLogFile()
if err != nil {
t.Fatal(err)
}
defer os.Remove(filename)

testCases := []struct {
args []string
want string
}{
{
[]string{"minikube", "start"},
localpath.LastStartLog(),
},
{
[]string{"minikube", "status"},
filename,
},
}

for _, tt := range testCases {
oldArgs := os.Args
defer func() { os.Args = oldArgs }()
os.Args = tt.args
got, err := latestLogFilePath()
if err != nil {
t.Fatalf("os.Args = %s; latestLogFilePath() failed with error = %v", tt.args, err)
}
if got != tt.want {
t.Errorf("os.Args = %s; latestLogFilePath() = %q; wanted %q", tt.args, got, tt.want)
}
}
}