Skip to content

Commit 4385933

Browse files
committed
WIP
1 parent 8aa1ee2 commit 4385933

File tree

18 files changed

+177
-161
lines changed

18 files changed

+177
-161
lines changed

cli/server.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1127,11 +1127,11 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd.
11271127
ctx, options.Database, options.Pubsub, options.PrometheusRegistry, coderAPI.TemplateScheduleStore, &coderAPI.Auditor, coderAPI.AccessControlStore, logger, autobuildTicker.C, options.NotificationsEnqueuer)
11281128
autobuildExecutor.Run()
11291129

1130-
hangDetectorTicker := time.NewTicker(vals.JobHangDetectorInterval.Value())
1131-
defer hangDetectorTicker.Stop()
1132-
hangDetector := jobreaper.New(ctx, options.Database, options.Pubsub, logger, hangDetectorTicker.C)
1133-
hangDetector.Start()
1134-
defer hangDetector.Close()
1130+
jobReaperTicker := time.NewTicker(vals.JobReaperDetectorInterval.Value())
1131+
defer jobReaperTicker.Stop()
1132+
jobReaper := jobreaper.New(ctx, options.Database, options.Pubsub, logger, jobReaperTicker.C)
1133+
jobReaper.Start()
1134+
defer jobReaper.Close()
11351135

11361136
waitForProvisionerJobs := false
11371137
// Currently there is no way to ask the server to shut

coderd/coderdtest/coderdtest.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -365,11 +365,11 @@ func NewOptions(t testing.TB, options *Options) (func(http.Handler), context.Can
365365
).WithStatsChannel(options.AutobuildStats)
366366
lifecycleExecutor.Run()
367367

368-
hangDetectorTicker := time.NewTicker(options.DeploymentValues.JobHangDetectorInterval.Value())
369-
defer hangDetectorTicker.Stop()
370-
hangDetector := jobreaper.New(ctx, options.Database, options.Pubsub, options.Logger.Named("reaper.detector"), hangDetectorTicker.C)
371-
hangDetector.Start()
372-
t.Cleanup(hangDetector.Close)
368+
jobReaperTicker := time.NewTicker(options.DeploymentValues.JobReaperDetectorInterval.Value())
369+
defer jobReaperTicker.Stop()
370+
jobReaper := jobreaper.New(ctx, options.Database, options.Pubsub, options.Logger.Named("reaper.detector"), jobReaperTicker.C)
371+
jobReaper.Start()
372+
t.Cleanup(jobReaper.Close)
373373

374374
if options.TelemetryReporter == nil {
375375
options.TelemetryReporter = telemetry.NewNoop()

coderd/database/dbauthz/dbauthz.go

Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -220,18 +220,19 @@ var (
220220
}.WithCachedASTValue()
221221

222222
// See reaper package.
223-
subjectHangDetector = rbac.Subject{
224-
Type: rbac.SubjectTypeHangDetector,
225-
FriendlyName: "Hang Detector",
223+
subjectJobReaper = rbac.Subject{
224+
Type: rbac.SubjectTypeJobReaper,
225+
FriendlyName: "Job Reaper",
226226
ID: uuid.Nil.String(),
227227
Roles: rbac.Roles([]rbac.Role{
228228
{
229-
Identifier: rbac.RoleIdentifier{Name: "hangdetector"},
230-
DisplayName: "Hang Detector Daemon",
229+
Identifier: rbac.RoleIdentifier{Name: "jobreaper"},
230+
DisplayName: "Job Reaper Daemon",
231231
Site: rbac.Permissions(map[string][]policy.Action{
232-
rbac.ResourceSystem.Type: {policy.WildcardSymbol},
233-
rbac.ResourceTemplate.Type: {policy.ActionRead},
234-
rbac.ResourceWorkspace.Type: {policy.ActionRead, policy.ActionUpdate},
232+
rbac.ResourceSystem.Type: {policy.WildcardSymbol},
233+
rbac.ResourceTemplate.Type: {policy.ActionRead},
234+
rbac.ResourceWorkspace.Type: {policy.ActionRead, policy.ActionUpdate},
235+
rbac.ResourceProvisionerJobs.Type: {policy.ActionRead, policy.ActionUpdate},
235236
}),
236237
Org: map[string][]rbac.Permission{},
237238
User: []rbac.Permission{},
@@ -407,10 +408,10 @@ func AsAutostart(ctx context.Context) context.Context {
407408
return As(ctx, subjectAutostart)
408409
}
409410

410-
// AsHangDetector returns a context with an actor that has permissions required
411+
// AsJobReaper returns a context with an actor that has permissions required
411412
// for reaper.Detector to function.
412-
func AsHangDetector(ctx context.Context) context.Context {
413-
return As(ctx, subjectHangDetector)
413+
func AsJobReaper(ctx context.Context) context.Context {
414+
return As(ctx, subjectJobReaper)
414415
}
415416

416417
// AsKeyRotator returns a context with an actor that has permissions required for rotating crypto keys.
@@ -1074,6 +1075,13 @@ func (q *querier) customRoleCheck(ctx context.Context, role database.CustomRole)
10741075
return nil
10751076
}
10761077

1078+
func (q *querier) GetPendingProvisionerJobs(ctx context.Context, lastUpdatedSince time.Time) ([]database.ProvisionerJob, error) {
1079+
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceProvisionerJobs); err != nil {
1080+
return nil, err
1081+
}
1082+
return q.db.GetPendingProvisionerJobs(ctx, lastUpdatedSince)
1083+
}
1084+
10771085
func (q *querier) AcquireLock(ctx context.Context, id int64) error {
10781086
return q.db.AcquireLock(ctx, id)
10791087
}
@@ -1912,11 +1920,10 @@ func (q *querier) GetHealthSettings(ctx context.Context) (string, error) {
19121920
return q.db.GetHealthSettings(ctx)
19131921
}
19141922

1915-
// TODO: We need to create a ProvisionerJob resource type
19161923
func (q *querier) GetHungProvisionerJobs(ctx context.Context, hungSince time.Time) ([]database.ProvisionerJob, error) {
1917-
// if err := q.authorizeContext(ctx, policy.ActionCreate, rbac.ResourceSystem); err != nil {
1918-
// return nil, err
1919-
// }
1924+
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceProvisionerJobs); err != nil {
1925+
return nil, err
1926+
}
19201927
return q.db.GetHungProvisionerJobs(ctx, hungSince)
19211928
}
19221929

@@ -1992,10 +1999,6 @@ func (q *querier) GetLogoURL(ctx context.Context) (string, error) {
19921999
return q.db.GetLogoURL(ctx)
19932000
}
19942001

1995-
func (q *querier) GetNotStartedProvisionerJobs(ctx context.Context, notStartedSince time.Time) ([]database.ProvisionerJob, error) {
1996-
return q.db.GetNotStartedProvisionerJobs(ctx, notStartedSince)
1997-
}
1998-
19992002
func (q *querier) GetNotificationMessagesByStatus(ctx context.Context, arg database.GetNotificationMessagesByStatusParams) ([]database.NotificationMessage, error) {
20002003
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceNotificationMessage); err != nil {
20012004
return nil, err
@@ -4180,6 +4183,10 @@ func (q *querier) UpdateProvisionerJobByID(ctx context.Context, arg database.Upd
41804183
}
41814184

41824185
func (q *querier) UpdateProvisionerJobWithCancelByID(ctx context.Context, arg database.UpdateProvisionerJobWithCancelByIDParams) error {
4186+
if err := q.authorizeContext(ctx, policy.ActionUpdate, rbac.ResourceProvisionerJobs); err != nil {
4187+
return err
4188+
}
4189+
41834190
job, err := q.db.GetProvisionerJobByID(ctx, arg.ID)
41844191
if err != nil {
41854192
return err
@@ -4246,15 +4253,17 @@ func (q *querier) UpdateProvisionerJobWithCancelByID(ctx context.Context, arg da
42464253
return q.db.UpdateProvisionerJobWithCancelByID(ctx, arg)
42474254
}
42484255

4249-
// TODO: We need to create a ProvisionerJob resource type
42504256
func (q *querier) UpdateProvisionerJobWithCompleteByID(ctx context.Context, arg database.UpdateProvisionerJobWithCompleteByIDParams) error {
4251-
// if err := q.authorizeContext(ctx, policy.ActionUpdate, rbac.ResourceSystem); err != nil {
4252-
// return err
4253-
// }
4257+
if err := q.authorizeContext(ctx, policy.ActionUpdate, rbac.ResourceProvisionerJobs); err != nil {
4258+
return err
4259+
}
42544260
return q.db.UpdateProvisionerJobWithCompleteByID(ctx, arg)
42554261
}
42564262

42574263
func (q *querier) UpdateProvisionerJobWithCompleteWithStartedAtByID(ctx context.Context, arg database.UpdateProvisionerJobWithCompleteWithStartedAtByIDParams) error {
4264+
if err := q.authorizeContext(ctx, policy.ActionUpdate, rbac.ResourceProvisionerJobs); err != nil {
4265+
return err
4266+
}
42584267
return q.db.UpdateProvisionerJobWithCompleteWithStartedAtByID(ctx, arg)
42594268
}
42604269

coderd/database/dbauthz/dbauthz_test.go

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3891,9 +3891,8 @@ func (s *MethodTestSuite) TestSystemFunctions() {
38913891
check.Args().Asserts(rbac.ResourceSystem, policy.ActionDelete)
38923892
}))
38933893
s.Run("GetProvisionerJobsCreatedAfter", s.Subtest(func(db database.Store, check *expects) {
3894-
// TODO: add provisioner job resource type
38953894
_ = dbgen.ProvisionerJob(s.T(), db, nil, database.ProvisionerJob{CreatedAt: time.Now().Add(-time.Hour)})
3896-
check.Args(time.Now()).Asserts( /*rbac.ResourceSystem, policy.ActionRead*/ )
3895+
check.Args(time.Now()).Asserts(rbac.ResourceSystem, policy.ActionRead)
38973896
}))
38983897
s.Run("GetTemplateVersionsByIDs", s.Subtest(func(db database.Store, check *expects) {
38993898
dbtestutil.DisableForeignKeysAndTriggers(s.T(), db)
@@ -3976,11 +3975,10 @@ func (s *MethodTestSuite) TestSystemFunctions() {
39763975
Returns([]database.WorkspaceAgent{agt})
39773976
}))
39783977
s.Run("GetProvisionerJobsByIDs", s.Subtest(func(db database.Store, check *expects) {
3979-
// TODO: add a ProvisionerJob resource type
39803978
a := dbgen.ProvisionerJob(s.T(), db, nil, database.ProvisionerJob{})
39813979
b := dbgen.ProvisionerJob(s.T(), db, nil, database.ProvisionerJob{})
39823980
check.Args([]uuid.UUID{a.ID, b.ID}).
3983-
Asserts( /*rbac.ResourceSystem, policy.ActionRead*/ ).
3981+
Asserts(rbac.ResourceSystem, policy.ActionRead).
39843982
Returns(slice.New(a, b))
39853983
}))
39863984
s.Run("InsertWorkspaceAgent", s.Subtest(func(db database.Store, check *expects) {
@@ -4015,7 +4013,6 @@ func (s *MethodTestSuite) TestSystemFunctions() {
40154013
}).Asserts(rbac.ResourceSystem, policy.ActionUpdate).Returns()
40164014
}))
40174015
s.Run("AcquireProvisionerJob", s.Subtest(func(db database.Store, check *expects) {
4018-
// TODO: we need to create a ProvisionerJob resource
40194016
j := dbgen.ProvisionerJob(s.T(), db, nil, database.ProvisionerJob{
40204017
StartedAt: sql.NullTime{Valid: false},
40214018
UpdatedAt: time.Now(),
@@ -4025,54 +4022,48 @@ func (s *MethodTestSuite) TestSystemFunctions() {
40254022
OrganizationID: j.OrganizationID,
40264023
Types: []database.ProvisionerType{j.Provisioner},
40274024
ProvisionerTags: must(json.Marshal(j.Tags)),
4028-
}).Asserts( /*rbac.ResourceSystem, policy.ActionUpdate*/ )
4025+
}).Asserts(rbac.ResourceSystem, policy.ActionUpdate)
40294026
}))
40304027
s.Run("UpdateProvisionerJobWithCompleteByID", s.Subtest(func(db database.Store, check *expects) {
4031-
// TODO: we need to create a ProvisionerJob resource
40324028
j := dbgen.ProvisionerJob(s.T(), db, nil, database.ProvisionerJob{})
40334029
check.Args(database.UpdateProvisionerJobWithCompleteByIDParams{
40344030
ID: j.ID,
4035-
}).Asserts( /*rbac.ResourceSystem, policy.ActionUpdate*/ )
4031+
}).Asserts(rbac.ResourceSystem, policy.ActionUpdate)
40364032
}))
40374033
s.Run("UpdateProvisionerJobWithCompleteWithStartedAtByID", s.Subtest(func(db database.Store, check *expects) {
4038-
// TODO: we need to create a ProvisionerJob resource
40394034
j := dbgen.ProvisionerJob(s.T(), db, nil, database.ProvisionerJob{})
40404035
check.Args(database.UpdateProvisionerJobWithCompleteWithStartedAtByIDParams{
40414036
ID: j.ID,
4042-
}).Asserts( /*rbac.ResourceSystem, policy.ActionUpdate*/ )
4037+
}).Asserts(rbac.ResourceSystem, policy.ActionUpdate)
40434038
}))
40444039
s.Run("UpdateProvisionerJobByID", s.Subtest(func(db database.Store, check *expects) {
4045-
// TODO: we need to create a ProvisionerJob resource
40464040
j := dbgen.ProvisionerJob(s.T(), db, nil, database.ProvisionerJob{})
40474041
check.Args(database.UpdateProvisionerJobByIDParams{
40484042
ID: j.ID,
40494043
UpdatedAt: time.Now(),
4050-
}).Asserts( /*rbac.ResourceSystem, policy.ActionUpdate*/ )
4044+
}).Asserts(rbac.ResourceSystem, policy.ActionUpdate)
40514045
}))
40524046
s.Run("InsertProvisionerJob", s.Subtest(func(db database.Store, check *expects) {
40534047
dbtestutil.DisableForeignKeysAndTriggers(s.T(), db)
4054-
// TODO: we need to create a ProvisionerJob resource
40554048
check.Args(database.InsertProvisionerJobParams{
40564049
ID: uuid.New(),
40574050
Provisioner: database.ProvisionerTypeEcho,
40584051
StorageMethod: database.ProvisionerStorageMethodFile,
40594052
Type: database.ProvisionerJobTypeWorkspaceBuild,
40604053
Input: json.RawMessage("{}"),
4061-
}).Asserts( /*rbac.ResourceSystem, policy.ActionCreate*/ )
4054+
}).Asserts(rbac.ResourceSystem, policy.ActionCreate)
40624055
}))
40634056
s.Run("InsertProvisionerJobLogs", s.Subtest(func(db database.Store, check *expects) {
4064-
// TODO: we need to create a ProvisionerJob resource
40654057
j := dbgen.ProvisionerJob(s.T(), db, nil, database.ProvisionerJob{})
40664058
check.Args(database.InsertProvisionerJobLogsParams{
40674059
JobID: j.ID,
4068-
}).Asserts( /*rbac.ResourceSystem, policy.ActionCreate*/ )
4060+
}).Asserts(rbac.ResourceSystem, policy.ActionCreate)
40694061
}))
40704062
s.Run("InsertProvisionerJobTimings", s.Subtest(func(db database.Store, check *expects) {
4071-
// TODO: we need to create a ProvisionerJob resource
40724063
j := dbgen.ProvisionerJob(s.T(), db, nil, database.ProvisionerJob{})
40734064
check.Args(database.InsertProvisionerJobTimingsParams{
40744065
JobID: j.ID,
4075-
}).Asserts( /*rbac.ResourceSystem, policy.ActionCreate*/ )
4066+
}).Asserts(rbac.ResourceSystem, policy.ActionCreate)
40764067
}))
40774068
s.Run("UpsertProvisionerDaemon", s.Subtest(func(db database.Store, check *expects) {
40784069
dbtestutil.DisableForeignKeysAndTriggers(s.T(), db)
@@ -4211,7 +4202,7 @@ func (s *MethodTestSuite) TestSystemFunctions() {
42114202
s.Run("GetHungProvisionerJobs", s.Subtest(func(db database.Store, check *expects) {
42124203
check.Args(time.Time{}).Asserts()
42134204
}))
4214-
s.Run("GetNotStartedProvisionerJobs", s.Subtest(func(db database.Store, check *expects) {
4205+
s.Run("GetPendingProvisionerJobs", s.Subtest(func(db database.Store, check *expects) {
42154206
check.Args(time.Time{}).Asserts()
42164207
}))
42174208
s.Run("UpsertOAuthSigningKey", s.Subtest(func(db database.Store, check *expects) {

coderd/database/dbmem/dbmem.go

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1386,6 +1386,10 @@ func isDeprecated(template database.Template) bool {
13861386
return template.Deprecated != ""
13871387
}
13881388

1389+
func (q *FakeQuerier) GetProvisionerJobsToBeReaped(ctx context.Context, updatedAt time.Time) ([]database.ProvisionerJob, error) {
1390+
panic("not implemented")
1391+
}
1392+
13891393
func (*FakeQuerier) AcquireLock(_ context.Context, _ int64) error {
13901394
return xerrors.New("AcquireLock must only be called within a transaction")
13911395
}
@@ -3897,23 +3901,6 @@ func (q *FakeQuerier) GetLogoURL(_ context.Context) (string, error) {
38973901
return q.logoURL, nil
38983902
}
38993903

3900-
func (q *FakeQuerier) GetNotStartedProvisionerJobs(ctx context.Context, notStartedSince time.Time) ([]database.ProvisionerJob, error) {
3901-
q.mutex.RLock()
3902-
defer q.mutex.RUnlock()
3903-
3904-
notStartedJobs := []database.ProvisionerJob{}
3905-
for _, provisionerJob := range q.provisionerJobs {
3906-
if !provisionerJob.StartedAt.Valid && !provisionerJob.CompletedAt.Valid && provisionerJob.UpdatedAt.Before(notStartedSince) {
3907-
// clone the Tags before appending, since maps are reference types and
3908-
// we don't want the caller to be able to mutate the map we have inside
3909-
// dbmem!
3910-
provisionerJob.Tags = maps.Clone(provisionerJob.Tags)
3911-
notStartedJobs = append(notStartedJobs, provisionerJob)
3912-
}
3913-
}
3914-
return notStartedJobs, nil
3915-
}
3916-
39173904
func (q *FakeQuerier) GetNotificationMessagesByStatus(_ context.Context, arg database.GetNotificationMessagesByStatusParams) ([]database.NotificationMessage, error) {
39183905
err := validateDatabaseType(arg)
39193906
if err != nil {
@@ -4291,6 +4278,23 @@ func (q *FakeQuerier) GetParameterSchemasByJobID(_ context.Context, jobID uuid.U
42914278
return parameters, nil
42924279
}
42934280

4281+
func (q *FakeQuerier) GetPendingProvisionerJobs(_ context.Context, lastUpdatedSince time.Time) ([]database.ProvisionerJob, error) {
4282+
q.mutex.RLock()
4283+
defer q.mutex.RUnlock()
4284+
4285+
pendingJobs := []database.ProvisionerJob{}
4286+
for _, provisionerJob := range q.provisionerJobs {
4287+
if !provisionerJob.StartedAt.Valid && !provisionerJob.CompletedAt.Valid && provisionerJob.UpdatedAt.Before(lastUpdatedSince) {
4288+
// clone the Tags before appending, since maps are reference types and
4289+
// we don't want the caller to be able to mutate the map we have inside
4290+
// dbmem!
4291+
provisionerJob.Tags = maps.Clone(provisionerJob.Tags)
4292+
pendingJobs = append(pendingJobs, provisionerJob)
4293+
}
4294+
}
4295+
return pendingJobs, nil
4296+
}
4297+
42944298
func (*FakeQuerier) GetPrebuildMetrics(_ context.Context) ([]database.GetPrebuildMetricsRow, error) {
42954299
return nil, ErrUnimplemented
42964300
}

coderd/database/dbmetrics/querymetrics.go

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/dbmock/dbmock.go

Lines changed: 15 additions & 15 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/querier.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)