From c9a5152e2178700b9baf0f5be44967a21628c8f9 Mon Sep 17 00:00:00 2001 From: Matt Rickard Date: Tue, 21 Mar 2017 09:36:45 -0700 Subject: [PATCH] Add -f --folow option to minikube logs Allows tailing of the logs --- cmd/minikube/cmd/logs.go | 7 +++++- docs/bash-completion | 3 +++ docs/minikube_logs.md | 6 +++++ pkg/minikube/cluster/cluster.go | 18 ++++++++++++++- pkg/minikube/cluster/cluster_test.go | 30 ++++++++++++++++++++---- pkg/minikube/cluster/commands.go | 34 ++++++++++++++++++++++++---- 6 files changed, 88 insertions(+), 10 deletions(-) diff --git a/cmd/minikube/cmd/logs.go b/cmd/minikube/cmd/logs.go index 73cbfede89..4345ddaaa7 100644 --- a/cmd/minikube/cmd/logs.go +++ b/cmd/minikube/cmd/logs.go @@ -27,6 +27,10 @@ import ( "k8s.io/minikube/pkg/minikube/machine" ) +var ( + follow bool +) + // logsCmd represents the logs command var logsCmd = &cobra.Command{ Use: "logs", @@ -39,7 +43,7 @@ var logsCmd = &cobra.Command{ os.Exit(1) } defer api.Close() - s, err := cluster.GetHostLogs(api) + s, err := cluster.GetHostLogs(api, follow) if err != nil { log.Println("Error getting machine logs:", err) cmdUtil.MaybeReportErrorAndExit(err) @@ -49,5 +53,6 @@ var logsCmd = &cobra.Command{ } func init() { + logsCmd.Flags().BoolVarP(&follow, "follow", "f", false, "Show only the most recent journal entries, and continuously print new entries as they are appended to the journal.") RootCmd.AddCommand(logsCmd) } diff --git a/docs/bash-completion b/docs/bash-completion index 3d91fd3e11..fc1c0017b0 100644 --- a/docs/bash-completion +++ b/docs/bash-completion @@ -706,6 +706,9 @@ _minikube_logs() flags_with_completion=() flags_completion=() + flags+=("--follow") + flags+=("-f") + local_nonpersistent_flags+=("--follow") flags+=("--alsologtostderr") flags+=("--log_backtrace_at=") flags+=("--log_dir=") diff --git a/docs/minikube_logs.md b/docs/minikube_logs.md index 30597e110a..affd1b6ce5 100644 --- a/docs/minikube_logs.md +++ b/docs/minikube_logs.md @@ -11,6 +11,12 @@ Gets the logs of the running localkube instance, used for debugging minikube, no minikube logs ``` +### Options + +``` + -f, --follow Show only the most recent journal entries, and continuously print new entries as they are appended to the journal. +``` + ### Options inherited from parent commands ``` diff --git a/pkg/minikube/cluster/cluster.go b/pkg/minikube/cluster/cluster.go index 970e04afe5..d9d097add7 100644 --- a/pkg/minikube/cluster/cluster.go +++ b/pkg/minikube/cluster/cluster.go @@ -369,11 +369,27 @@ func GetHostDockerEnv(api libmachine.API) (map[string]string, error) { } // GetHostLogs gets the localkube logs of the host VM. -func GetHostLogs(api libmachine.API) (string, error) { +// If follow is specified, it will tail the logs +func GetHostLogs(api libmachine.API, follow bool) (string, error) { h, err := CheckIfApiExistsAndLoad(api) if err != nil { return "", errors.Wrap(err, "Error checking that api exists and loading it") } + logsCommand, err := GetLogsCommand(follow) + if err != nil { + return "", errors.Wrap(err, "Error getting logs command") + } + if follow { + c, err := h.CreateSSHClient() + if err != nil { + return "", errors.Wrap(err, "Error creating ssh client") + } + err = c.Shell(logsCommand) + if err != nil { + return "", errors.Wrap(err, "error ssh shell") + } + return "", err + } s, err := h.RunSSHCommand(logsCommand) if err != nil { return "", err diff --git a/pkg/minikube/cluster/cluster_test.go b/pkg/minikube/cluster/cluster_test.go index c30111d605..1c48f84a90 100644 --- a/pkg/minikube/cluster/cluster_test.go +++ b/pkg/minikube/cluster/cluster_test.go @@ -487,12 +487,34 @@ func TestHostGetLogs(t *testing.T) { } api.Hosts[constants.MachineName] = &host.Host{Driver: d} - if _, err := GetHostLogs(api); err != nil { - t.Fatalf("Error getting host logs: %s", err) + tests := []struct { + description string + follow bool + }{ + { + description: "logs", + follow: false, + }, + { + description: "logs -f", + follow: true, + }, } - if _, ok := s.Commands[logsCommand]; !ok { - t.Fatalf("Expected command not run: %s", logsCommand) + for _, test := range tests { + t.Run(test.description, func(t *testing.T) { + t.Parallel() + cmd, err := GetLogsCommand(test.follow) + if err != nil { + t.Errorf("Error getting the logs command: %s", err) + } + if _, err = GetHostLogs(api, test.follow); err != nil { + t.Errorf("Error getting host logs: %s", err) + } + if _, ok := s.Commands[cmd]; !ok { + t.Errorf("Expected command to run but did not: %s", cmd) + } + }) } } diff --git a/pkg/minikube/cluster/commands.go b/pkg/minikube/cluster/commands.go index b05b486397..be59f7243c 100644 --- a/pkg/minikube/cluster/commands.go +++ b/pkg/minikube/cluster/commands.go @@ -180,13 +180,39 @@ func GenLocalkubeStartCmd(kubernetesConfig KubernetesConfig) (string, error) { return buf.String(), nil } -var logsCommand = fmt.Sprintf(` +const logsTemplate = ` if which systemctl 2>&1 1>/dev/null; then - sudo journalctl -u localkube + sudo journalctl {{.Flags}} -u localkube else - tail -n +1 %s %s + tail -n +1 {{.Flags}} {{.RemoteLocalkubeErrPath}} {{.RemoteLocalkubeOutPath}} %s fi -`, constants.RemoteLocalKubeErrPath, constants.RemoteLocalKubeOutPath) +` + +func GetLogsCommand(follow bool) (string, error) { + t, err := template.New("logsTemplate").Parse(logsTemplate) + if err != nil { + return "", err + } + var flags []string + if follow { + flags = append(flags, "-f") + } + + buf := bytes.Buffer{} + data := struct { + RemoteLocalkubeErrPath string + RemoteLocalkubeOutPath string + Flags string + }{ + RemoteLocalkubeErrPath: constants.RemoteLocalKubeErrPath, + RemoteLocalkubeOutPath: constants.RemoteLocalKubeOutPath, + Flags: strings.Join(flags, " "), + } + if err := t.Execute(&buf, data); err != nil { + return "", err + } + return buf.String(), nil +} var localkubeStatusCommand = fmt.Sprintf(` if which systemctl 2>&1 1>/dev/null; then