Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commite852db3

Browse files
committed
feat(cli): improve exp task status --watch
Improves logic for task status --watch so that it will also exit on taskidle status.
1 parenteb55f0a commite852db3

File tree

2 files changed

+74
-56
lines changed

2 files changed

+74
-56
lines changed

‎cli/exp_task_status.go‎

Lines changed: 47 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ func (r *RootCmd) taskStatus() *serpent.Command {
2121
[]string{
2222
"state changed",
2323
"status",
24+
"healthy",
2425
"state",
2526
"message",
2627
},
@@ -92,44 +93,46 @@ func (r *RootCmd) taskStatus() *serpent.Command {
9293
returnerr
9394
}
9495

95-
out,err:=formatter.Format(ctx,toStatusRow(task))
96+
tsr:=toStatusRow(task)
97+
out,err:=formatter.Format(ctx, []taskStatusRow{tsr})
9698
iferr!=nil {
9799
returnxerrors.Errorf("format task status: %w",err)
98100
}
99101
_,_=fmt.Fprintln(i.Stdout,out)
100102

101-
if!watchArg {
103+
if!watchArg||taskWatchIsEnded(task){
102104
returnnil
103105
}
104106

105-
lastStatus:=task.Status
106-
lastState:=task.CurrentState
107107
t:=time.NewTicker(watchIntervalArg)
108108
defert.Stop()
109109
// TODO: implement streaming updates instead of polling
110+
lastStatusRow:=tsr
110111
forranget.C {
111112
task,err:=ec.TaskByID(ctx,taskID)
112113
iferr!=nil {
113114
returnerr
114115
}
115-
iflastStatus==task.Status&&taskStatusEqual(lastState,task.CurrentState) {
116-
continue
117-
}
118-
out,err:=formatter.Format(ctx,toStatusRow(task))
119-
iferr!=nil {
120-
returnxerrors.Errorf("format task status: %w",err)
121-
}
122-
// hack: skip the extra column header from formatter
123-
ifformatter.FormatID()!=cliui.JSONFormat().ID() {
124-
out=strings.SplitN(out,"\n",2)[1]
116+
117+
// Only print if something changed
118+
newStatusRow:=toStatusRow(task)
119+
if!taskStatusRowEqual(lastStatusRow,newStatusRow) {
120+
out,err:=formatter.Format(ctx, []taskStatusRow{newStatusRow})
121+
iferr!=nil {
122+
returnxerrors.Errorf("format task status: %w",err)
123+
}
124+
// hack: skip the extra column header from formatter
125+
ifformatter.FormatID()!=cliui.JSONFormat().ID() {
126+
out=strings.SplitN(out,"\n",2)[1]
127+
}
128+
_,_=fmt.Fprintln(i.Stdout,out)
125129
}
126-
_,_=fmt.Fprintln(i.Stdout,out)
127130

128-
iftask.Status==codersdk.WorkspaceStatusStopped {
131+
iftaskWatchIsEnded(task) {
129132
returnnil
130133
}
131-
lastStatus=task.Status
132-
lastState=task.CurrentState
134+
135+
lastStatusRow=newStatusRow
133136
}
134137
returnnil
135138
},
@@ -138,37 +141,57 @@ func (r *RootCmd) taskStatus() *serpent.Command {
138141
returncmd
139142
}
140143

141-
functaskStatusEqual(s1,s2*codersdk.TaskStateEntry)bool {
142-
ifs1==nil&&s2==nil {
144+
functaskWatchIsEnded(taskcodersdk.Task)bool {
145+
iftask.Status==codersdk.WorkspaceStatusStopped {
143146
returntrue
144147
}
145-
ifs1==nil||s2==nil {
148+
iftask.WorkspaceAgentHealth==nil||!task.WorkspaceAgentHealth.Healthy {
146149
returnfalse
147150
}
148-
returns1.State==s2.State
151+
iftask.WorkspaceAgentLifecycle==nil||task.WorkspaceAgentLifecycle.Starting()||task.WorkspaceAgentLifecycle.ShuttingDown() {
152+
returnfalse
153+
}
154+
iftask.CurrentState==nil||task.CurrentState.State==codersdk.TaskStateWorking {
155+
returnfalse
156+
}
157+
returntrue
149158
}
150159

151160
typetaskStatusRowstruct {
152161
codersdk.Task`table:"-"`
153162
ChangedAgostring`json:"-" table:"state changed,default_sort"`
154163
Timestamp time.Time`json:"-" table:"-"`
155164
TaskStatusstring`json:"-" table:"status"`
165+
Healthybool`json:"-" table:"healthy"`
156166
TaskStatestring`json:"-" table:"state"`
157167
Messagestring`json:"-" table:"message"`
158168
}
159169

160-
functoStatusRow(task codersdk.Task) []taskStatusRow {
170+
functaskStatusRowEqual(r1,r2taskStatusRow)bool {
171+
returnr1.TaskStatus==r2.TaskStatus&&
172+
r1.Healthy==r2.Healthy&&
173+
r1.TaskState==r2.TaskState&&
174+
r1.Message==r2.Message
175+
}
176+
177+
functoStatusRow(task codersdk.Task)taskStatusRow {
161178
tsr:=taskStatusRow{
162179
Task:task,
163180
ChangedAgo:time.Since(task.UpdatedAt).Truncate(time.Second).String()+" ago",
164181
Timestamp:task.UpdatedAt,
165182
TaskStatus:string(task.Status),
166183
}
184+
tsr.Healthy=task.WorkspaceAgentHealth!=nil&&
185+
task.WorkspaceAgentHealth.Healthy&&
186+
task.WorkspaceAgentLifecycle!=nil&&
187+
!task.WorkspaceAgentLifecycle.Starting()&&
188+
!task.WorkspaceAgentLifecycle.ShuttingDown()
189+
167190
iftask.CurrentState!=nil {
168191
tsr.ChangedAgo=time.Since(task.CurrentState.Timestamp).Truncate(time.Second).String()+" ago"
169192
tsr.Timestamp=task.CurrentState.Timestamp
170193
tsr.TaskState=string(task.CurrentState.State)
171194
tsr.Message=task.CurrentState.Message
172195
}
173-
return[]taskStatusRow{tsr}
196+
returntsr
174197
}

‎cli/exp_task_status_test.go‎

Lines changed: 27 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616

1717
"github.com/coder/coder/v2/cli/clitest"
1818
"github.com/coder/coder/v2/coderd/httpapi"
19+
"github.com/coder/coder/v2/coderd/util/ptr"
1920
"github.com/coder/coder/v2/codersdk"
2021
"github.com/coder/coder/v2/testutil"
2122
)
@@ -63,8 +64,8 @@ func Test_TaskStatus(t *testing.T) {
6364
},
6465
{
6566
args: []string{"exists"},
66-
expectOutput:`STATE CHANGED STATUS STATE MESSAGE
67-
0s ago running working Thinking furiously...`,
67+
expectOutput:`STATE CHANGED STATUSHEALTHYSTATE MESSAGE
68+
0s ago runningtrueworking Thinking furiously...`,
6869
hf:func(ctx context.Context,now time.Time)func(w http.ResponseWriter,r*http.Request) {
6970
returnfunc(w http.ResponseWriter,r*http.Request) {
7071
switchr.URL.Path {
@@ -83,6 +84,10 @@ func Test_TaskStatus(t *testing.T) {
8384
Timestamp:now,
8485
Message:"Thinking furiously...",
8586
},
87+
WorkspaceAgentHealth:&codersdk.WorkspaceAgentHealth{
88+
Healthy:true,
89+
},
90+
WorkspaceAgentLifecycle:ptr.Ref(codersdk.WorkspaceAgentLifecycleReady),
8691
})
8792
default:
8893
t.Errorf("unexpected path: %s",r.URL.Path)
@@ -93,12 +98,10 @@ func Test_TaskStatus(t *testing.T) {
9398
{
9499
args: []string{"exists","--watch"},
95100
expectOutput:`
96-
STATE CHANGED STATUS STATE MESSAGE
97-
4s ago running
98-
3s ago running working Reticulating splines...
99-
2s ago running complete Splines reticulated successfully!
100-
2s ago stopping complete Splines reticulated successfully!
101-
2s ago stopped complete Splines reticulated successfully!`,
101+
STATE CHANGED STATUS HEALTHY STATE MESSAGE
102+
4s ago running true
103+
3s ago running true working Reticulating splines...
104+
2s ago running true complete Splines reticulated successfully!`,
102105
hf:func(ctx context.Context,now time.Time)func(http.ResponseWriter,*http.Request) {
103106
varcalls atomic.Int64
104107
returnfunc(w http.ResponseWriter,r*http.Request) {
@@ -116,20 +119,32 @@ STATE CHANGED STATUS STATE MESSAGE
116119
Status:codersdk.WorkspaceStatusPending,
117120
CreatedAt:now.Add(-5*time.Second),
118121
UpdatedAt:now.Add(-5*time.Second),
122+
WorkspaceAgentHealth:&codersdk.WorkspaceAgentHealth{
123+
Healthy:true,
124+
},
125+
WorkspaceAgentLifecycle:ptr.Ref(codersdk.WorkspaceAgentLifecycleReady),
119126
})
120127
case1:
121128
httpapi.Write(ctx,w,http.StatusOK, codersdk.Task{
122129
ID:uuid.MustParse("11111111-1111-1111-1111-111111111111"),
123130
Status:codersdk.WorkspaceStatusRunning,
124131
CreatedAt:now.Add(-5*time.Second),
125-
UpdatedAt:now.Add(-4*time.Second),
132+
WorkspaceAgentHealth:&codersdk.WorkspaceAgentHealth{
133+
Healthy:true,
134+
},
135+
WorkspaceAgentLifecycle:ptr.Ref(codersdk.WorkspaceAgentLifecycleReady),
136+
UpdatedAt:now.Add(-4*time.Second),
126137
})
127138
case2:
128139
httpapi.Write(ctx,w,http.StatusOK, codersdk.Task{
129140
ID:uuid.MustParse("11111111-1111-1111-1111-111111111111"),
130141
Status:codersdk.WorkspaceStatusRunning,
131142
CreatedAt:now.Add(-5*time.Second),
132143
UpdatedAt:now.Add(-4*time.Second),
144+
WorkspaceAgentHealth:&codersdk.WorkspaceAgentHealth{
145+
Healthy:true,
146+
},
147+
WorkspaceAgentLifecycle:ptr.Ref(codersdk.WorkspaceAgentLifecycleReady),
133148
CurrentState:&codersdk.TaskStateEntry{
134149
State:codersdk.TaskStateWorking,
135150
Timestamp:now.Add(-3*time.Second),
@@ -142,30 +157,10 @@ STATE CHANGED STATUS STATE MESSAGE
142157
Status:codersdk.WorkspaceStatusRunning,
143158
CreatedAt:now.Add(-5*time.Second),
144159
UpdatedAt:now.Add(-4*time.Second),
145-
CurrentState:&codersdk.TaskStateEntry{
146-
State:codersdk.TaskStateComplete,
147-
Timestamp:now.Add(-2*time.Second),
148-
Message:"Splines reticulated successfully!",
149-
},
150-
})
151-
case4:
152-
httpapi.Write(ctx,w,http.StatusOK, codersdk.Task{
153-
ID:uuid.MustParse("11111111-1111-1111-1111-111111111111"),
154-
Status:codersdk.WorkspaceStatusStopping,
155-
CreatedAt:now.Add(-5*time.Second),
156-
UpdatedAt:now.Add(-1*time.Second),
157-
CurrentState:&codersdk.TaskStateEntry{
158-
State:codersdk.TaskStateComplete,
159-
Timestamp:now.Add(-2*time.Second),
160-
Message:"Splines reticulated successfully!",
160+
WorkspaceAgentHealth:&codersdk.WorkspaceAgentHealth{
161+
Healthy:true,
161162
},
162-
})
163-
case5:
164-
httpapi.Write(ctx,w,http.StatusOK, codersdk.Task{
165-
ID:uuid.MustParse("11111111-1111-1111-1111-111111111111"),
166-
Status:codersdk.WorkspaceStatusStopped,
167-
CreatedAt:now.Add(-5*time.Second),
168-
UpdatedAt:now,
163+
WorkspaceAgentLifecycle:ptr.Ref(codersdk.WorkspaceAgentLifecycleReady),
169164
CurrentState:&codersdk.TaskStateEntry{
170165
State:codersdk.TaskStateComplete,
171166
Timestamp:now.Add(-2*time.Second),

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp