Skip to content

Commit 709db5b

Browse files
committed
fixup! cli: templatecreate: add CLI flags --max-ttl --min-autostart-interval
1 parent 245795e commit 709db5b

File tree

4 files changed

+49
-26
lines changed

4 files changed

+49
-26
lines changed

cli/create.go

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010

1111
"github.com/coder/coder/cli/cliflag"
1212
"github.com/coder/coder/cli/cliui"
13+
"github.com/coder/coder/coderd/autobuild/schedule"
1314
"github.com/coder/coder/coderd/util/ptr"
1415
"github.com/coder/coder/codersdk"
1516
)
@@ -114,10 +115,22 @@ func create() *cobra.Command {
114115
}
115116
}
116117

117-
schedSpec := buildSchedule(autostartMinute, autostartHour, autostartDow, tzName)
118+
schedSpec, err := validSchedule(
119+
autostartMinute,
120+
autostartHour,
121+
autostartDow,
122+
tzName,
123+
time.Duration(template.MinAutostartIntervalMillis)*time.Millisecond,
124+
)
125+
if err != nil {
126+
return xerrors.Errorf("Invalid autostart schedule: %w", err)
127+
}
118128
if ttl < time.Minute {
119129
return xerrors.Errorf("TTL must be at least 1 minute")
120130
}
131+
if ttlMax := time.Duration(template.MaxTTLMillis) * time.Millisecond; ttl > ttlMax {
132+
return xerrors.Errorf("TTL must be below template maximum %s", ttlMax)
133+
}
121134

122135
templateVersion, err := client.TemplateVersion(cmd.Context(), template.ActiveVersionID)
123136
if err != nil {
@@ -257,11 +270,17 @@ func create() *cobra.Command {
257270
return cmd
258271
}
259272

260-
func buildSchedule(minute, hour, dow, tzName string) *string {
261-
if minute == "" || hour == "" || dow == "" {
262-
return nil
273+
func validSchedule(minute, hour, dow, tzName string, min time.Duration) (*string, error) {
274+
schedSpec := fmt.Sprintf("CRON_TZ=%s %s %s * * %s", tzName, minute, hour, dow)
275+
276+
sched, err := schedule.Weekly(schedSpec)
277+
if err != nil {
278+
return nil, err
263279
}
264280

265-
schedSpec := fmt.Sprintf("CRON_TZ=%s %s %s * * %s", tzName, minute, hour, dow)
266-
return &schedSpec
281+
if schedMin := sched.Min(); schedMin < min {
282+
return nil, xerrors.Errorf("minimum autostart interval %s is above template constraint %s", schedMin, min)
283+
}
284+
285+
return &schedSpec, nil
267286
}

cli/create_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ func TestCreate(t *testing.T) {
8585
cmd.SetIn(pty.Input())
8686
cmd.SetOut(pty.Output())
8787
err := cmd.Execute()
88-
assert.ErrorContains(t, err, "ttl_ms: ttl must be below template maximum 12h0m0s")
88+
assert.ErrorContains(t, err, "TTL must be below template maximum 12h0m0s")
8989
})
9090

9191
t.Run("BelowTemplateMinAutostartInterval", func(t *testing.T) {
@@ -111,7 +111,7 @@ func TestCreate(t *testing.T) {
111111
cmd.SetIn(pty.Input())
112112
cmd.SetOut(pty.Output())
113113
err := cmd.Execute()
114-
assert.ErrorContains(t, err, "Minimum autostart interval 1m0s below template minimum 1h0m0s")
114+
assert.ErrorContains(t, err, "minimum autostart interval 1m0s is above template constraint 1h0m0s")
115115
})
116116

117117
t.Run("CreateErrInvalidTz", func(t *testing.T) {

coderd/templates.go

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -314,14 +314,16 @@ func convertTemplates(templates []database.Template, workspaceCounts []database.
314314

315315
func convertTemplate(template database.Template, workspaceOwnerCount uint32) codersdk.Template {
316316
return codersdk.Template{
317-
ID: template.ID,
318-
CreatedAt: template.CreatedAt,
319-
UpdatedAt: template.UpdatedAt,
320-
OrganizationID: template.OrganizationID,
321-
Name: template.Name,
322-
Provisioner: codersdk.ProvisionerType(template.Provisioner),
323-
ActiveVersionID: template.ActiveVersionID,
324-
WorkspaceOwnerCount: workspaceOwnerCount,
325-
Description: template.Description,
317+
ID: template.ID,
318+
CreatedAt: template.CreatedAt,
319+
UpdatedAt: template.UpdatedAt,
320+
OrganizationID: template.OrganizationID,
321+
Name: template.Name,
322+
Provisioner: codersdk.ProvisionerType(template.Provisioner),
323+
ActiveVersionID: template.ActiveVersionID,
324+
WorkspaceOwnerCount: workspaceOwnerCount,
325+
Description: template.Description,
326+
MaxTTLMillis: time.Duration(template.MaxTtl).Milliseconds(),
327+
MinAutostartIntervalMillis: time.Duration(template.MinAutostartInterval).Milliseconds(),
326328
}
327329
}

codersdk/templates.go

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,17 @@ import (
1313
// Template is the JSON representation of a Coder template. This type matches the
1414
// database object for now, but is abstracted for ease of change later on.
1515
type Template struct {
16-
ID uuid.UUID `json:"id"`
17-
CreatedAt time.Time `json:"created_at"`
18-
UpdatedAt time.Time `json:"updated_at"`
19-
OrganizationID uuid.UUID `json:"organization_id"`
20-
Name string `json:"name"`
21-
Provisioner ProvisionerType `json:"provisioner"`
22-
ActiveVersionID uuid.UUID `json:"active_version_id"`
23-
WorkspaceOwnerCount uint32 `json:"workspace_owner_count"`
24-
Description string `json:"description"`
16+
ID uuid.UUID `json:"id"`
17+
CreatedAt time.Time `json:"created_at"`
18+
UpdatedAt time.Time `json:"updated_at"`
19+
OrganizationID uuid.UUID `json:"organization_id"`
20+
Name string `json:"name"`
21+
Provisioner ProvisionerType `json:"provisioner"`
22+
ActiveVersionID uuid.UUID `json:"active_version_id"`
23+
WorkspaceOwnerCount uint32 `json:"workspace_owner_count"`
24+
Description string `json:"description"`
25+
MaxTTLMillis int64 `json:"max_ttl_ms"`
26+
MinAutostartIntervalMillis int64 `json:"min_autostart_interval_ms"`
2527
}
2628

2729
type UpdateActiveTemplateVersion struct {

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy