chore: add prebuilds system user (#16916)

Pre-requisite for https://github.com/coder/coder/pull/16891

Closes https://github.com/coder/internal/issues/515

This PR introduces a new concept of a "system" user.

Our data model requires that all workspaces have an owner (a `users`
relation), and prebuilds is a feature that will spin up workspaces to be
claimed later by actual users - and thus needs to own the workspaces in
the interim.

Naturally, introducing a change like this touches a few aspects around
the codebase and we've taken the approach _default hidden_ here; in
other words, queries for users will by default _exclude_ all system
users, but there is a flag to ensure they can be displayed. This keeps
the changeset relatively small.

This user has minimal permissions (it's equivalent to a `member` since
it has no roles). It will be associated with the default org in the
initial migration, and thereafter we'll need to somehow ensure its
membership aligns with templates (which are org-scoped) for which it'll
need to provision prebuilds; that's a solution we'll have in a
subsequent PR.

---------

Signed-off-by: Danny Kopping <dannykopping@gmail.com>
Co-authored-by: Sas Swart <sas.swart.cdk@gmail.com>
This commit is contained in:
Danny Kopping
2025-03-25 14:18:06 +02:00
committed by GitHub
parent 117e4c2fe7
commit 4c33846f6d
38 changed files with 591 additions and 143 deletions

View File

@ -103,18 +103,18 @@ func (mr *MockStoreMockRecorder) ActivityBumpWorkspace(ctx, arg any) *gomock.Cal
}
// AllUserIDs mocks base method.
func (m *MockStore) AllUserIDs(ctx context.Context) ([]uuid.UUID, error) {
func (m *MockStore) AllUserIDs(ctx context.Context, includeSystem bool) ([]uuid.UUID, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "AllUserIDs", ctx)
ret := m.ctrl.Call(m, "AllUserIDs", ctx, includeSystem)
ret0, _ := ret[0].([]uuid.UUID)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// AllUserIDs indicates an expected call of AllUserIDs.
func (mr *MockStoreMockRecorder) AllUserIDs(ctx any) *gomock.Call {
func (mr *MockStoreMockRecorder) AllUserIDs(ctx, includeSystem any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AllUserIDs", reflect.TypeOf((*MockStore)(nil).AllUserIDs), ctx)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AllUserIDs", reflect.TypeOf((*MockStore)(nil).AllUserIDs), ctx, includeSystem)
}
// ArchiveUnusedTemplateVersions mocks base method.
@ -923,18 +923,18 @@ func (mr *MockStoreMockRecorder) GetAPIKeysLastUsedAfter(ctx, lastUsed any) *gom
}
// GetActiveUserCount mocks base method.
func (m *MockStore) GetActiveUserCount(ctx context.Context) (int64, error) {
func (m *MockStore) GetActiveUserCount(ctx context.Context, includeSystem bool) (int64, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetActiveUserCount", ctx)
ret := m.ctrl.Call(m, "GetActiveUserCount", ctx, includeSystem)
ret0, _ := ret[0].(int64)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetActiveUserCount indicates an expected call of GetActiveUserCount.
func (mr *MockStoreMockRecorder) GetActiveUserCount(ctx any) *gomock.Call {
func (mr *MockStoreMockRecorder) GetActiveUserCount(ctx, includeSystem any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetActiveUserCount", reflect.TypeOf((*MockStore)(nil).GetActiveUserCount), ctx)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetActiveUserCount", reflect.TypeOf((*MockStore)(nil).GetActiveUserCount), ctx, includeSystem)
}
// GetActiveWorkspaceBuildsByTemplateID mocks base method.
@ -1523,48 +1523,48 @@ func (mr *MockStoreMockRecorder) GetGroupByOrgAndName(ctx, arg any) *gomock.Call
}
// GetGroupMembers mocks base method.
func (m *MockStore) GetGroupMembers(ctx context.Context) ([]database.GroupMember, error) {
func (m *MockStore) GetGroupMembers(ctx context.Context, includeSystem bool) ([]database.GroupMember, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetGroupMembers", ctx)
ret := m.ctrl.Call(m, "GetGroupMembers", ctx, includeSystem)
ret0, _ := ret[0].([]database.GroupMember)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetGroupMembers indicates an expected call of GetGroupMembers.
func (mr *MockStoreMockRecorder) GetGroupMembers(ctx any) *gomock.Call {
func (mr *MockStoreMockRecorder) GetGroupMembers(ctx, includeSystem any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetGroupMembers", reflect.TypeOf((*MockStore)(nil).GetGroupMembers), ctx)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetGroupMembers", reflect.TypeOf((*MockStore)(nil).GetGroupMembers), ctx, includeSystem)
}
// GetGroupMembersByGroupID mocks base method.
func (m *MockStore) GetGroupMembersByGroupID(ctx context.Context, groupID uuid.UUID) ([]database.GroupMember, error) {
func (m *MockStore) GetGroupMembersByGroupID(ctx context.Context, arg database.GetGroupMembersByGroupIDParams) ([]database.GroupMember, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetGroupMembersByGroupID", ctx, groupID)
ret := m.ctrl.Call(m, "GetGroupMembersByGroupID", ctx, arg)
ret0, _ := ret[0].([]database.GroupMember)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetGroupMembersByGroupID indicates an expected call of GetGroupMembersByGroupID.
func (mr *MockStoreMockRecorder) GetGroupMembersByGroupID(ctx, groupID any) *gomock.Call {
func (mr *MockStoreMockRecorder) GetGroupMembersByGroupID(ctx, arg any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetGroupMembersByGroupID", reflect.TypeOf((*MockStore)(nil).GetGroupMembersByGroupID), ctx, groupID)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetGroupMembersByGroupID", reflect.TypeOf((*MockStore)(nil).GetGroupMembersByGroupID), ctx, arg)
}
// GetGroupMembersCountByGroupID mocks base method.
func (m *MockStore) GetGroupMembersCountByGroupID(ctx context.Context, groupID uuid.UUID) (int64, error) {
func (m *MockStore) GetGroupMembersCountByGroupID(ctx context.Context, arg database.GetGroupMembersCountByGroupIDParams) (int64, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetGroupMembersCountByGroupID", ctx, groupID)
ret := m.ctrl.Call(m, "GetGroupMembersCountByGroupID", ctx, arg)
ret0, _ := ret[0].(int64)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetGroupMembersCountByGroupID indicates an expected call of GetGroupMembersCountByGroupID.
func (mr *MockStoreMockRecorder) GetGroupMembersCountByGroupID(ctx, groupID any) *gomock.Call {
func (mr *MockStoreMockRecorder) GetGroupMembersCountByGroupID(ctx, arg any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetGroupMembersCountByGroupID", reflect.TypeOf((*MockStore)(nil).GetGroupMembersCountByGroupID), ctx, groupID)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetGroupMembersCountByGroupID", reflect.TypeOf((*MockStore)(nil).GetGroupMembersCountByGroupID), ctx, arg)
}
// GetGroups mocks base method.
@ -2978,18 +2978,18 @@ func (mr *MockStoreMockRecorder) GetUserByID(ctx, id any) *gomock.Call {
}
// GetUserCount mocks base method.
func (m *MockStore) GetUserCount(ctx context.Context) (int64, error) {
func (m *MockStore) GetUserCount(ctx context.Context, includeSystem bool) (int64, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetUserCount", ctx)
ret := m.ctrl.Call(m, "GetUserCount", ctx, includeSystem)
ret0, _ := ret[0].(int64)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetUserCount indicates an expected call of GetUserCount.
func (mr *MockStoreMockRecorder) GetUserCount(ctx any) *gomock.Call {
func (mr *MockStoreMockRecorder) GetUserCount(ctx, includeSystem any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUserCount", reflect.TypeOf((*MockStore)(nil).GetUserCount), ctx)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUserCount", reflect.TypeOf((*MockStore)(nil).GetUserCount), ctx, includeSystem)
}
// GetUserLatencyInsights mocks base method.