diff --git a/coderd/database/queries.sql.go b/coderd/database/queries.sql.go index 75560ffec4..49ecffbe51 100644 --- a/coderd/database/queries.sql.go +++ b/coderd/database/queries.sql.go @@ -5408,6 +5408,7 @@ WHERE w.id IN (SELECT p.id WHERE (b.transition = 'start'::workspace_transition AND pj.job_status IN ('succeeded'::provisioner_job_status)) AND b.template_version_id = t.active_version_id + AND b.template_version_preset_id = $3::uuid ORDER BY random() LIMIT 1 FOR UPDATE OF p SKIP LOCKED) RETURNING w.id, w.name @@ -5416,6 +5417,7 @@ RETURNING w.id, w.name type ClaimPrebuildParams struct { NewUserID uuid.UUID `db:"new_user_id" json:"new_user_id"` NewName string `db:"new_name" json:"new_name"` + PresetID uuid.UUID `db:"preset_id" json:"preset_id"` } type ClaimPrebuildRow struct { @@ -5425,7 +5427,7 @@ type ClaimPrebuildRow struct { // TODO: rewrite to use named CTE instead? func (q *sqlQuerier) ClaimPrebuild(ctx context.Context, arg ClaimPrebuildParams) (ClaimPrebuildRow, error) { - row := q.db.QueryRowContext(ctx, claimPrebuild, arg.NewUserID, arg.NewName) + row := q.db.QueryRowContext(ctx, claimPrebuild, arg.NewUserID, arg.NewName, arg.PresetID) var i ClaimPrebuildRow err := row.Scan(&i.ID, &i.Name) return i, err diff --git a/coderd/database/queries/prebuilds.sql b/coderd/database/queries/prebuilds.sql index ea729d3ee9..c1071e7a66 100644 --- a/coderd/database/queries/prebuilds.sql +++ b/coderd/database/queries/prebuilds.sql @@ -105,6 +105,7 @@ WHERE w.id IN (SELECT p.id WHERE (b.transition = 'start'::workspace_transition AND pj.job_status IN ('succeeded'::provisioner_job_status)) AND b.template_version_id = t.active_version_id + AND b.template_version_preset_id = @preset_id::uuid ORDER BY random() LIMIT 1 FOR UPDATE OF p SKIP LOCKED) RETURNING w.id, w.name; diff --git a/coderd/prebuilds/claim.go b/coderd/prebuilds/claim.go index 339c532418..120dae13d0 100644 --- a/coderd/prebuilds/claim.go +++ b/coderd/prebuilds/claim.go @@ -9,7 +9,7 @@ import ( "golang.org/x/xerrors" ) -func Claim(ctx context.Context, store database.Store, userID uuid.UUID, name string) (*uuid.UUID, error) { +func Claim(ctx context.Context, store database.Store, userID uuid.UUID, name string, presetID uuid.UUID) (*uuid.UUID, error) { var prebuildID *uuid.UUID err := store.InTx(func(db database.Store) error { // TODO: do we need this? @@ -22,6 +22,7 @@ func Claim(ctx context.Context, store database.Store, userID uuid.UUID, name str result, err := db.ClaimPrebuild(ctx, database.ClaimPrebuildParams{ NewUserID: userID, NewName: name, + PresetID: presetID, }) if err != nil { switch { diff --git a/coderd/presets.go b/coderd/presets.go index a2787b63e7..1b5f646438 100644 --- a/coderd/presets.go +++ b/coderd/presets.go @@ -45,6 +45,10 @@ func (api *API) templateVersionPresets(rw http.ResponseWriter, r *http.Request) Name: preset.Name, } for _, presetParam := range presetParams { + if presetParam.TemplateVersionPresetID != preset.ID { + continue + } + sdkPreset.Parameters = append(sdkPreset.Parameters, codersdk.PresetParameter{ Name: presetParam.Name, Value: presetParam.Value, diff --git a/coderd/workspaces.go b/coderd/workspaces.go index c6419567bf..36d1c6060e 100644 --- a/coderd/workspaces.go +++ b/coderd/workspaces.go @@ -633,12 +633,18 @@ func createWorkspace( runningWorkspaceAgentID uuid.UUID ) err = api.Database.InTx(func(db database.Store) error { - var workspaceID uuid.UUID + var ( + workspaceID uuid.UUID + claimedWorkspace *database.Workspace + ) - // Try and claim an eligible prebuild, if available. - claimedWorkspace, err := claimPrebuild(ctx, db, api.Logger, req, owner) - if err != nil { - return xerrors.Errorf("claim prebuild: %w", err) + // If a template preset was chosen, try claim a prebuild. + if req.TemplateVersionPresetID != uuid.Nil { + // Try and claim an eligible prebuild, if available. + claimedWorkspace, err = claimPrebuild(ctx, db, api.Logger, req, owner) + if err != nil { + return xerrors.Errorf("claim prebuild: %w", err) + } } // No prebuild found; regular flow. @@ -813,9 +819,7 @@ func claimPrebuild(ctx context.Context, db database.Store, logger slog.Logger, r claimCtx, cancel := context.WithTimeout(ownerCtx, time.Second*10) // TODO: don't use elevated authz context defer cancel() - // TODO: implement matching logic - // TODO: pass down rich params for matching - claimedID, err := prebuilds.Claim(claimCtx, db, owner.ID, req.Name) + claimedID, err := prebuilds.Claim(claimCtx, db, owner.ID, req.Name, req.TemplateVersionPresetID) if err != nil { // TODO: enhance this by clarifying whether this *specific* prebuild failed or whether there are none to claim. return nil, xerrors.Errorf("claim prebuild: %w", err)