Skip to content

Commit 83f9bd1

Browse files
author
priyawadhwa
authored
Merge pull request #9793 from tharun208/feat/show_scheduled_stop_status
feat(minikube) display scheduledstop status in minikube status
2 parents 47217f4 + c6e6f2d commit 83f9bd1

File tree

4 files changed

+53
-19
lines changed

4 files changed

+53
-19
lines changed

Diff for: cmd/minikube/cmd/status.go

+11-1
Original file line numberDiff line numberDiff line change
@@ -135,13 +135,15 @@ type Status struct {
135135
APIServer string
136136
Kubeconfig string
137137
Worker bool
138+
TimeToStop string
138139
}
139140

140141
// ClusterState holds a cluster state representation
141142
type ClusterState struct {
142143
BaseState
143144

144145
BinaryVersion string
146+
TimeToStop string
145147
Components map[string]BaseState
146148
Nodes []NodeState
147149
}
@@ -180,6 +182,7 @@ host: {{.Host}}
180182
kubelet: {{.Kubelet}}
181183
apiserver: {{.APIServer}}
182184
kubeconfig: {{.Kubeconfig}}
185+
timeToStop: {{.TimeToStop}}
183186
184187
`
185188
workerStatusFormat = `{{.Name}}
@@ -307,6 +310,7 @@ func nodeStatus(api libmachine.API, cc config.ClusterConfig, n config.Node) (*St
307310
Kubelet: Nonexistent,
308311
Kubeconfig: Nonexistent,
309312
Worker: !controlPlane,
313+
TimeToStop: Nonexistent,
310314
}
311315

312316
hs, err := machine.Status(api, name)
@@ -366,7 +370,10 @@ func nodeStatus(api libmachine.API, cc config.ClusterConfig, n config.Node) (*St
366370

367371
stk := kverify.ServiceStatus(cr, "kubelet")
368372
st.Kubelet = stk.String()
369-
373+
if cc.ScheduledStop != nil {
374+
initiationTime := time.Unix(cc.ScheduledStop.InitiationTime, 0)
375+
st.TimeToStop = time.Until(initiationTime.Add(cc.ScheduledStop.Duration)).String()
376+
}
370377
// Early exit for worker nodes
371378
if !controlPlane {
372379
return st, nil
@@ -478,6 +485,7 @@ func clusterState(sts []*Status) ClusterState {
478485
statusName = sts[0].Host
479486
}
480487
sc := statusCode(statusName)
488+
481489
cs := ClusterState{
482490
BinaryVersion: version.GetVersion(),
483491

@@ -488,6 +496,8 @@ func clusterState(sts []*Status) ClusterState {
488496
StatusDetail: codeDetails[sc],
489497
},
490498

499+
TimeToStop: sts[0].TimeToStop,
500+
491501
Components: map[string]BaseState{
492502
"kubeconfig": {Name: "kubeconfig", StatusCode: statusCode(sts[0].Kubeconfig)},
493503
},

Diff for: cmd/minikube/cmd/status_test.go

+9-9
Original file line numberDiff line numberDiff line change
@@ -51,18 +51,18 @@ func TestStatusText(t *testing.T) {
5151
}{
5252
{
5353
name: "ok",
54-
state: &Status{Name: "minikube", Host: "Running", Kubelet: "Running", APIServer: "Running", Kubeconfig: Configured},
55-
want: "minikube\ntype: Control Plane\nhost: Running\nkubelet: Running\napiserver: Running\nkubeconfig: Configured\n\n",
54+
state: &Status{Name: "minikube", Host: "Running", Kubelet: "Running", APIServer: "Running", Kubeconfig: Configured, TimeToStop: "10m"},
55+
want: "minikube\ntype: Control Plane\nhost: Running\nkubelet: Running\napiserver: Running\nkubeconfig: Configured\ntimeToStop: 10m\n\n",
5656
},
5757
{
5858
name: "paused",
59-
state: &Status{Name: "minikube", Host: "Running", Kubelet: "Stopped", APIServer: "Paused", Kubeconfig: Configured},
60-
want: "minikube\ntype: Control Plane\nhost: Running\nkubelet: Stopped\napiserver: Paused\nkubeconfig: Configured\n\n",
59+
state: &Status{Name: "minikube", Host: "Running", Kubelet: "Stopped", APIServer: "Paused", Kubeconfig: Configured, TimeToStop: Nonexistent},
60+
want: "minikube\ntype: Control Plane\nhost: Running\nkubelet: Stopped\napiserver: Paused\nkubeconfig: Configured\ntimeToStop: Nonexistent\n\n",
6161
},
6262
{
6363
name: "down",
64-
state: &Status{Name: "minikube", Host: "Stopped", Kubelet: "Stopped", APIServer: "Stopped", Kubeconfig: Misconfigured},
65-
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",
64+
state: &Status{Name: "minikube", Host: "Stopped", Kubelet: "Stopped", APIServer: "Stopped", Kubeconfig: Misconfigured, TimeToStop: Nonexistent},
65+
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",
6666
},
6767
}
6868
for _, tc := range tests {
@@ -86,9 +86,9 @@ func TestStatusJSON(t *testing.T) {
8686
name string
8787
state *Status
8888
}{
89-
{"ok", &Status{Host: "Running", Kubelet: "Running", APIServer: "Running", Kubeconfig: Configured}},
90-
{"paused", &Status{Host: "Running", Kubelet: "Stopped", APIServer: "Paused", Kubeconfig: Configured}},
91-
{"down", &Status{Host: "Stopped", Kubelet: "Stopped", APIServer: "Stopped", Kubeconfig: Misconfigured}},
89+
{"ok", &Status{Host: "Running", Kubelet: "Running", APIServer: "Running", Kubeconfig: Configured, TimeToStop: "10m"}},
90+
{"paused", &Status{Host: "Running", Kubelet: "Stopped", APIServer: "Paused", Kubeconfig: Configured, TimeToStop: Nonexistent}},
91+
{"down", &Status{Host: "Stopped", Kubelet: "Stopped", APIServer: "Stopped", Kubeconfig: Misconfigured, TimeToStop: Nonexistent}},
9292
}
9393
for _, tc := range tests {
9494
t.Run(tc.name, func(t *testing.T) {

Diff for: site/content/en/docs/commands/status.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ minikube status [flags]
2323

2424
```
2525
-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/
26-
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")
26+
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")
2727
-l, --layout string output layout (EXPERIMENTAL, JSON only): 'nodes' or 'cluster' (default "nodes")
2828
-n, --node string The node to check status for. Defaults to control plane. Leave blank with default format for status on all nodes.
2929
-o, --output string minikube status --output OUTPUT. json, text (default "text")

Diff for: test/integration/scheduled_stop_test.go

+32-8
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ func TestScheduledStopWindows(t *testing.T) {
5151

5252
// schedule a stop for 5m from now
5353
stopMinikube(ctx, t, profile, []string{"--schedule", "5m"})
54-
54+
// make sure timeToStop is present in status
55+
ensureMinikubeScheduledTime(ctx, t, profile, 5*time.Minute)
5556
// make sure the systemd service is running
5657
rr, err := Run(t, exec.CommandContext(ctx, Target(), []string{"ssh", "-p", profile, "--", "sudo", "systemctl", "show", constants.ScheduledStopSystemdService, "--no-page"}...))
5758
if err != nil {
@@ -67,7 +68,9 @@ func TestScheduledStopWindows(t *testing.T) {
6768
// sleep for 5 seconds
6869
time.Sleep(5 * time.Second)
6970
// make sure minikube status is "Stopped"
70-
ensureMinikubeStatus(ctx, t, profile, state.Stopped.String())
71+
ensureMinikubeStatus(ctx, t, profile, "Host", state.Stopped.String())
72+
// make sure minikube timtostop is "Nonexistent"
73+
ensureMinikubeStatus(ctx, t, profile, "TimeToStop", "Nonexistent")
7174
}
7275

7376
func TestScheduledStopUnix(t *testing.T) {
@@ -84,6 +87,8 @@ func TestScheduledStopUnix(t *testing.T) {
8487

8588
// schedule a stop for 5 min from now and make sure PID is created
8689
stopMinikube(ctx, t, profile, []string{"--schedule", "5m"})
90+
// make sure timeToStop is present in status
91+
ensureMinikubeScheduledTime(ctx, t, profile, 5*time.Minute)
8792
pid := checkPID(t, profile)
8893
if !processRunning(t, pid) {
8994
t.Fatalf("process %v is not running", pid)
@@ -100,14 +105,18 @@ func TestScheduledStopUnix(t *testing.T) {
100105
// sleep 12 just to be safe
101106
stopMinikube(ctx, t, profile, []string{"--cancel-scheduled"})
102107
time.Sleep(12 * time.Second)
103-
ensureMinikubeStatus(ctx, t, profile, state.Running.String())
108+
ensureMinikubeStatus(ctx, t, profile, "Host", state.Running.String())
104109

105110
// schedule another stop, make sure minikube status is "Stopped"
106111
stopMinikube(ctx, t, profile, []string{"--schedule", "5s"})
107112
if processRunning(t, pid) {
108113
t.Fatalf("process %v running but should have been killed on reschedule of stop", pid)
109114
}
110-
ensureMinikubeStatus(ctx, t, profile, state.Stopped.String())
115+
116+
// make sure minikube status is "Stopped"
117+
ensureMinikubeStatus(ctx, t, profile, "Host", state.Stopped.String())
118+
// make sure minikube timtostop is "Nonexistent"
119+
ensureMinikubeStatus(ctx, t, profile, "TimeToStop", "Nonexistent")
111120
}
112121

113122
func startMinikube(ctx context.Context, t *testing.T, profile string) {
@@ -156,18 +165,33 @@ func processRunning(t *testing.T, pid string) bool {
156165
t.Log("signal error was: ", err)
157166
return err == nil
158167
}
159-
func ensureMinikubeStatus(ctx context.Context, t *testing.T, profile, wantStatus string) {
160-
// wait allotted time to make sure minikube status is "Stopped"
168+
func ensureMinikubeStatus(ctx context.Context, t *testing.T, profile, key string, wantStatus string) {
161169
checkStatus := func() error {
162170
ctx, cancel := context.WithDeadline(ctx, time.Now().Add(10*time.Second))
163171
defer cancel()
164-
got := Status(ctx, t, Target(), profile, "Host", profile)
172+
got := Status(ctx, t, Target(), profile, key, profile)
165173
if got != wantStatus {
166-
return fmt.Errorf("expected post-stop host status to be -%q- but got *%q*", state.Stopped, got)
174+
return fmt.Errorf("expected post-stop %q status to be -%q- but got *%q*", key, wantStatus, got)
167175
}
168176
return nil
169177
}
170178
if err := retry.Expo(checkStatus, time.Second, time.Minute); err != nil {
171179
t.Fatalf("error %v", err)
172180
}
173181
}
182+
183+
func ensureMinikubeScheduledTime(ctx context.Context, t *testing.T, profile string, givenTime time.Duration) {
184+
checkTime := func() error {
185+
ctx, cancel := context.WithDeadline(ctx, time.Now().Add(10*time.Second))
186+
defer cancel()
187+
got := Status(ctx, t, Target(), profile, "TimeToStop", profile)
188+
gotTime, _ := time.ParseDuration(got)
189+
if gotTime < givenTime {
190+
return nil
191+
}
192+
return fmt.Errorf("expected scheduled stop TimeToStop to be less than *%q* but got *%q*", givenTime, got)
193+
}
194+
if err := retry.Expo(checkTime, time.Second, time.Minute); err != nil {
195+
t.Fatalf("error %v", err)
196+
}
197+
}

0 commit comments

Comments
 (0)