Skip to content

Commit 549aea5

Browse files
fix: bug with deletion of prebuilt workspaces
1 parent 4ac71e9 commit 549aea5

File tree

2 files changed

+79
-5
lines changed

2 files changed

+79
-5
lines changed

enterprise/coderd/prebuilds/reconcile.go

+10-5
Original file line numberDiff line numberDiff line change
@@ -549,13 +549,18 @@ func (c *StoreReconciler) provision(
549549
builder := wsbuilder.New(workspace, transition).
550550
Reason(database.BuildReasonInitiator).
551551
Initiator(prebuilds.SystemUserID).
552-
VersionID(template.ActiveVersionID).
553-
MarkPrebuild().
554-
TemplateVersionPresetID(presetID)
552+
MarkPrebuild()
555553

556-
// We only inject the required params when the prebuild is being created.
557-
// This mirrors the behavior of regular workspace deletion (see cli/delete.go).
558554
if transition != database.WorkspaceTransitionDelete {
555+
// We don't specify the version for a delete transition,
556+
// because the prebuilt workspace may have been created using an older template version.
557+
// If the version isn't explicitly set, the builder will automatically use the version
558+
// from the last workspace build — which is the desired behavior.
559+
builder = builder.VersionID(template.ActiveVersionID)
560+
561+
// We only inject the required params when the prebuild is being created.
562+
// This mirrors the behavior of regular workspace deletion (see cli/delete.go).
563+
builder = builder.TemplateVersionPresetID(presetID)
559564
builder = builder.RichParameterValues(params)
560565
}
561566

enterprise/coderd/prebuilds/reconcile_test.go

+69
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,75 @@ func TestInvalidPreset(t *testing.T) {
554554
}
555555
}
556556

557+
func TestInvalidPresetV2(t *testing.T) {
558+
t.Parallel()
559+
560+
if !dbtestutil.WillUsePostgres() {
561+
t.Skip("This test requires postgres")
562+
}
563+
564+
templateDeleted := false
565+
566+
clock := quartz.NewMock(t)
567+
ctx := testutil.Context(t, testutil.WaitShort)
568+
cfg := codersdk.PrebuildsConfig{}
569+
logger := slogtest.Make(
570+
t, &slogtest.Options{IgnoreErrors: true},
571+
).Leveled(slog.LevelDebug)
572+
db, pubSub := dbtestutil.NewDB(t)
573+
controller := prebuilds.NewStoreReconciler(db, pubSub, cfg, logger, quartz.NewMock(t), prometheus.NewRegistry())
574+
575+
ownerID := uuid.New()
576+
dbgen.User(t, db, database.User{
577+
ID: ownerID,
578+
})
579+
org, template := setupTestDBTemplate(t, db, ownerID, templateDeleted)
580+
templateVersionID := setupTestDBTemplateVersion(ctx, t, clock, db, pubSub, org.ID, ownerID, template.ID)
581+
preset := setupTestDBPreset(t, db, templateVersionID, 1, uuid.New().String())
582+
prebuiltWorkspace := setupTestDBPrebuild(
583+
t,
584+
clock,
585+
db,
586+
pubSub,
587+
database.WorkspaceTransitionStart,
588+
database.ProvisionerJobStatusSucceeded,
589+
org.ID,
590+
preset,
591+
template.ID,
592+
templateVersionID,
593+
)
594+
595+
workspaces, err := db.GetWorkspacesByTemplateID(ctx, template.ID)
596+
require.NoError(t, err)
597+
// make sure we have only one workspace
598+
require.Equal(t, 1, len(workspaces))
599+
600+
// Create a new template version and mark it as active.
601+
// This marks the previous template version as inactive.
602+
templateVersionID = setupTestDBTemplateVersion(ctx, t, clock, db, pubSub, org.ID, ownerID, template.ID)
603+
// Add required param, which is not set in preset.
604+
// It means that creating of new prebuilt workspace will fail, but we should be able to clean up old prebuilt workspaces.
605+
dbgen.TemplateVersionParameter(t, db, database.TemplateVersionParameter{
606+
TemplateVersionID: templateVersionID,
607+
Name: "required-param",
608+
Description: "required param which isn't set in preset",
609+
Type: "bool",
610+
DefaultValue: "",
611+
Required: true,
612+
})
613+
614+
// Old prebuilt workspace should be deleted.
615+
require.NoError(t, controller.ReconcileAll(ctx))
616+
617+
builds, err := db.GetWorkspaceBuildsByWorkspaceID(ctx, database.GetWorkspaceBuildsByWorkspaceIDParams{
618+
WorkspaceID: prebuiltWorkspace.ID,
619+
})
620+
require.NoError(t, err)
621+
// Make sure old prebuild workspace was deleted, despite it contains required parameter which isn't set in preset.
622+
require.Equal(t, 2, len(builds))
623+
require.Equal(t, database.WorkspaceTransitionDelete, builds[0].Transition)
624+
}
625+
557626
func TestRunLoop(t *testing.T) {
558627
t.Parallel()
559628

0 commit comments

Comments
 (0)