mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
feat: update workspace deadline when template policy changes (#8964)
This commit is contained in:
@@ -784,6 +784,14 @@ func (q *querier) GetActiveUserCount(ctx context.Context) (int64, error) {
|
||||
return q.db.GetActiveUserCount(ctx)
|
||||
}
|
||||
|
||||
func (q *querier) GetActiveWorkspaceBuildsByTemplateID(ctx context.Context, templateID uuid.UUID) ([]database.WorkspaceBuild, error) {
|
||||
// This is a system-only function.
|
||||
if err := q.authorizeContext(ctx, rbac.ActionRead, rbac.ResourceSystem); err != nil {
|
||||
return []database.WorkspaceBuild{}, err
|
||||
}
|
||||
return q.db.GetActiveWorkspaceBuildsByTemplateID(ctx, templateID)
|
||||
}
|
||||
|
||||
func (q *querier) GetAllTailnetAgents(ctx context.Context) ([]database.TailnetAgent, error) {
|
||||
if err := q.authorizeContext(ctx, rbac.ActionRead, rbac.ResourceTailnetCoordinator); err != nil {
|
||||
return []database.TailnetAgent{}, err
|
||||
|
||||
@@ -918,6 +918,34 @@ func (q *FakeQuerier) GetActiveUserCount(_ context.Context) (int64, error) {
|
||||
return active, nil
|
||||
}
|
||||
|
||||
func (q *FakeQuerier) GetActiveWorkspaceBuildsByTemplateID(ctx context.Context, templateID uuid.UUID) ([]database.WorkspaceBuild, error) {
|
||||
workspaceIDs := func() []uuid.UUID {
|
||||
q.mutex.RLock()
|
||||
defer q.mutex.RUnlock()
|
||||
|
||||
ids := []uuid.UUID{}
|
||||
for _, workspace := range q.workspaces {
|
||||
if workspace.TemplateID == templateID {
|
||||
ids = append(ids, workspace.ID)
|
||||
}
|
||||
}
|
||||
return ids
|
||||
}()
|
||||
|
||||
builds, err := q.GetLatestWorkspaceBuildsByWorkspaceIDs(ctx, workspaceIDs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
filteredBuilds := []database.WorkspaceBuild{}
|
||||
for _, build := range builds {
|
||||
if build.Transition == database.WorkspaceTransitionStart {
|
||||
filteredBuilds = append(filteredBuilds, build)
|
||||
}
|
||||
}
|
||||
return filteredBuilds, nil
|
||||
}
|
||||
|
||||
func (*FakeQuerier) GetAllTailnetAgents(_ context.Context) ([]database.TailnetAgent, error) {
|
||||
return nil, ErrUnimplemented
|
||||
}
|
||||
|
||||
@@ -237,6 +237,13 @@ func (m metricsStore) GetActiveUserCount(ctx context.Context) (int64, error) {
|
||||
return count, err
|
||||
}
|
||||
|
||||
func (m metricsStore) GetActiveWorkspaceBuildsByTemplateID(ctx context.Context, templateID uuid.UUID) ([]database.WorkspaceBuild, error) {
|
||||
start := time.Now()
|
||||
r0, r1 := m.s.GetActiveWorkspaceBuildsByTemplateID(ctx, templateID)
|
||||
m.queryLatencies.WithLabelValues("GetActiveWorkspaceBuildsByTemplateID").Observe(time.Since(start).Seconds())
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
func (m metricsStore) GetAllTailnetAgents(ctx context.Context) ([]database.TailnetAgent, error) {
|
||||
start := time.Now()
|
||||
r0, r1 := m.s.GetAllTailnetAgents(ctx)
|
||||
|
||||
@@ -371,6 +371,21 @@ func (mr *MockStoreMockRecorder) GetActiveUserCount(arg0 interface{}) *gomock.Ca
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetActiveUserCount", reflect.TypeOf((*MockStore)(nil).GetActiveUserCount), arg0)
|
||||
}
|
||||
|
||||
// GetActiveWorkspaceBuildsByTemplateID mocks base method.
|
||||
func (m *MockStore) GetActiveWorkspaceBuildsByTemplateID(arg0 context.Context, arg1 uuid.UUID) ([]database.WorkspaceBuild, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetActiveWorkspaceBuildsByTemplateID", arg0, arg1)
|
||||
ret0, _ := ret[0].([]database.WorkspaceBuild)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetActiveWorkspaceBuildsByTemplateID indicates an expected call of GetActiveWorkspaceBuildsByTemplateID.
|
||||
func (mr *MockStoreMockRecorder) GetActiveWorkspaceBuildsByTemplateID(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetActiveWorkspaceBuildsByTemplateID", reflect.TypeOf((*MockStore)(nil).GetActiveWorkspaceBuildsByTemplateID), arg0, arg1)
|
||||
}
|
||||
|
||||
// GetAllTailnetAgents mocks base method.
|
||||
func (m *MockStore) GetAllTailnetAgents(arg0 context.Context) ([]database.TailnetAgent, error) {
|
||||
m.ctrl.T.Helper()
|
||||
|
||||
@@ -48,6 +48,7 @@ type sqlcQuerier interface {
|
||||
GetAPIKeysByUserID(ctx context.Context, arg GetAPIKeysByUserIDParams) ([]APIKey, error)
|
||||
GetAPIKeysLastUsedAfter(ctx context.Context, lastUsed time.Time) ([]APIKey, error)
|
||||
GetActiveUserCount(ctx context.Context) (int64, error)
|
||||
GetActiveWorkspaceBuildsByTemplateID(ctx context.Context, templateID uuid.UUID) ([]WorkspaceBuild, error)
|
||||
GetAllTailnetAgents(ctx context.Context) ([]TailnetAgent, error)
|
||||
GetAllTailnetClients(ctx context.Context) ([]TailnetClient, error)
|
||||
GetAppSecurityKey(ctx context.Context) (string, error)
|
||||
|
||||
@@ -7884,6 +7884,72 @@ func (q *sqlQuerier) InsertWorkspaceBuildParameters(ctx context.Context, arg Ins
|
||||
return err
|
||||
}
|
||||
|
||||
const getActiveWorkspaceBuildsByTemplateID = `-- name: GetActiveWorkspaceBuildsByTemplateID :many
|
||||
SELECT wb.id, wb.created_at, wb.updated_at, wb.workspace_id, wb.template_version_id, wb.build_number, wb.transition, wb.initiator_id, wb.provisioner_state, wb.job_id, wb.deadline, wb.reason, wb.daily_cost, wb.max_deadline, wb.initiator_by_avatar_url, wb.initiator_by_username
|
||||
FROM (
|
||||
SELECT
|
||||
workspace_id, MAX(build_number) as max_build_number
|
||||
FROM
|
||||
workspace_build_with_user AS workspace_builds
|
||||
WHERE
|
||||
workspace_id IN (
|
||||
SELECT
|
||||
id
|
||||
FROM
|
||||
workspaces
|
||||
WHERE
|
||||
template_id = $1
|
||||
)
|
||||
GROUP BY
|
||||
workspace_id
|
||||
) m
|
||||
JOIN
|
||||
workspace_build_with_user AS wb
|
||||
ON m.workspace_id = wb.workspace_id AND m.max_build_number = wb.build_number
|
||||
WHERE
|
||||
wb.transition = 'start'::workspace_transition
|
||||
`
|
||||
|
||||
func (q *sqlQuerier) GetActiveWorkspaceBuildsByTemplateID(ctx context.Context, templateID uuid.UUID) ([]WorkspaceBuild, error) {
|
||||
rows, err := q.db.QueryContext(ctx, getActiveWorkspaceBuildsByTemplateID, templateID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []WorkspaceBuild
|
||||
for rows.Next() {
|
||||
var i WorkspaceBuild
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
&i.WorkspaceID,
|
||||
&i.TemplateVersionID,
|
||||
&i.BuildNumber,
|
||||
&i.Transition,
|
||||
&i.InitiatorID,
|
||||
&i.ProvisionerState,
|
||||
&i.JobID,
|
||||
&i.Deadline,
|
||||
&i.Reason,
|
||||
&i.DailyCost,
|
||||
&i.MaxDeadline,
|
||||
&i.InitiatorByAvatarUrl,
|
||||
&i.InitiatorByUsername,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const getLatestWorkspaceBuildByWorkspaceID = `-- name: GetLatestWorkspaceBuildByWorkspaceID :one
|
||||
SELECT
|
||||
id, created_at, updated_at, workspace_id, template_version_id, build_number, transition, initiator_id, provisioner_state, job_id, deadline, reason, daily_cost, max_deadline, initiator_by_avatar_url, initiator_by_username
|
||||
|
||||
@@ -144,3 +144,27 @@ SET
|
||||
WHERE
|
||||
id = $1;
|
||||
|
||||
-- name: GetActiveWorkspaceBuildsByTemplateID :many
|
||||
SELECT wb.*
|
||||
FROM (
|
||||
SELECT
|
||||
workspace_id, MAX(build_number) as max_build_number
|
||||
FROM
|
||||
workspace_build_with_user AS workspace_builds
|
||||
WHERE
|
||||
workspace_id IN (
|
||||
SELECT
|
||||
id
|
||||
FROM
|
||||
workspaces
|
||||
WHERE
|
||||
template_id = $1
|
||||
)
|
||||
GROUP BY
|
||||
workspace_id
|
||||
) m
|
||||
JOIN
|
||||
workspace_build_with_user AS wb
|
||||
ON m.workspace_id = wb.workspace_id AND m.max_build_number = wb.build_number
|
||||
WHERE
|
||||
wb.transition = 'start'::workspace_transition;
|
||||
|
||||
Reference in New Issue
Block a user