Skip to content

Commit 47cb6fc

Browse files
feat: implement autoscaling mechanism for prebuilds
1 parent 9b9b894 commit 47cb6fc

33 files changed

+2286
-839
lines changed

coderd/database/dbauthz/dbauthz.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2282,6 +2282,13 @@ func (q *querier) GetPresetParametersByTemplateVersionID(ctx context.Context, ar
22822282
return q.db.GetPresetParametersByTemplateVersionID(ctx, args)
22832283
}
22842284

2285+
func (q *querier) GetPresetPrebuildSchedules(ctx context.Context) ([]database.TemplateVersionPresetPrebuildSchedule, error) {
2286+
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceTemplate.All()); err != nil {
2287+
return nil, err
2288+
}
2289+
return q.db.GetPresetPrebuildSchedules(ctx)
2290+
}
2291+
22852292
func (q *querier) GetPresetsAtFailureLimit(ctx context.Context, hardLimit int64) ([]database.GetPresetsAtFailureLimitRow, error) {
22862293
// GetPresetsAtFailureLimit returns a list of template version presets that have reached the hard failure limit.
22872294
// Request the same authorization permissions as GetPresetsBackoff, since the methods are similar.
@@ -3633,6 +3640,15 @@ func (q *querier) InsertPresetParameters(ctx context.Context, arg database.Inser
36333640
return q.db.InsertPresetParameters(ctx, arg)
36343641
}
36353642

3643+
func (q *querier) InsertPresetPrebuildSchedule(ctx context.Context, arg database.InsertPresetPrebuildScheduleParams) (database.TemplateVersionPresetPrebuildSchedule, error) {
3644+
err := q.authorizeContext(ctx, policy.ActionUpdate, rbac.ResourceTemplate)
3645+
if err != nil {
3646+
return database.TemplateVersionPresetPrebuildSchedule{}, err
3647+
}
3648+
3649+
return q.db.InsertPresetPrebuildSchedule(ctx, arg)
3650+
}
3651+
36363652
func (q *querier) InsertProvisionerJob(ctx context.Context, arg database.InsertProvisionerJobParams) (database.ProvisionerJob, error) {
36373653
// TODO: Remove this once we have a proper rbac check for provisioner jobs.
36383654
// Details in https://github.com/coder/coder/issues/16160

coderd/database/dbauthz/dbauthz_test.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -979,6 +979,29 @@ func (s *MethodTestSuite) TestOrganization() {
979979
}
980980
check.Args(insertPresetParametersParams).Asserts(rbac.ResourceTemplate, policy.ActionUpdate)
981981
}))
982+
s.Run("InsertPresetPrebuildSchedule", s.Subtest(func(db database.Store, check *expects) {
983+
org := dbgen.Organization(s.T(), db, database.Organization{})
984+
user := dbgen.User(s.T(), db, database.User{})
985+
template := dbgen.Template(s.T(), db, database.Template{
986+
CreatedBy: user.ID,
987+
OrganizationID: org.ID,
988+
})
989+
templateVersion := dbgen.TemplateVersion(s.T(), db, database.TemplateVersion{
990+
TemplateID: uuid.NullUUID{UUID: template.ID, Valid: true},
991+
OrganizationID: org.ID,
992+
CreatedBy: user.ID,
993+
})
994+
preset := dbgen.Preset(s.T(), db, database.InsertPresetParams{
995+
TemplateVersionID: templateVersion.ID,
996+
Name: "test",
997+
})
998+
arg := database.InsertPresetPrebuildScheduleParams{
999+
PresetID: preset.ID,
1000+
}
1001+
check.Args(arg).
1002+
Asserts(rbac.ResourceTemplate, policy.ActionUpdate).
1003+
ErrorsWithInMemDB(dbmem.ErrUnimplemented)
1004+
}))
9821005
s.Run("DeleteOrganizationMember", s.Subtest(func(db database.Store, check *expects) {
9831006
o := dbgen.Organization(s.T(), db, database.Organization{})
9841007
u := dbgen.User(s.T(), db, database.User{})
@@ -4913,6 +4936,12 @@ func (s *MethodTestSuite) TestPrebuilds() {
49134936
Asserts(template.RBACObject(), policy.ActionRead).
49144937
Returns(insertedParameters)
49154938
}))
4939+
s.Run("GetPresetPrebuildSchedules", s.Subtest(func(db database.Store, check *expects) {
4940+
check.Args().
4941+
Asserts(rbac.ResourceTemplate.All(), policy.ActionRead).
4942+
Returns([]database.TemplateVersionPresetPrebuildSchedule{}).
4943+
ErrorsWithInMemDB(dbmem.ErrUnimplemented)
4944+
}))
49164945
s.Run("GetPresetsByTemplateVersionID", s.Subtest(func(db database.Store, check *expects) {
49174946
ctx := context.Background()
49184947
org := dbgen.Organization(s.T(), db, database.Organization{})

coderd/database/dbfake/dbfake.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,7 @@ func (t TemplateVersionBuilder) Do() TemplateVersionResponse {
395395
CreatedAt: version.CreatedAt,
396396
DesiredInstances: preset.DesiredInstances,
397397
InvalidateAfterSecs: preset.InvalidateAfterSecs,
398+
AutoscalingTimezone: preset.AutoscalingTimezone,
398399
})
399400
}
400401

coderd/database/dbgen/dbgen.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1259,11 +1259,22 @@ func Preset(t testing.TB, db database.Store, seed database.InsertPresetParams) d
12591259
CreatedAt: takeFirst(seed.CreatedAt, dbtime.Now()),
12601260
DesiredInstances: seed.DesiredInstances,
12611261
InvalidateAfterSecs: seed.InvalidateAfterSecs,
1262+
AutoscalingTimezone: seed.AutoscalingTimezone,
12621263
})
12631264
require.NoError(t, err, "insert preset")
12641265
return preset
12651266
}
12661267

1268+
func PresetPrebuildSchedule(t testing.TB, db database.Store, seed database.InsertPresetPrebuildScheduleParams) database.TemplateVersionPresetPrebuildSchedule {
1269+
schedule, err := db.InsertPresetPrebuildSchedule(genCtx, database.InsertPresetPrebuildScheduleParams{
1270+
PresetID: seed.PresetID,
1271+
CronExpression: seed.CronExpression,
1272+
Instances: seed.Instances,
1273+
})
1274+
require.NoError(t, err, "insert preset")
1275+
return schedule
1276+
}
1277+
12671278
func PresetParameter(t testing.TB, db database.Store, seed database.InsertPresetParametersParams) []database.TemplateVersionPresetParameter {
12681279
parameters, err := db.InsertPresetParameters(genCtx, database.InsertPresetParametersParams{
12691280
TemplateVersionPresetID: takeFirst(seed.TemplateVersionPresetID, uuid.New()),

coderd/database/dbmem/dbmem.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4369,6 +4369,10 @@ func (q *FakeQuerier) GetPresetParametersByTemplateVersionID(_ context.Context,
43694369
return parameters, nil
43704370
}
43714371

4372+
func (q *FakeQuerier) GetPresetPrebuildSchedules(ctx context.Context) ([]database.TemplateVersionPresetPrebuildSchedule, error) {
4373+
return nil, ErrUnimplemented
4374+
}
4375+
43724376
func (q *FakeQuerier) GetPresetsAtFailureLimit(ctx context.Context, hardLimit int64) ([]database.GetPresetsAtFailureLimitRow, error) {
43734377
return nil, ErrUnimplemented
43744378
}
@@ -9158,6 +9162,15 @@ func (q *FakeQuerier) InsertPresetParameters(_ context.Context, arg database.Ins
91589162
return presetParameters, nil
91599163
}
91609164

9165+
func (q *FakeQuerier) InsertPresetPrebuildSchedule(ctx context.Context, arg database.InsertPresetPrebuildScheduleParams) (database.TemplateVersionPresetPrebuildSchedule, error) {
9166+
err := validateDatabaseType(arg)
9167+
if err != nil {
9168+
return database.TemplateVersionPresetPrebuildSchedule{}, err
9169+
}
9170+
9171+
return database.TemplateVersionPresetPrebuildSchedule{}, ErrUnimplemented
9172+
}
9173+
91619174
func (q *FakeQuerier) InsertProvisionerJob(_ context.Context, arg database.InsertProvisionerJobParams) (database.ProvisionerJob, error) {
91629175
if err := validateDatabaseType(arg); err != nil {
91639176
return database.ProvisionerJob{}, err

coderd/database/dbmetrics/querymetrics.go

Lines changed: 14 additions & 0 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: 30 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/dump.sql

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

coderd/database/foreign_key_constraint.go

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
-- Drop the autoscaling schedules table
2+
DROP TABLE template_version_preset_prebuild_schedules;
3+
4+
-- Remove autoscaling_timezone column from template_version_presets table
5+
ALTER TABLE template_version_presets
6+
DROP COLUMN autoscaling_timezone;
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
-- Add autoscaling_timezone column to template_version_presets table
2+
ALTER TABLE template_version_presets
3+
ADD COLUMN autoscaling_timezone TEXT DEFAULT 'UTC' NOT NULL;
4+
5+
-- Add table for autoscaling schedules
6+
CREATE TABLE template_version_preset_prebuild_schedules (
7+
id UUID PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
8+
preset_id UUID NOT NULL,
9+
cron_expression TEXT NOT NULL,
10+
instances INTEGER NOT NULL,
11+
FOREIGN KEY (preset_id) REFERENCES template_version_presets (id) ON DELETE CASCADE
12+
);
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
INSERT INTO
2+
template_version_preset_prebuild_schedules (
3+
id,
4+
preset_id,
5+
cron_expression,
6+
instances
7+
)
8+
VALUES (
9+
'e387cac1-9bf1-4fb6-8a34-db8cfb750dd0',
10+
'28b42cc0-c4fe-4907-a0fe-e4d20f1e9bfe',
11+
'* 8-18 * * 1-5',
12+
1
13+
);

coderd/database/models.go

Lines changed: 8 additions & 0 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: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)