diff --git a/cli/schedule.go b/cli/schedule.go index 15f837bc16..a4b02d6d8b 100644 --- a/cli/schedule.go +++ b/cli/schedule.go @@ -176,6 +176,22 @@ func (r *RootCmd) scheduleStart() *serpent.Command { } schedStr = ptr.Ref(sched.String()) + + // Check if the template has autostart requirements that may conflict + // with the user's schedule. + template, err := client.Template(inv.Context(), workspace.TemplateID) + if err != nil { + return xerrors.Errorf("get template: %w", err) + } + + if len(template.AutostartRequirement.DaysOfWeek) > 0 { + _, _ = fmt.Fprintf( + inv.Stderr, + "Warning: your workspace template restricts autostart to the following days: %s.\n"+ + "Your workspace may only autostart on these days.\n", + strings.Join(template.AutostartRequirement.DaysOfWeek, ", "), + ) + } } err = client.UpdateWorkspaceAutostart(inv.Context(), workspace.ID, codersdk.UpdateWorkspaceAutostartRequest{ diff --git a/cli/schedule_test.go b/cli/schedule_test.go index b161f41cbc..bc473279f7 100644 --- a/cli/schedule_test.go +++ b/cli/schedule_test.go @@ -373,3 +373,67 @@ func TestScheduleOverride(t *testing.T) { }) } } + +//nolint:paralleltest // t.Setenv +func TestScheduleStart_TemplateAutostartRequirement(t *testing.T) { + t.Setenv("TZ", "UTC") + loc, err := tz.TimezoneIANA() + require.NoError(t, err) + require.Equal(t, "UTC", loc.String()) + + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true}) + user := coderdtest.CreateFirstUser(t, client) + + version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) + coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID) + template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) + + // Update template to have autostart requirement + // Note: In AGPL, this will be ignored and all days will be allowed (enterprise feature). + template, err = client.UpdateTemplateMeta(context.Background(), template.ID, codersdk.UpdateTemplateMeta{ + AutostartRequirement: &codersdk.TemplateAutostartRequirement{ + DaysOfWeek: []string{"monday", "wednesday", "friday"}, + }, + }) + require.NoError(t, err) + + // Verify the template - in AGPL, AutostartRequirement will have all days (enterprise feature) + template, err = client.Template(context.Background(), template.ID) + require.NoError(t, err) + require.NotEmpty(t, template.AutostartRequirement.DaysOfWeek, "template should have autostart requirement days") + + workspace := coderdtest.CreateWorkspace(t, client, template.ID) + coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, workspace.LatestBuild.ID) + + t.Run("ShowsWarning", func(t *testing.T) { + // When: user sets autostart schedule + inv, root := clitest.New(t, + "schedule", "start", workspace.Name, "9:30AM", "Mon-Fri", + ) + clitest.SetupConfig(t, client, root) + pty := ptytest.New(t).Attach(inv) + require.NoError(t, inv.Run()) + + // Then: warning should be shown + // In AGPL, this will show all days (enterprise feature defaults to all days allowed) + pty.ExpectMatch("Warning") + pty.ExpectMatch("may only autostart") + }) + + t.Run("NoWarningWhenManual", func(t *testing.T) { + // When: user sets manual schedule + inv, root := clitest.New(t, + "schedule", "start", workspace.Name, "manual", + ) + clitest.SetupConfig(t, client, root) + + var stderrBuf bytes.Buffer + inv.Stderr = &stderrBuf + + require.NoError(t, inv.Run()) + + // Then: no warning should be shown on stderr + stderrOutput := stderrBuf.String() + require.NotContains(t, stderrOutput, "Warning") + }) +}