@@ -280,81 +280,61 @@ func (api *API) patchWorkspaceAgentStartupLogs(rw http.ResponseWriter, r *http.R
280
280
level = append (level , parsedLevel )
281
281
}
282
282
283
- var logs []database.WorkspaceAgentStartupLog
284
- // Ensure logs are not written after script ended.
285
- scriptEndedError := xerrors .New ("startup script has ended" )
286
- err := api .Database .InTx (func (db database.Store ) error {
287
- state , err := db .GetWorkspaceAgentLifecycleStateByID (ctx , workspaceAgent .ID )
288
- if err != nil {
289
- return xerrors .Errorf ("workspace agent startup script status: %w" , err )
283
+ logs , err := api .Database .InsertWorkspaceAgentStartupLogs (ctx , database.InsertWorkspaceAgentStartupLogsParams {
284
+ AgentID : workspaceAgent .ID ,
285
+ CreatedAt : createdAt ,
286
+ Output : output ,
287
+ Level : level ,
288
+ OutputLength : int32 (outputLength ),
289
+ })
290
+ if err != nil {
291
+ if ! database .IsStartupLogsLimitError (err ) {
292
+ httpapi .Write (ctx , rw , http .StatusInternalServerError , codersdk.Response {
293
+ Message : "Failed to upload startup logs" ,
294
+ Detail : err .Error (),
295
+ })
296
+ return
290
297
}
291
-
292
- if state .ReadyAt .Valid {
293
- // The agent startup script has already ended, so we don't want to
294
- // process any more logs.
295
- return scriptEndedError
298
+ if workspaceAgent .StartupLogsOverflowed {
299
+ httpapi .Write (ctx , rw , http .StatusRequestEntityTooLarge , codersdk.Response {
300
+ Message : "Startup logs limit exceeded" ,
301
+ Detail : err .Error (),
302
+ })
303
+ return
296
304
}
297
-
298
- logs , err = db .InsertWorkspaceAgentStartupLogs (ctx , database.InsertWorkspaceAgentStartupLogsParams {
299
- AgentID : workspaceAgent .ID ,
300
- CreatedAt : createdAt ,
301
- Output : output ,
302
- Level : level ,
303
- OutputLength : int32 (outputLength ),
305
+ err := api .Database .UpdateWorkspaceAgentStartupLogOverflowByID (ctx , database.UpdateWorkspaceAgentStartupLogOverflowByIDParams {
306
+ ID : workspaceAgent .ID ,
307
+ StartupLogsOverflowed : true ,
304
308
})
305
- return err
306
- }, nil )
307
- if err != nil {
308
- if errors .Is (err , scriptEndedError ) {
309
- httpapi .Write (ctx , rw , http .StatusConflict , codersdk.Response {
310
- Message : "Failed to upload logs, startup script has already ended." ,
309
+ if err != nil {
310
+ // We don't want to return here, because the agent will retry
311
+ // on failure and this isn't a huge deal. The overflow state
312
+ // is just a hint to the user that the logs are incomplete.
313
+ api .Logger .Warn (ctx , "failed to update workspace agent startup log overflow" , slog .Error (err ))
314
+ }
315
+
316
+ resource , err := api .Database .GetWorkspaceResourceByID (ctx , workspaceAgent .ResourceID )
317
+ if err != nil {
318
+ httpapi .Write (ctx , rw , http .StatusBadRequest , codersdk.Response {
319
+ Message : "Failed to get workspace resource." ,
311
320
Detail : err .Error (),
312
321
})
313
322
return
314
323
}
315
- if database .IsStartupLogsLimitError (err ) {
316
- if ! workspaceAgent .StartupLogsOverflowed {
317
- err := api .Database .UpdateWorkspaceAgentStartupLogOverflowByID (ctx , database.UpdateWorkspaceAgentStartupLogOverflowByIDParams {
318
- ID : workspaceAgent .ID ,
319
- StartupLogsOverflowed : true ,
320
- })
321
- if err != nil {
322
- // We don't want to return here, because the agent will retry
323
- // on failure and this isn't a huge deal. The overflow state
324
- // is just a hint to the user that the logs are incomplete.
325
- api .Logger .Warn (ctx , "failed to update workspace agent startup log overflow" , slog .Error (err ))
326
- }
327
324
328
- resource , err := api .Database .GetWorkspaceResourceByID (ctx , workspaceAgent .ResourceID )
329
- if err != nil {
330
- httpapi .Write (ctx , rw , http .StatusBadRequest , codersdk.Response {
331
- Message : "Failed to get workspace resource." ,
332
- Detail : err .Error (),
333
- })
334
- return
335
- }
336
-
337
- build , err := api .Database .GetWorkspaceBuildByJobID (ctx , resource .JobID )
338
- if err != nil {
339
- httpapi .Write (ctx , rw , http .StatusBadRequest , codersdk.Response {
340
- Message : "Internal error fetching workspace build job." ,
341
- Detail : err .Error (),
342
- })
343
- return
344
- }
345
-
346
- api .publishWorkspaceUpdate (ctx , build .WorkspaceID )
347
- }
348
-
349
- httpapi .Write (ctx , rw , http .StatusRequestEntityTooLarge , codersdk.Response {
350
- Message : "Startup logs limit exceeded" ,
325
+ build , err := api .Database .GetWorkspaceBuildByJobID (ctx , resource .JobID )
326
+ if err != nil {
327
+ httpapi .Write (ctx , rw , http .StatusBadRequest , codersdk.Response {
328
+ Message : "Internal error fetching workspace build job." ,
351
329
Detail : err .Error (),
352
330
})
353
331
return
354
332
}
355
- httpapi .Write (ctx , rw , http .StatusInternalServerError , codersdk.Response {
356
- Message : "Failed to upload startup logs" ,
357
- Detail : err .Error (),
333
+
334
+ api .publishWorkspaceUpdate (ctx , build .WorkspaceID )
335
+
336
+ httpapi .Write (ctx , rw , http .StatusRequestEntityTooLarge , codersdk.Response {
337
+ Message : "Startup logs limit exceeded" ,
358
338
})
359
339
return
360
340
}
@@ -497,18 +477,6 @@ func (api *API) workspaceAgentStartupLogs(rw http.ResponseWriter, r *http.Reques
497
477
return
498
478
}
499
479
500
- if workspaceAgent .ReadyAt .Valid {
501
- // Fast path, the startup script has finished running, so we can close
502
- // the connection.
503
- return
504
- }
505
- if ! codersdk .WorkspaceAgentLifecycle (workspaceAgent .LifecycleState ).Starting () {
506
- // Backwards compatibility: Avoid waiting forever in case this agent is
507
- // older than the current release and has already reported the ready
508
- // state.
509
- return
510
- }
511
-
512
480
lastSentLogID := after
513
481
if len (logs ) > 0 {
514
482
lastSentLogID = logs [len (logs )- 1 ].ID
@@ -543,11 +511,9 @@ func (api *API) workspaceAgentStartupLogs(rw http.ResponseWriter, r *http.Reques
543
511
t := time .NewTicker (recheckInterval )
544
512
defer t .Stop ()
545
513
546
- var state database.GetWorkspaceAgentLifecycleStateByIDRow
547
514
go func () {
548
515
defer close (bufferedLogs )
549
516
550
- var err error
551
517
for {
552
518
select {
553
519
case <- ctx .Done ():
@@ -557,17 +523,6 @@ func (api *API) workspaceAgentStartupLogs(rw http.ResponseWriter, r *http.Reques
557
523
t .Reset (recheckInterval )
558
524
}
559
525
560
- if ! state .ReadyAt .Valid {
561
- state , err = api .Database .GetWorkspaceAgentLifecycleStateByID (ctx , workspaceAgent .ID )
562
- if err != nil {
563
- if xerrors .Is (err , context .Canceled ) {
564
- return
565
- }
566
- logger .Warn (ctx , "failed to get workspace agent lifecycle state" , slog .Error (err ))
567
- continue
568
- }
569
- }
570
-
571
526
logs , err := api .Database .GetWorkspaceAgentStartupLogsAfter (ctx , database.GetWorkspaceAgentStartupLogsAfterParams {
572
527
AgentID : workspaceAgent .ID ,
573
528
CreatedAfter : lastSentLogID ,
@@ -580,9 +535,7 @@ func (api *API) workspaceAgentStartupLogs(rw http.ResponseWriter, r *http.Reques
580
535
continue
581
536
}
582
537
if len (logs ) == 0 {
583
- if state .ReadyAt .Valid {
584
- return
585
- }
538
+ // Just keep listening - more logs might come in the future!
586
539
continue
587
540
}
588
541
@@ -1689,12 +1642,6 @@ func (api *API) workspaceAgentReportLifecycle(rw http.ResponseWriter, r *http.Re
1689
1642
return
1690
1643
}
1691
1644
1692
- if readyAt .Valid {
1693
- api .publishWorkspaceAgentStartupLogsUpdate (ctx , workspaceAgent .ID , agentsdk.StartupLogsNotifyMessage {
1694
- EndOfLogs : true ,
1695
- })
1696
- }
1697
-
1698
1645
api .publishWorkspaceUpdate (ctx , workspace .ID )
1699
1646
1700
1647
httpapi .Write (ctx , rw , http .StatusNoContent , nil )
0 commit comments