diff --git a/cli/templatecreate.go b/cli/templatecreate.go
index da0793121d949..e6904d2a065f6 100644
--- a/cli/templatecreate.go
+++ b/cli/templatecreate.go
@@ -31,10 +31,11 @@ func (r *RootCmd) templateCreate() *clibase.Cmd {
disableEveryone bool
requireActiveVersion bool
- defaultTTL time.Duration
- failureTTL time.Duration
- inactivityTTL time.Duration
- maxTTL time.Duration
+ defaultTTL time.Duration
+ failureTTL time.Duration
+ dormancyThreshold time.Duration
+ dormancyAutoDeletion time.Duration
+ maxTTL time.Duration
uploadFlags templateUploadFlags
)
@@ -47,10 +48,10 @@ func (r *RootCmd) templateCreate() *clibase.Cmd {
r.InitClient(client),
),
Handler: func(inv *clibase.Invocation) error {
- isTemplateSchedulingOptionsSet := failureTTL != 0 || inactivityTTL != 0 || maxTTL != 0
+ isTemplateSchedulingOptionsSet := failureTTL != 0 || dormancyThreshold != 0 || dormancyAutoDeletion != 0 || maxTTL != 0
if isTemplateSchedulingOptionsSet || requireActiveVersion {
- if failureTTL != 0 || inactivityTTL != 0 {
+ if failureTTL != 0 || dormancyThreshold != 0 || dormancyAutoDeletion != 0 {
// This call can be removed when workspace_actions is no longer experimental
experiments, exErr := client.Experiments(inv.Context())
if exErr != nil {
@@ -58,7 +59,7 @@ func (r *RootCmd) templateCreate() *clibase.Cmd {
}
if !experiments.Enabled(codersdk.ExperimentWorkspaceActions) {
- return xerrors.Errorf("--failure-ttl and --inactivity-ttl are experimental features. Use the workspace_actions CODER_EXPERIMENTS flag to set these configuration values.")
+ return xerrors.Errorf("--failure-ttl, --dormancy-threshold, and --dormancy-auto-deletion are experimental features. Use the workspace_actions CODER_EXPERIMENTS flag to set these configuration values.")
}
}
@@ -153,14 +154,15 @@ func (r *RootCmd) templateCreate() *clibase.Cmd {
}
createReq := codersdk.CreateTemplateRequest{
- Name: templateName,
- VersionID: job.ID,
- DefaultTTLMillis: ptr.Ref(defaultTTL.Milliseconds()),
- FailureTTLMillis: ptr.Ref(failureTTL.Milliseconds()),
- MaxTTLMillis: ptr.Ref(maxTTL.Milliseconds()),
- TimeTilDormantMillis: ptr.Ref(inactivityTTL.Milliseconds()),
- DisableEveryoneGroupAccess: disableEveryone,
- RequireActiveVersion: requireActiveVersion,
+ Name: templateName,
+ VersionID: job.ID,
+ DefaultTTLMillis: ptr.Ref(defaultTTL.Milliseconds()),
+ FailureTTLMillis: ptr.Ref(failureTTL.Milliseconds()),
+ MaxTTLMillis: ptr.Ref(maxTTL.Milliseconds()),
+ TimeTilDormantMillis: ptr.Ref(dormancyThreshold.Milliseconds()),
+ TimeTilDormantAutoDeleteMillis: ptr.Ref(dormancyAutoDeletion.Milliseconds()),
+ DisableEveryoneGroupAccess: disableEveryone,
+ RequireActiveVersion: requireActiveVersion,
}
_, err = client.CreateTemplate(inv.Context(), organization.ID, createReq)
@@ -220,11 +222,18 @@ func (r *RootCmd) templateCreate() *clibase.Cmd {
Value: clibase.DurationOf(&failureTTL),
},
{
- Flag: "inactivity-ttl",
- Description: "Specify an inactivity TTL for workspaces created from this template. It is the amount of time the workspace is not used before it is be stopped and auto-locked. This includes across multiple builds (e.g. auto-starts and stops). This licensed feature's default is 0h (off). Maps to \"Dormancy threshold\" in the UI.",
+ Flag: "dormancy-threshold",
+ Description: "Specify a duration workspaces may be inactive prior to being moved to the dormant state. This licensed feature's default is 0h (off). Maps to \"Dormancy threshold\" in the UI.",
Default: "0h",
- Value: clibase.DurationOf(&inactivityTTL),
+ Value: clibase.DurationOf(&dormancyThreshold),
},
+ {
+ Flag: "dormancy-auto-deletion",
+ Description: "Specify a duration workspaces may be in the dormant state prior to being deleted. This licensed feature's default is 0h (off). Maps to \"Dormancy Auto-Deletion\" in the UI.",
+ Default: "0h",
+ Value: clibase.DurationOf(&dormancyAutoDeletion),
+ },
+
{
Flag: "max-ttl",
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.",
diff --git a/cli/templateedit.go b/cli/templateedit.go
index 9c46e98427f8d..91d09486139d5 100644
--- a/cli/templateedit.go
+++ b/cli/templateedit.go
@@ -28,7 +28,8 @@ func (r *RootCmd) templateEdit() *clibase.Cmd {
autostopRequirementWeeks int64
autostartRequirementDaysOfWeek []string
failureTTL time.Duration
- inactivityTTL time.Duration
+ dormancyThreshold time.Duration
+ dormancyAutoDeletion time.Duration
allowUserCancelWorkspaceJobs bool
allowUserAutostart bool
allowUserAutostop bool
@@ -46,14 +47,14 @@ func (r *RootCmd) templateEdit() *clibase.Cmd {
Short: "Edit the metadata of a template by name.",
Handler: func(inv *clibase.Invocation) error {
// This clause can be removed when workspace_actions is no longer experimental
- if failureTTL != 0 || inactivityTTL != 0 {
+ if failureTTL != 0 || dormancyThreshold != 0 || dormancyAutoDeletion != 0 {
experiments, exErr := client.Experiments(inv.Context())
if exErr != nil {
return xerrors.Errorf("get experiments: %w", exErr)
}
if !experiments.Enabled(codersdk.ExperimentWorkspaceActions) {
- return xerrors.Errorf("--failure-ttl and --inactivity-ttl are experimental features. Use the workspace_actions CODER_EXPERIMENTS flag to set these configuration values.")
+ return xerrors.Errorf("--failure-ttl, --dormancy-threshold, and --dormancy-auto-deletion are experimental features. Use the workspace_actions CODER_EXPERIMENTS flag to set these configuration values.")
}
}
@@ -64,7 +65,8 @@ func (r *RootCmd) templateEdit() *clibase.Cmd {
!allowUserAutostop ||
maxTTL != 0 ||
failureTTL != 0 ||
- inactivityTTL != 0 ||
+ dormancyThreshold != 0 ||
+ dormancyAutoDeletion != 0 ||
len(autostartRequirementDaysOfWeek) > 0
requiresEntitlement := requiresScheduling || requireActiveVersion
@@ -119,6 +121,15 @@ func (r *RootCmd) templateEdit() *clibase.Cmd {
if unsetAutostopRequirementDaysOfWeek {
autostopRequirementDaysOfWeek = []string{}
}
+ if failureTTL == 0 {
+ failureTTL = time.Duration(template.FailureTTLMillis) * time.Millisecond
+ }
+ if dormancyThreshold == 0 {
+ dormancyThreshold = time.Duration(template.TimeTilDormantMillis) * time.Millisecond
+ }
+ if dormancyAutoDeletion == 0 {
+ dormancyAutoDeletion = time.Duration(template.TimeTilDormantAutoDeleteMillis) * time.Millisecond
+ }
// Only pass explicitly set deprecated values since the empty string
// removes the deprecated message. By default if we pass a nil,
@@ -129,7 +140,6 @@ func (r *RootCmd) templateEdit() *clibase.Cmd {
deprecated = &deprecationMessage
}
- // NOTE: coderd will ignore empty fields.
req := codersdk.UpdateTemplateMeta{
Name: name,
DisplayName: displayName,
@@ -144,13 +154,14 @@ func (r *RootCmd) templateEdit() *clibase.Cmd {
AutostartRequirement: &codersdk.TemplateAutostartRequirement{
DaysOfWeek: autostartRequirementDaysOfWeek,
},
- FailureTTLMillis: failureTTL.Milliseconds(),
- TimeTilDormantMillis: inactivityTTL.Milliseconds(),
- AllowUserCancelWorkspaceJobs: allowUserCancelWorkspaceJobs,
- AllowUserAutostart: allowUserAutostart,
- AllowUserAutostop: allowUserAutostop,
- RequireActiveVersion: requireActiveVersion,
- DeprecationMessage: deprecated,
+ FailureTTLMillis: failureTTL.Milliseconds(),
+ TimeTilDormantMillis: dormancyThreshold.Milliseconds(),
+ TimeTilDormantAutoDeleteMillis: dormancyAutoDeletion.Milliseconds(),
+ AllowUserCancelWorkspaceJobs: allowUserCancelWorkspaceJobs,
+ AllowUserAutostart: allowUserAutostart,
+ AllowUserAutostop: allowUserAutostop,
+ RequireActiveVersion: requireActiveVersion,
+ DeprecationMessage: deprecated,
}
_, err = client.UpdateTemplateMeta(inv.Context(), template.ID, req)
@@ -246,10 +257,16 @@ func (r *RootCmd) templateEdit() *clibase.Cmd {
Value: clibase.DurationOf(&failureTTL),
},
{
- Flag: "inactivity-ttl",
- Description: "Specify an inactivity TTL for workspaces created from this template. It is the amount of time the workspace is not used before it is be stopped and auto-locked. This includes across multiple builds (e.g. auto-starts and stops). This licensed feature's default is 0h (off). Maps to \"Dormancy threshold\" in the UI.",
+ Flag: "dormancy-threshold",
+ Description: "Specify a duration workspaces may be inactive prior to being moved to the dormant state. This licensed feature's default is 0h (off). Maps to \"Dormancy threshold\" in the UI.",
+ Default: "0h",
+ Value: clibase.DurationOf(&dormancyThreshold),
+ },
+ {
+ Flag: "dormancy-auto-deletion",
+ Description: "Specify a duration workspaces may be in the dormant state prior to being deleted. This licensed feature's default is 0h (off). Maps to \"Dormancy Auto-Deletion\" in the UI.",
Default: "0h",
- Value: clibase.DurationOf(&inactivityTTL),
+ Value: clibase.DurationOf(&dormancyAutoDeletion),
},
{
Flag: "allow-user-cancel-workspace-jobs",
diff --git a/cli/testdata/coder_templates_create_--help.golden b/cli/testdata/coder_templates_create_--help.golden
index f458d3954dd62..ea896d944288b 100644
--- a/cli/testdata/coder_templates_create_--help.golden
+++ b/cli/testdata/coder_templates_create_--help.golden
@@ -14,6 +14,16 @@ OPTIONS:
-d, --directory string (default: .)
Specify the directory to create from, use '-' to read tar from stdin.
+ --dormancy-auto-deletion duration (default: 0h)
+ Specify a duration workspaces may be in the dormant state prior to
+ being deleted. This licensed feature's default is 0h (off). Maps to
+ "Dormancy Auto-Deletion" in the UI.
+
+ --dormancy-threshold duration (default: 0h)
+ Specify a duration workspaces may be inactive prior to being moved to
+ the dormant state. This licensed feature's default is 0h (off). Maps
+ to "Dormancy threshold" in the UI.
+
--failure-ttl duration (default: 0h)
Specify a failure TTL for workspaces created from this template. It is
the amount of time after a failed "start" build before coder
@@ -24,13 +34,6 @@ OPTIONS:
Ignore warnings about not having a .terraform.lock.hcl file present in
the template.
- --inactivity-ttl duration (default: 0h)
- Specify an inactivity TTL for workspaces created from this template.
- It is the amount of time the workspace is not used before it is be
- stopped and auto-locked. This includes across multiple builds (e.g.
- auto-starts and stops). This licensed feature's default is 0h (off).
- Maps to "Dormancy threshold" in the UI.
-
--max-ttl duration
Edit the template maximum time before shutdown - workspaces created
from this template must shutdown within the given duration after
diff --git a/cli/testdata/coder_templates_edit_--help.golden b/cli/testdata/coder_templates_edit_--help.golden
index bd4cdee8d8482..94fa1ac45276c 100644
--- a/cli/testdata/coder_templates_edit_--help.golden
+++ b/cli/testdata/coder_templates_edit_--help.golden
@@ -38,6 +38,16 @@ OPTIONS:
--display-name string
Edit the template display name.
+ --dormancy-auto-deletion duration (default: 0h)
+ Specify a duration workspaces may be in the dormant state prior to
+ being deleted. This licensed feature's default is 0h (off). Maps to
+ "Dormancy Auto-Deletion" in the UI.
+
+ --dormancy-threshold duration (default: 0h)
+ Specify a duration workspaces may be inactive prior to being moved to
+ the dormant state. This licensed feature's default is 0h (off). Maps
+ to "Dormancy threshold" in the UI.
+
--failure-ttl duration (default: 0h)
Specify a failure TTL for workspaces created from this template. It is
the amount of time after a failed "start" build before coder
@@ -47,13 +57,6 @@ OPTIONS:
--icon string
Edit the template icon path.
- --inactivity-ttl duration (default: 0h)
- Specify an inactivity TTL for workspaces created from this template.
- It is the amount of time the workspace is not used before it is be
- stopped and auto-locked. This includes across multiple builds (e.g.
- auto-starts and stops). This licensed feature's default is 0h (off).
- Maps to "Dormancy threshold" in the UI.
-
--max-ttl duration
Edit the template maximum time before shutdown - workspaces created
from this template must shutdown within the given duration after
diff --git a/docs/cli/templates_create.md b/docs/cli/templates_create.md
index 83c3b3c5b9aff..9535e2f12e6da 100644
--- a/docs/cli/templates_create.md
+++ b/docs/cli/templates_create.md
@@ -30,6 +30,24 @@ Specify a default TTL for workspaces created from this template. It is the defau
Specify the directory to create from, use '-' to read tar from stdin.
+### --dormancy-auto-deletion
+
+| | |
+| ------- | --------------------- |
+| Type | duration
|
+| Default | 0h
|
+
+Specify a duration workspaces may be in the dormant state prior to being deleted. This licensed feature's default is 0h (off). Maps to "Dormancy Auto-Deletion" in the UI.
+
+### --dormancy-threshold
+
+| | |
+| ------- | --------------------- |
+| Type | duration
|
+| Default | 0h
|
+
+Specify a duration workspaces may be inactive prior to being moved to the dormant state. This licensed feature's default is 0h (off). Maps to "Dormancy threshold" in the UI.
+
### --failure-ttl
| | |
@@ -48,15 +66,6 @@ Specify a failure TTL for workspaces created from this template. It is the amoun
Ignore warnings about not having a .terraform.lock.hcl file present in the template.
-### --inactivity-ttl
-
-| | |
-| ------- | --------------------- |
-| Type | duration
|
-| Default | 0h
|
-
-Specify an inactivity TTL for workspaces created from this template. It is the amount of time the workspace is not used before it is be stopped and auto-locked. This includes across multiple builds (e.g. auto-starts and stops). This licensed feature's default is 0h (off). Maps to "Dormancy threshold" in the UI.
-
### --max-ttl
| | |
diff --git a/docs/cli/templates_edit.md b/docs/cli/templates_edit.md
index 0157b06404720..12577cbcaba23 100644
--- a/docs/cli/templates_edit.md
+++ b/docs/cli/templates_edit.md
@@ -79,31 +79,40 @@ Edit the template description.
Edit the template display name.
-### --failure-ttl
+### --dormancy-auto-deletion
| | |
| ------- | --------------------- |
| Type | duration
|
| Default | 0h
|
-Specify a failure TTL for workspaces created from this template. It is the amount of time after a failed "start" build before coder automatically schedules a "stop" build to cleanup.This licensed feature's default is 0h (off). Maps to "Failure cleanup" in the UI.
+Specify a duration workspaces may be in the dormant state prior to being deleted. This licensed feature's default is 0h (off). Maps to "Dormancy Auto-Deletion" in the UI.
-### --icon
+### --dormancy-threshold
-| | |
-| ---- | ------------------- |
-| Type | string
|
+| | |
+| ------- | --------------------- |
+| Type | duration
|
+| Default | 0h
|
-Edit the template icon path.
+Specify a duration workspaces may be inactive prior to being moved to the dormant state. This licensed feature's default is 0h (off). Maps to "Dormancy threshold" in the UI.
-### --inactivity-ttl
+### --failure-ttl
| | |
| ------- | --------------------- |
| Type | duration
|
| Default | 0h
|
-Specify an inactivity TTL for workspaces created from this template. It is the amount of time the workspace is not used before it is be stopped and auto-locked. This includes across multiple builds (e.g. auto-starts and stops). This licensed feature's default is 0h (off). Maps to "Dormancy threshold" in the UI.
+Specify a failure TTL for workspaces created from this template. It is the amount of time after a failed "start" build before coder automatically schedules a "stop" build to cleanup.This licensed feature's default is 0h (off). Maps to "Failure cleanup" in the UI.
+
+### --icon
+
+| | |
+| ---- | ------------------- |
+| Type | string
|
+
+Edit the template icon path.
### --max-ttl
diff --git a/enterprise/cli/templatecreate_test.go b/enterprise/cli/templatecreate_test.go
index 8bbc84aba7b81..c95298f903be3 100644
--- a/enterprise/cli/templatecreate_test.go
+++ b/enterprise/cli/templatecreate_test.go
@@ -2,6 +2,7 @@ package cli_test
import (
"testing"
+ "time"
"github.com/stretchr/testify/require"
@@ -19,7 +20,7 @@ import (
func TestTemplateCreate(t *testing.T) {
t.Parallel()
- t.Run("OK", func(t *testing.T) {
+ t.Run("RequireActiveVersion", func(t *testing.T) {
t.Parallel()
dv := coderdtest.DeploymentValues(t)
@@ -64,6 +65,62 @@ func TestTemplateCreate(t *testing.T) {
require.True(t, template.RequireActiveVersion)
})
+ t.Run("WorkspaceCleanup", func(t *testing.T) {
+ t.Parallel()
+
+ dv := coderdtest.DeploymentValues(t)
+ dv.Experiments = []string{
+ string(codersdk.ExperimentWorkspaceActions),
+ }
+
+ client, user := coderdenttest.New(t, &coderdenttest.Options{
+ LicenseOptions: &coderdenttest.LicenseOptions{
+ Features: license.Features{
+ codersdk.FeatureAdvancedTemplateScheduling: 1,
+ },
+ },
+ Options: &coderdtest.Options{
+ DeploymentValues: dv,
+ IncludeProvisionerDaemon: true,
+ },
+ })
+ templateAdmin, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleTemplateAdmin())
+
+ source := clitest.CreateTemplateVersionSource(t, &echo.Responses{
+ Parse: echo.ParseComplete,
+ ProvisionApply: echo.ApplyComplete,
+ })
+
+ const (
+ expectedFailureTTL = time.Hour * 3
+ expectedDormancyThreshold = time.Hour * 4
+ expectedDormancyAutoDeletion = time.Minute * 10
+ )
+
+ inv, conf := newCLI(t, "templates",
+ "create", "new",
+ "--directory", source,
+ "--test.provisioner", string(database.ProvisionerTypeEcho),
+ "--failure-ttl="+expectedFailureTTL.String(),
+ "--dormancy-threshold="+expectedDormancyThreshold.String(),
+ "--dormancy-auto-deletion="+expectedDormancyAutoDeletion.String(),
+ "-y",
+ "--",
+ )
+
+ clitest.SetupConfig(t, templateAdmin, conf)
+
+ err := inv.Run()
+ require.NoError(t, err)
+
+ ctx := testutil.Context(t, testutil.WaitMedium)
+ template, err := templateAdmin.TemplateByName(ctx, user.OrganizationID, "new")
+ require.NoError(t, err)
+ require.Equal(t, expectedFailureTTL.Milliseconds(), template.FailureTTLMillis)
+ require.Equal(t, expectedDormancyThreshold.Milliseconds(), template.TimeTilDormantMillis)
+ require.Equal(t, expectedDormancyAutoDeletion.Milliseconds(), template.TimeTilDormantAutoDeleteMillis)
+ })
+
t.Run("NotEntitled", func(t *testing.T) {
t.Parallel()
diff --git a/enterprise/cli/templateedit_test.go b/enterprise/cli/templateedit_test.go
index c1b069e938e4c..ceeeb2aceb629 100644
--- a/enterprise/cli/templateedit_test.go
+++ b/enterprise/cli/templateedit_test.go
@@ -2,6 +2,7 @@ package cli_test
import (
"testing"
+ "time"
"github.com/stretchr/testify/require"
@@ -96,4 +97,75 @@ func TestTemplateEdit(t *testing.T) {
require.Error(t, err)
require.Contains(t, err.Error(), "your license is not entitled to use enterprise access control, so you cannot set --require-active-version")
})
+
+ t.Run("WorkspaceCleanup", func(t *testing.T) {
+ t.Parallel()
+
+ dv := coderdtest.DeploymentValues(t)
+ dv.Experiments = []string{
+ string(codersdk.ExperimentWorkspaceActions),
+ }
+
+ ownerClient, owner := coderdenttest.New(t, &coderdenttest.Options{
+ LicenseOptions: &coderdenttest.LicenseOptions{
+ Features: license.Features{
+ codersdk.FeatureAdvancedTemplateScheduling: 1,
+ },
+ },
+ Options: &coderdtest.Options{
+ DeploymentValues: dv,
+ IncludeProvisionerDaemon: true,
+ },
+ })
+
+ templateAdmin, _ := coderdtest.CreateAnotherUser(t, ownerClient, owner.OrganizationID, rbac.RoleTemplateAdmin())
+ version := coderdtest.CreateTemplateVersion(t, templateAdmin, owner.OrganizationID, nil)
+ _ = coderdtest.AwaitTemplateVersionJobCompleted(t, templateAdmin, version.ID)
+ template := coderdtest.CreateTemplate(t, templateAdmin, owner.OrganizationID, version.ID)
+ require.False(t, template.RequireActiveVersion)
+
+ const (
+ expectedFailureTTL = time.Hour * 3
+ expectedDormancyThreshold = time.Hour * 4
+ expectedDormancyAutoDeletion = time.Minute * 10
+ )
+ inv, conf := newCLI(t, "templates",
+ "edit", template.Name,
+ "--failure-ttl="+expectedFailureTTL.String(),
+ "--dormancy-threshold="+expectedDormancyThreshold.String(),
+ "--dormancy-auto-deletion="+expectedDormancyAutoDeletion.String(),
+ "-y",
+ )
+
+ clitest.SetupConfig(t, templateAdmin, conf)
+
+ err := inv.Run()
+ require.NoError(t, err)
+
+ ctx := testutil.Context(t, testutil.WaitMedium)
+ template, err = templateAdmin.Template(ctx, template.ID)
+ require.NoError(t, err)
+ require.Equal(t, expectedFailureTTL.Milliseconds(), template.FailureTTLMillis)
+ require.Equal(t, expectedDormancyThreshold.Milliseconds(), template.TimeTilDormantMillis)
+ require.Equal(t, expectedDormancyAutoDeletion.Milliseconds(), template.TimeTilDormantAutoDeleteMillis)
+
+ inv, conf = newCLI(t, "templates",
+ "edit", template.Name,
+ "--display-name=idc",
+ "-y",
+ )
+
+ clitest.SetupConfig(t, templateAdmin, conf)
+
+ err = inv.Run()
+ require.NoError(t, err)
+
+ // Refetch the template to assert we haven't inadvertently updated
+ // the values to their default values.
+ template, err = templateAdmin.Template(ctx, template.ID)
+ require.NoError(t, err)
+ require.Equal(t, expectedFailureTTL.Milliseconds(), template.FailureTTLMillis)
+ require.Equal(t, expectedDormancyThreshold.Milliseconds(), template.TimeTilDormantMillis)
+ require.Equal(t, expectedDormancyAutoDeletion.Milliseconds(), template.TimeTilDormantAutoDeleteMillis)
+ })
}