From 1b2076122e305f1523e1eb0b874160877a012863 Mon Sep 17 00:00:00 2001 From: Tharun Date: Fri, 27 Nov 2020 23:55:31 +0530 Subject: [PATCH 01/12] feat(minikube) display scheduledstop status in minikube status Signed-off-by: Tharun --- cmd/minikube/cmd/status.go | 55 +++++++++++++++++++++++++++ cmd/minikube/cmd/status_test.go | 67 +++++++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+) diff --git a/cmd/minikube/cmd/status.go b/cmd/minikube/cmd/status.go index 11950ee7d0..e35b2b4685 100644 --- a/cmd/minikube/cmd/status.go +++ b/cmd/minikube/cmd/status.go @@ -170,6 +170,12 @@ type BaseState struct { StepDetail string `json:",omitempty"` } +// ScheduledStopStatus holds string representation of scheduledStopDuration +type ScheduledStopStatus struct { + InitiatedTime string `json:",omitempty"` + ScheduledTime string `json:",omitempty"` +} + const ( minikubeNotRunningStatusFlag = 1 << 0 clusterNotRunningStatusFlag = 1 << 1 @@ -187,6 +193,12 @@ type: Worker host: {{.Host}} kubelet: {{.Kubelet}} +` + + scheduledStopStatusFormat = `type: ScheduledDuration +initiatedTime: {{.InitiatedTime}} +scheduledTime: {{.ScheduledTime}} + ` ) @@ -256,6 +268,11 @@ func writeStatusesAtInterval(duration time.Duration, api libmachine.API, cc *con exit.Error(reason.InternalStatusText, "status text failure", err) } } + if cc.ScheduledStop != nil { + if err := scheduledStopStatusText(cc.ScheduledStop, os.Stdout); err != nil { + exit.Error(reason.InternalStatusText, "status text failure", err) + } + } case "json": // Layout is currently only supported for JSON mode if layout == "cluster" { @@ -267,6 +284,11 @@ func writeStatusesAtInterval(duration time.Duration, api libmachine.API, cc *con exit.Error(reason.InternalStatusJSON, "status json failure", err) } } + if cc.ScheduledStop != nil { + if err := scheduledStopStatusJSON(cc.ScheduledStop, os.Stdout); err != nil { + exit.Error(reason.InternalStatusJSON, "scheduledstop status json failure", err) + } + } default: exit.Message(reason.Usage, fmt.Sprintf("invalid output format: %s. Valid values: 'text', 'json'", output)) } @@ -444,6 +466,39 @@ func statusJSON(st []*Status, w io.Writer) error { return err } +func scheduledStopStatusText(sd *config.ScheduledStopConfig, w io.Writer) error { + var scheduledStopStatus ScheduledStopStatus + if sd.InitiationTime == 0 { + scheduledStopStatus.InitiatedTime = "-" + } else { + scheduledStopStatus.InitiatedTime = time.Unix(sd.InitiationTime, 0).String() + } + if sd.Duration == 0 { + scheduledStopStatus.ScheduledTime = "-" + } else { + stopAt := time.Now().Add(sd.Duration).Unix() + scheduledStopStatus.ScheduledTime = time.Unix(stopAt, 0).String() + } + tmpl, err := template.New("scheduled-stop-status").Parse(scheduledStopStatusFormat) + if err != nil { + return err + } + if err := tmpl.Execute(w, scheduledStopStatus); err != nil { + return err + } + return nil +} + +func scheduledStopStatusJSON(sd *config.ScheduledStopConfig, w io.Writer) error { + var js []byte + js, err := json.Marshal(sd) + if err != nil { + return err + } + _, err = w.Write(js) + return err +} + // readEventLog reads cloudevent logs from $MINIKUBE_HOME/profiles//events.json func readEventLog(name string) ([]cloudevents.Event, time.Time, error) { path := localpath.EventLog(name) diff --git a/cmd/minikube/cmd/status_test.go b/cmd/minikube/cmd/status_test.go index 8bae781037..dc3d9b6e65 100644 --- a/cmd/minikube/cmd/status_test.go +++ b/cmd/minikube/cmd/status_test.go @@ -20,6 +20,9 @@ import ( "bytes" "encoding/json" "testing" + "time" + + "k8s.io/minikube/pkg/minikube/config" ) func TestExitCode(t *testing.T) { @@ -105,3 +108,67 @@ func TestStatusJSON(t *testing.T) { }) } } + +func TestScheduledStopStatusText(t *testing.T) { + now := time.Now().Unix() + initiationTime := time.Unix(now, 0).String() + + stopAt := time.Now().Add(time.Minute * 10).Unix() + scheduledTime := time.Unix(stopAt, 0).String() + var tests = []struct { + name string + state *config.ScheduledStopConfig + want string + }{ + { + name: "valid", + state: &config.ScheduledStopConfig{InitiationTime: now, Duration: time.Minute * 10}, + want: "type: ScheduledDuration\ninitiatedTime: " + initiationTime + "\nscheduledTime: " + scheduledTime + "\n\n", + }, + { + name: "missing", + state: &config.ScheduledStopConfig{}, + want: "type: ScheduledDuration\ninitiatedTime: -\nscheduledTime: -\n\n", + }, + } + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + var b bytes.Buffer + err := scheduledStopStatusText(tc.state, &b) + if err != nil { + t.Errorf("text(%+v) error: %v", tc.state, err) + } + + got := b.String() + if got != tc.want { + t.Errorf("text(%+v) = %q, want: %q", tc.state, got, tc.want) + } + }) + } +} + +func TestScheduledStopStatusJSON(t *testing.T) { + var tests = []struct { + name string + state *config.ScheduledStopConfig + }{ + { + name: "valid", + state: &config.ScheduledStopConfig{InitiationTime: time.Now().Unix(), Duration: time.Minute * 5}, + }, + } + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + var b bytes.Buffer + err := scheduledStopStatusJSON(tc.state, &b) + if err != nil { + t.Errorf("json(%+v) error: %v", tc.state, err) + } + + st := &Status{} + if err := json.Unmarshal(b.Bytes(), st); err != nil { + t.Errorf("json(%+v) unmarshal error: %v", tc.state, err) + } + }) + } +} From 81e27dd7b42c1d953f5628ce2a1f483fcbddd962 Mon Sep 17 00:00:00 2001 From: Tharun Date: Wed, 2 Dec 2020 16:50:02 +0530 Subject: [PATCH 02/12] fixed review feedbacks Signed-off-by: Tharun --- cmd/minikube/cmd/status.go | 65 +++---------------- cmd/minikube/cmd/status_test.go | 85 +++---------------------- site/content/en/docs/commands/status.md | 2 +- 3 files changed, 19 insertions(+), 133 deletions(-) diff --git a/cmd/minikube/cmd/status.go b/cmd/minikube/cmd/status.go index e35b2b4685..c985c72157 100644 --- a/cmd/minikube/cmd/status.go +++ b/cmd/minikube/cmd/status.go @@ -135,6 +135,7 @@ type Status struct { APIServer string Kubeconfig string Worker bool + TimeToStop string } // ClusterState holds a cluster state representation @@ -170,12 +171,6 @@ type BaseState struct { StepDetail string `json:",omitempty"` } -// ScheduledStopStatus holds string representation of scheduledStopDuration -type ScheduledStopStatus struct { - InitiatedTime string `json:",omitempty"` - ScheduledTime string `json:",omitempty"` -} - const ( minikubeNotRunningStatusFlag = 1 << 0 clusterNotRunningStatusFlag = 1 << 1 @@ -186,6 +181,7 @@ host: {{.Host}} kubelet: {{.Kubelet}} apiserver: {{.APIServer}} kubeconfig: {{.Kubeconfig}} +timeToStop: {{.TimeToStop}} ` workerStatusFormat = `{{.Name}} @@ -193,12 +189,6 @@ type: Worker host: {{.Host}} kubelet: {{.Kubelet}} -` - - scheduledStopStatusFormat = `type: ScheduledDuration -initiatedTime: {{.InitiatedTime}} -scheduledTime: {{.ScheduledTime}} - ` ) @@ -268,11 +258,6 @@ func writeStatusesAtInterval(duration time.Duration, api libmachine.API, cc *con exit.Error(reason.InternalStatusText, "status text failure", err) } } - if cc.ScheduledStop != nil { - if err := scheduledStopStatusText(cc.ScheduledStop, os.Stdout); err != nil { - exit.Error(reason.InternalStatusText, "status text failure", err) - } - } case "json": // Layout is currently only supported for JSON mode if layout == "cluster" { @@ -284,11 +269,6 @@ func writeStatusesAtInterval(duration time.Duration, api libmachine.API, cc *con exit.Error(reason.InternalStatusJSON, "status json failure", err) } } - if cc.ScheduledStop != nil { - if err := scheduledStopStatusJSON(cc.ScheduledStop, os.Stdout); err != nil { - exit.Error(reason.InternalStatusJSON, "scheduledstop status json failure", err) - } - } default: exit.Message(reason.Usage, fmt.Sprintf("invalid output format: %s. Valid values: 'text', 'json'", output)) } @@ -329,6 +309,7 @@ func nodeStatus(api libmachine.API, cc config.ClusterConfig, n config.Node) (*St Kubelet: Nonexistent, Kubeconfig: Nonexistent, Worker: !controlPlane, + TimeToStop: Nonexistent, } hs, err := machine.Status(api, name) @@ -388,7 +369,12 @@ func nodeStatus(api libmachine.API, cc config.ClusterConfig, n config.Node) (*St stk := kverify.ServiceStatus(cr, "kubelet") st.Kubelet = stk.String() - + if cc.ScheduledStop != nil { + initiationTime := time.Unix(cc.ScheduledStop.InitiationTime, 0) + st.TimeToStop = time.Until(initiationTime.Add(cc.ScheduledStop.Duration)).String() + } else { + st.TimeToStop = Irrelevant + } // Early exit for worker nodes if !controlPlane { return st, nil @@ -466,39 +452,6 @@ func statusJSON(st []*Status, w io.Writer) error { return err } -func scheduledStopStatusText(sd *config.ScheduledStopConfig, w io.Writer) error { - var scheduledStopStatus ScheduledStopStatus - if sd.InitiationTime == 0 { - scheduledStopStatus.InitiatedTime = "-" - } else { - scheduledStopStatus.InitiatedTime = time.Unix(sd.InitiationTime, 0).String() - } - if sd.Duration == 0 { - scheduledStopStatus.ScheduledTime = "-" - } else { - stopAt := time.Now().Add(sd.Duration).Unix() - scheduledStopStatus.ScheduledTime = time.Unix(stopAt, 0).String() - } - tmpl, err := template.New("scheduled-stop-status").Parse(scheduledStopStatusFormat) - if err != nil { - return err - } - if err := tmpl.Execute(w, scheduledStopStatus); err != nil { - return err - } - return nil -} - -func scheduledStopStatusJSON(sd *config.ScheduledStopConfig, w io.Writer) error { - var js []byte - js, err := json.Marshal(sd) - if err != nil { - return err - } - _, err = w.Write(js) - return err -} - // readEventLog reads cloudevent logs from $MINIKUBE_HOME/profiles//events.json func readEventLog(name string) ([]cloudevents.Event, time.Time, error) { path := localpath.EventLog(name) diff --git a/cmd/minikube/cmd/status_test.go b/cmd/minikube/cmd/status_test.go index dc3d9b6e65..aa9f905c22 100644 --- a/cmd/minikube/cmd/status_test.go +++ b/cmd/minikube/cmd/status_test.go @@ -20,9 +20,6 @@ import ( "bytes" "encoding/json" "testing" - "time" - - "k8s.io/minikube/pkg/minikube/config" ) func TestExitCode(t *testing.T) { @@ -54,18 +51,18 @@ func TestStatusText(t *testing.T) { }{ { name: "ok", - state: &Status{Name: "minikube", Host: "Running", Kubelet: "Running", APIServer: "Running", Kubeconfig: Configured}, - want: "minikube\ntype: Control Plane\nhost: Running\nkubelet: Running\napiserver: Running\nkubeconfig: Configured\n\n", + state: &Status{Name: "minikube", Host: "Running", Kubelet: "Running", APIServer: "Running", Kubeconfig: Configured, TimeToStop: "10m"}, + want: "minikube\ntype: Control Plane\nhost: Running\nkubelet: Running\napiserver: Running\nkubeconfig: Configured\ntimeToStop: 10m\n\n", }, { name: "paused", - state: &Status{Name: "minikube", Host: "Running", Kubelet: "Stopped", APIServer: "Paused", Kubeconfig: Configured}, - want: "minikube\ntype: Control Plane\nhost: Running\nkubelet: Stopped\napiserver: Paused\nkubeconfig: Configured\n\n", + state: &Status{Name: "minikube", Host: "Running", Kubelet: "Stopped", APIServer: "Paused", Kubeconfig: Configured, TimeToStop: Nonexistent}, + want: "minikube\ntype: Control Plane\nhost: Running\nkubelet: Stopped\napiserver: Paused\nkubeconfig: Configured\ntimeToStop: Nonexistent\n\n", }, { name: "down", - state: &Status{Name: "minikube", Host: "Stopped", Kubelet: "Stopped", APIServer: "Stopped", Kubeconfig: Misconfigured}, - want: "minikube\ntype: Control Plane\nhost: Stopped\nkubelet: Stopped\napiserver: Stopped\nkubeconfig: Misconfigured\n\n\nWARNING: Your kubectl is pointing to stale minikube-vm.\nTo fix the kubectl context, run `minikube update-context`\n", + state: &Status{Name: "minikube", Host: "Stopped", Kubelet: "Stopped", APIServer: "Stopped", Kubeconfig: Misconfigured, TimeToStop: Nonexistent}, + want: "minikube\ntype: Control Plane\nhost: Stopped\nkubelet: Stopped\napiserver: Stopped\nkubeconfig: Misconfigured\ntimeToStop: Nonexistent\n\n\nWARNING: Your kubectl is pointing to stale minikube-vm.\nTo fix the kubectl context, run `minikube update-context`\n", }, } for _, tc := range tests { @@ -89,9 +86,9 @@ func TestStatusJSON(t *testing.T) { name string state *Status }{ - {"ok", &Status{Host: "Running", Kubelet: "Running", APIServer: "Running", Kubeconfig: Configured}}, - {"paused", &Status{Host: "Running", Kubelet: "Stopped", APIServer: "Paused", Kubeconfig: Configured}}, - {"down", &Status{Host: "Stopped", Kubelet: "Stopped", APIServer: "Stopped", Kubeconfig: Misconfigured}}, + {"ok", &Status{Host: "Running", Kubelet: "Running", APIServer: "Running", Kubeconfig: Configured, TimeToStop: "10m"}}, + {"paused", &Status{Host: "Running", Kubelet: "Stopped", APIServer: "Paused", Kubeconfig: Configured, TimeToStop: Nonexistent}}, + {"down", &Status{Host: "Stopped", Kubelet: "Stopped", APIServer: "Stopped", Kubeconfig: Misconfigured, TimeToStop: Nonexistent}}, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { @@ -108,67 +105,3 @@ func TestStatusJSON(t *testing.T) { }) } } - -func TestScheduledStopStatusText(t *testing.T) { - now := time.Now().Unix() - initiationTime := time.Unix(now, 0).String() - - stopAt := time.Now().Add(time.Minute * 10).Unix() - scheduledTime := time.Unix(stopAt, 0).String() - var tests = []struct { - name string - state *config.ScheduledStopConfig - want string - }{ - { - name: "valid", - state: &config.ScheduledStopConfig{InitiationTime: now, Duration: time.Minute * 10}, - want: "type: ScheduledDuration\ninitiatedTime: " + initiationTime + "\nscheduledTime: " + scheduledTime + "\n\n", - }, - { - name: "missing", - state: &config.ScheduledStopConfig{}, - want: "type: ScheduledDuration\ninitiatedTime: -\nscheduledTime: -\n\n", - }, - } - for _, tc := range tests { - t.Run(tc.name, func(t *testing.T) { - var b bytes.Buffer - err := scheduledStopStatusText(tc.state, &b) - if err != nil { - t.Errorf("text(%+v) error: %v", tc.state, err) - } - - got := b.String() - if got != tc.want { - t.Errorf("text(%+v) = %q, want: %q", tc.state, got, tc.want) - } - }) - } -} - -func TestScheduledStopStatusJSON(t *testing.T) { - var tests = []struct { - name string - state *config.ScheduledStopConfig - }{ - { - name: "valid", - state: &config.ScheduledStopConfig{InitiationTime: time.Now().Unix(), Duration: time.Minute * 5}, - }, - } - for _, tc := range tests { - t.Run(tc.name, func(t *testing.T) { - var b bytes.Buffer - err := scheduledStopStatusJSON(tc.state, &b) - if err != nil { - t.Errorf("json(%+v) error: %v", tc.state, err) - } - - st := &Status{} - if err := json.Unmarshal(b.Bytes(), st); err != nil { - t.Errorf("json(%+v) unmarshal error: %v", tc.state, err) - } - }) - } -} diff --git a/site/content/en/docs/commands/status.md b/site/content/en/docs/commands/status.md index f4902dab0b..e5c3c89e7d 100644 --- a/site/content/en/docs/commands/status.md +++ b/site/content/en/docs/commands/status.md @@ -23,7 +23,7 @@ minikube status [flags] ``` -f, --format string Go template format string for the status output. The format for Go templates can be found here: https://golang.org/pkg/text/template/ - For the list accessible variables for the template, see the struct values here: https://godoc.org/k8s.io/minikube/cmd/minikube/cmd#Status (default "{{.Name}}\ntype: Control Plane\nhost: {{.Host}}\nkubelet: {{.Kubelet}}\napiserver: {{.APIServer}}\nkubeconfig: {{.Kubeconfig}}\n\n") + For the list accessible variables for the template, see the struct values here: https://godoc.org/k8s.io/minikube/cmd/minikube/cmd#Status (default "{{.Name}}\ntype: Control Plane\nhost: {{.Host}}\nkubelet: {{.Kubelet}}\napiserver: {{.APIServer}}\nkubeconfig: {{.Kubeconfig}}\ntimeToStop: {{.TimeToStop}}\n\n") -l, --layout string output layout (EXPERIMENTAL, JSON only): 'nodes' or 'cluster' (default "nodes") -n, --node string The node to check status for. Defaults to control plane. Leave blank with default format for status on all nodes. -o, --output string minikube status --output OUTPUT. json, text (default "text") From 3f57033c60d37abe6380dfd22c083fcf742d530e Mon Sep 17 00:00:00 2001 From: Tharun Date: Fri, 4 Dec 2020 13:05:39 +0530 Subject: [PATCH 03/12] added timetostop status in cluster layout --- cmd/minikube/cmd/status.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/cmd/minikube/cmd/status.go b/cmd/minikube/cmd/status.go index c985c72157..2ce2f2064a 100644 --- a/cmd/minikube/cmd/status.go +++ b/cmd/minikube/cmd/status.go @@ -372,8 +372,6 @@ func nodeStatus(api libmachine.API, cc config.ClusterConfig, n config.Node) (*St if cc.ScheduledStop != nil { initiationTime := time.Unix(cc.ScheduledStop.InitiationTime, 0) st.TimeToStop = time.Until(initiationTime.Add(cc.ScheduledStop.Duration)).String() - } else { - st.TimeToStop = Irrelevant } // Early exit for worker nodes if !controlPlane { @@ -486,6 +484,11 @@ func clusterState(sts []*Status) ClusterState { statusName = sts[0].Host } sc := statusCode(statusName) + + timeToStopStatusCode := Configured + if sts[0].TimeToStop == Nonexistent { + timeToStopStatusCode = Nonexistent + } cs := ClusterState{ BinaryVersion: version.GetVersion(), @@ -498,6 +501,7 @@ func clusterState(sts []*Status) ClusterState { Components: map[string]BaseState{ "kubeconfig": {Name: "kubeconfig", StatusCode: statusCode(sts[0].Kubeconfig)}, + "timetostop": {Name: "timetostop", StatusCode: statusCode(timeToStopStatusCode)}, }, } From 35e2ce2dcfa147a6a161e72bb9478a5e1f2c0f39 Mon Sep 17 00:00:00 2001 From: Tharun Date: Fri, 4 Dec 2020 16:05:24 +0530 Subject: [PATCH 04/12] added check for timetostop status --- test/integration/scheduled_stop_test.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/integration/scheduled_stop_test.go b/test/integration/scheduled_stop_test.go index 508a385999..3de450e629 100644 --- a/test/integration/scheduled_stop_test.go +++ b/test/integration/scheduled_stop_test.go @@ -165,6 +165,10 @@ func ensureMinikubeStatus(ctx context.Context, t *testing.T, profile, wantStatus if got != wantStatus { return fmt.Errorf("expected post-stop host status to be -%q- but got *%q*", state.Stopped, got) } + got = Status(ctx, t, Target(), profile, "TimeToStop", profile) + if got != "Nonexistent" { + return fmt.Errorf("expected post-stop timetostop status to be -%q- but got *%q*", "Nonexistent", got) + } return nil } if err := retry.Expo(checkStatus, time.Second, time.Minute); err != nil { From 4ca4491124b95d83982236b80bfa6b8cf4b8c74d Mon Sep 17 00:00:00 2001 From: Tharun Date: Sat, 5 Dec 2020 14:23:34 +0530 Subject: [PATCH 05/12] fixed review feedbacks on clusterstate field and tests Signed-off-by: Tharun --- cmd/minikube/cmd/status.go | 8 +++----- test/integration/scheduled_stop_test.go | 17 +++++++++++++++++ 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/cmd/minikube/cmd/status.go b/cmd/minikube/cmd/status.go index 2ce2f2064a..bfcde0880b 100644 --- a/cmd/minikube/cmd/status.go +++ b/cmd/minikube/cmd/status.go @@ -143,6 +143,7 @@ type ClusterState struct { BaseState BinaryVersion string + TimeToStop string Components map[string]BaseState Nodes []NodeState } @@ -485,10 +486,6 @@ func clusterState(sts []*Status) ClusterState { } sc := statusCode(statusName) - timeToStopStatusCode := Configured - if sts[0].TimeToStop == Nonexistent { - timeToStopStatusCode = Nonexistent - } cs := ClusterState{ BinaryVersion: version.GetVersion(), @@ -499,9 +496,10 @@ func clusterState(sts []*Status) ClusterState { StatusDetail: codeDetails[sc], }, + TimeToStop: sts[0].TimeToStop, + Components: map[string]BaseState{ "kubeconfig": {Name: "kubeconfig", StatusCode: statusCode(sts[0].Kubeconfig)}, - "timetostop": {Name: "timetostop", StatusCode: statusCode(timeToStopStatusCode)}, }, } diff --git a/test/integration/scheduled_stop_test.go b/test/integration/scheduled_stop_test.go index 3de450e629..81ee9e9e30 100644 --- a/test/integration/scheduled_stop_test.go +++ b/test/integration/scheduled_stop_test.go @@ -52,6 +52,11 @@ func TestScheduledStopWindows(t *testing.T) { // schedule a stop for 5m from now stopMinikube(ctx, t, profile, []string{"--schedule", "5m"}) + scheduledStopMinikube(ctx, t, profile, "5m") + // sleep for 1 second + time.Sleep(time.Second) + // make sure timeToStop is present in status + checkTimetoStop(ctx, t, profile, "4m") // make sure the systemd service is running rr, err := Run(t, exec.CommandContext(ctx, Target(), []string{"ssh", "-p", profile, "--", "sudo", "systemctl", "show", constants.ScheduledStopSystemdService, "--no-page"}...)) if err != nil { @@ -84,6 +89,11 @@ func TestScheduledStopUnix(t *testing.T) { // schedule a stop for 5 min from now and make sure PID is created stopMinikube(ctx, t, profile, []string{"--schedule", "5m"}) + scheduledStopMinikube(ctx, t, profile, "5m") + // sleep for 1 second + time.Sleep(time.Second) + // make sure timeToStop is present in status + checkTimetoStop(ctx, t, profile, "4m") pid := checkPID(t, profile) if !processRunning(t, pid) { t.Fatalf("process %v is not running", pid) @@ -175,3 +185,10 @@ func ensureMinikubeStatus(ctx context.Context, t *testing.T, profile, wantStatus t.Fatalf("error %v", err) } } + +func checkTimetoStop(ctx context.Context, t *testing.T, profile string, currentTimeToStop string) { + got := Status(ctx, t, Target(), profile, "TimeToStop", profile) + if !strings.Contains(got, currentTimeToStop) { + t.Fatalf("expected timetostop status to be -%q- but got *%q*", currentTimeToStop, got) + } +} From c51a20401d14cd4b09d05a51cb8fff650eb41556 Mon Sep 17 00:00:00 2001 From: Tharun Date: Sat, 5 Dec 2020 14:49:56 +0530 Subject: [PATCH 06/12] updated scheduled_stop tests Signed-off-by: Tharun --- test/integration/scheduled_stop_test.go | 32 +++++++++---------------- 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/test/integration/scheduled_stop_test.go b/test/integration/scheduled_stop_test.go index 81ee9e9e30..e38ff1b28d 100644 --- a/test/integration/scheduled_stop_test.go +++ b/test/integration/scheduled_stop_test.go @@ -51,12 +51,10 @@ func TestScheduledStopWindows(t *testing.T) { // schedule a stop for 5m from now stopMinikube(ctx, t, profile, []string{"--schedule", "5m"}) - - scheduledStopMinikube(ctx, t, profile, "5m") // sleep for 1 second time.Sleep(time.Second) // make sure timeToStop is present in status - checkTimetoStop(ctx, t, profile, "4m") + ensureMinikubeStatus(ctx, t, profile, "TimeToStop", "4m") // make sure the systemd service is running rr, err := Run(t, exec.CommandContext(ctx, Target(), []string{"ssh", "-p", profile, "--", "sudo", "systemctl", "show", constants.ScheduledStopSystemdService, "--no-page"}...)) if err != nil { @@ -72,7 +70,9 @@ func TestScheduledStopWindows(t *testing.T) { // sleep for 5 seconds time.Sleep(5 * time.Second) // make sure minikube status is "Stopped" - ensureMinikubeStatus(ctx, t, profile, state.Stopped.String()) + ensureMinikubeStatus(ctx, t, profile, "Host", state.Stopped.String()) + // make sure minikube timtostop is "Nonexistent" + ensureMinikubeStatus(ctx, t, profile, "TimeToStop", "Nonexistent") } func TestScheduledStopUnix(t *testing.T) { @@ -89,11 +89,10 @@ func TestScheduledStopUnix(t *testing.T) { // schedule a stop for 5 min from now and make sure PID is created stopMinikube(ctx, t, profile, []string{"--schedule", "5m"}) - scheduledStopMinikube(ctx, t, profile, "5m") // sleep for 1 second time.Sleep(time.Second) // make sure timeToStop is present in status - checkTimetoStop(ctx, t, profile, "4m") + ensureMinikubeStatus(ctx, t, profile, "TimeToStop", "4m") pid := checkPID(t, profile) if !processRunning(t, pid) { t.Fatalf("process %v is not running", pid) @@ -110,14 +109,16 @@ func TestScheduledStopUnix(t *testing.T) { // sleep 12 just to be safe stopMinikube(ctx, t, profile, []string{"--cancel-scheduled"}) time.Sleep(12 * time.Second) - ensureMinikubeStatus(ctx, t, profile, state.Running.String()) + ensureMinikubeStatus(ctx, t, profile, "Host", state.Running.String()) // schedule another stop, make sure minikube status is "Stopped" stopMinikube(ctx, t, profile, []string{"--schedule", "5s"}) if processRunning(t, pid) { t.Fatalf("process %v running but should have been killed on reschedule of stop", pid) } - ensureMinikubeStatus(ctx, t, profile, state.Stopped.String()) + ensureMinikubeStatus(ctx, t, profile, "Host", state.Stopped.String()) + // make sure minikube timtostop is "Nonexistent" + ensureMinikubeStatus(ctx, t, profile, "TimeToStop", "Nonexistent") } func startMinikube(ctx context.Context, t *testing.T, profile string) { @@ -166,29 +167,18 @@ func processRunning(t *testing.T, pid string) bool { t.Log("signal error was: ", err) return err == nil } -func ensureMinikubeStatus(ctx context.Context, t *testing.T, profile, wantStatus string) { +func ensureMinikubeStatus(ctx context.Context, t *testing.T, profile, key string, wantStatus string) { // wait allotted time to make sure minikube status is "Stopped" checkStatus := func() error { ctx, cancel := context.WithDeadline(ctx, time.Now().Add(10*time.Second)) defer cancel() - got := Status(ctx, t, Target(), profile, "Host", profile) + got := Status(ctx, t, Target(), profile, key, profile) if got != wantStatus { return fmt.Errorf("expected post-stop host status to be -%q- but got *%q*", state.Stopped, got) } - got = Status(ctx, t, Target(), profile, "TimeToStop", profile) - if got != "Nonexistent" { - return fmt.Errorf("expected post-stop timetostop status to be -%q- but got *%q*", "Nonexistent", got) - } return nil } if err := retry.Expo(checkStatus, time.Second, time.Minute); err != nil { t.Fatalf("error %v", err) } } - -func checkTimetoStop(ctx context.Context, t *testing.T, profile string, currentTimeToStop string) { - got := Status(ctx, t, Target(), profile, "TimeToStop", profile) - if !strings.Contains(got, currentTimeToStop) { - t.Fatalf("expected timetostop status to be -%q- but got *%q*", currentTimeToStop, got) - } -} From 40cf0dab1c9c39bbf7f7a9e4efc40b104e9ff16f Mon Sep 17 00:00:00 2001 From: Tharun Date: Sat, 5 Dec 2020 15:50:24 +0530 Subject: [PATCH 07/12] refractored minikube status function Signed-off-by: Tharun --- test/integration/scheduled_stop_test.go | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/test/integration/scheduled_stop_test.go b/test/integration/scheduled_stop_test.go index e38ff1b28d..81998a0016 100644 --- a/test/integration/scheduled_stop_test.go +++ b/test/integration/scheduled_stop_test.go @@ -51,10 +51,8 @@ func TestScheduledStopWindows(t *testing.T) { // schedule a stop for 5m from now stopMinikube(ctx, t, profile, []string{"--schedule", "5m"}) - // sleep for 1 second - time.Sleep(time.Second) // make sure timeToStop is present in status - ensureMinikubeStatus(ctx, t, profile, "TimeToStop", "4m") + ensureMinikubeStatus(ctx, t, profile, "TimeToStop", "3m") // make sure the systemd service is running rr, err := Run(t, exec.CommandContext(ctx, Target(), []string{"ssh", "-p", profile, "--", "sudo", "systemctl", "show", constants.ScheduledStopSystemdService, "--no-page"}...)) if err != nil { @@ -89,10 +87,8 @@ func TestScheduledStopUnix(t *testing.T) { // schedule a stop for 5 min from now and make sure PID is created stopMinikube(ctx, t, profile, []string{"--schedule", "5m"}) - // sleep for 1 second - time.Sleep(time.Second) // make sure timeToStop is present in status - ensureMinikubeStatus(ctx, t, profile, "TimeToStop", "4m") + ensureMinikubeStatus(ctx, t, profile, "TimeToStop", "3m") pid := checkPID(t, profile) if !processRunning(t, pid) { t.Fatalf("process %v is not running", pid) @@ -173,8 +169,8 @@ func ensureMinikubeStatus(ctx context.Context, t *testing.T, profile, key string ctx, cancel := context.WithDeadline(ctx, time.Now().Add(10*time.Second)) defer cancel() got := Status(ctx, t, Target(), profile, key, profile) - if got != wantStatus { - return fmt.Errorf("expected post-stop host status to be -%q- but got *%q*", state.Stopped, got) + if !strings.Contains(got, wantStatus) { + return fmt.Errorf("expected post-stop %q status to be -%q- but got *%q*", key, wantStatus, got) } return nil } From c6e6f2dc93a4c045660840484a422875bb294abf Mon Sep 17 00:00:00 2001 From: Tharun Date: Tue, 8 Dec 2020 13:09:54 +0530 Subject: [PATCH 08/12] added function to check scheduledstop time comparison Signed-off-by: Tharun --- test/integration/scheduled_stop_test.go | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/test/integration/scheduled_stop_test.go b/test/integration/scheduled_stop_test.go index 81998a0016..f10c4e2d6b 100644 --- a/test/integration/scheduled_stop_test.go +++ b/test/integration/scheduled_stop_test.go @@ -52,7 +52,7 @@ func TestScheduledStopWindows(t *testing.T) { // schedule a stop for 5m from now stopMinikube(ctx, t, profile, []string{"--schedule", "5m"}) // make sure timeToStop is present in status - ensureMinikubeStatus(ctx, t, profile, "TimeToStop", "3m") + ensureMinikubeScheduledTime(ctx, t, profile, 5*time.Minute) // make sure the systemd service is running rr, err := Run(t, exec.CommandContext(ctx, Target(), []string{"ssh", "-p", profile, "--", "sudo", "systemctl", "show", constants.ScheduledStopSystemdService, "--no-page"}...)) if err != nil { @@ -88,7 +88,7 @@ func TestScheduledStopUnix(t *testing.T) { // schedule a stop for 5 min from now and make sure PID is created stopMinikube(ctx, t, profile, []string{"--schedule", "5m"}) // make sure timeToStop is present in status - ensureMinikubeStatus(ctx, t, profile, "TimeToStop", "3m") + ensureMinikubeScheduledTime(ctx, t, profile, 5*time.Minute) pid := checkPID(t, profile) if !processRunning(t, pid) { t.Fatalf("process %v is not running", pid) @@ -112,6 +112,8 @@ func TestScheduledStopUnix(t *testing.T) { if processRunning(t, pid) { t.Fatalf("process %v running but should have been killed on reschedule of stop", pid) } + + // make sure minikube status is "Stopped" ensureMinikubeStatus(ctx, t, profile, "Host", state.Stopped.String()) // make sure minikube timtostop is "Nonexistent" ensureMinikubeStatus(ctx, t, profile, "TimeToStop", "Nonexistent") @@ -164,12 +166,11 @@ func processRunning(t *testing.T, pid string) bool { return err == nil } func ensureMinikubeStatus(ctx context.Context, t *testing.T, profile, key string, wantStatus string) { - // wait allotted time to make sure minikube status is "Stopped" checkStatus := func() error { ctx, cancel := context.WithDeadline(ctx, time.Now().Add(10*time.Second)) defer cancel() got := Status(ctx, t, Target(), profile, key, profile) - if !strings.Contains(got, wantStatus) { + if got != wantStatus { return fmt.Errorf("expected post-stop %q status to be -%q- but got *%q*", key, wantStatus, got) } return nil @@ -178,3 +179,19 @@ func ensureMinikubeStatus(ctx context.Context, t *testing.T, profile, key string t.Fatalf("error %v", err) } } + +func ensureMinikubeScheduledTime(ctx context.Context, t *testing.T, profile string, givenTime time.Duration) { + checkTime := func() error { + ctx, cancel := context.WithDeadline(ctx, time.Now().Add(10*time.Second)) + defer cancel() + got := Status(ctx, t, Target(), profile, "TimeToStop", profile) + gotTime, _ := time.ParseDuration(got) + if gotTime < givenTime { + return nil + } + return fmt.Errorf("expected scheduled stop TimeToStop to be less than *%q* but got *%q*", givenTime, got) + } + if err := retry.Expo(checkTime, time.Second, time.Minute); err != nil { + t.Fatalf("error %v", err) + } +} From 0e85b1819aecdcfe39c1f4f9e3fdbb67961c57c0 Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Tue, 8 Dec 2020 13:49:17 -0800 Subject: [PATCH 09/12] bump kic base on head --- pkg/drivers/kic/types.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/drivers/kic/types.go b/pkg/drivers/kic/types.go index d38b979b05..2a8b06c215 100644 --- a/pkg/drivers/kic/types.go +++ b/pkg/drivers/kic/types.go @@ -24,9 +24,9 @@ import ( const ( // Version is the current version of kic - Version = "v0.0.15-snapshot2" + Version = "v0.0.15-snapshot3" // SHA of the kic base image - baseImageSHA = "0973e4bcdfef0dc8c5a581ecfcca5e36fa6a1cc8773e832ecfd31de3d2b6bf46" + baseImageSHA = "d6162757b2cb147e4afc5217372171518f15683f6c1a63f25f9121ff61ca654c" ) var ( From c6badf60a4435afc0cd34d6414c3a53c5d0c3b5f Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Tue, 8 Dec 2020 13:50:41 -0800 Subject: [PATCH 10/12] update docs --- site/content/en/docs/commands/start.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site/content/en/docs/commands/start.md b/site/content/en/docs/commands/start.md index d24e0f719e..df2ae1a176 100644 --- a/site/content/en/docs/commands/start.md +++ b/site/content/en/docs/commands/start.md @@ -26,7 +26,7 @@ minikube start [flags] --apiserver-names strings A set of apiserver names which are used in the generated certificate for kubernetes. This can be used if you want to make the apiserver available from outside the machine --apiserver-port int The apiserver listening port (default 8443) --auto-update-drivers If set, automatically updates drivers to the latest version. Defaults to true. (default true) - --base-image string The base image to use for docker/podman drivers. Intended for local development. (default "gcr.io/k8s-minikube/kicbase:v0.0.15-snapshot2@sha256:0973e4bcdfef0dc8c5a581ecfcca5e36fa6a1cc8773e832ecfd31de3d2b6bf46") + --base-image string The base image to use for docker/podman drivers. Intended for local development. (default "gcr.io/k8s-minikube/kicbase:v0.0.15-snapshot3@sha256:d6162757b2cb147e4afc5217372171518f15683f6c1a63f25f9121ff61ca654c") --cache-images If true, cache docker images for the current bootstrapper and load them into the machine. Always false with --driver=none. (default true) --cni string CNI plug-in to use. Valid options: auto, bridge, calico, cilium, flannel, kindnet, or path to a CNI manifest (default: auto) --container-runtime string The container runtime to be used (docker, cri-o, containerd). (default "docker") From c1486f3f65be62828b74348c190cafefe7df7c37 Mon Sep 17 00:00:00 2001 From: Sharif Elgamal Date: Tue, 8 Dec 2020 16:08:44 -0800 Subject: [PATCH 11/12] reduce hyperkit tests to functional --- hack/jenkins/common.sh | 16 ++++++++-------- hack/jenkins/osx_integration_tests_hyperkit.sh | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/hack/jenkins/common.sh b/hack/jenkins/common.sh index aebdb5cea0..16de6740fc 100755 --- a/hack/jenkins/common.sh +++ b/hack/jenkins/common.sh @@ -221,17 +221,17 @@ fi # clean up none drivers binding on 8443 - none_procs=$(sudo lsof -i :8443 | tail -n +2 | awk '{print $2}' || true) - if [[ "${none_procs}" != "" ]]; then - echo "Found stale api servers listening on 8443 processes to kill: " - for p in $none_procs - do +none_procs=$(sudo lsof -i :8443 | tail -n +2 | awk '{print $2}' || true) +if [[ "${none_procs}" != "" ]]; then + echo "Found stale api servers listening on 8443 processes to kill: " + for p in $none_procs + do echo "Kiling stale none driver: $p" sudo -E ps -f -p $p || true sudo -E kill $p || true sudo -E kill -9 $p || true - done - fi + done +fi function cleanup_stale_routes() { local show="netstat -rn -f inet" @@ -296,7 +296,7 @@ touch "${TEST_OUT}" ${SUDO_PREFIX}${E2E_BIN} \ -minikube-start-args="--driver=${VM_DRIVER} ${EXTRA_START_ARGS}" \ -test.timeout=70m -test.v \ - ${EXTRA_TEST_ARGS} \ + ${EXTRA_ARGS} \ -binary="${MINIKUBE_BIN}" 2>&1 | tee "${TEST_OUT}" result=${PIPESTATUS[0]} # capture the exit code of the first cmd in pipe. diff --git a/hack/jenkins/osx_integration_tests_hyperkit.sh b/hack/jenkins/osx_integration_tests_hyperkit.sh index 74eb7e8380..a52329b75a 100755 --- a/hack/jenkins/osx_integration_tests_hyperkit.sh +++ b/hack/jenkins/osx_integration_tests_hyperkit.sh @@ -29,7 +29,7 @@ set -e OS_ARCH="darwin-amd64" VM_DRIVER="hyperkit" JOB_NAME="HyperKit_macOS" -EXTRA_ARGS="--bootstrapper=kubeadm" +EXTRA_ARGS="-test.run TestFunctional" EXTRA_START_ARGS="" EXPECTED_DEFAULT_DRIVER="hyperkit" From aef091198a1da18f1226fbc06cce96abd41105a6 Mon Sep 17 00:00:00 2001 From: Sharif Elgamal Date: Tue, 8 Dec 2020 16:18:12 -0800 Subject: [PATCH 12/12] fix up screwy env vars --- hack/jenkins/common.sh | 4 ++-- hack/jenkins/linux_integration_tests_none.sh | 2 +- hack/jenkins/linux_integration_tests_podman.sh | 2 +- hack/jenkins/osx_integration_tests_hyperkit.sh | 3 +-- hack/jenkins/osx_integration_tests_virtualbox.sh | 2 +- 5 files changed, 6 insertions(+), 7 deletions(-) diff --git a/hack/jenkins/common.sh b/hack/jenkins/common.sh index 16de6740fc..7592218c26 100755 --- a/hack/jenkins/common.sh +++ b/hack/jenkins/common.sh @@ -21,7 +21,7 @@ # OS_ARCH: The operating system and the architecture separated by a hyphen '-' (e.g. darwin-amd64, linux-amd64, windows-amd64) # VM_DRIVER: the driver to use for the test # EXTRA_START_ARGS: additional flags to pass into minikube start -# EXTRA_ARGS: additional flags to pass into minikube +# EXTRA_TEST_ARGS: additional flags to pass into go test # JOB_NAME: the name of the logfile and check name to update on github readonly TEST_ROOT="${HOME}/minikube-integration" @@ -296,7 +296,7 @@ touch "${TEST_OUT}" ${SUDO_PREFIX}${E2E_BIN} \ -minikube-start-args="--driver=${VM_DRIVER} ${EXTRA_START_ARGS}" \ -test.timeout=70m -test.v \ - ${EXTRA_ARGS} \ + ${EXTRA_TEST_ARGS} \ -binary="${MINIKUBE_BIN}" 2>&1 | tee "${TEST_OUT}" result=${PIPESTATUS[0]} # capture the exit code of the first cmd in pipe. diff --git a/hack/jenkins/linux_integration_tests_none.sh b/hack/jenkins/linux_integration_tests_none.sh index 0549fde508..ce36afee5f 100755 --- a/hack/jenkins/linux_integration_tests_none.sh +++ b/hack/jenkins/linux_integration_tests_none.sh @@ -29,7 +29,7 @@ set -e OS_ARCH="linux-amd64" VM_DRIVER="none" JOB_NAME="none_Linux" -EXTRA_ARGS="--bootstrapper=kubeadm" +EXTRA_START_ARGS="--bootstrapper=kubeadm" EXPECTED_DEFAULT_DRIVER="kvm2" SUDO_PREFIX="sudo -E " diff --git a/hack/jenkins/linux_integration_tests_podman.sh b/hack/jenkins/linux_integration_tests_podman.sh index 3b61c15604..186e9e0a43 100755 --- a/hack/jenkins/linux_integration_tests_podman.sh +++ b/hack/jenkins/linux_integration_tests_podman.sh @@ -32,7 +32,7 @@ JOB_NAME="Experimental_Podman_Linux" mkdir -p cron && gsutil -qm rsync "gs://minikube-builds/${MINIKUBE_LOCATION}/cron" cron || echo "FAILED TO GET CRON FILES" sudo install cron/cleanup_and_reboot_Linux.sh /etc/cron.hourly/cleanup_and_reboot || echo "FAILED TO INSTALL CLEANUP" -EXTRA_ARGS="--container-runtime=containerd" +EXTRA_START_ARGS="--container-runtime=containerd" # remove possible left over podman containers sudo podman rm -f -v $(sudo podman ps -aq) || true diff --git a/hack/jenkins/osx_integration_tests_hyperkit.sh b/hack/jenkins/osx_integration_tests_hyperkit.sh index a52329b75a..f4e6726d77 100755 --- a/hack/jenkins/osx_integration_tests_hyperkit.sh +++ b/hack/jenkins/osx_integration_tests_hyperkit.sh @@ -29,8 +29,7 @@ set -e OS_ARCH="darwin-amd64" VM_DRIVER="hyperkit" JOB_NAME="HyperKit_macOS" -EXTRA_ARGS="-test.run TestFunctional" -EXTRA_START_ARGS="" +EXTRA_TEST_ARGS="-test.run TestFunctional" EXPECTED_DEFAULT_DRIVER="hyperkit" diff --git a/hack/jenkins/osx_integration_tests_virtualbox.sh b/hack/jenkins/osx_integration_tests_virtualbox.sh index c897457e3d..67505da506 100755 --- a/hack/jenkins/osx_integration_tests_virtualbox.sh +++ b/hack/jenkins/osx_integration_tests_virtualbox.sh @@ -28,7 +28,7 @@ set -e OS_ARCH="darwin-amd64" VM_DRIVER="virtualbox" JOB_NAME="VirtualBox_macOS" -EXTRA_ARGS="--bootstrapper=kubeadm" +EXTRA_START_ARGS="--bootstrapper=kubeadm" # hyperkit behaves better, so it has higher precedence. # Assumes that hyperkit is also installed on the VirtualBox CI host. EXPECTED_DEFAULT_DRIVER="hyperkit"