fix(coderd/database): avoid clobbering workspace build state (#9826)

Fixes #9823.

- Decomposes UpdateWorkspaceBuildByID into UpdateWorkspaceBuildProvisionerStateByID and UpdateWorkspaceBuildDeadlineByID.
- Replaces existing invocations of UpdateWorkspaceBuildByID with the newer queries where applicable.
- Modifies GetActiveWorkspaceBuildsByTemplateID to not return incomplete workspace builds.
This commit is contained in:
Cian Johnston
2023-09-22 16:22:07 +01:00
committed by GitHub
parent a1f3a6b606
commit 8d8402da00
14 changed files with 258 additions and 135 deletions
+13 -6
View File
@@ -2675,7 +2675,15 @@ func (q *querier) UpdateWorkspaceAutostart(ctx context.Context, arg database.Upd
return update(q.log, q.auth, fetch, q.db.UpdateWorkspaceAutostart)(ctx, arg)
}
func (q *querier) UpdateWorkspaceBuildByID(ctx context.Context, arg database.UpdateWorkspaceBuildByIDParams) error {
// UpdateWorkspaceBuildCostByID is used by the provisioning system to update the cost of a workspace build.
func (q *querier) UpdateWorkspaceBuildCostByID(ctx context.Context, arg database.UpdateWorkspaceBuildCostByIDParams) error {
if err := q.authorizeContext(ctx, rbac.ActionUpdate, rbac.ResourceSystem); err != nil {
return err
}
return q.db.UpdateWorkspaceBuildCostByID(ctx, arg)
}
func (q *querier) UpdateWorkspaceBuildDeadlineByID(ctx context.Context, arg database.UpdateWorkspaceBuildDeadlineByIDParams) error {
build, err := q.db.GetWorkspaceBuildByID(ctx, arg.ID)
if err != nil {
return err
@@ -2685,20 +2693,19 @@ func (q *querier) UpdateWorkspaceBuildByID(ctx context.Context, arg database.Upd
if err != nil {
return err
}
err = q.authorizeContext(ctx, rbac.ActionUpdate, workspace.RBACObject())
if err != nil {
return err
}
return q.db.UpdateWorkspaceBuildByID(ctx, arg)
return q.db.UpdateWorkspaceBuildDeadlineByID(ctx, arg)
}
// UpdateWorkspaceBuildCostByID is used by the provisioning system to update the cost of a workspace build.
func (q *querier) UpdateWorkspaceBuildCostByID(ctx context.Context, arg database.UpdateWorkspaceBuildCostByIDParams) error {
func (q *querier) UpdateWorkspaceBuildProvisionerStateByID(ctx context.Context, arg database.UpdateWorkspaceBuildProvisionerStateByIDParams) error {
if err := q.authorizeContext(ctx, rbac.ActionUpdate, rbac.ResourceSystem); err != nil {
return err
}
return q.db.UpdateWorkspaceBuildCostByID(ctx, arg)
return q.db.UpdateWorkspaceBuildProvisionerStateByID(ctx, arg)
}
// Deprecated: Use SoftDeleteWorkspaceByID
+13 -6
View File
@@ -1232,14 +1232,13 @@ func (s *MethodTestSuite) TestWorkspace() {
ID: ws.ID,
}).Asserts(ws, rbac.ActionUpdate).Returns()
}))
s.Run("UpdateWorkspaceBuildByID", s.Subtest(func(db database.Store, check *expects) {
s.Run("UpdateWorkspaceBuildDeadlineByID", s.Subtest(func(db database.Store, check *expects) {
ws := dbgen.Workspace(s.T(), db, database.Workspace{})
build := dbgen.WorkspaceBuild(s.T(), db, database.WorkspaceBuild{WorkspaceID: ws.ID, JobID: uuid.New()})
check.Args(database.UpdateWorkspaceBuildByIDParams{
ID: build.ID,
UpdatedAt: build.UpdatedAt,
Deadline: build.Deadline,
ProvisionerState: []byte{},
check.Args(database.UpdateWorkspaceBuildDeadlineByIDParams{
ID: build.ID,
UpdatedAt: build.UpdatedAt,
Deadline: build.Deadline,
}).Asserts(ws, rbac.ActionUpdate)
}))
s.Run("SoftDeleteWorkspaceByID", s.Subtest(func(db database.Store, check *expects) {
@@ -1378,6 +1377,14 @@ func (s *MethodTestSuite) TestSystemFunctions() {
DailyCost: 10,
}).Asserts(rbac.ResourceSystem, rbac.ActionUpdate)
}))
s.Run("UpdateWorkspaceBuildProvisionerStateByID", s.Subtest(func(db database.Store, check *expects) {
ws := dbgen.Workspace(s.T(), db, database.Workspace{})
build := dbgen.WorkspaceBuild(s.T(), db, database.WorkspaceBuild{WorkspaceID: ws.ID, JobID: uuid.New()})
check.Args(database.UpdateWorkspaceBuildProvisionerStateByIDParams{
ID: build.ID,
ProvisionerState: []byte("testing"),
}).Asserts(rbac.ResourceSystem, rbac.ActionUpdate)
}))
s.Run("UpsertLastUpdateCheck", s.Subtest(func(db database.Store, check *expects) {
check.Args("value").Asserts(rbac.ResourceSystem, rbac.ActionUpdate)
}))