Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit9cfb23a

Browse files
committed
feat: cancel pending prebuilds on template publish
1 parent77e8d2b commit9cfb23a

File tree

9 files changed

+320
-51
lines changed

9 files changed

+320
-51
lines changed

‎coderd/database/dbauthz/dbauthz.go‎

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2934,6 +2934,25 @@ func (q *querier) GetTemplateByID(ctx context.Context, id uuid.UUID) (database.T
29342934
returnfetch(q.log,q.auth,q.db.GetTemplateByID)(ctx,id)
29352935
}
29362936

2937+
// GetTemplateByIDWithLock acquires an exclusive lock on the template and returns it.
2938+
// This method MUST be called within a transaction, otherwise the lock
2939+
// will be released immediately after acquisition, defeating its purpose.
2940+
func (q*querier)GetTemplateByIDWithLock(ctx context.Context,id uuid.UUID) (database.TemplateTable,error) {
2941+
// Acquire the lock on the templates table
2942+
templateTable,err:=q.db.GetTemplateByIDWithLock(ctx,id)
2943+
iferr!=nil {
2944+
return database.TemplateTable{},xerrors.Errorf("acquire template lock: %w",err)
2945+
}
2946+
2947+
// Authorize read access to the template
2948+
_,err=q.GetTemplateByID(ctx,id)
2949+
iferr!=nil {
2950+
return database.TemplateTable{},xerrors.Errorf("fetch template: %w",err)
2951+
}
2952+
2953+
returntemplateTable,nil
2954+
}
2955+
29372956
func (q*querier)GetTemplateByOrganizationAndName(ctx context.Context,arg database.GetTemplateByOrganizationAndNameParams) (database.Template,error) {
29382957
returnfetch(q.log,q.auth,q.db.GetTemplateByOrganizationAndName)(ctx,arg)
29392958
}
@@ -4820,6 +4839,16 @@ func (q *querier) UpdateOrganizationDeletedByID(ctx context.Context, arg databas
48204839
returndeleteQ(q.log,q.auth,q.db.GetOrganizationByID,deleteF)(ctx,arg.ID)
48214840
}
48224841

4842+
func (q*querier)UpdatePrebuildProvisionerJobWithCancel(ctx context.Context,arg database.UpdatePrebuildProvisionerJobWithCancelParams) ([]uuid.UUID,error) {
4843+
// This is a system-only operation for canceling pending prebuild-related jobs
4844+
// when a new template version is promoted.
4845+
// User authorization is checked at the template promotion level.
4846+
iferr:=q.authorizeContext(ctx,policy.ActionRead,rbac.ResourceSystem);err!=nil {
4847+
return []uuid.UUID{},err
4848+
}
4849+
returnq.db.UpdatePrebuildProvisionerJobWithCancel(ctx,arg)
4850+
}
4851+
48234852
func (q*querier)UpdatePresetPrebuildStatus(ctx context.Context,arg database.UpdatePresetPrebuildStatusParams)error {
48244853
preset,err:=q.db.GetPresetByID(ctx,arg.PresetID)
48254854
iferr!=nil {

‎coderd/database/dbauthz/dbauthz_test.go‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -641,6 +641,17 @@ func (s *MethodTestSuite) TestProvisionerJob() {
641641
dbm.EXPECT().UpdateProvisionerJobWithCancelByID(gomock.Any(),arg).Return(nil).AnyTimes()
642642
check.Args(arg).Asserts(v.RBACObject(tpl), []policy.Action{policy.ActionRead,policy.ActionUpdate}).Returns()
643643
}))
644+
s.Run("UpdatePrebuildProvisionerJobWithCancel",s.Mocked(func(dbm*dbmock.MockStore,faker*gofakeit.Faker,check*expects) {
645+
arg:= database.UpdatePrebuildProvisionerJobWithCancelParams{
646+
Now:dbtime.Now(),
647+
TemplateID:uuid.New(),
648+
TemplateVersionID:uuid.New(),
649+
}
650+
jobIDs:= []uuid.UUID{uuid.New(),uuid.New()}
651+
652+
dbm.EXPECT().UpdatePrebuildProvisionerJobWithCancel(gomock.Any(),arg).Return(jobIDs,nil).AnyTimes()
653+
check.Args(arg).Asserts(rbac.ResourceSystem,policy.ActionRead).Returns(jobIDs)
654+
}))
644655
s.Run("GetProvisionerJobsByIDs",s.Mocked(func(dbm*dbmock.MockStore,faker*gofakeit.Faker,check*expects) {
645656
org:=testutil.Fake(s.T(),faker, database.Organization{})
646657
org2:=testutil.Fake(s.T(),faker, database.Organization{})
@@ -1009,6 +1020,16 @@ func (s *MethodTestSuite) TestTemplate() {
10091020
dbm.EXPECT().GetTemplateByID(gomock.Any(),t1.ID).Return(t1,nil).AnyTimes()
10101021
check.Args(t1.ID).Asserts(t1,policy.ActionRead).Returns(t1)
10111022
}))
1023+
s.Run("GetTemplateByIDWithLock",s.Mocked(func(dbm*dbmock.MockStore,faker*gofakeit.Faker,check*expects) {
1024+
tt1:=testutil.Fake(s.T(),faker, database.TemplateTable{})
1025+
t1:=testutil.Fake(s.T(),faker, database.Template{})
1026+
t1.ID=tt1.ID
1027+
1028+
dbm.EXPECT().GetTemplateByIDWithLock(gomock.Any(),tt1.ID).Return(tt1,nil).AnyTimes()
1029+
dbm.EXPECT().GetTemplateByID(gomock.Any(),t1.ID).Return(t1,nil).AnyTimes()
1030+
1031+
check.Args(tt1.ID).Asserts(t1,policy.ActionRead).Returns(tt1)
1032+
}))
10121033
s.Run("GetTemplateByOrganizationAndName",s.Mocked(func(dbm*dbmock.MockStore,faker*gofakeit.Faker,check*expects) {
10131034
t1:=testutil.Fake(s.T(),faker, database.Template{})
10141035
arg:= database.GetTemplateByOrganizationAndNameParams{Name:t1.Name,OrganizationID:t1.OrganizationID}

‎coderd/database/dbmetrics/querymetrics.go‎

Lines changed: 14 additions & 0 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎coderd/database/dbmock/dbmock.go‎

Lines changed: 30 additions & 0 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎coderd/database/querier.go‎

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎coderd/database/queries.sql.go‎

Lines changed: 103 additions & 2 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎coderd/database/queries/provisionerjobs.sql‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,32 @@ SET
282282
WHERE
283283
id= $1;
284284

285+
-- name: UpdatePrebuildProvisionerJobWithCancel :many
286+
-- Cancels all pending provisioner jobs for prebuilt workspaces on a specific template version.
287+
-- This is called when a new template version is promoted to active.
288+
UPDATE provisioner_jobs
289+
SET
290+
canceled_at= @now::timestamptz,
291+
completed_at= @now::timestamptz
292+
WHERE idIN (
293+
SELECTpj.id
294+
FROM provisioner_jobs pj
295+
INNER JOIN workspace_builds wbONwb.job_id=pj.id
296+
INNER JOIN workspaces wONw.id=wb.workspace_id
297+
WHERE
298+
w.template_id= @template_id
299+
ANDwb.template_version_id= @template_version_id
300+
-- Prebuilds system user: prebuild-related provisioner jobs
301+
ANDw.owner_id='c42fdf75-3097-471c-8c33-fb52454d81c0'::uuid
302+
ANDwb.transition='start'::workspace_transition
303+
-- Pending jobs that have not been picked up by a provisioner yet
304+
ANDpj.worker_id ISNULL
305+
ANDpj.job_status='pending'::provisioner_job_status
306+
ANDpj.canceled_at ISNULL
307+
ANDpj.completed_at ISNULL
308+
)
309+
RETURNING id;
310+
285311
-- name: UpdateProvisionerJobWithCompleteByID :exec
286312
UPDATE
287313
provisioner_jobs

‎coderd/database/queries/templates.sql‎

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,14 @@ FROM
55
template_with_names
66
WHERE
77
id= $1
8-
LIMIT
9-
1;
8+
LIMIT1;
9+
10+
-- name: GetTemplateByIDWithLock :one
11+
-- Gets a template by ID with an exclusive lock for update.
12+
SELECT*
13+
FROM templates
14+
WHERE id= $1
15+
FORUPDATE;
1016

1117
-- name: GetTemplatesWithFilter :many
1218
SELECT

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp