Claim prebuild by preset ID

Signed-off-by: Danny Kopping <danny@coder.com>
This commit is contained in:
Danny Kopping
2025-02-14 13:38:17 +00:00
parent 2b296244a5
commit c3f67f8169
5 changed files with 22 additions and 10 deletions

View File

@ -5408,6 +5408,7 @@ WHERE w.id IN (SELECT p.id
WHERE (b.transition = 'start'::workspace_transition WHERE (b.transition = 'start'::workspace_transition
AND pj.job_status IN ('succeeded'::provisioner_job_status)) AND pj.job_status IN ('succeeded'::provisioner_job_status))
AND b.template_version_id = t.active_version_id AND b.template_version_id = t.active_version_id
AND b.template_version_preset_id = $3::uuid
ORDER BY random() ORDER BY random()
LIMIT 1 FOR UPDATE OF p SKIP LOCKED) LIMIT 1 FOR UPDATE OF p SKIP LOCKED)
RETURNING w.id, w.name RETURNING w.id, w.name
@ -5416,6 +5417,7 @@ RETURNING w.id, w.name
type ClaimPrebuildParams struct { type ClaimPrebuildParams struct {
NewUserID uuid.UUID `db:"new_user_id" json:"new_user_id"` NewUserID uuid.UUID `db:"new_user_id" json:"new_user_id"`
NewName string `db:"new_name" json:"new_name"` NewName string `db:"new_name" json:"new_name"`
PresetID uuid.UUID `db:"preset_id" json:"preset_id"`
} }
type ClaimPrebuildRow struct { type ClaimPrebuildRow struct {
@ -5425,7 +5427,7 @@ type ClaimPrebuildRow struct {
// TODO: rewrite to use named CTE instead? // TODO: rewrite to use named CTE instead?
func (q *sqlQuerier) ClaimPrebuild(ctx context.Context, arg ClaimPrebuildParams) (ClaimPrebuildRow, error) { 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 var i ClaimPrebuildRow
err := row.Scan(&i.ID, &i.Name) err := row.Scan(&i.ID, &i.Name)
return i, err return i, err

View File

@ -105,6 +105,7 @@ WHERE w.id IN (SELECT p.id
WHERE (b.transition = 'start'::workspace_transition WHERE (b.transition = 'start'::workspace_transition
AND pj.job_status IN ('succeeded'::provisioner_job_status)) AND pj.job_status IN ('succeeded'::provisioner_job_status))
AND b.template_version_id = t.active_version_id AND b.template_version_id = t.active_version_id
AND b.template_version_preset_id = @preset_id::uuid
ORDER BY random() ORDER BY random()
LIMIT 1 FOR UPDATE OF p SKIP LOCKED) LIMIT 1 FOR UPDATE OF p SKIP LOCKED)
RETURNING w.id, w.name; RETURNING w.id, w.name;

View File

@ -9,7 +9,7 @@ import (
"golang.org/x/xerrors" "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 var prebuildID *uuid.UUID
err := store.InTx(func(db database.Store) error { err := store.InTx(func(db database.Store) error {
// TODO: do we need this? // 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{ result, err := db.ClaimPrebuild(ctx, database.ClaimPrebuildParams{
NewUserID: userID, NewUserID: userID,
NewName: name, NewName: name,
PresetID: presetID,
}) })
if err != nil { if err != nil {
switch { switch {

View File

@ -45,6 +45,10 @@ func (api *API) templateVersionPresets(rw http.ResponseWriter, r *http.Request)
Name: preset.Name, Name: preset.Name,
} }
for _, presetParam := range presetParams { for _, presetParam := range presetParams {
if presetParam.TemplateVersionPresetID != preset.ID {
continue
}
sdkPreset.Parameters = append(sdkPreset.Parameters, codersdk.PresetParameter{ sdkPreset.Parameters = append(sdkPreset.Parameters, codersdk.PresetParameter{
Name: presetParam.Name, Name: presetParam.Name,
Value: presetParam.Value, Value: presetParam.Value,

View File

@ -633,13 +633,19 @@ func createWorkspace(
runningWorkspaceAgentID uuid.UUID runningWorkspaceAgentID uuid.UUID
) )
err = api.Database.InTx(func(db database.Store) error { err = api.Database.InTx(func(db database.Store) error {
var workspaceID uuid.UUID var (
workspaceID uuid.UUID
claimedWorkspace *database.Workspace
)
// If a template preset was chosen, try claim a prebuild.
if req.TemplateVersionPresetID != uuid.Nil {
// Try and claim an eligible prebuild, if available. // Try and claim an eligible prebuild, if available.
claimedWorkspace, err := claimPrebuild(ctx, db, api.Logger, req, owner) claimedWorkspace, err = claimPrebuild(ctx, db, api.Logger, req, owner)
if err != nil { if err != nil {
return xerrors.Errorf("claim prebuild: %w", err) return xerrors.Errorf("claim prebuild: %w", err)
} }
}
// No prebuild found; regular flow. // No prebuild found; regular flow.
if claimedWorkspace == nil { if claimedWorkspace == nil {
@ -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 claimCtx, cancel := context.WithTimeout(ownerCtx, time.Second*10) // TODO: don't use elevated authz context
defer cancel() defer cancel()
// TODO: implement matching logic claimedID, err := prebuilds.Claim(claimCtx, db, owner.ID, req.Name, req.TemplateVersionPresetID)
// TODO: pass down rich params for matching
claimedID, err := prebuilds.Claim(claimCtx, db, owner.ID, req.Name)
if err != nil { if err != nil {
// TODO: enhance this by clarifying whether this *specific* prebuild failed or whether there are none to claim. // 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) return nil, xerrors.Errorf("claim prebuild: %w", err)