@@ -3,6 +3,7 @@ package coderd
3
3
import (
4
4
"context"
5
5
"database/sql"
6
+ "encoding/json"
6
7
"errors"
7
8
"fmt"
8
9
"net/http"
@@ -22,6 +23,7 @@ import (
22
23
"github.com/coder/coder/v2/coderd/rbac/policy"
23
24
"github.com/coder/coder/v2/coderd/searchquery"
24
25
"github.com/coder/coder/v2/coderd/taskname"
26
+ "github.com/coder/coder/v2/coderd/util/rwsink"
25
27
"github.com/coder/coder/v2/codersdk"
26
28
)
27
29
@@ -186,9 +188,86 @@ func (api *API) tasksCreate(rw http.ResponseWriter, r *http.Request) {
186
188
WorkspaceOwner : owner .Username ,
187
189
},
188
190
})
189
-
190
191
defer commitAudit ()
191
- createWorkspace (ctx , aReq , apiKey .UserID , api , owner , createReq , rw , r )
192
+
193
+ rwSink := rwsink .New ()
194
+ createWorkspace (ctx , aReq , apiKey .UserID , api , owner , createReq , rwSink , r )
195
+
196
+ if rwSink .StatusCode != nil && * rwSink .StatusCode == http .StatusCreated {
197
+ bytes := rwSink .ResetBody ()
198
+
199
+ var ws codersdk.Workspace
200
+ if err := json .Unmarshal (bytes , & ws ); err != nil {
201
+ httpapi .Write (ctx , rw , http .StatusInternalServerError , codersdk.Response {
202
+ Message : "Internal error decoding created workspace" ,
203
+ Detail : err .Error (),
204
+ })
205
+ return
206
+ }
207
+
208
+ task := taskFromWorkspace (ws , req .Prompt )
209
+
210
+ httpapi .Write (ctx , rwSink , http .StatusCreated , task )
211
+ }
212
+
213
+ _ = rwSink .FlushTo (rw )
214
+ }
215
+
216
+ func taskFromWorkspace (ws codersdk.Workspace , initialPrompt string ) codersdk.Task {
217
+ // TODO(DanielleMaywood):
218
+ // This just picks up the first agent it discovers.
219
+ // This approach _might_ break when a task has multiple agents,
220
+ // depending on which agent was found first.
221
+ //
222
+ // We explicitly do not have support for running tasks
223
+ // inside of a sub agent at the moment, so we can be sure
224
+ // that any sub agents are not the agent we're looking for.
225
+ var taskAgentID uuid.NullUUID
226
+ var taskAgentLifecycle * codersdk.WorkspaceAgentLifecycle
227
+ var taskAgentHealth * codersdk.WorkspaceAgentHealth
228
+ for _ , resource := range ws .LatestBuild .Resources {
229
+ for _ , agent := range resource .Agents {
230
+ if agent .ParentID .Valid {
231
+ continue
232
+ }
233
+
234
+ taskAgentID = uuid.NullUUID {Valid : true , UUID : agent .ID }
235
+ taskAgentLifecycle = & agent .LifecycleState
236
+ taskAgentHealth = & agent .Health
237
+ break
238
+ }
239
+ }
240
+
241
+ var currentState * codersdk.TaskStateEntry
242
+ if ws .LatestAppStatus != nil {
243
+ currentState = & codersdk.TaskStateEntry {
244
+ Timestamp : ws .LatestAppStatus .CreatedAt ,
245
+ State : codersdk .TaskState (ws .LatestAppStatus .State ),
246
+ Message : ws .LatestAppStatus .Message ,
247
+ URI : ws .LatestAppStatus .URI ,
248
+ }
249
+ }
250
+
251
+ return codersdk.Task {
252
+ ID : ws .ID ,
253
+ OrganizationID : ws .OrganizationID ,
254
+ OwnerID : ws .OwnerID ,
255
+ OwnerName : ws .OwnerName ,
256
+ Name : ws .Name ,
257
+ TemplateID : ws .TemplateID ,
258
+ TemplateName : ws .TemplateName ,
259
+ TemplateDisplayName : ws .TemplateDisplayName ,
260
+ TemplateIcon : ws .TemplateIcon ,
261
+ WorkspaceID : uuid.NullUUID {Valid : true , UUID : ws .ID },
262
+ WorkspaceAgentID : taskAgentID ,
263
+ WorkspaceAgentLifecycle : taskAgentLifecycle ,
264
+ WorkspaceAgentHealth : taskAgentHealth ,
265
+ CreatedAt : ws .CreatedAt ,
266
+ UpdatedAt : ws .UpdatedAt ,
267
+ InitialPrompt : initialPrompt ,
268
+ Status : ws .LatestBuild .Status ,
269
+ CurrentState : currentState ,
270
+ }
192
271
}
193
272
194
273
// tasksFromWorkspaces converts a slice of API workspaces into tasks, fetching
@@ -213,60 +292,7 @@ func (api *API) tasksFromWorkspaces(ctx context.Context, apiWorkspaces []codersd
213
292
214
293
tasks := make ([]codersdk.Task , 0 , len (apiWorkspaces ))
215
294
for _ , ws := range apiWorkspaces {
216
- // TODO(DanielleMaywood):
217
- // This just picks up the first agent it discovers.
218
- // This approach _might_ break when a task has multiple agents,
219
- // depending on which agent was found first.
220
- //
221
- // We explicitly do not have support for running tasks
222
- // inside of a sub agent at the moment, so we can be sure
223
- // that any sub agents are not the agent we're looking for.
224
- var taskAgentID uuid.NullUUID
225
- var taskAgentLifecycle * codersdk.WorkspaceAgentLifecycle
226
- var taskAgentHealth * codersdk.WorkspaceAgentHealth
227
- for _ , resource := range ws .LatestBuild .Resources {
228
- for _ , agent := range resource .Agents {
229
- if agent .ParentID .Valid {
230
- continue
231
- }
232
-
233
- taskAgentID = uuid.NullUUID {Valid : true , UUID : agent .ID }
234
- taskAgentLifecycle = & agent .LifecycleState
235
- taskAgentHealth = & agent .Health
236
- break
237
- }
238
- }
239
-
240
- var currentState * codersdk.TaskStateEntry
241
- if ws .LatestAppStatus != nil {
242
- currentState = & codersdk.TaskStateEntry {
243
- Timestamp : ws .LatestAppStatus .CreatedAt ,
244
- State : codersdk .TaskState (ws .LatestAppStatus .State ),
245
- Message : ws .LatestAppStatus .Message ,
246
- URI : ws .LatestAppStatus .URI ,
247
- }
248
- }
249
-
250
- tasks = append (tasks , codersdk.Task {
251
- ID : ws .ID ,
252
- OrganizationID : ws .OrganizationID ,
253
- OwnerID : ws .OwnerID ,
254
- OwnerName : ws .OwnerName ,
255
- Name : ws .Name ,
256
- TemplateID : ws .TemplateID ,
257
- TemplateName : ws .TemplateName ,
258
- TemplateDisplayName : ws .TemplateDisplayName ,
259
- TemplateIcon : ws .TemplateIcon ,
260
- WorkspaceID : uuid.NullUUID {Valid : true , UUID : ws .ID },
261
- WorkspaceAgentID : taskAgentID ,
262
- WorkspaceAgentLifecycle : taskAgentLifecycle ,
263
- WorkspaceAgentHealth : taskAgentHealth ,
264
- CreatedAt : ws .CreatedAt ,
265
- UpdatedAt : ws .UpdatedAt ,
266
- InitialPrompt : promptsByBuildID [ws .LatestBuild .ID ],
267
- Status : ws .LatestBuild .Status ,
268
- CurrentState : currentState ,
269
- })
295
+ tasks = append (tasks , taskFromWorkspace (ws , promptsByBuildID [ws .LatestBuild .ID ]))
270
296
}
271
297
272
298
return tasks , nil
0 commit comments