Skip to content

Commit 6318c4c

Browse files
feat(site): increase TTL and max TTL validation to 30 days (#8258)
Co-authored-by: Dean Sheather <dean@deansheather.com>
1 parent 4232a2e commit 6318c4c

File tree

10 files changed

+47
-23
lines changed

10 files changed

+47
-23
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
11
-- Set a cap of 7 days on template max_ttl
2+
--
3+
-- NOTE: this migration was added in August 2022, but the cap has been changed
4+
-- to 30 days in July 2023.
25
UPDATE templates SET max_ttl = 604800000000000 WHERE max_ttl > 604800000000000;

coderd/workspaces.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,10 @@ import (
3232

3333
var (
3434
ttlMin = time.Minute //nolint:revive // min here means 'minimum' not 'minutes'
35-
ttlMax = 7 * 24 * time.Hour
35+
ttlMax = 30 * 24 * time.Hour
3636

3737
errTTLMin = xerrors.New("time until shutdown must be at least one minute")
38-
errTTLMax = xerrors.New("time until shutdown must be less than 7 days")
38+
errTTLMax = xerrors.New("time until shutdown must be less than 30 days")
3939
errDeadlineTooSoon = xerrors.New("new deadline must be at least 30 minutes in the future")
4040
errDeadlineBeforeStart = xerrors.New("new deadline must be before workspace start time")
4141
)

coderd/workspaces_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1837,13 +1837,13 @@ func TestWorkspaceUpdateTTL(t *testing.T) {
18371837
},
18381838
{
18391839
name: "maximum ttl",
1840-
ttlMillis: ptr.Ref((24 * 7 * time.Hour).Milliseconds()),
1840+
ttlMillis: ptr.Ref((24 * 30 * time.Hour).Milliseconds()),
18411841
expectedError: "",
18421842
},
18431843
{
18441844
name: "above maximum ttl",
1845-
ttlMillis: ptr.Ref((24*7*time.Hour + time.Minute).Milliseconds()),
1846-
expectedError: "time until shutdown must be less than 7 days",
1845+
ttlMillis: ptr.Ref((24*30*time.Hour + time.Minute).Milliseconds()),
1846+
expectedError: "time until shutdown must be less than 30 days",
18471847
},
18481848
}
18491849

site/src/components/WorkspaceScheduleForm/WorkspaceScheduleForm.test.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,10 +158,19 @@ describe("validationSchema", () => {
158158
expect(validate).not.toThrowError()
159159
})
160160

161-
it("disallows a ttl of 7 days + 1 hour", () => {
161+
it("allows a ttl of 30 days", () => {
162162
const values: WorkspaceScheduleFormValues = {
163163
...valid,
164-
ttl: 24 * 7 + 1,
164+
ttl: 24 * 30,
165+
}
166+
const validate = () => validationSchema.validateSync(values)
167+
expect(validate).not.toThrowError()
168+
})
169+
170+
it("disallows a ttl of 30 days + 1 hour", () => {
171+
const values: WorkspaceScheduleFormValues = {
172+
...valid,
173+
ttl: 24 * 30 + 1,
165174
}
166175
const validate = () => validationSchema.validateSync(values)
167176
expect(validate).toThrowError(Language.errorTtlMax)

site/src/components/WorkspaceScheduleForm/WorkspaceScheduleForm.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ export const Language = {
4848
errorNoStop:
4949
"Time until shutdown must be greater than zero when autostop is enabled.",
5050
errorTtlMax:
51-
"Please enter a limit that is less than or equal to 168 hours (7 days).",
51+
"Please enter a limit that is less than or equal to 720 hours (30 days).",
5252
daysOfWeekLabel: "Days of Week",
5353
daySundayLabel: "Sun",
5454
dayMondayLabel: "Mon",
@@ -172,7 +172,7 @@ export const validationSchema = Yup.object({
172172
ttl: Yup.number()
173173
.integer()
174174
.min(0)
175-
.max(24 * 7 /* 7 days */, Language.errorTtlMax)
175+
.max(24 * 30 /* 30 days */, Language.errorTtlMax)
176176
.test("positive-if-autostop", Language.errorNoStop, function (value) {
177177
const parent = this.parent as WorkspaceScheduleFormValues
178178
if (parent.autostopEnabled) {

site/src/i18n/en/createTemplatePage.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,9 @@
4848
},
4949
"error": {
5050
"descriptionMax": "Please enter a description that is less than or equal to 128 characters.",
51-
"defaultTTLMax": "Please enter a limit that is less than or equal to 168 hours (7 days).",
51+
"defaultTTLMax": "Please enter a limit that is less than or equal to 720 hours (30 days).",
5252
"defaultTTLMin": "Default time until autostop must not be less than 0.",
53-
"maxTTLMax": "Please enter a limit that is less than or equal to 168 hours (7 days).",
53+
"maxTTLMax": "Please enter a limit that is less than or equal to 720 hours (30 days).",
5454
"maxTTLMin": "Maximum time until autostop must not be less than 0."
5555
}
5656
}

site/src/i18n/en/templateSettingsPage.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@
99
"iconLabel": "Icon",
1010
"formAriaLabel": "Template settings form",
1111
"selectEmoji": "Select emoji",
12-
"defaultTTLMaxError": "Please enter a limit that is less than or equal to 168 hours (7 days).",
12+
"defaultTTLMaxError": "Please enter a limit that is less than or equal to 720 hours (30 days).",
1313
"defaultTTLMinError": "Default time until autostop must not be less than 0.",
1414
"defaultTTLHelperText_zero": "Workspaces will run until stopped manually.",
1515
"defaultTTLHelperText_one": "Workspaces will default to stopping after {{count}} hour. If Coder detects workspace connection activity, the autostop timer is bumped up one hour.",
1616
"defaultTTLHelperText_other": "Workspaces will default to stopping after {{count}} hours. If Coder detects workspace connection activity, the autostop timer is bumped up one hour.",
17-
"maxTTLMaxError": "Please enter a limit that is less than or equal to 168 hours (7 days).",
17+
"maxTTLMaxError": "Please enter a limit that is less than or equal to 720 hours (30 days).",
1818
"maxTTLMinError": "Maximum time until autostop must not be less than 0.",
1919
"maxTTLHelperText_zero": "Workspaces may run indefinitely.",
2020
"maxTTLHelperText_one": "Workspaces must stop within 1 hour of starting, regardless of any active connections.",

site/src/pages/CreateTemplatePage/CreateTemplateForm.tsx

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ import capitalize from "lodash/capitalize"
4141
import { VariableInput } from "./VariableInput"
4242

4343
const MAX_DESCRIPTION_CHAR_LIMIT = 128
44-
const MAX_TTL_DAYS = 7
44+
const MAX_TTL_DAYS = 30
4545

4646
const TTLHelperText = ({
4747
ttl,
@@ -78,15 +78,15 @@ const validationSchema = Yup.object({
7878
.integer()
7979
.min(0, "Default time until autostop must not be less than 0.")
8080
.max(
81-
24 * MAX_TTL_DAYS /* 7 days in hours */,
82-
"Please enter a limit that is less than or equal to 168 hours (7 days).",
81+
24 * MAX_TTL_DAYS /* 30 days in hours */,
82+
"Please enter a limit that is less than or equal to 720 hours (30 days).",
8383
),
8484
max_ttl_hours: Yup.number()
8585
.integer()
8686
.min(0, "Maximum time until autostop must not be less than 0.")
8787
.max(
88-
24 * MAX_TTL_DAYS /* 7 days in hours */,
89-
"Please enter a limit that is less than or equal to 168 hours(7 days).",
88+
24 * MAX_TTL_DAYS /* 30 days in hours */,
89+
"Please enter a limit that is less than or equal to 720 hours (30 days).",
9090
),
9191
})
9292

@@ -98,6 +98,9 @@ const defaultInitialValues: CreateTemplateData = {
9898
default_ttl_hours: 24,
9999
// max_ttl is an enterprise-only feature, and the server ignores the value if
100100
// you are not licensed. We hide the form value based on entitlements.
101+
//
102+
// The maximum value is 30 days but we default to 7 days as it's a much more
103+
// sensible value for most teams.
101104
max_ttl_hours: 24 * 7,
102105
allow_user_cancel_workspace_jobs: false,
103106
allow_user_autostart: false,

site/src/pages/TemplateSettingsPage/TemplateSchedulePage/TemplateScheduleForm/formHelpers.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export interface TemplateScheduleFormValues extends UpdateTemplateMeta {
88
locked_cleanup_enabled: boolean
99
}
1010

11-
const MAX_TTL_DAYS = 7
11+
const MAX_TTL_DAYS = 30
1212

1313
export const getValidationSchema = (): Yup.AnyObjectSchema =>
1414
Yup.object({
@@ -21,7 +21,7 @@ export const getValidationSchema = (): Yup.AnyObjectSchema =>
2121
.toString(),
2222
)
2323
.max(
24-
24 * MAX_TTL_DAYS /* 7 days in hours */,
24+
24 * MAX_TTL_DAYS /* 30 days in hours */,
2525
i18next
2626
.t("defaultTTLMaxError", { ns: "templateSettingsPage" })
2727
.toString(),
@@ -33,7 +33,7 @@ export const getValidationSchema = (): Yup.AnyObjectSchema =>
3333
i18next.t("maxTTLMinError", { ns: "templateSettingsPage" }).toString(),
3434
)
3535
.max(
36-
24 * MAX_TTL_DAYS /* 7 days in hours */,
36+
24 * MAX_TTL_DAYS /* 30 days in hours */,
3737
i18next.t("maxTTLMaxError", { ns: "templateSettingsPage" }).toString(),
3838
),
3939
failure_ttl_ms: Yup.number()

site/src/pages/TemplateSettingsPage/TemplateSchedulePage/TemplateSchedulePage.test.tsx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,10 +159,19 @@ describe("TemplateSchedulePage", () => {
159159
expect(validate).not.toThrowError()
160160
})
161161

162-
it("disallows a default ttl of 7 days + 1 hour", () => {
162+
it("allows a default ttl of 30 days", () => {
163163
const values: UpdateTemplateMeta = {
164164
...validFormValues,
165-
default_ttl_ms: 24 * 7 + 1,
165+
default_ttl_ms: 24 * 30,
166+
}
167+
const validate = () => getValidationSchema().validateSync(values)
168+
expect(validate).not.toThrowError()
169+
})
170+
171+
it("disallows a default ttl of 30 days + 1 hour", () => {
172+
const values: UpdateTemplateMeta = {
173+
...validFormValues,
174+
default_ttl_ms: 24 * 30 + 1,
166175
}
167176
const validate = () => getValidationSchema().validateSync(values)
168177
expect(validate).toThrowError(

0 commit comments

Comments
 (0)