@@ -19,7 +19,6 @@ import (
19
19
"github.com/coder/coder/coderd/httpmw"
20
20
"github.com/coder/coder/coderd/rbac"
21
21
"github.com/coder/coder/codersdk"
22
- "github.com/coder/coder/provisionersdk"
23
22
)
24
23
25
24
func (api * API ) workspaceBuild (rw http.ResponseWriter , r * http.Request ) {
@@ -319,6 +318,7 @@ func (api *API) postWorkspaceBuilds(rw http.ResponseWriter, r *http.Request) {
319
318
}
320
319
createBuild .TemplateVersionID = latestBuild .TemplateVersionID
321
320
}
321
+
322
322
templateVersion , err := api .Database .GetTemplateVersionByID (r .Context (), createBuild .TemplateVersionID )
323
323
if errors .Is (err , sql .ErrNoRows ) {
324
324
httpapi .Write (rw , http .StatusBadRequest , codersdk.Response {
@@ -337,6 +337,47 @@ func (api *API) postWorkspaceBuilds(rw http.ResponseWriter, r *http.Request) {
337
337
})
338
338
return
339
339
}
340
+
341
+ template , err := api .Database .GetTemplateByID (r .Context (), templateVersion .TemplateID .UUID )
342
+ if err != nil {
343
+ httpapi .Write (rw , http .StatusInternalServerError , codersdk.Response {
344
+ Message : "Failed to get template" ,
345
+ Detail : err .Error (),
346
+ })
347
+ return
348
+ }
349
+
350
+ var state []byte
351
+ // If custom state, deny request since user could be corrupting or leaking
352
+ // cloud state.
353
+ if createBuild .ProvisionerState != nil || createBuild .Orphan {
354
+ if ! api .Authorize (r , rbac .ActionUpdate , template .RBACObject ()) {
355
+ httpapi .Write (rw , http .StatusForbidden , codersdk.Response {
356
+ Message : "Only template managers may provide custom state" ,
357
+ })
358
+ return
359
+ }
360
+ state = createBuild .ProvisionerState
361
+ }
362
+
363
+ if createBuild .Orphan {
364
+ if createBuild .Transition != codersdk .WorkspaceTransitionDelete {
365
+ httpapi .Write (rw , http .StatusBadRequest , codersdk.Response {
366
+ Message : "Orphan is only permitted when deleting a workspace." ,
367
+ Detail : err .Error (),
368
+ })
369
+ return
370
+ }
371
+
372
+ if createBuild .ProvisionerState != nil && createBuild .Orphan {
373
+ httpapi .Write (rw , http .StatusBadRequest , codersdk.Response {
374
+ Message : "ProvisionerState cannot be set alongside Orphan since state intent is unclear." ,
375
+ })
376
+ return
377
+ }
378
+ state = []byte {}
379
+ }
380
+
340
381
templateVersionJob , err := api .Database .GetProvisionerJobByID (r .Context (), templateVersion .JobID )
341
382
if err != nil {
342
383
httpapi .Write (rw , http .StatusInternalServerError , codersdk.Response {
@@ -364,15 +405,6 @@ func (api *API) postWorkspaceBuilds(rw http.ResponseWriter, r *http.Request) {
364
405
return
365
406
}
366
407
367
- template , err := api .Database .GetTemplateByID (r .Context (), templateVersion .TemplateID .UUID )
368
- if err != nil {
369
- httpapi .Write (rw , http .StatusInternalServerError , codersdk.Response {
370
- Message : "Internal error fetching template job." ,
371
- Detail : err .Error (),
372
- })
373
- return
374
- }
375
-
376
408
// Store prior build number to compute new build number
377
409
var priorBuildNum int32
378
410
priorHistory , err := api .Database .GetLatestWorkspaceBuildByWorkspaceID (r .Context (), workspace .ID )
@@ -394,40 +426,8 @@ func (api *API) postWorkspaceBuilds(rw http.ResponseWriter, r *http.Request) {
394
426
return
395
427
}
396
428
397
- if createBuild .Orphan {
398
- if createBuild .Transition != codersdk .WorkspaceTransitionDelete {
399
- httpapi .Write (rw , http .StatusBadRequest , codersdk.Response {
400
- Message : "Orphan is only permitted when deleting a workspace." ,
401
- Detail : err .Error (),
402
- })
403
- return
404
- }
405
- if createBuild .ProvisionerState != nil && createBuild .Orphan {
406
- httpapi .Write (rw , http .StatusBadRequest , codersdk.Response {
407
- Message : "ProvisionerState cannot be set alongside Orphan since state intent is unclear." ,
408
- })
409
- return
410
- }
411
-
412
- createBuild .ProvisionerState , err = provisionersdk .OrphanState (priorHistory .ProvisionerState )
413
- if err != nil {
414
- httpapi .Write (rw , http .StatusInternalServerError , codersdk.Response {
415
- Message : "Failed to manipulate state." ,
416
- Detail : err .Error (),
417
- })
418
- return
419
- }
420
- }
421
-
422
- // If custom state, deny request since user could be orphaning their
423
- // cloud resources.
424
- if createBuild .ProvisionerState != nil {
425
- if ! api .Authorize (r , rbac .ActionUpdate , template .RBACObject ()) {
426
- httpapi .Write (rw , http .StatusForbidden , codersdk.Response {
427
- Message : "Only template managers may provide custom state" ,
428
- })
429
- return
430
- }
429
+ if state == nil {
430
+ state = priorHistory .ProvisionerState
431
431
}
432
432
433
433
var workspaceBuild database.WorkspaceBuild
@@ -494,10 +494,6 @@ func (api *API) postWorkspaceBuilds(rw http.ResponseWriter, r *http.Request) {
494
494
if err != nil {
495
495
return xerrors .Errorf ("insert provisioner job: %w" , err )
496
496
}
497
- state := createBuild .ProvisionerState
498
- if len (state ) == 0 {
499
- state = priorHistory .ProvisionerState
500
- }
501
497
502
498
workspaceBuild , err = db .InsertWorkspaceBuild (r .Context (), database.InsertWorkspaceBuildParams {
503
499
ID : workspaceBuildID ,
0 commit comments