Skip to content

Commit 4414f40

Browse files
committed
Merge branch 'main' into 7452-banner-legacy-params
2 parents 9b3fa89 + b7f4f3a commit 4414f40

File tree

286 files changed

+2406
-2540
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

286 files changed

+2406
-2540
lines changed

cli/templatecreate.go

+44-3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"errors"
55
"fmt"
66
"io"
7+
"net/http"
78
"os"
89
"path/filepath"
910
"strings"
@@ -29,6 +30,8 @@ func (r *RootCmd) templateCreate() *clibase.Cmd {
2930
variablesFile string
3031
variables []string
3132
defaultTTL time.Duration
33+
failureTTL time.Duration
34+
inactivityTTL time.Duration
3235

3336
uploadFlags templateUploadFlags
3437
)
@@ -41,6 +44,30 @@ func (r *RootCmd) templateCreate() *clibase.Cmd {
4144
r.InitClient(client),
4245
),
4346
Handler: func(inv *clibase.Invocation) error {
47+
if failureTTL != 0 || inactivityTTL != 0 {
48+
// This call can be removed when workspace_actions is no longer experimental
49+
experiments, exErr := client.Experiments(inv.Context())
50+
if exErr != nil {
51+
return xerrors.Errorf("get experiments: %w", exErr)
52+
}
53+
54+
if !experiments.Enabled(codersdk.ExperimentWorkspaceActions) {
55+
return xerrors.Errorf("--failure-ttl and --inactivityTTL are experimental features. Use the workspace_actions CODER_EXPERIMENTS flag to set these configuration values.")
56+
}
57+
58+
entitlements, err := client.Entitlements(inv.Context())
59+
var sdkErr *codersdk.Error
60+
if xerrors.As(err, &sdkErr) && sdkErr.StatusCode() == http.StatusNotFound {
61+
return xerrors.Errorf("your deployment appears to be an AGPL deployment, so you cannot set --failure-ttl or --inactivityTTL")
62+
} else if err != nil {
63+
return xerrors.Errorf("get entitlements: %w", err)
64+
}
65+
66+
if !entitlements.Features[codersdk.FeatureAdvancedTemplateScheduling].Enabled {
67+
return xerrors.Errorf("your license is not entitled to use advanced template scheduling, so you cannot set --failure-ttl or --inactivityTTL")
68+
}
69+
}
70+
4471
organization, err := CurrentOrganization(inv, client)
4572
if err != nil {
4673
return err
@@ -96,9 +123,11 @@ func (r *RootCmd) templateCreate() *clibase.Cmd {
96123
}
97124

98125
createReq := codersdk.CreateTemplateRequest{
99-
Name: templateName,
100-
VersionID: job.ID,
101-
DefaultTTLMillis: ptr.Ref(defaultTTL.Milliseconds()),
126+
Name: templateName,
127+
VersionID: job.ID,
128+
DefaultTTLMillis: ptr.Ref(defaultTTL.Milliseconds()),
129+
FailureTTLMillis: ptr.Ref(failureTTL.Milliseconds()),
130+
InactivityTTLMillis: ptr.Ref(inactivityTTL.Milliseconds()),
102131
}
103132

104133
_, err = client.CreateTemplate(inv.Context(), organization.ID, createReq)
@@ -143,6 +172,18 @@ func (r *RootCmd) templateCreate() *clibase.Cmd {
143172
Default: "24h",
144173
Value: clibase.DurationOf(&defaultTTL),
145174
},
175+
{
176+
Flag: "failure-ttl",
177+
Description: "Specify a failure TTL for workspaces created from this template. This licensed feature's default is 0h (off).",
178+
Default: "0h",
179+
Value: clibase.DurationOf(&failureTTL),
180+
},
181+
{
182+
Flag: "inactivity-ttl",
183+
Description: "Specify an inactivity TTL for workspaces created from this template. This licensed feature's default is 0h (off).",
184+
Default: "0h",
185+
Value: clibase.DurationOf(&inactivityTTL),
186+
},
146187
uploadFlags.option(),
147188
{
148189
Flag: "test.provisioner",

cli/templateedit.go

+31-3
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ func (r *RootCmd) templateEdit() *clibase.Cmd {
2020
icon string
2121
defaultTTL time.Duration
2222
maxTTL time.Duration
23+
failureTTL time.Duration
24+
inactivityTTL time.Duration
2325
allowUserCancelWorkspaceJobs bool
2426
allowUserAutostart bool
2527
allowUserAutostop bool
@@ -34,17 +36,29 @@ func (r *RootCmd) templateEdit() *clibase.Cmd {
3436
),
3537
Short: "Edit the metadata of a template by name.",
3638
Handler: func(inv *clibase.Invocation) error {
37-
if maxTTL != 0 || !allowUserAutostart || !allowUserAutostop {
39+
// This clause can be removed when workspace_actions is no longer experimental
40+
if failureTTL != 0 || inactivityTTL != 0 {
41+
experiments, exErr := client.Experiments(inv.Context())
42+
if exErr != nil {
43+
return xerrors.Errorf("get experiments: %w", exErr)
44+
}
45+
46+
if !experiments.Enabled(codersdk.ExperimentWorkspaceActions) {
47+
return xerrors.Errorf("--failure-ttl and --inactivityTTL are experimental features. Use the workspace_actions CODER_EXPERIMENTS flag to set these configuration values.")
48+
}
49+
}
50+
51+
if maxTTL != 0 || !allowUserAutostart || !allowUserAutostop || failureTTL != 0 || inactivityTTL != 0 {
3852
entitlements, err := client.Entitlements(inv.Context())
3953
var sdkErr *codersdk.Error
4054
if xerrors.As(err, &sdkErr) && sdkErr.StatusCode() == http.StatusNotFound {
41-
return xerrors.Errorf("your deployment appears to be an AGPL deployment, so you cannot set --max-ttl, --allow-user-autostart=false or --allow-user-autostop=false")
55+
return xerrors.Errorf("your deployment appears to be an AGPL deployment, so you cannot set --max-ttl, --failure-ttl, --inactivityTTL, --allow-user-autostart=false or --allow-user-autostop=false")
4256
} else if err != nil {
4357
return xerrors.Errorf("get entitlements: %w", err)
4458
}
4559

4660
if !entitlements.Features[codersdk.FeatureAdvancedTemplateScheduling].Enabled {
47-
return xerrors.Errorf("your license is not entitled to use advanced template scheduling, so you cannot set --max-ttl, --allow-user-autostart=false or --allow-user-autostop=false")
61+
return xerrors.Errorf("your license is not entitled to use advanced template scheduling, so you cannot set --max-ttl, --failure-ttl, --inactivityTTL, --allow-user-autostart=false or --allow-user-autostop=false")
4862
}
4963
}
5064

@@ -65,6 +79,8 @@ func (r *RootCmd) templateEdit() *clibase.Cmd {
6579
Icon: icon,
6680
DefaultTTLMillis: defaultTTL.Milliseconds(),
6781
MaxTTLMillis: maxTTL.Milliseconds(),
82+
FailureTTLMillis: failureTTL.Milliseconds(),
83+
InactivityTTLMillis: inactivityTTL.Milliseconds(),
6884
AllowUserCancelWorkspaceJobs: allowUserCancelWorkspaceJobs,
6985
AllowUserAutostart: allowUserAutostart,
7086
AllowUserAutostop: allowUserAutostop,
@@ -110,6 +126,18 @@ func (r *RootCmd) templateEdit() *clibase.Cmd {
110126
Description: "Edit the template maximum time before shutdown - workspaces created from this template must shutdown within the given duration after starting. This is an enterprise-only feature.",
111127
Value: clibase.DurationOf(&maxTTL),
112128
},
129+
{
130+
Flag: "failure-ttl",
131+
Description: "Specify a failure TTL for workspaces created from this template. This licensed feature's default is 0h (off).",
132+
Default: "0h",
133+
Value: clibase.DurationOf(&failureTTL),
134+
},
135+
{
136+
Flag: "inactivity-ttl",
137+
Description: "Specify an inactivity TTL for workspaces created from this template. This licensed feature's default is 0h (off).",
138+
Default: "0h",
139+
Value: clibase.DurationOf(&inactivityTTL),
140+
},
113141
{
114142
Flag: "allow-user-cancel-workspace-jobs",
115143
Description: "Allow users to cancel in-progress workspace jobs.",

cli/templateedit_test.go

+8
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,8 @@ func TestTemplateEdit(t *testing.T) {
453453
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID, func(ctr *codersdk.CreateTemplateRequest) {
454454
ctr.DefaultTTLMillis = nil
455455
ctr.MaxTTLMillis = nil
456+
ctr.FailureTTLMillis = nil
457+
ctr.InactivityTTLMillis = nil
456458
})
457459

458460
// Test the cli command with --allow-user-autostart.
@@ -496,6 +498,8 @@ func TestTemplateEdit(t *testing.T) {
496498
assert.Equal(t, template.MaxTTLMillis, updated.MaxTTLMillis)
497499
assert.Equal(t, template.AllowUserAutostart, updated.AllowUserAutostart)
498500
assert.Equal(t, template.AllowUserAutostop, updated.AllowUserAutostop)
501+
assert.Equal(t, template.FailureTTLMillis, updated.FailureTTLMillis)
502+
assert.Equal(t, template.InactivityTTLMillis, updated.InactivityTTLMillis)
499503
})
500504

501505
t.Run("BlockedNotEntitled", func(t *testing.T) {
@@ -582,6 +586,8 @@ func TestTemplateEdit(t *testing.T) {
582586
assert.Equal(t, template.MaxTTLMillis, updated.MaxTTLMillis)
583587
assert.Equal(t, template.AllowUserAutostart, updated.AllowUserAutostart)
584588
assert.Equal(t, template.AllowUserAutostop, updated.AllowUserAutostop)
589+
assert.Equal(t, template.FailureTTLMillis, updated.FailureTTLMillis)
590+
assert.Equal(t, template.InactivityTTLMillis, updated.InactivityTTLMillis)
585591
})
586592
t.Run("Entitled", func(t *testing.T) {
587593
t.Parallel()
@@ -672,6 +678,8 @@ func TestTemplateEdit(t *testing.T) {
672678
assert.Equal(t, template.MaxTTLMillis, updated.MaxTTLMillis)
673679
assert.Equal(t, template.AllowUserAutostart, updated.AllowUserAutostart)
674680
assert.Equal(t, template.AllowUserAutostop, updated.AllowUserAutostop)
681+
assert.Equal(t, template.FailureTTLMillis, updated.FailureTTLMillis)
682+
assert.Equal(t, template.InactivityTTLMillis, updated.InactivityTTLMillis)
675683
})
676684
})
677685
}

cli/testdata/coder_templates_create_--help.golden

+8
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,14 @@ Create a template from the current directory or as specified by flag
99
-d, --directory string (default: .)
1010
Specify the directory to create from, use '-' to read tar from stdin.
1111

12+
--failure-ttl duration (default: 0h)
13+
Specify a failure TTL for workspaces created from this template. This
14+
licensed feature's default is 0h (off).
15+
16+
--inactivity-ttl duration (default: 0h)
17+
Specify an inactivity TTL for workspaces created from this template.
18+
This licensed feature's default is 0h (off).
19+
1220
--parameter-file string
1321
Specify a file path with parameter values.
1422

cli/testdata/coder_templates_edit_--help.golden

+8
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,17 @@ Edit the metadata of a template by name.
2424
--display-name string
2525
Edit the template display name.
2626

27+
--failure-ttl duration (default: 0h)
28+
Specify a failure TTL for workspaces created from this template. This
29+
licensed feature's default is 0h (off).
30+
2731
--icon string
2832
Edit the template icon path.
2933

34+
--inactivity-ttl duration (default: 0h)
35+
Specify an inactivity TTL for workspaces created from this template.
36+
This licensed feature's default is 0h (off).
37+
3038
--max-ttl duration
3139
Edit the template maximum time before shutdown - workspaces created
3240
from this template must shutdown within the given duration after

coderd/apidoc/docs.go

+30-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/apidoc/swagger.json

+26-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/httpmw/csp.go

+2
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,8 @@ func CSPHeaders(websocketHosts func() []string) func(next http.Handler) http.Han
104104
if len(extraConnect) > 0 {
105105
for _, extraHost := range extraConnect {
106106
cspSrcs.Append(cspDirectiveConnectSrc, fmt.Sprintf("wss://%[1]s ws://%[1]s", extraHost))
107+
// We also require this to make http/https requests to the workspace proxy for latency checking.
108+
cspSrcs.Append(cspDirectiveConnectSrc, fmt.Sprintf("https://%[1]s http://%[1]s", extraHost))
107109
}
108110
}
109111

coderd/templates.go

+22-3
Original file line numberDiff line numberDiff line change
@@ -214,15 +214,23 @@ func (api *API) postTemplateByOrganization(rw http.ResponseWriter, r *http.Reque
214214
}
215215

216216
var (
217-
defaultTTL time.Duration
218-
maxTTL time.Duration
217+
defaultTTL time.Duration
218+
maxTTL time.Duration
219+
failureTTL time.Duration
220+
inactivityTTL time.Duration
219221
)
220222
if createTemplate.DefaultTTLMillis != nil {
221223
defaultTTL = time.Duration(*createTemplate.DefaultTTLMillis) * time.Millisecond
222224
}
223225
if createTemplate.MaxTTLMillis != nil {
224226
maxTTL = time.Duration(*createTemplate.MaxTTLMillis) * time.Millisecond
225227
}
228+
if createTemplate.FailureTTLMillis != nil {
229+
failureTTL = time.Duration(*createTemplate.FailureTTLMillis) * time.Millisecond
230+
}
231+
if createTemplate.InactivityTTLMillis != nil {
232+
inactivityTTL = time.Duration(*createTemplate.InactivityTTLMillis) * time.Millisecond
233+
}
226234

227235
var validErrs []codersdk.ValidationError
228236
if defaultTTL < 0 {
@@ -234,6 +242,12 @@ func (api *API) postTemplateByOrganization(rw http.ResponseWriter, r *http.Reque
234242
if maxTTL != 0 && defaultTTL > maxTTL {
235243
validErrs = append(validErrs, codersdk.ValidationError{Field: "default_ttl_ms", Detail: "Must be less than or equal to max_ttl_ms if max_ttl_ms is set."})
236244
}
245+
if failureTTL < 0 {
246+
validErrs = append(validErrs, codersdk.ValidationError{Field: "failure_ttl_ms", Detail: "Must be a positive integer."})
247+
}
248+
if inactivityTTL < 0 {
249+
validErrs = append(validErrs, codersdk.ValidationError{Field: "inactivity_ttl_ms", Detail: "Must be a positive integer."})
250+
}
237251
if len(validErrs) > 0 {
238252
httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{
239253
Message: "Invalid create template request.",
@@ -279,7 +293,12 @@ func (api *API) postTemplateByOrganization(rw http.ResponseWriter, r *http.Reque
279293
UserAutostartEnabled: allowUserAutostart,
280294
UserAutostopEnabled: allowUserAutostop,
281295
DefaultTTL: defaultTTL,
282-
MaxTTL: maxTTL,
296+
// Some of these values are enterprise-only, but the
297+
// TemplateScheduleStore will handle avoiding setting them if
298+
// unlicensed.
299+
MaxTTL: maxTTL,
300+
FailureTTL: failureTTL,
301+
InactivityTTL: inactivityTTL,
283302
})
284303
if err != nil {
285304
return xerrors.Errorf("set template schedule options: %s", err)

codersdk/workspaceproxy.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ import (
1515
type ProxyHealthStatus string
1616

1717
const (
18-
// ProxyReachable means the proxy access url is reachable and returns a healthy
18+
// ProxyHealthy means the proxy access url is reachable and returns a healthy
1919
// status code.
20-
ProxyReachable ProxyHealthStatus = "reachable"
20+
ProxyHealthy ProxyHealthStatus = "ok"
2121
// ProxyUnreachable means the proxy access url is not responding.
2222
ProxyUnreachable ProxyHealthStatus = "unreachable"
2323
// ProxyUnhealthy means the proxy access url is responding, but there is some

0 commit comments

Comments
 (0)