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

Commited0e3ab

Browse files
committed
feat: cancel pending prebuilds on template publish
1 parent86f0f39 commited0e3ab

File tree

10 files changed

+327
-51
lines changed

10 files changed

+327
-51
lines changed

‎coderd/database/dbauthz/dbauthz.go‎

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2942,6 +2942,30 @@ func (q *querier) GetTemplateByID(ctx context.Context, id uuid.UUID) (database.T
29422942
returnfetch(q.log,q.auth,q.db.GetTemplateByID)(ctx,id)
29432943
}
29442944

2945+
// GetTemplateByIDWithLock acquires an exclusive lock on the template and returns it.
2946+
// This method MUST be called within a transaction, otherwise the lock
2947+
// will be released immediately after acquisition, defeating its purpose.
2948+
func (q*querier)GetTemplateByIDWithLock(ctx context.Context,id uuid.UUID) (database.TemplateTable,error) {
2949+
act,ok:=ActorFromContext(ctx)
2950+
if!ok {
2951+
return database.TemplateTable{},ErrNoActor
2952+
}
2953+
2954+
// Acquire the lock on the templates table
2955+
templateTable,err:=q.db.GetTemplateByIDWithLock(ctx,id)
2956+
iferr!=nil {
2957+
return database.TemplateTable{},xerrors.Errorf("acquire template lock: %w",err)
2958+
}
2959+
2960+
// Authorize read access to the template
2961+
err=q.auth.Authorize(ctx,act,policy.ActionRead,templateTable.RBACObject())
2962+
iferr!=nil {
2963+
return database.TemplateTable{},logNotAuthorizedError(ctx,q.log,err)
2964+
}
2965+
2966+
returntemplateTable,nil
2967+
}
2968+
29452969
func (q*querier)GetTemplateByOrganizationAndName(ctx context.Context,arg database.GetTemplateByOrganizationAndNameParams) (database.Template,error) {
29462970
returnfetch(q.log,q.auth,q.db.GetTemplateByOrganizationAndName)(ctx,arg)
29472971
}
@@ -4828,6 +4852,16 @@ func (q *querier) UpdateOrganizationDeletedByID(ctx context.Context, arg databas
48284852
returndeleteQ(q.log,q.auth,q.db.GetOrganizationByID,deleteF)(ctx,arg.ID)
48294853
}
48304854

4855+
func (q*querier)UpdatePrebuildProvisionerJobWithCancel(ctx context.Context,arg database.UpdatePrebuildProvisionerJobWithCancelParams) ([]uuid.UUID,error) {
4856+
// This is a system-only operation for canceling pending prebuild-related jobs
4857+
// when a new template version is promoted.
4858+
// User authorization is checked at the template promotion level.
4859+
iferr:=q.authorizeContext(ctx,policy.ActionRead,rbac.ResourceSystem);err!=nil {
4860+
return []uuid.UUID{},err
4861+
}
4862+
returnq.db.UpdatePrebuildProvisionerJobWithCancel(ctx,arg)
4863+
}
4864+
48314865
func (q*querier)UpdatePresetPrebuildStatus(ctx context.Context,arg database.UpdatePresetPrebuildStatusParams)error {
48324866
preset,err:=q.db.GetPresetByID(ctx,arg.PresetID)
48334867
iferr!=nil {

‎coderd/database/dbauthz/dbauthz_test.go‎

Lines changed: 16 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,11 @@ 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+
dbm.EXPECT().GetTemplateByIDWithLock(gomock.Any(),tt1.ID).Return(tt1,nil).AnyTimes()
1026+
check.Args(tt1.ID).Asserts(tt1,policy.ActionRead).Returns(tt1)
1027+
}))
10121028
s.Run("GetTemplateByOrganizationAndName",s.Mocked(func(dbm*dbmock.MockStore,faker*gofakeit.Faker,check*expects) {
10131029
t1:=testutil.Fake(s.T(),faker, database.Template{})
10141030
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/modelmethods.go‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,13 @@ func (t Template) RBACObject() rbac.Object {
288288
WithGroupACL(t.GroupACL)
289289
}
290290

291+
func (tTemplateTable)RBACObject() rbac.Object {
292+
returnrbac.ResourceTemplate.WithID(t.ID).
293+
InOrg(t.OrganizationID).
294+
WithACLUserList(t.UserACL).
295+
WithGroupACL(t.GroupACL)
296+
}
297+
291298
func (tGetFileTemplatesRow)RBACObject() rbac.Object {
292299
returnrbac.ResourceTemplate.WithID(t.TemplateID).
293300
InOrg(t.TemplateOrganizationID).

‎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+
ANDpj.job_status='pending'::provisioner_job_status
304+
-- Pending jobs that have not yet been picked up by a provisioner
305+
ANDpj.worker_id ISNULL
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