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

feat: add migrations and queries to support prebuilds#16891

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
SasSwart merged 77 commits intomainfromprebuilds-db
Apr 3, 2025
Merged
Show file tree
Hide file tree
Changes fromall commits
Commits
Show all changes
77 commits
Select commitHold shift + click to select a range
300e80f
add prebuilds system user database changes and associated changes
SasSwartMar 12, 2025
b788237
optionally prevent system users from counting to user count
dannykoppingMar 13, 2025
8122595
appease the linter
dannykoppingMar 13, 2025
bfb7c28
add unit test for system user behaviour
dannykoppingMar 13, 2025
6639167
reverting RBAC changes; not relevant here
dannykoppingMar 13, 2025
769ae1d
removing unnecessary changes
dannykoppingMar 13, 2025
e7e9c27
exclude system user db tests from non-linux OSs
dannykoppingMar 13, 2025
3936047
Rename prebuild system user reference
SasSwartMar 17, 2025
8bdcafb
ensure that users.IsSystem is not nullable
SasSwartMar 17, 2025
412d198
feat: add migrations and queries to support prebuilds
SasSwartMar 12, 2025
51773ec
Simplify workspace_latest_build view
dannykoppingMar 14, 2025
23773c2
Revert test change
dannykoppingMar 17, 2025
bc3ff44
make gen
dannykoppingMar 17, 2025
baa3076
refactor: add comments to SQL queries
evgeniy-scherbinaMar 19, 2025
ed14fb3
test: added get-presets-backoff test
evgeniy-scherbinaMar 20, 2025
3cc74fb
refactor: add comment to SQL query
evgeniy-scherbinaMar 20, 2025
fc32154
refactor: add comments + improve tests
evgeniy-scherbinaMar 21, 2025
d7b4ec4
fix: bug in SQL
evgeniy-scherbinaMar 21, 2025
e8b53f7
test: minor changes to the test
evgeniy-scherbinaMar 21, 2025
9df6554
refactor: remove job_status from SQL query
evgeniy-scherbinaMar 21, 2025
ccc309e
refactor: embed preset_prebuilds table into presets table
evgeniy-scherbinaMar 21, 2025
ee1f16a
refactor: rename sql table
evgeniy-scherbinaMar 21, 2025
d040ddd
refactor: remove unnecessary JOIN
evgeniy-scherbinaMar 23, 2025
83a6722
refactor: remove unnecessary JOIN
evgeniy-scherbinaMar 23, 2025
cd70710
refactor: use INNER JOIN for consistency
evgeniy-scherbinaMar 23, 2025
97cc4ff
refactor: simplify GetPresetsBackoff SQL Query
evgeniy-scherbinaMar 24, 2025
4d59039
Revert "refactor: simplify GetPresetsBackoff SQL Query"
evgeniy-scherbinaMar 24, 2025
205d6af
refactor: improve GetPresetsBackoff query
evgeniy-scherbinaMar 24, 2025
e489e1b
Merge remote-tracking branch 'origin/main' into prebuilds-db
evgeniy-scherbinaMar 25, 2025
1b29686
Merge remote-tracking branch 'origin/main' into prebuilds-db
evgeniy-scherbinaMar 25, 2025
20470e4
fix: bump migration numbers
evgeniy-scherbinaMar 25, 2025
7b9c8ce
test: remove deprecated test
evgeniy-scherbinaMar 25, 2025
e189a0b
fix: fix linter
evgeniy-scherbinaMar 25, 2025
692c0e5
fix: fix 000310_prebuilds.down migration
evgeniy-scherbinaMar 25, 2025
f747db0
fix: fix fixture migration
evgeniy-scherbinaMar 25, 2025
3166a42
fix: fix get-presets-backoff test
evgeniy-scherbinaMar 25, 2025
aa6b490
fix: fix linter
evgeniy-scherbinaMar 25, 2025
bc4e7d2
fix: fix linter
evgeniy-scherbinaMar 25, 2025
f167b92
correctly select for the latest built with a preset in latest_prebuil…
SasSwartMar 26, 2025
8fd34ab
Merge remote-tracking branch 'origin/main' into prebuilds-db
SasSwartMar 26, 2025
7a8ec49
Properly label and filter metrics for prebuilds
SasSwartMar 26, 2025
a64d661
test: fix db tests
evgeniy-scherbinaMar 27, 2025
c787cd2
test: added tests for workspaces with multiple agents
evgeniy-scherbinaMar 27, 2025
bd38603
refactor: avoid code duplication
evgeniy-scherbinaMar 27, 2025
097f9c3
clarify query clause
SasSwartMar 27, 2025
4cfdd6f
tidy up dbauthz_test.go
SasSwartMar 27, 2025
4a34d52
refactor: remove * usage from prebuilds.sql queries
evgeniy-scherbinaMar 27, 2025
8d9cd45
refactor: remove * usage from prebuilds views
evgeniy-scherbinaMar 27, 2025
f870d7e
refactor: join wlb with pj
evgeniy-scherbinaMar 27, 2025
18ad931
refactor: Rename SQL query
evgeniy-scherbinaMar 27, 2025
4667171
Added comments for SQL query
evgeniy-scherbinaMar 27, 2025
a26c094
refactor: fix down migration
evgeniy-scherbinaMar 27, 2025
6ed4121
Merge remote-tracking branch 'origin/main' into prebuilds-db
SasSwartMar 28, 2025
2312f41
renumber migrations
SasSwartMar 28, 2025
5150a5c
refactor: clarify comment for SQL query
evgeniy-scherbinaMar 28, 2025
bff34ea
refactor: fix indentations
evgeniy-scherbinaMar 28, 2025
ef462b6
refactor: rename helper func in test package
evgeniy-scherbinaMar 28, 2025
dc45165
refactor: database level tests
evgeniy-scherbinaMar 28, 2025
9c8a352
refactor: database level tests
evgeniy-scherbinaMar 28, 2025
eb80919
refactor: helper funcs in db-level tests
evgeniy-scherbinaMar 28, 2025
0b2bbee
refactor: minor improvement in SQL query
evgeniy-scherbinaMar 28, 2025
3a97bf6
refactor: rename SQL queries
evgeniy-scherbinaMar 28, 2025
2eeb884
refactor: rename SQL queries
evgeniy-scherbinaMar 28, 2025
73f99e8
refactor: rename fields in SQL query
evgeniy-scherbinaMar 31, 2025
113e12b
fix: improve rbac policies
evgeniy-scherbinaApr 1, 2025
217cae0
fix: minor fix in filtered_builds CTE
evgeniy-scherbinaApr 1, 2025
b0bf220
fix: formatting
evgeniy-scherbinaApr 2, 2025
ff72a00
refactor: minor refactoring
evgeniy-scherbinaApr 2, 2025
a007d4a
fix: handle presets with the same tv.id and name
evgeniy-scherbinaApr 2, 2025
ea9c53b
fix: redefine RBAC permissions for prebuilds
evgeniy-scherbinaApr 2, 2025
66d44ed
Merge remote-tracking branch 'origin/main' into prebuilds-db
evgeniy-scherbinaApr 2, 2025
29e121f
fix: fix migration numbers
evgeniy-scherbinaApr 2, 2025
f64754f
test: fix dbmem tests
evgeniy-scherbinaApr 2, 2025
7e02397
test: fix dbmem tests
evgeniy-scherbinaApr 2, 2025
55d9827
fix: linter
evgeniy-scherbinaApr 2, 2025
866454b
fix: linter
evgeniy-scherbinaApr 2, 2025
4fa959a
fix: linter
evgeniy-scherbinaApr 2, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 111 additions & 2 deletionscoderd/database/dbauthz/dbauthz.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -18,6 +18,7 @@ import (

"cdr.dev/slog"

"github.com/coder/coder/v2/coderd/prebuilds"
"github.com/coder/coder/v2/coderd/rbac/policy"
"github.com/coder/coder/v2/coderd/rbac/rolestore"

Expand DownExpand Up@@ -361,6 +362,27 @@ var (
}),
Scope: rbac.ScopeAll,
}.WithCachedASTValue()

subjectPrebuildsOrchestrator = rbac.Subject{
FriendlyName: "Prebuilds Orchestrator",
ID: prebuilds.SystemUserID.String(),
Roles: rbac.Roles([]rbac.Role{
{
Identifier: rbac.RoleIdentifier{Name: "prebuilds-orchestrator"},
DisplayName: "Coder",
Site: rbac.Permissions(map[string][]policy.Action{
// May use template, read template-related info, & insert template-related resources (preset prebuilds).
rbac.ResourceTemplate.Type: {policy.ActionRead, policy.ActionUpdate, policy.ActionUse, policy.ActionViewInsights},
// May CRUD workspaces, and start/stop them.
rbac.ResourceWorkspace.Type: {
policy.ActionCreate, policy.ActionDelete, policy.ActionRead, policy.ActionUpdate,
policy.ActionWorkspaceStart, policy.ActionWorkspaceStop,
},
}),
},
}),
Scope: rbac.ScopeAll,
}.WithCachedASTValue()
)

// AsProvisionerd returns a context with an actor that has permissions required
Expand DownExpand Up@@ -415,6 +437,12 @@ func AsSystemReadProvisionerDaemons(ctx context.Context) context.Context {
return context.WithValue(ctx, authContextKey{}, subjectSystemReadProvisionerDaemons)
}

// AsPrebuildsOrchestrator returns a context with an actor that has permissions
// to read orchestrator workspace prebuilds.
func AsPrebuildsOrchestrator(ctx context.Context) context.Context {
return context.WithValue(ctx, authContextKey{}, subjectPrebuildsOrchestrator)
}

var AsRemoveActor = rbac.Subject{
ID: "remove-actor",
}
Expand DownExpand Up@@ -1109,6 +1137,31 @@ func (q *querier) BulkMarkNotificationMessagesSent(ctx context.Context, arg data
return q.db.BulkMarkNotificationMessagesSent(ctx, arg)
}

func (q *querier) ClaimPrebuiltWorkspace(ctx context.Context, arg database.ClaimPrebuiltWorkspaceParams) (database.ClaimPrebuiltWorkspaceRow, error) {
empty := database.ClaimPrebuiltWorkspaceRow{}

preset, err := q.db.GetPresetByID(ctx, arg.PresetID)
if err != nil {
return empty, err
}

workspaceObject := rbac.ResourceWorkspace.WithOwner(arg.NewUserID.String()).InOrg(preset.OrganizationID)
err = q.authorizeContext(ctx, policy.ActionCreate, workspaceObject.RBACObject())
if err != nil {
return empty, err
}

tpl, err := q.GetTemplateByID(ctx, preset.TemplateID.UUID)
if err != nil {
return empty, xerrors.Errorf("verify template by id: %w", err)
}
if err := q.authorizeContext(ctx, policy.ActionUse, tpl); err != nil {
return empty, xerrors.Errorf("use template for workspace: %w", err)
}
Comment on lines +1148 to +1160
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Just leave a comment this should matchInsertWorkspace


return q.db.ClaimPrebuiltWorkspace(ctx, arg)
}

func (q *querier) CleanTailnetCoordinators(ctx context.Context) error {
if err := q.authorizeContext(ctx, policy.ActionDelete, rbac.ResourceTailnetCoordinator); err != nil {
return err
Expand All@@ -1130,6 +1183,13 @@ func (q *querier) CleanTailnetTunnels(ctx context.Context) error {
return q.db.CleanTailnetTunnels(ctx)
}

func (q *querier) CountInProgressPrebuilds(ctx context.Context) ([]database.CountInProgressPrebuildsRow, error) {
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceWorkspace.All()); err != nil {
return nil, err
}
return q.db.CountInProgressPrebuilds(ctx)
}
Comment on lines +1186 to +1191
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

This query spans all organizations, and prebuilds are just workspaces 👍


func (q *querier) CountUnreadInboxNotificationsByUserID(ctx context.Context, userID uuid.UUID) (int64, error) {
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceInboxNotification.WithOwner(userID.String())); err != nil {
return 0, err
Expand DownExpand Up@@ -2096,6 +2156,30 @@ func (q *querier) GetParameterSchemasByJobID(ctx context.Context, jobID uuid.UUI
return q.db.GetParameterSchemasByJobID(ctx, jobID)
}

func (q *querier) GetPrebuildMetrics(ctx context.Context) ([]database.GetPrebuildMetricsRow, error) {
// GetPrebuildMetrics returns metrics related to prebuilt workspaces,
// such as the number of created and failed prebuilt workspaces.
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceWorkspace.All()); err != nil {
return nil, err
}
return q.db.GetPrebuildMetrics(ctx)
}

func (q *querier) GetPresetByID(ctx context.Context, presetID uuid.UUID) (database.GetPresetByIDRow, error) {
empty := database.GetPresetByIDRow{}

preset, err := q.db.GetPresetByID(ctx, presetID)
if err != nil {
return empty, err
}
_, err = q.GetTemplateByID(ctx, preset.TemplateID.UUID)
if err != nil {
return empty, err
}

return preset, nil
}

func (q *querier) GetPresetByWorkspaceBuildID(ctx context.Context, workspaceID uuid.UUID) (database.TemplateVersionPreset, error) {
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceTemplate); err != nil {
return database.TemplateVersionPreset{}, err
Expand All@@ -2113,6 +2197,14 @@ func (q *querier) GetPresetParametersByTemplateVersionID(ctx context.Context, te
return q.db.GetPresetParametersByTemplateVersionID(ctx, templateVersionID)
}

func (q *querier) GetPresetsBackoff(ctx context.Context, lookback time.Time) ([]database.GetPresetsBackoffRow, error) {
// GetPresetsBackoff returns a list of template version presets along with metadata such as the number of failed prebuilds.
if err := q.authorizeContext(ctx, policy.ActionViewInsights, rbac.ResourceTemplate.All()); err != nil {
return nil, err
}
return q.db.GetPresetsBackoff(ctx, lookback)
}
Comment on lines +2200 to +2206
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

@spikecurtis we decided to just lump in the preset metrics with template insights. Since template insights are metrics related to a template, prebuild metrics metadata is essentially the same imo.


func (q *querier) GetPresetsByTemplateVersionID(ctx context.Context, templateVersionID uuid.UUID) ([]database.TemplateVersionPreset, error) {
// An actor can read template version presets if they can read the related template version.
_, err := q.GetTemplateVersionByID(ctx, templateVersionID)
Expand DownExpand Up@@ -2164,13 +2256,13 @@ func (q *querier) GetProvisionerJobByID(ctx context.Context, id uuid.UUID) (data
// can read the job.
_, err := q.GetWorkspaceBuildByJobID(ctx, id)
if err != nil {
return database.ProvisionerJob{}, err
return database.ProvisionerJob{},xerrors.Errorf("fetch related workspace build: %w",err)
}
case database.ProvisionerJobTypeTemplateVersionDryRun, database.ProvisionerJobTypeTemplateVersionImport:
// Authorized call to get template version.
_, err := authorizedTemplateVersionFromJob(ctx, q, job)
if err != nil {
return database.ProvisionerJob{}, err
return database.ProvisionerJob{},xerrors.Errorf("fetch related template version: %w",err)
}
default:
return database.ProvisionerJob{}, xerrors.Errorf("unknown job type: %q", job.Type)
Expand DownExpand Up@@ -2263,6 +2355,14 @@ func (q *querier) GetReplicasUpdatedAfter(ctx context.Context, updatedAt time.Ti
return q.db.GetReplicasUpdatedAfter(ctx, updatedAt)
}

func (q *querier) GetRunningPrebuiltWorkspaces(ctx context.Context) ([]database.GetRunningPrebuiltWorkspacesRow, error) {
// This query returns only prebuilt workspaces, but we decided to require permissions for all workspaces.
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceWorkspace.All()); err != nil {
return nil, err
}
return q.db.GetRunningPrebuiltWorkspaces(ctx)
}

func (q *querier) GetRuntimeConfig(ctx context.Context, key string) (string, error) {
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceSystem); err != nil {
return "", err
Expand DownExpand Up@@ -2387,6 +2487,15 @@ func (q *querier) GetTemplateParameterInsights(ctx context.Context, arg database
return q.db.GetTemplateParameterInsights(ctx, arg)
}

func (q *querier) GetTemplatePresetsWithPrebuilds(ctx context.Context, templateID uuid.NullUUID) ([]database.GetTemplatePresetsWithPrebuildsRow, error) {
// GetTemplatePresetsWithPrebuilds retrieves template versions with configured presets and prebuilds.
// Presets and prebuilds are part of the template, so if you can access templates - you can access them as well.
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceTemplate.All()); err != nil {
return nil, err
}
return q.db.GetTemplatePresetsWithPrebuilds(ctx, templateID)
}

func (q *querier) GetTemplateUsageStats(ctx context.Context, arg database.GetTemplateUsageStatsParams) ([]database.TemplateUsageStat, error) {
if err := q.authorizeTemplateInsights(ctx, arg.TemplateIDs); err != nil {
return nil, err
Expand Down
90 changes: 90 additions & 0 deletionscoderd/database/dbauthz/dbauthz_test.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -4838,6 +4838,96 @@ func (s *MethodTestSuite) TestNotifications() {
}))
}

func (s *MethodTestSuite) TestPrebuilds() {
s.Run("ClaimPrebuiltWorkspace", s.Subtest(func(db database.Store, check *expects) {
org := dbgen.Organization(s.T(), db, database.Organization{})
user := dbgen.User(s.T(), db, database.User{})
template := dbgen.Template(s.T(), db, database.Template{
OrganizationID: org.ID,
CreatedBy: user.ID,
})
templateVersion := dbgen.TemplateVersion(s.T(), db, database.TemplateVersion{
TemplateID: uuid.NullUUID{
UUID: template.ID,
Valid: true,
},
OrganizationID: org.ID,
CreatedBy: user.ID,
})
preset := dbgen.Preset(s.T(), db, database.InsertPresetParams{
TemplateVersionID: templateVersion.ID,
})
check.Args(database.ClaimPrebuiltWorkspaceParams{
NewUserID: user.ID,
NewName: "",
PresetID: preset.ID,
}).Asserts(
rbac.ResourceWorkspace.WithOwner(user.ID.String()).InOrg(org.ID), policy.ActionCreate,
template, policy.ActionRead,
template, policy.ActionUse,
).ErrorsWithInMemDB(dbmem.ErrUnimplemented).
ErrorsWithPG(sql.ErrNoRows)
}))
s.Run("GetPrebuildMetrics", s.Subtest(func(_ database.Store, check *expects) {
check.Args().
Asserts(rbac.ResourceWorkspace.All(), policy.ActionRead).
ErrorsWithInMemDB(dbmem.ErrUnimplemented)
}))
s.Run("CountInProgressPrebuilds", s.Subtest(func(_ database.Store, check *expects) {
check.Args().
Asserts(rbac.ResourceWorkspace.All(), policy.ActionRead).
ErrorsWithInMemDB(dbmem.ErrUnimplemented)
}))
s.Run("GetPresetsBackoff", s.Subtest(func(_ database.Store, check *expects) {
check.Args(time.Time{}).
Asserts(rbac.ResourceTemplate.All(), policy.ActionViewInsights).
ErrorsWithInMemDB(dbmem.ErrUnimplemented)
}))
s.Run("GetRunningPrebuiltWorkspaces", s.Subtest(func(_ database.Store, check *expects) {
check.Args().
Asserts(rbac.ResourceWorkspace.All(), policy.ActionRead).
ErrorsWithInMemDB(dbmem.ErrUnimplemented)
}))
s.Run("GetTemplatePresetsWithPrebuilds", s.Subtest(func(db database.Store, check *expects) {
user := dbgen.User(s.T(), db, database.User{})
check.Args(uuid.NullUUID{UUID: user.ID, Valid: true}).
Asserts(rbac.ResourceTemplate.All(), policy.ActionRead).
ErrorsWithInMemDB(dbmem.ErrUnimplemented)
}))
s.Run("GetPresetByID", s.Subtest(func(db database.Store, check *expects) {
org := dbgen.Organization(s.T(), db, database.Organization{})
user := dbgen.User(s.T(), db, database.User{})
template := dbgen.Template(s.T(), db, database.Template{
OrganizationID: org.ID,
CreatedBy: user.ID,
})
templateVersion := dbgen.TemplateVersion(s.T(), db, database.TemplateVersion{
TemplateID: uuid.NullUUID{
UUID: template.ID,
Valid: true,
},
OrganizationID: org.ID,
CreatedBy: user.ID,
})
preset := dbgen.Preset(s.T(), db, database.InsertPresetParams{
TemplateVersionID: templateVersion.ID,
})
check.Args(preset.ID).
Asserts(template, policy.ActionRead).
Returns(database.GetPresetByIDRow{
ID: preset.ID,
TemplateVersionID: preset.TemplateVersionID,
Name: preset.Name,
CreatedAt: preset.CreatedAt,
TemplateID: uuid.NullUUID{
UUID: template.ID,
Valid: true,
},
OrganizationID: org.ID,
})
}))
}

func (s *MethodTestSuite) TestOAuth2ProviderApps() {
s.Run("GetOAuth2ProviderApps", s.Subtest(func(db database.Store, check *expects) {
apps := []database.OAuth2ProviderApp{
Expand Down
23 changes: 23 additions & 0 deletionscoderd/database/dbgen/dbgen.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -1196,6 +1196,29 @@ func TelemetryItem(t testing.TB, db database.Store, seed database.TelemetryItem)
return item
}

func Preset(t testing.TB, db database.Store, seed database.InsertPresetParams) database.TemplateVersionPreset {
preset, err := db.InsertPreset(genCtx, database.InsertPresetParams{
TemplateVersionID: takeFirst(seed.TemplateVersionID, uuid.New()),
Name: takeFirst(seed.Name, testutil.GetRandomName(t)),
CreatedAt: takeFirst(seed.CreatedAt, dbtime.Now()),
DesiredInstances: seed.DesiredInstances,
InvalidateAfterSecs: seed.InvalidateAfterSecs,
})
require.NoError(t, err, "insert preset")
return preset
}

func PresetParameter(t testing.TB, db database.Store, seed database.InsertPresetParametersParams) []database.TemplateVersionPresetParameter {
parameters, err := db.InsertPresetParameters(genCtx, database.InsertPresetParametersParams{
TemplateVersionPresetID: takeFirst(seed.TemplateVersionPresetID, uuid.New()),
Names: takeFirstSlice(seed.Names, []string{testutil.GetRandomName(t)}),
Values: takeFirstSlice(seed.Values, []string{testutil.GetRandomName(t)}),
})

require.NoError(t, err, "insert preset parameters")
return parameters
}

func provisionerJobTiming(t testing.TB, db database.Store, seed database.ProvisionerJobTiming) database.ProvisionerJobTiming {
timing, err := db.InsertProvisionerJobTimings(genCtx, database.InsertProvisionerJobTimingsParams{
JobID: takeFirst(seed.JobID, uuid.New()),
Expand Down
Loading
Loading

[8]ページ先頭

©2009-2025 Movatter.jp