chore: rename locked to dormant (#9290)

* chore: rename locked to dormant

- The following columns have been updated:
  - workspace.locked_at -> dormant_at
  - template.inactivity_ttl -> time_til_dormant
  - template.locked_ttl -> time_til_dormant_autodelete

This change has also been reflected in the SDK.

A route has also been updated from /workspaces/<id>/lock to /workspaces/<id>/dormant
This commit is contained in:
Jon Ayers
2023-08-24 13:25:54 -05:00
committed by GitHub
parent ebd878b6b5
commit 7f14b50dbe
67 changed files with 1174 additions and 1206 deletions
+10 -10
View File
@@ -2636,6 +2636,13 @@ func (q *querier) UpdateWorkspaceDeletedByID(ctx context.Context, arg database.U
return deleteQ(q.log, q.auth, fetch, q.db.UpdateWorkspaceDeletedByID)(ctx, arg)
}
func (q *querier) UpdateWorkspaceDormantDeletingAt(ctx context.Context, arg database.UpdateWorkspaceDormantDeletingAtParams) (database.Workspace, error) {
fetch := func(ctx context.Context, arg database.UpdateWorkspaceDormantDeletingAtParams) (database.Workspace, error) {
return q.db.GetWorkspaceByID(ctx, arg.ID)
}
return updateWithReturn(q.log, q.auth, fetch, q.db.UpdateWorkspaceDormantDeletingAt)(ctx, arg)
}
func (q *querier) UpdateWorkspaceLastUsedAt(ctx context.Context, arg database.UpdateWorkspaceLastUsedAtParams) error {
fetch := func(ctx context.Context, arg database.UpdateWorkspaceLastUsedAtParams) (database.Workspace, error) {
return q.db.GetWorkspaceByID(ctx, arg.ID)
@@ -2643,13 +2650,6 @@ func (q *querier) UpdateWorkspaceLastUsedAt(ctx context.Context, arg database.Up
return update(q.log, q.auth, fetch, q.db.UpdateWorkspaceLastUsedAt)(ctx, arg)
}
func (q *querier) UpdateWorkspaceLockedDeletingAt(ctx context.Context, arg database.UpdateWorkspaceLockedDeletingAtParams) (database.Workspace, error) {
fetch := func(ctx context.Context, arg database.UpdateWorkspaceLockedDeletingAtParams) (database.Workspace, error) {
return q.db.GetWorkspaceByID(ctx, arg.ID)
}
return updateWithReturn(q.log, q.auth, fetch, q.db.UpdateWorkspaceLockedDeletingAt)(ctx, arg)
}
func (q *querier) UpdateWorkspaceProxy(ctx context.Context, arg database.UpdateWorkspaceProxyParams) (database.WorkspaceProxy, error) {
fetch := func(ctx context.Context, arg database.UpdateWorkspaceProxyParams) (database.WorkspaceProxy, error) {
return q.db.GetWorkspaceProxyByID(ctx, arg.ID)
@@ -2671,12 +2671,12 @@ func (q *querier) UpdateWorkspaceTTL(ctx context.Context, arg database.UpdateWor
return update(q.log, q.auth, fetch, q.db.UpdateWorkspaceTTL)(ctx, arg)
}
func (q *querier) UpdateWorkspacesLockedDeletingAtByTemplateID(ctx context.Context, arg database.UpdateWorkspacesLockedDeletingAtByTemplateIDParams) error {
fetch := func(ctx context.Context, arg database.UpdateWorkspacesLockedDeletingAtByTemplateIDParams) (database.Template, error) {
func (q *querier) UpdateWorkspacesDormantDeletingAtByTemplateID(ctx context.Context, arg database.UpdateWorkspacesDormantDeletingAtByTemplateIDParams) error {
fetch := func(ctx context.Context, arg database.UpdateWorkspacesDormantDeletingAtByTemplateIDParams) (database.Template, error) {
return q.db.GetTemplateByID(ctx, arg.TemplateID)
}
return fetchAndExec(q.log, q.auth, rbac.ActionUpdate, fetch, q.db.UpdateWorkspacesLockedDeletingAtByTemplateID)(ctx, arg)
return fetchAndExec(q.log, q.auth, rbac.ActionUpdate, fetch, q.db.UpdateWorkspacesDormantDeletingAtByTemplateID)(ctx, arg)
}
func (q *querier) UpsertAppSecurityKey(ctx context.Context, data string) error {
+56 -56
View File
@@ -341,7 +341,7 @@ func (q *FakeQuerier) convertToWorkspaceRowsNoLock(ctx context.Context, workspac
AutostartSchedule: w.AutostartSchedule,
Ttl: w.Ttl,
LastUsedAt: w.LastUsedAt,
LockedAt: w.LockedAt,
DormantAt: w.DormantAt,
DeletingAt: w.DeletingAt,
Count: count,
}
@@ -3737,14 +3737,14 @@ func (q *FakeQuerier) GetWorkspacesEligibleForTransition(ctx context.Context, no
if build.Transition == database.WorkspaceTransitionStart &&
!build.Deadline.IsZero() &&
build.Deadline.Before(now) &&
!workspace.LockedAt.Valid {
!workspace.DormantAt.Valid {
workspaces = append(workspaces, workspace)
continue
}
if build.Transition == database.WorkspaceTransitionStop &&
workspace.AutostartSchedule.Valid &&
!workspace.LockedAt.Valid {
!workspace.DormantAt.Valid {
workspaces = append(workspaces, workspace)
continue
}
@@ -3762,11 +3762,11 @@ func (q *FakeQuerier) GetWorkspacesEligibleForTransition(ctx context.Context, no
if err != nil {
return nil, xerrors.Errorf("get template by ID: %w", err)
}
if !workspace.LockedAt.Valid && template.InactivityTTL > 0 {
if !workspace.DormantAt.Valid && template.TimeTilDormant > 0 {
workspaces = append(workspaces, workspace)
continue
}
if workspace.LockedAt.Valid && template.LockedTTL > 0 {
if workspace.DormantAt.Valid && template.TimeTilDormantAutoDelete > 0 {
workspaces = append(workspaces, workspace)
continue
}
@@ -5130,8 +5130,8 @@ func (q *FakeQuerier) UpdateTemplateScheduleByID(_ context.Context, arg database
tpl.RestartRequirementDaysOfWeek = arg.RestartRequirementDaysOfWeek
tpl.RestartRequirementWeeks = arg.RestartRequirementWeeks
tpl.FailureTTL = arg.FailureTTL
tpl.InactivityTTL = arg.InactivityTTL
tpl.LockedTTL = arg.LockedTTL
tpl.TimeTilDormant = arg.TimeTilDormant
tpl.TimeTilDormantAutoDelete = arg.TimeTilDormantAutoDelete
q.templates[idx] = tpl
return nil
}
@@ -5699,6 +5699,45 @@ func (q *FakeQuerier) UpdateWorkspaceDeletedByID(_ context.Context, arg database
return sql.ErrNoRows
}
func (q *FakeQuerier) UpdateWorkspaceDormantDeletingAt(_ context.Context, arg database.UpdateWorkspaceDormantDeletingAtParams) (database.Workspace, error) {
if err := validateDatabaseType(arg); err != nil {
return database.Workspace{}, err
}
q.mutex.Lock()
defer q.mutex.Unlock()
for index, workspace := range q.workspaces {
if workspace.ID != arg.ID {
continue
}
workspace.DormantAt = arg.DormantAt
if workspace.DormantAt.Time.IsZero() {
workspace.LastUsedAt = database.Now()
workspace.DeletingAt = sql.NullTime{}
}
if !workspace.DormantAt.Time.IsZero() {
var template database.TemplateTable
for _, t := range q.templates {
if t.ID == workspace.TemplateID {
template = t
break
}
}
if template.ID == uuid.Nil {
return database.Workspace{}, xerrors.Errorf("unable to find workspace template")
}
if template.TimeTilDormantAutoDelete > 0 {
workspace.DeletingAt = sql.NullTime{
Valid: true,
Time: workspace.DormantAt.Time.Add(time.Duration(template.TimeTilDormantAutoDelete)),
}
}
}
q.workspaces[index] = workspace
return workspace, nil
}
return database.Workspace{}, sql.ErrNoRows
}
func (q *FakeQuerier) UpdateWorkspaceLastUsedAt(_ context.Context, arg database.UpdateWorkspaceLastUsedAtParams) error {
if err := validateDatabaseType(arg); err != nil {
return err
@@ -5719,45 +5758,6 @@ func (q *FakeQuerier) UpdateWorkspaceLastUsedAt(_ context.Context, arg database.
return sql.ErrNoRows
}
func (q *FakeQuerier) UpdateWorkspaceLockedDeletingAt(_ context.Context, arg database.UpdateWorkspaceLockedDeletingAtParams) (database.Workspace, error) {
if err := validateDatabaseType(arg); err != nil {
return database.Workspace{}, err
}
q.mutex.Lock()
defer q.mutex.Unlock()
for index, workspace := range q.workspaces {
if workspace.ID != arg.ID {
continue
}
workspace.LockedAt = arg.LockedAt
if workspace.LockedAt.Time.IsZero() {
workspace.LastUsedAt = database.Now()
workspace.DeletingAt = sql.NullTime{}
}
if !workspace.LockedAt.Time.IsZero() {
var template database.TemplateTable
for _, t := range q.templates {
if t.ID == workspace.TemplateID {
template = t
break
}
}
if template.ID == uuid.Nil {
return database.Workspace{}, xerrors.Errorf("unable to find workspace template")
}
if template.LockedTTL > 0 {
workspace.DeletingAt = sql.NullTime{
Valid: true,
Time: workspace.LockedAt.Time.Add(time.Duration(template.LockedTTL)),
}
}
}
q.workspaces[index] = workspace
return workspace, nil
}
return database.Workspace{}, sql.ErrNoRows
}
func (q *FakeQuerier) UpdateWorkspaceProxy(_ context.Context, arg database.UpdateWorkspaceProxyParams) (database.WorkspaceProxy, error) {
q.mutex.Lock()
defer q.mutex.Unlock()
@@ -5818,7 +5818,7 @@ func (q *FakeQuerier) UpdateWorkspaceTTL(_ context.Context, arg database.UpdateW
return sql.ErrNoRows
}
func (q *FakeQuerier) UpdateWorkspacesLockedDeletingAtByTemplateID(_ context.Context, arg database.UpdateWorkspacesLockedDeletingAtByTemplateIDParams) error {
func (q *FakeQuerier) UpdateWorkspacesDormantDeletingAtByTemplateID(_ context.Context, arg database.UpdateWorkspacesDormantDeletingAtByTemplateIDParams) error {
q.mutex.Lock()
defer q.mutex.Unlock()
@@ -5832,22 +5832,22 @@ func (q *FakeQuerier) UpdateWorkspacesLockedDeletingAtByTemplateID(_ context.Con
continue
}
if ws.LockedAt.Time.IsZero() {
if ws.DormantAt.Time.IsZero() {
continue
}
if !arg.LockedAt.IsZero() {
ws.LockedAt = sql.NullTime{
if !arg.DormantAt.IsZero() {
ws.DormantAt = sql.NullTime{
Valid: true,
Time: arg.LockedAt,
Time: arg.DormantAt,
}
}
deletingAt := sql.NullTime{
Valid: arg.LockedTtlMs > 0,
Valid: arg.TimeTilDormantAutodeleteMs > 0,
}
if arg.LockedTtlMs > 0 {
deletingAt.Time = ws.LockedAt.Time.Add(time.Duration(arg.LockedTtlMs) * time.Millisecond)
if arg.TimeTilDormantAutodeleteMs > 0 {
deletingAt.Time = ws.DormantAt.Time.Add(time.Duration(arg.TimeTilDormantAutodeleteMs) * time.Millisecond)
}
ws.DeletingAt = deletingAt
q.workspaces[i] = ws
@@ -6224,12 +6224,12 @@ func (q *FakeQuerier) GetAuthorizedWorkspaces(ctx context.Context, arg database.
}
// We omit locked workspaces by default.
if arg.LockedAt.IsZero() && workspace.LockedAt.Valid {
if arg.DormantAt.IsZero() && workspace.DormantAt.Valid {
continue
}
// Filter out workspaces that are locked after the timestamp.
if !arg.LockedAt.IsZero() && workspace.LockedAt.Time.Before(arg.LockedAt) {
if !arg.DormantAt.IsZero() && workspace.DormantAt.Time.Before(arg.DormantAt) {
continue
}
+10 -10
View File
@@ -1607,6 +1607,13 @@ func (m metricsStore) UpdateWorkspaceDeletedByID(ctx context.Context, arg databa
return err
}
func (m metricsStore) UpdateWorkspaceDormantDeletingAt(ctx context.Context, arg database.UpdateWorkspaceDormantDeletingAtParams) (database.Workspace, error) {
start := time.Now()
ws, r0 := m.s.UpdateWorkspaceDormantDeletingAt(ctx, arg)
m.queryLatencies.WithLabelValues("UpdateWorkspaceDormantDeletingAt").Observe(time.Since(start).Seconds())
return ws, r0
}
func (m metricsStore) UpdateWorkspaceLastUsedAt(ctx context.Context, arg database.UpdateWorkspaceLastUsedAtParams) error {
start := time.Now()
err := m.s.UpdateWorkspaceLastUsedAt(ctx, arg)
@@ -1614,13 +1621,6 @@ func (m metricsStore) UpdateWorkspaceLastUsedAt(ctx context.Context, arg databas
return err
}
func (m metricsStore) UpdateWorkspaceLockedDeletingAt(ctx context.Context, arg database.UpdateWorkspaceLockedDeletingAtParams) (database.Workspace, error) {
start := time.Now()
ws, r0 := m.s.UpdateWorkspaceLockedDeletingAt(ctx, arg)
m.queryLatencies.WithLabelValues("UpdateWorkspaceLockedDeletingAt").Observe(time.Since(start).Seconds())
return ws, r0
}
func (m metricsStore) UpdateWorkspaceProxy(ctx context.Context, arg database.UpdateWorkspaceProxyParams) (database.WorkspaceProxy, error) {
start := time.Now()
proxy, err := m.s.UpdateWorkspaceProxy(ctx, arg)
@@ -1642,10 +1642,10 @@ func (m metricsStore) UpdateWorkspaceTTL(ctx context.Context, arg database.Updat
return r0
}
func (m metricsStore) UpdateWorkspacesLockedDeletingAtByTemplateID(ctx context.Context, arg database.UpdateWorkspacesLockedDeletingAtByTemplateIDParams) error {
func (m metricsStore) UpdateWorkspacesDormantDeletingAtByTemplateID(ctx context.Context, arg database.UpdateWorkspacesDormantDeletingAtByTemplateIDParams) error {
start := time.Now()
r0 := m.s.UpdateWorkspacesLockedDeletingAtByTemplateID(ctx, arg)
m.queryLatencies.WithLabelValues("UpdateWorkspacesLockedDeletingAtByTemplateID").Observe(time.Since(start).Seconds())
r0 := m.s.UpdateWorkspacesDormantDeletingAtByTemplateID(ctx, arg)
m.queryLatencies.WithLabelValues("UpdateWorkspacesDormantDeletingAtByTemplateID").Observe(time.Since(start).Seconds())
return r0
}
+21 -21
View File
@@ -3379,6 +3379,21 @@ func (mr *MockStoreMockRecorder) UpdateWorkspaceDeletedByID(arg0, arg1 interface
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateWorkspaceDeletedByID", reflect.TypeOf((*MockStore)(nil).UpdateWorkspaceDeletedByID), arg0, arg1)
}
// UpdateWorkspaceDormantDeletingAt mocks base method.
func (m *MockStore) UpdateWorkspaceDormantDeletingAt(arg0 context.Context, arg1 database.UpdateWorkspaceDormantDeletingAtParams) (database.Workspace, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "UpdateWorkspaceDormantDeletingAt", arg0, arg1)
ret0, _ := ret[0].(database.Workspace)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// UpdateWorkspaceDormantDeletingAt indicates an expected call of UpdateWorkspaceDormantDeletingAt.
func (mr *MockStoreMockRecorder) UpdateWorkspaceDormantDeletingAt(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateWorkspaceDormantDeletingAt", reflect.TypeOf((*MockStore)(nil).UpdateWorkspaceDormantDeletingAt), arg0, arg1)
}
// UpdateWorkspaceLastUsedAt mocks base method.
func (m *MockStore) UpdateWorkspaceLastUsedAt(arg0 context.Context, arg1 database.UpdateWorkspaceLastUsedAtParams) error {
m.ctrl.T.Helper()
@@ -3393,21 +3408,6 @@ func (mr *MockStoreMockRecorder) UpdateWorkspaceLastUsedAt(arg0, arg1 interface{
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateWorkspaceLastUsedAt", reflect.TypeOf((*MockStore)(nil).UpdateWorkspaceLastUsedAt), arg0, arg1)
}
// UpdateWorkspaceLockedDeletingAt mocks base method.
func (m *MockStore) UpdateWorkspaceLockedDeletingAt(arg0 context.Context, arg1 database.UpdateWorkspaceLockedDeletingAtParams) (database.Workspace, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "UpdateWorkspaceLockedDeletingAt", arg0, arg1)
ret0, _ := ret[0].(database.Workspace)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// UpdateWorkspaceLockedDeletingAt indicates an expected call of UpdateWorkspaceLockedDeletingAt.
func (mr *MockStoreMockRecorder) UpdateWorkspaceLockedDeletingAt(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateWorkspaceLockedDeletingAt", reflect.TypeOf((*MockStore)(nil).UpdateWorkspaceLockedDeletingAt), arg0, arg1)
}
// UpdateWorkspaceProxy mocks base method.
func (m *MockStore) UpdateWorkspaceProxy(arg0 context.Context, arg1 database.UpdateWorkspaceProxyParams) (database.WorkspaceProxy, error) {
m.ctrl.T.Helper()
@@ -3451,18 +3451,18 @@ func (mr *MockStoreMockRecorder) UpdateWorkspaceTTL(arg0, arg1 interface{}) *gom
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateWorkspaceTTL", reflect.TypeOf((*MockStore)(nil).UpdateWorkspaceTTL), arg0, arg1)
}
// UpdateWorkspacesLockedDeletingAtByTemplateID mocks base method.
func (m *MockStore) UpdateWorkspacesLockedDeletingAtByTemplateID(arg0 context.Context, arg1 database.UpdateWorkspacesLockedDeletingAtByTemplateIDParams) error {
// UpdateWorkspacesDormantDeletingAtByTemplateID mocks base method.
func (m *MockStore) UpdateWorkspacesDormantDeletingAtByTemplateID(arg0 context.Context, arg1 database.UpdateWorkspacesDormantDeletingAtByTemplateIDParams) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "UpdateWorkspacesLockedDeletingAtByTemplateID", arg0, arg1)
ret := m.ctrl.Call(m, "UpdateWorkspacesDormantDeletingAtByTemplateID", arg0, arg1)
ret0, _ := ret[0].(error)
return ret0
}
// UpdateWorkspacesLockedDeletingAtByTemplateID indicates an expected call of UpdateWorkspacesLockedDeletingAtByTemplateID.
func (mr *MockStoreMockRecorder) UpdateWorkspacesLockedDeletingAtByTemplateID(arg0, arg1 interface{}) *gomock.Call {
// UpdateWorkspacesDormantDeletingAtByTemplateID indicates an expected call of UpdateWorkspacesDormantDeletingAtByTemplateID.
func (mr *MockStoreMockRecorder) UpdateWorkspacesDormantDeletingAtByTemplateID(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateWorkspacesLockedDeletingAtByTemplateID", reflect.TypeOf((*MockStore)(nil).UpdateWorkspacesLockedDeletingAtByTemplateID), arg0, arg1)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateWorkspacesDormantDeletingAtByTemplateID", reflect.TypeOf((*MockStore)(nil).UpdateWorkspacesDormantDeletingAtByTemplateID), arg0, arg1)
}
// UpsertAppSecurityKey mocks base method.
+5 -5
View File
@@ -635,8 +635,8 @@ CREATE TABLE templates (
allow_user_autostart boolean DEFAULT true NOT NULL,
allow_user_autostop boolean DEFAULT true NOT NULL,
failure_ttl bigint DEFAULT 0 NOT NULL,
inactivity_ttl bigint DEFAULT 0 NOT NULL,
locked_ttl bigint DEFAULT 0 NOT NULL,
time_til_dormant bigint DEFAULT 0 NOT NULL,
time_til_dormant_autodelete bigint DEFAULT 0 NOT NULL,
restart_requirement_days_of_week smallint DEFAULT 0 NOT NULL,
restart_requirement_weeks bigint DEFAULT 0 NOT NULL
);
@@ -676,8 +676,8 @@ CREATE VIEW template_with_users AS
templates.allow_user_autostart,
templates.allow_user_autostop,
templates.failure_ttl,
templates.inactivity_ttl,
templates.locked_ttl,
templates.time_til_dormant,
templates.time_til_dormant_autodelete,
templates.restart_requirement_days_of_week,
templates.restart_requirement_weeks,
COALESCE(visible_users.avatar_url, ''::text) AS created_by_avatar_url,
@@ -1003,7 +1003,7 @@ CREATE TABLE workspaces (
autostart_schedule text,
ttl bigint,
last_used_at timestamp without time zone DEFAULT '0001-01-01 00:00:00'::timestamp without time zone NOT NULL,
locked_at timestamp with time zone,
dormant_at timestamp with time zone,
deleting_at timestamp with time zone
);
@@ -0,0 +1,26 @@
BEGIN;
ALTER TABLE templates RENAME COLUMN time_til_dormant TO inactivity_ttl;
ALTER TABLE templates RENAME COLUMN time_til_dormant_autodelete TO locked_ttl;
ALTER TABLE workspaces RENAME COLUMN dormant_at TO locked_at;
-- Update the template_with_users view;
DROP VIEW template_with_users;
-- If you need to update this view, put 'DROP VIEW template_with_users;' before this.
CREATE VIEW
template_with_users
AS
SELECT
templates.*,
coalesce(visible_users.avatar_url, '') AS created_by_avatar_url,
coalesce(visible_users.username, '') AS created_by_username
FROM
templates
LEFT JOIN
visible_users
ON
templates.created_by = visible_users.id;
COMMENT ON VIEW template_with_users IS 'Joins in the username + avatar url of the created by user.';
COMMIT;
@@ -0,0 +1,25 @@
BEGIN;
ALTER TABLE templates RENAME COLUMN inactivity_ttl TO time_til_dormant;
ALTER TABLE templates RENAME COLUMN locked_ttl TO time_til_dormant_autodelete;
ALTER TABLE workspaces RENAME COLUMN locked_at TO dormant_at;
-- Update the template_with_users view;a
DROP VIEW template_with_users;
-- If you need to update this view, put 'DROP VIEW template_with_users;' before this.
CREATE VIEW
template_with_users
AS
SELECT
templates.*,
coalesce(visible_users.avatar_url, '') AS created_by_avatar_url,
coalesce(visible_users.username, '') AS created_by_username
FROM
templates
LEFT JOIN
visible_users
ON
templates.created_by = visible_users.id;
COMMENT ON VIEW template_with_users IS 'Joins in the username + avatar url of the created by user.';
COMMIT;
+9 -9
View File
@@ -146,8 +146,8 @@ func (w Workspace) RBACObject() rbac.Object {
func (w Workspace) ExecutionRBAC() rbac.Object {
// If a workspace is locked it cannot be accessed.
if w.LockedAt.Valid {
return w.LockedRBAC()
if w.DormantAt.Valid {
return w.DormantRBAC()
}
return rbac.ResourceWorkspaceExecution.
@@ -158,8 +158,8 @@ func (w Workspace) ExecutionRBAC() rbac.Object {
func (w Workspace) ApplicationConnectRBAC() rbac.Object {
// If a workspace is locked it cannot be accessed.
if w.LockedAt.Valid {
return w.LockedRBAC()
if w.DormantAt.Valid {
return w.DormantRBAC()
}
return rbac.ResourceWorkspaceApplicationConnect.
@@ -173,9 +173,9 @@ func (w Workspace) WorkspaceBuildRBAC(transition WorkspaceTransition) rbac.Objec
// However we need to allow stopping a workspace by a caller once a workspace
// is locked (e.g. for autobuild). Additionally, if a user wants to delete
// a locked workspace, they shouldn't have to have it unlocked first.
if w.LockedAt.Valid && transition != WorkspaceTransitionStop &&
if w.DormantAt.Valid && transition != WorkspaceTransitionStop &&
transition != WorkspaceTransitionDelete {
return w.LockedRBAC()
return w.DormantRBAC()
}
return rbac.ResourceWorkspaceBuild.
@@ -184,8 +184,8 @@ func (w Workspace) WorkspaceBuildRBAC(transition WorkspaceTransition) rbac.Objec
WithOwner(w.OwnerID.String())
}
func (w Workspace) LockedRBAC() rbac.Object {
return rbac.ResourceWorkspaceLocked.
func (w Workspace) DormantRBAC() rbac.Object {
return rbac.ResourceWorkspaceDormant.
WithID(w.ID).
InOrg(w.OrganizationID).
WithOwner(w.OwnerID.String())
@@ -355,7 +355,7 @@ func ConvertWorkspaceRows(rows []GetWorkspacesRow) []Workspace {
AutostartSchedule: r.AutostartSchedule,
Ttl: r.Ttl,
LastUsedAt: r.LastUsedAt,
LockedAt: r.LockedAt,
DormantAt: r.DormantAt,
DeletingAt: r.DeletingAt,
}
}
+4 -4
View File
@@ -81,8 +81,8 @@ func (q *sqlQuerier) GetAuthorizedTemplates(ctx context.Context, arg GetTemplate
&i.AllowUserAutostart,
&i.AllowUserAutostop,
&i.FailureTTL,
&i.InactivityTTL,
&i.LockedTTL,
&i.TimeTilDormant,
&i.TimeTilDormantAutoDelete,
&i.RestartRequirementDaysOfWeek,
&i.RestartRequirementWeeks,
&i.CreatedByAvatarURL,
@@ -217,7 +217,7 @@ func (q *sqlQuerier) GetAuthorizedWorkspaces(ctx context.Context, arg GetWorkspa
arg.Name,
arg.HasAgent,
arg.AgentInactiveDisconnectTimeoutSeconds,
arg.LockedAt,
arg.DormantAt,
arg.LastUsedBefore,
arg.LastUsedAfter,
arg.Offset,
@@ -242,7 +242,7 @@ func (q *sqlQuerier) GetAuthorizedWorkspaces(ctx context.Context, arg GetWorkspa
&i.AutostartSchedule,
&i.Ttl,
&i.LastUsedAt,
&i.LockedAt,
&i.DormantAt,
&i.DeletingAt,
&i.TemplateName,
&i.TemplateVersionID,
+7 -7
View File
@@ -1729,8 +1729,8 @@ type Template struct {
AllowUserAutostart bool `db:"allow_user_autostart" json:"allow_user_autostart"`
AllowUserAutostop bool `db:"allow_user_autostop" json:"allow_user_autostop"`
FailureTTL int64 `db:"failure_ttl" json:"failure_ttl"`
InactivityTTL int64 `db:"inactivity_ttl" json:"inactivity_ttl"`
LockedTTL int64 `db:"locked_ttl" json:"locked_ttl"`
TimeTilDormant int64 `db:"time_til_dormant" json:"time_til_dormant"`
TimeTilDormantAutoDelete int64 `db:"time_til_dormant_autodelete" json:"time_til_dormant_autodelete"`
RestartRequirementDaysOfWeek int16 `db:"restart_requirement_days_of_week" json:"restart_requirement_days_of_week"`
RestartRequirementWeeks int64 `db:"restart_requirement_weeks" json:"restart_requirement_weeks"`
CreatedByAvatarURL sql.NullString `db:"created_by_avatar_url" json:"created_by_avatar_url"`
@@ -1761,10 +1761,10 @@ type TemplateTable struct {
// Allow users to specify an autostart schedule for workspaces (enterprise).
AllowUserAutostart bool `db:"allow_user_autostart" json:"allow_user_autostart"`
// Allow users to specify custom autostop values for workspaces (enterprise).
AllowUserAutostop bool `db:"allow_user_autostop" json:"allow_user_autostop"`
FailureTTL int64 `db:"failure_ttl" json:"failure_ttl"`
InactivityTTL int64 `db:"inactivity_ttl" json:"inactivity_ttl"`
LockedTTL int64 `db:"locked_ttl" json:"locked_ttl"`
AllowUserAutostop bool `db:"allow_user_autostop" json:"allow_user_autostop"`
FailureTTL int64 `db:"failure_ttl" json:"failure_ttl"`
TimeTilDormant int64 `db:"time_til_dormant" json:"time_til_dormant"`
TimeTilDormantAutoDelete int64 `db:"time_til_dormant_autodelete" json:"time_til_dormant_autodelete"`
// A bitmap of days of week to restart the workspace on, starting with Monday as the 0th bit, and Sunday as the 6th bit. The 7th bit is unused.
RestartRequirementDaysOfWeek int16 `db:"restart_requirement_days_of_week" json:"restart_requirement_days_of_week"`
// The number of weeks between restarts. 0 or 1 weeks means "every week", 2 week means "every second week", etc. Weeks are counted from January 2, 2023, which is the first Monday of 2023. This is to ensure workspaces are started consistently for all customers on the same n-week cycles.
@@ -1903,7 +1903,7 @@ type Workspace struct {
AutostartSchedule sql.NullString `db:"autostart_schedule" json:"autostart_schedule"`
Ttl sql.NullInt64 `db:"ttl" json:"ttl"`
LastUsedAt time.Time `db:"last_used_at" json:"last_used_at"`
LockedAt sql.NullTime `db:"locked_at" json:"locked_at"`
DormantAt sql.NullTime `db:"dormant_at" json:"dormant_at"`
DeletingAt sql.NullTime `db:"deleting_at" json:"deleting_at"`
}
+2 -2
View File
@@ -292,13 +292,13 @@ type sqlcQuerier interface {
UpdateWorkspaceBuildByID(ctx context.Context, arg UpdateWorkspaceBuildByIDParams) error
UpdateWorkspaceBuildCostByID(ctx context.Context, arg UpdateWorkspaceBuildCostByIDParams) error
UpdateWorkspaceDeletedByID(ctx context.Context, arg UpdateWorkspaceDeletedByIDParams) error
UpdateWorkspaceDormantDeletingAt(ctx context.Context, arg UpdateWorkspaceDormantDeletingAtParams) (Workspace, error)
UpdateWorkspaceLastUsedAt(ctx context.Context, arg UpdateWorkspaceLastUsedAtParams) error
UpdateWorkspaceLockedDeletingAt(ctx context.Context, arg UpdateWorkspaceLockedDeletingAtParams) (Workspace, error)
// This allows editing the properties of a workspace proxy.
UpdateWorkspaceProxy(ctx context.Context, arg UpdateWorkspaceProxyParams) (WorkspaceProxy, error)
UpdateWorkspaceProxyDeleted(ctx context.Context, arg UpdateWorkspaceProxyDeletedParams) error
UpdateWorkspaceTTL(ctx context.Context, arg UpdateWorkspaceTTLParams) error
UpdateWorkspacesLockedDeletingAtByTemplateID(ctx context.Context, arg UpdateWorkspacesLockedDeletingAtByTemplateIDParams) error
UpdateWorkspacesDormantDeletingAtByTemplateID(ctx context.Context, arg UpdateWorkspacesDormantDeletingAtByTemplateIDParams) error
UpsertAppSecurityKey(ctx context.Context, value string) error
// The default proxy is implied and not actually stored in the database.
// So we need to store it's configuration here for display purposes.
+103 -103
View File
@@ -4317,7 +4317,7 @@ func (q *sqlQuerier) GetTemplateAverageBuildTime(ctx context.Context, arg GetTem
const getTemplateByID = `-- name: GetTemplateByID :one
SELECT
id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, default_ttl, created_by, icon, user_acl, group_acl, display_name, allow_user_cancel_workspace_jobs, max_ttl, allow_user_autostart, allow_user_autostop, failure_ttl, inactivity_ttl, locked_ttl, restart_requirement_days_of_week, restart_requirement_weeks, created_by_avatar_url, created_by_username
id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, default_ttl, created_by, icon, user_acl, group_acl, display_name, allow_user_cancel_workspace_jobs, max_ttl, allow_user_autostart, allow_user_autostop, failure_ttl, time_til_dormant, time_til_dormant_autodelete, restart_requirement_days_of_week, restart_requirement_weeks, created_by_avatar_url, created_by_username
FROM
template_with_users
WHERE
@@ -4350,8 +4350,8 @@ func (q *sqlQuerier) GetTemplateByID(ctx context.Context, id uuid.UUID) (Templat
&i.AllowUserAutostart,
&i.AllowUserAutostop,
&i.FailureTTL,
&i.InactivityTTL,
&i.LockedTTL,
&i.TimeTilDormant,
&i.TimeTilDormantAutoDelete,
&i.RestartRequirementDaysOfWeek,
&i.RestartRequirementWeeks,
&i.CreatedByAvatarURL,
@@ -4362,7 +4362,7 @@ func (q *sqlQuerier) GetTemplateByID(ctx context.Context, id uuid.UUID) (Templat
const getTemplateByOrganizationAndName = `-- name: GetTemplateByOrganizationAndName :one
SELECT
id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, default_ttl, created_by, icon, user_acl, group_acl, display_name, allow_user_cancel_workspace_jobs, max_ttl, allow_user_autostart, allow_user_autostop, failure_ttl, inactivity_ttl, locked_ttl, restart_requirement_days_of_week, restart_requirement_weeks, created_by_avatar_url, created_by_username
id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, default_ttl, created_by, icon, user_acl, group_acl, display_name, allow_user_cancel_workspace_jobs, max_ttl, allow_user_autostart, allow_user_autostop, failure_ttl, time_til_dormant, time_til_dormant_autodelete, restart_requirement_days_of_week, restart_requirement_weeks, created_by_avatar_url, created_by_username
FROM
template_with_users AS templates
WHERE
@@ -4403,8 +4403,8 @@ func (q *sqlQuerier) GetTemplateByOrganizationAndName(ctx context.Context, arg G
&i.AllowUserAutostart,
&i.AllowUserAutostop,
&i.FailureTTL,
&i.InactivityTTL,
&i.LockedTTL,
&i.TimeTilDormant,
&i.TimeTilDormantAutoDelete,
&i.RestartRequirementDaysOfWeek,
&i.RestartRequirementWeeks,
&i.CreatedByAvatarURL,
@@ -4414,7 +4414,7 @@ func (q *sqlQuerier) GetTemplateByOrganizationAndName(ctx context.Context, arg G
}
const getTemplates = `-- name: GetTemplates :many
SELECT id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, default_ttl, created_by, icon, user_acl, group_acl, display_name, allow_user_cancel_workspace_jobs, max_ttl, allow_user_autostart, allow_user_autostop, failure_ttl, inactivity_ttl, locked_ttl, restart_requirement_days_of_week, restart_requirement_weeks, created_by_avatar_url, created_by_username FROM template_with_users AS templates
SELECT id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, default_ttl, created_by, icon, user_acl, group_acl, display_name, allow_user_cancel_workspace_jobs, max_ttl, allow_user_autostart, allow_user_autostop, failure_ttl, time_til_dormant, time_til_dormant_autodelete, restart_requirement_days_of_week, restart_requirement_weeks, created_by_avatar_url, created_by_username FROM template_with_users AS templates
ORDER BY (name, id) ASC
`
@@ -4448,8 +4448,8 @@ func (q *sqlQuerier) GetTemplates(ctx context.Context) ([]Template, error) {
&i.AllowUserAutostart,
&i.AllowUserAutostop,
&i.FailureTTL,
&i.InactivityTTL,
&i.LockedTTL,
&i.TimeTilDormant,
&i.TimeTilDormantAutoDelete,
&i.RestartRequirementDaysOfWeek,
&i.RestartRequirementWeeks,
&i.CreatedByAvatarURL,
@@ -4470,7 +4470,7 @@ func (q *sqlQuerier) GetTemplates(ctx context.Context) ([]Template, error) {
const getTemplatesWithFilter = `-- name: GetTemplatesWithFilter :many
SELECT
id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, default_ttl, created_by, icon, user_acl, group_acl, display_name, allow_user_cancel_workspace_jobs, max_ttl, allow_user_autostart, allow_user_autostop, failure_ttl, inactivity_ttl, locked_ttl, restart_requirement_days_of_week, restart_requirement_weeks, created_by_avatar_url, created_by_username
id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, default_ttl, created_by, icon, user_acl, group_acl, display_name, allow_user_cancel_workspace_jobs, max_ttl, allow_user_autostart, allow_user_autostop, failure_ttl, time_til_dormant, time_til_dormant_autodelete, restart_requirement_days_of_week, restart_requirement_weeks, created_by_avatar_url, created_by_username
FROM
template_with_users AS templates
WHERE
@@ -4541,8 +4541,8 @@ func (q *sqlQuerier) GetTemplatesWithFilter(ctx context.Context, arg GetTemplate
&i.AllowUserAutostart,
&i.AllowUserAutostop,
&i.FailureTTL,
&i.InactivityTTL,
&i.LockedTTL,
&i.TimeTilDormant,
&i.TimeTilDormantAutoDelete,
&i.RestartRequirementDaysOfWeek,
&i.RestartRequirementWeeks,
&i.CreatedByAvatarURL,
@@ -4732,8 +4732,8 @@ SET
restart_requirement_days_of_week = $7,
restart_requirement_weeks = $8,
failure_ttl = $9,
inactivity_ttl = $10,
locked_ttl = $11
time_til_dormant = $10,
time_til_dormant_autodelete = $11
WHERE
id = $1
`
@@ -4748,8 +4748,8 @@ type UpdateTemplateScheduleByIDParams struct {
RestartRequirementDaysOfWeek int16 `db:"restart_requirement_days_of_week" json:"restart_requirement_days_of_week"`
RestartRequirementWeeks int64 `db:"restart_requirement_weeks" json:"restart_requirement_weeks"`
FailureTTL int64 `db:"failure_ttl" json:"failure_ttl"`
InactivityTTL int64 `db:"inactivity_ttl" json:"inactivity_ttl"`
LockedTTL int64 `db:"locked_ttl" json:"locked_ttl"`
TimeTilDormant int64 `db:"time_til_dormant" json:"time_til_dormant"`
TimeTilDormantAutoDelete int64 `db:"time_til_dormant_autodelete" json:"time_til_dormant_autodelete"`
}
func (q *sqlQuerier) UpdateTemplateScheduleByID(ctx context.Context, arg UpdateTemplateScheduleByIDParams) error {
@@ -4763,8 +4763,8 @@ func (q *sqlQuerier) UpdateTemplateScheduleByID(ctx context.Context, arg UpdateT
arg.RestartRequirementDaysOfWeek,
arg.RestartRequirementWeeks,
arg.FailureTTL,
arg.InactivityTTL,
arg.LockedTTL,
arg.TimeTilDormant,
arg.TimeTilDormantAutoDelete,
)
return err
}
@@ -9104,7 +9104,7 @@ func (q *sqlQuerier) GetDeploymentWorkspaceStats(ctx context.Context) (GetDeploy
const getWorkspaceByAgentID = `-- name: GetWorkspaceByAgentID :one
SELECT
id, created_at, updated_at, owner_id, organization_id, template_id, deleted, name, autostart_schedule, ttl, last_used_at, locked_at, deleting_at
id, created_at, updated_at, owner_id, organization_id, template_id, deleted, name, autostart_schedule, ttl, last_used_at, dormant_at, deleting_at
FROM
workspaces
WHERE
@@ -9147,7 +9147,7 @@ func (q *sqlQuerier) GetWorkspaceByAgentID(ctx context.Context, agentID uuid.UUI
&i.AutostartSchedule,
&i.Ttl,
&i.LastUsedAt,
&i.LockedAt,
&i.DormantAt,
&i.DeletingAt,
)
return i, err
@@ -9155,7 +9155,7 @@ func (q *sqlQuerier) GetWorkspaceByAgentID(ctx context.Context, agentID uuid.UUI
const getWorkspaceByID = `-- name: GetWorkspaceByID :one
SELECT
id, created_at, updated_at, owner_id, organization_id, template_id, deleted, name, autostart_schedule, ttl, last_used_at, locked_at, deleting_at
id, created_at, updated_at, owner_id, organization_id, template_id, deleted, name, autostart_schedule, ttl, last_used_at, dormant_at, deleting_at
FROM
workspaces
WHERE
@@ -9179,7 +9179,7 @@ func (q *sqlQuerier) GetWorkspaceByID(ctx context.Context, id uuid.UUID) (Worksp
&i.AutostartSchedule,
&i.Ttl,
&i.LastUsedAt,
&i.LockedAt,
&i.DormantAt,
&i.DeletingAt,
)
return i, err
@@ -9187,7 +9187,7 @@ func (q *sqlQuerier) GetWorkspaceByID(ctx context.Context, id uuid.UUID) (Worksp
const getWorkspaceByOwnerIDAndName = `-- name: GetWorkspaceByOwnerIDAndName :one
SELECT
id, created_at, updated_at, owner_id, organization_id, template_id, deleted, name, autostart_schedule, ttl, last_used_at, locked_at, deleting_at
id, created_at, updated_at, owner_id, organization_id, template_id, deleted, name, autostart_schedule, ttl, last_used_at, dormant_at, deleting_at
FROM
workspaces
WHERE
@@ -9218,7 +9218,7 @@ func (q *sqlQuerier) GetWorkspaceByOwnerIDAndName(ctx context.Context, arg GetWo
&i.AutostartSchedule,
&i.Ttl,
&i.LastUsedAt,
&i.LockedAt,
&i.DormantAt,
&i.DeletingAt,
)
return i, err
@@ -9226,7 +9226,7 @@ func (q *sqlQuerier) GetWorkspaceByOwnerIDAndName(ctx context.Context, arg GetWo
const getWorkspaceByWorkspaceAppID = `-- name: GetWorkspaceByWorkspaceAppID :one
SELECT
id, created_at, updated_at, owner_id, organization_id, template_id, deleted, name, autostart_schedule, ttl, last_used_at, locked_at, deleting_at
id, created_at, updated_at, owner_id, organization_id, template_id, deleted, name, autostart_schedule, ttl, last_used_at, dormant_at, deleting_at
FROM
workspaces
WHERE
@@ -9276,7 +9276,7 @@ func (q *sqlQuerier) GetWorkspaceByWorkspaceAppID(ctx context.Context, workspace
&i.AutostartSchedule,
&i.Ttl,
&i.LastUsedAt,
&i.LockedAt,
&i.DormantAt,
&i.DeletingAt,
)
return i, err
@@ -9284,7 +9284,7 @@ func (q *sqlQuerier) GetWorkspaceByWorkspaceAppID(ctx context.Context, workspace
const getWorkspaces = `-- name: GetWorkspaces :many
SELECT
workspaces.id, workspaces.created_at, workspaces.updated_at, workspaces.owner_id, workspaces.organization_id, workspaces.template_id, workspaces.deleted, workspaces.name, workspaces.autostart_schedule, workspaces.ttl, workspaces.last_used_at, workspaces.locked_at, workspaces.deleting_at,
workspaces.id, workspaces.created_at, workspaces.updated_at, workspaces.owner_id, workspaces.organization_id, workspaces.template_id, workspaces.deleted, workspaces.name, workspaces.autostart_schedule, workspaces.ttl, workspaces.last_used_at, workspaces.dormant_at, workspaces.deleting_at,
COALESCE(template_name.template_name, 'unknown') as template_name,
latest_build.template_version_id,
latest_build.template_version_name,
@@ -9468,13 +9468,13 @@ WHERE
) > 0
ELSE true
END
-- Filter by locked workspaces. By default we do not return locked
-- Filter by dormant workspaces. By default we do not return dormant
-- workspaces since they are considered soft-deleted.
AND CASE
WHEN $10 :: timestamptz > '0001-01-01 00:00:00+00'::timestamptz THEN
locked_at IS NOT NULL AND locked_at >= $10
dormant_at IS NOT NULL AND dormant_at >= $10
ELSE
locked_at IS NULL
dormant_at IS NULL
END
-- Filter by last_used
AND CASE
@@ -9515,7 +9515,7 @@ type GetWorkspacesParams struct {
Name string `db:"name" json:"name"`
HasAgent string `db:"has_agent" json:"has_agent"`
AgentInactiveDisconnectTimeoutSeconds int64 `db:"agent_inactive_disconnect_timeout_seconds" json:"agent_inactive_disconnect_timeout_seconds"`
LockedAt time.Time `db:"locked_at" json:"locked_at"`
DormantAt time.Time `db:"dormant_at" json:"dormant_at"`
LastUsedBefore time.Time `db:"last_used_before" json:"last_used_before"`
LastUsedAfter time.Time `db:"last_used_after" json:"last_used_after"`
Offset int32 `db:"offset_" json:"offset_"`
@@ -9534,7 +9534,7 @@ type GetWorkspacesRow struct {
AutostartSchedule sql.NullString `db:"autostart_schedule" json:"autostart_schedule"`
Ttl sql.NullInt64 `db:"ttl" json:"ttl"`
LastUsedAt time.Time `db:"last_used_at" json:"last_used_at"`
LockedAt sql.NullTime `db:"locked_at" json:"locked_at"`
DormantAt sql.NullTime `db:"dormant_at" json:"dormant_at"`
DeletingAt sql.NullTime `db:"deleting_at" json:"deleting_at"`
TemplateName string `db:"template_name" json:"template_name"`
TemplateVersionID uuid.UUID `db:"template_version_id" json:"template_version_id"`
@@ -9553,7 +9553,7 @@ func (q *sqlQuerier) GetWorkspaces(ctx context.Context, arg GetWorkspacesParams)
arg.Name,
arg.HasAgent,
arg.AgentInactiveDisconnectTimeoutSeconds,
arg.LockedAt,
arg.DormantAt,
arg.LastUsedBefore,
arg.LastUsedAfter,
arg.Offset,
@@ -9578,7 +9578,7 @@ func (q *sqlQuerier) GetWorkspaces(ctx context.Context, arg GetWorkspacesParams)
&i.AutostartSchedule,
&i.Ttl,
&i.LastUsedAt,
&i.LockedAt,
&i.DormantAt,
&i.DeletingAt,
&i.TemplateName,
&i.TemplateVersionID,
@@ -9600,7 +9600,7 @@ func (q *sqlQuerier) GetWorkspaces(ctx context.Context, arg GetWorkspacesParams)
const getWorkspacesEligibleForTransition = `-- name: GetWorkspacesEligibleForTransition :many
SELECT
workspaces.id, workspaces.created_at, workspaces.updated_at, workspaces.owner_id, workspaces.organization_id, workspaces.template_id, workspaces.deleted, workspaces.name, workspaces.autostart_schedule, workspaces.ttl, workspaces.last_used_at, workspaces.locked_at, workspaces.deleting_at
workspaces.id, workspaces.created_at, workspaces.updated_at, workspaces.owner_id, workspaces.organization_id, workspaces.template_id, workspaces.deleted, workspaces.name, workspaces.autostart_schedule, workspaces.ttl, workspaces.last_used_at, workspaces.dormant_at, workspaces.deleting_at
FROM
workspaces
LEFT JOIN
@@ -9649,17 +9649,17 @@ WHERE
) OR
-- If the workspace's template has an inactivity_ttl set
-- it may be eligible for locking.
-- it may be eligible for dormancy.
(
templates.inactivity_ttl > 0 AND
workspaces.locked_at IS NULL
templates.time_til_dormant > 0 AND
workspaces.dormant_at IS NULL
) OR
-- If the workspace's template has a locked_ttl set
-- and the workspace is already locked
-- If the workspace's template has a time_til_dormant_autodelete set
-- and the workspace is already dormant.
(
templates.locked_ttl > 0 AND
workspaces.locked_at IS NOT NULL
templates.time_til_dormant_autodelete > 0 AND
workspaces.dormant_at IS NOT NULL
)
) AND workspaces.deleted = 'false'
`
@@ -9685,7 +9685,7 @@ func (q *sqlQuerier) GetWorkspacesEligibleForTransition(ctx context.Context, now
&i.AutostartSchedule,
&i.Ttl,
&i.LastUsedAt,
&i.LockedAt,
&i.DormantAt,
&i.DeletingAt,
); err != nil {
return nil, err
@@ -9716,7 +9716,7 @@ INSERT INTO
last_used_at
)
VALUES
($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) RETURNING id, created_at, updated_at, owner_id, organization_id, template_id, deleted, name, autostart_schedule, ttl, last_used_at, locked_at, deleting_at
($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) RETURNING id, created_at, updated_at, owner_id, organization_id, template_id, deleted, name, autostart_schedule, ttl, last_used_at, dormant_at, deleting_at
`
type InsertWorkspaceParams struct {
@@ -9758,7 +9758,7 @@ func (q *sqlQuerier) InsertWorkspace(ctx context.Context, arg InsertWorkspacePar
&i.AutostartSchedule,
&i.Ttl,
&i.LastUsedAt,
&i.LockedAt,
&i.DormantAt,
&i.DeletingAt,
)
return i, err
@@ -9790,7 +9790,7 @@ SET
WHERE
id = $1
AND deleted = false
RETURNING id, created_at, updated_at, owner_id, organization_id, template_id, deleted, name, autostart_schedule, ttl, last_used_at, locked_at, deleting_at
RETURNING id, created_at, updated_at, owner_id, organization_id, template_id, deleted, name, autostart_schedule, ttl, last_used_at, dormant_at, deleting_at
`
type UpdateWorkspaceParams struct {
@@ -9813,7 +9813,7 @@ func (q *sqlQuerier) UpdateWorkspace(ctx context.Context, arg UpdateWorkspacePar
&i.AutostartSchedule,
&i.Ttl,
&i.LastUsedAt,
&i.LockedAt,
&i.DormantAt,
&i.DeletingAt,
)
return i, err
@@ -9857,6 +9857,52 @@ func (q *sqlQuerier) UpdateWorkspaceDeletedByID(ctx context.Context, arg UpdateW
return err
}
const updateWorkspaceDormantDeletingAt = `-- name: UpdateWorkspaceDormantDeletingAt :one
UPDATE
workspaces
SET
dormant_at = $2,
-- When a workspace is active we want to update the last_used_at to avoid the workspace going
-- immediately dormant. If we're transition the workspace to dormant then we leave it alone.
last_used_at = CASE WHEN $2::timestamptz IS NULL THEN now() at time zone 'utc' ELSE last_used_at END,
-- If dormant_at is null (meaning active) or the template-defined time_til_dormant_autodelete is 0 we should set
-- deleting_at to NULL else set it to the dormant_at + time_til_dormant_autodelete duration.
deleting_at = CASE WHEN $2::timestamptz IS NULL OR templates.time_til_dormant_autodelete = 0 THEN NULL ELSE $2::timestamptz + INTERVAL '1 milliseconds' * templates.time_til_dormant_autodelete / 1000000 END
FROM
templates
WHERE
workspaces.template_id = templates.id
AND
workspaces.id = $1
RETURNING workspaces.id, workspaces.created_at, workspaces.updated_at, workspaces.owner_id, workspaces.organization_id, workspaces.template_id, workspaces.deleted, workspaces.name, workspaces.autostart_schedule, workspaces.ttl, workspaces.last_used_at, workspaces.dormant_at, workspaces.deleting_at
`
type UpdateWorkspaceDormantDeletingAtParams struct {
ID uuid.UUID `db:"id" json:"id"`
DormantAt sql.NullTime `db:"dormant_at" json:"dormant_at"`
}
func (q *sqlQuerier) UpdateWorkspaceDormantDeletingAt(ctx context.Context, arg UpdateWorkspaceDormantDeletingAtParams) (Workspace, error) {
row := q.db.QueryRowContext(ctx, updateWorkspaceDormantDeletingAt, arg.ID, arg.DormantAt)
var i Workspace
err := row.Scan(
&i.ID,
&i.CreatedAt,
&i.UpdatedAt,
&i.OwnerID,
&i.OrganizationID,
&i.TemplateID,
&i.Deleted,
&i.Name,
&i.AutostartSchedule,
&i.Ttl,
&i.LastUsedAt,
&i.DormantAt,
&i.DeletingAt,
)
return i, err
}
const updateWorkspaceLastUsedAt = `-- name: UpdateWorkspaceLastUsedAt :exec
UPDATE
workspaces
@@ -9876,52 +9922,6 @@ func (q *sqlQuerier) UpdateWorkspaceLastUsedAt(ctx context.Context, arg UpdateWo
return err
}
const updateWorkspaceLockedDeletingAt = `-- name: UpdateWorkspaceLockedDeletingAt :one
UPDATE
workspaces
SET
locked_at = $2,
-- When a workspace is unlocked we want to update the last_used_at to avoid the workspace getting re-locked.
-- if we're locking the workspace then we leave it alone.
last_used_at = CASE WHEN $2::timestamptz IS NULL THEN now() at time zone 'utc' ELSE last_used_at END,
-- If locked_at is null (meaning unlocked) or the template-defined locked_ttl is 0 we should set
-- deleting_at to NULL else set it to the locked_at + locked_ttl duration.
deleting_at = CASE WHEN $2::timestamptz IS NULL OR templates.locked_ttl = 0 THEN NULL ELSE $2::timestamptz + INTERVAL '1 milliseconds' * templates.locked_ttl / 1000000 END
FROM
templates
WHERE
workspaces.template_id = templates.id
AND
workspaces.id = $1
RETURNING workspaces.id, workspaces.created_at, workspaces.updated_at, workspaces.owner_id, workspaces.organization_id, workspaces.template_id, workspaces.deleted, workspaces.name, workspaces.autostart_schedule, workspaces.ttl, workspaces.last_used_at, workspaces.locked_at, workspaces.deleting_at
`
type UpdateWorkspaceLockedDeletingAtParams struct {
ID uuid.UUID `db:"id" json:"id"`
LockedAt sql.NullTime `db:"locked_at" json:"locked_at"`
}
func (q *sqlQuerier) UpdateWorkspaceLockedDeletingAt(ctx context.Context, arg UpdateWorkspaceLockedDeletingAtParams) (Workspace, error) {
row := q.db.QueryRowContext(ctx, updateWorkspaceLockedDeletingAt, arg.ID, arg.LockedAt)
var i Workspace
err := row.Scan(
&i.ID,
&i.CreatedAt,
&i.UpdatedAt,
&i.OwnerID,
&i.OrganizationID,
&i.TemplateID,
&i.Deleted,
&i.Name,
&i.AutostartSchedule,
&i.Ttl,
&i.LastUsedAt,
&i.LockedAt,
&i.DeletingAt,
)
return i, err
}
const updateWorkspaceTTL = `-- name: UpdateWorkspaceTTL :exec
UPDATE
workspaces
@@ -9941,28 +9941,28 @@ func (q *sqlQuerier) UpdateWorkspaceTTL(ctx context.Context, arg UpdateWorkspace
return err
}
const updateWorkspacesLockedDeletingAtByTemplateID = `-- name: UpdateWorkspacesLockedDeletingAtByTemplateID :exec
const updateWorkspacesDormantDeletingAtByTemplateID = `-- name: UpdateWorkspacesDormantDeletingAtByTemplateID :exec
UPDATE workspaces
SET
deleting_at = CASE
WHEN $1::bigint = 0 THEN NULL
WHEN $2::timestamptz > '0001-01-01 00:00:00+00'::timestamptz THEN ($2::timestamptz) + interval '1 milliseconds' * $1::bigint
ELSE locked_at + interval '1 milliseconds' * $1::bigint
ELSE dormant_at + interval '1 milliseconds' * $1::bigint
END,
locked_at = CASE WHEN $2::timestamptz > '0001-01-01 00:00:00+00'::timestamptz THEN $2::timestamptz ELSE locked_at END
dormant_at = CASE WHEN $2::timestamptz > '0001-01-01 00:00:00+00'::timestamptz THEN $2::timestamptz ELSE dormant_at END
WHERE
template_id = $3
AND
locked_at IS NOT NULL
dormant_at IS NOT NULL
`
type UpdateWorkspacesLockedDeletingAtByTemplateIDParams struct {
LockedTtlMs int64 `db:"locked_ttl_ms" json:"locked_ttl_ms"`
LockedAt time.Time `db:"locked_at" json:"locked_at"`
TemplateID uuid.UUID `db:"template_id" json:"template_id"`
type UpdateWorkspacesDormantDeletingAtByTemplateIDParams struct {
TimeTilDormantAutodeleteMs int64 `db:"time_til_dormant_autodelete_ms" json:"time_til_dormant_autodelete_ms"`
DormantAt time.Time `db:"dormant_at" json:"dormant_at"`
TemplateID uuid.UUID `db:"template_id" json:"template_id"`
}
func (q *sqlQuerier) UpdateWorkspacesLockedDeletingAtByTemplateID(ctx context.Context, arg UpdateWorkspacesLockedDeletingAtByTemplateIDParams) error {
_, err := q.db.ExecContext(ctx, updateWorkspacesLockedDeletingAtByTemplateID, arg.LockedTtlMs, arg.LockedAt, arg.TemplateID)
func (q *sqlQuerier) UpdateWorkspacesDormantDeletingAtByTemplateID(ctx context.Context, arg UpdateWorkspacesDormantDeletingAtByTemplateIDParams) error {
_, err := q.db.ExecContext(ctx, updateWorkspacesDormantDeletingAtByTemplateID, arg.TimeTilDormantAutodeleteMs, arg.DormantAt, arg.TemplateID)
return err
}
+2 -2
View File
@@ -121,8 +121,8 @@ SET
restart_requirement_days_of_week = $7,
restart_requirement_weeks = $8,
failure_ttl = $9,
inactivity_ttl = $10,
locked_ttl = $11
time_til_dormant = $10,
time_til_dormant_autodelete = $11
WHERE
id = $1
;
+24 -24
View File
@@ -259,13 +259,13 @@ WHERE
) > 0
ELSE true
END
-- Filter by locked workspaces. By default we do not return locked
-- Filter by dormant workspaces. By default we do not return dormant
-- workspaces since they are considered soft-deleted.
AND CASE
WHEN @locked_at :: timestamptz > '0001-01-01 00:00:00+00'::timestamptz THEN
locked_at IS NOT NULL AND locked_at >= @locked_at
WHEN @dormant_at :: timestamptz > '0001-01-01 00:00:00+00'::timestamptz THEN
dormant_at IS NOT NULL AND dormant_at >= @dormant_at
ELSE
locked_at IS NULL
dormant_at IS NULL
END
-- Filter by last_used
AND CASE
@@ -479,31 +479,31 @@ WHERE
) OR
-- If the workspace's template has an inactivity_ttl set
-- it may be eligible for locking.
-- it may be eligible for dormancy.
(
templates.inactivity_ttl > 0 AND
workspaces.locked_at IS NULL
templates.time_til_dormant > 0 AND
workspaces.dormant_at IS NULL
) OR
-- If the workspace's template has a locked_ttl set
-- and the workspace is already locked
-- If the workspace's template has a time_til_dormant_autodelete set
-- and the workspace is already dormant.
(
templates.locked_ttl > 0 AND
workspaces.locked_at IS NOT NULL
templates.time_til_dormant_autodelete > 0 AND
workspaces.dormant_at IS NOT NULL
)
) AND workspaces.deleted = 'false';
-- name: UpdateWorkspaceLockedDeletingAt :one
-- name: UpdateWorkspaceDormantDeletingAt :one
UPDATE
workspaces
SET
locked_at = $2,
-- When a workspace is unlocked we want to update the last_used_at to avoid the workspace getting re-locked.
-- if we're locking the workspace then we leave it alone.
dormant_at = $2,
-- When a workspace is active we want to update the last_used_at to avoid the workspace going
-- immediately dormant. If we're transition the workspace to dormant then we leave it alone.
last_used_at = CASE WHEN $2::timestamptz IS NULL THEN now() at time zone 'utc' ELSE last_used_at END,
-- If locked_at is null (meaning unlocked) or the template-defined locked_ttl is 0 we should set
-- deleting_at to NULL else set it to the locked_at + locked_ttl duration.
deleting_at = CASE WHEN $2::timestamptz IS NULL OR templates.locked_ttl = 0 THEN NULL ELSE $2::timestamptz + INTERVAL '1 milliseconds' * templates.locked_ttl / 1000000 END
-- If dormant_at is null (meaning active) or the template-defined time_til_dormant_autodelete is 0 we should set
-- deleting_at to NULL else set it to the dormant_at + time_til_dormant_autodelete duration.
deleting_at = CASE WHEN $2::timestamptz IS NULL OR templates.time_til_dormant_autodelete = 0 THEN NULL ELSE $2::timestamptz + INTERVAL '1 milliseconds' * templates.time_til_dormant_autodelete / 1000000 END
FROM
templates
WHERE
@@ -512,19 +512,19 @@ AND
workspaces.id = $1
RETURNING workspaces.*;
-- name: UpdateWorkspacesLockedDeletingAtByTemplateID :exec
-- name: UpdateWorkspacesDormantDeletingAtByTemplateID :exec
UPDATE workspaces
SET
deleting_at = CASE
WHEN @locked_ttl_ms::bigint = 0 THEN NULL
WHEN @locked_at::timestamptz > '0001-01-01 00:00:00+00'::timestamptz THEN (@locked_at::timestamptz) + interval '1 milliseconds' * @locked_ttl_ms::bigint
ELSE locked_at + interval '1 milliseconds' * @locked_ttl_ms::bigint
WHEN @time_til_dormant_autodelete_ms::bigint = 0 THEN NULL
WHEN @dormant_at::timestamptz > '0001-01-01 00:00:00+00'::timestamptz THEN (@dormant_at::timestamptz) + interval '1 milliseconds' * @time_til_dormant_autodelete_ms::bigint
ELSE dormant_at + interval '1 milliseconds' * @time_til_dormant_autodelete_ms::bigint
END,
locked_at = CASE WHEN @locked_at::timestamptz > '0001-01-01 00:00:00+00'::timestamptz THEN @locked_at::timestamptz ELSE locked_at END
dormant_at = CASE WHEN @dormant_at::timestamptz > '0001-01-01 00:00:00+00'::timestamptz THEN @dormant_at::timestamptz ELSE dormant_at END
WHERE
template_id = @template_id
AND
locked_at IS NOT NULL;
dormant_at IS NOT NULL;
-- name: UpdateTemplateWorkspacesLastUsedAt :exec
UPDATE workspaces
+1 -2
View File
@@ -67,9 +67,8 @@ overrides:
motd_file: MOTDFile
uuid: UUID
failure_ttl: FailureTTL
inactivity_ttl: InactivityTTL
time_til_dormant_autodelete: TimeTilDormantAutoDelete
eof: EOF
locked_ttl: LockedTTL
template_ids: TemplateIDs
active_user_ids: ActiveUserIDs