From 7b3e862485da8e5b1e7a877509171c7632e5289e Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Fri, 13 May 2022 18:33:18 +0000 Subject: [PATCH 1/2] feat: add autostart/autostop show, show autostart/autostop schedule in ls output --- cli/autostart.go | 40 +++++++++++++++++++++++++++++++++++ cli/autostart_test.go | 32 ++++++++++++++++++++++++++++ cli/autostop.go | 49 +++++++++++++++++++++++++++++++++++++++---- cli/autostop_test.go | 32 ++++++++++++++++++++++++++++ cli/list.go | 14 ++++++++++++- 5 files changed, 162 insertions(+), 5 deletions(-) diff --git a/cli/autostart.go b/cli/autostart.go index 87b2e7d707eca..2dbfb23c41099 100644 --- a/cli/autostart.go +++ b/cli/autostart.go @@ -25,12 +25,52 @@ func autostart() *cobra.Command { Example: "coder autostart enable my-workspace --minute 30 --hour 9 --days 1-5 --tz Europe/Dublin", } + autostartCmd.AddCommand(autostartShow()) autostartCmd.AddCommand(autostartEnable()) autostartCmd.AddCommand(autostartDisable()) return autostartCmd } +func autostartShow() *cobra.Command { + cmd := &cobra.Command{ + Use: "show ", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + client, err := createClient(cmd) + if err != nil { + return err + } + organization, err := currentOrganization(cmd, client) + if err != nil { + return err + } + + workspace, err := client.WorkspaceByOwnerAndName(cmd.Context(), organization.ID, codersdk.Me, args[0]) + if err != nil { + return err + } + + if workspace.AutostartSchedule == "" { + _, _ = fmt.Fprintf(cmd.OutOrStdout(), "not enabled") + return nil + } + + validSchedule, err := schedule.Weekly(workspace.AutostartSchedule) + if err != nil { + // This should never happen. + _, _ = fmt.Fprintf(cmd.OutOrStdout(), "invalid autostart schedule %q for workspace %s: %s", workspace.AutostartSchedule, workspace.Name, err.Error()) + return nil + } + + _, _ = fmt.Fprintf(cmd.OutOrStdout(), "\nschedule: %s\nnext: %s\n", workspace.AutostartSchedule, validSchedule.Next(time.Now())) + + return nil + }, + } + return cmd +} + func autostartEnable() *cobra.Command { // yes some of these are technically numbers but the cron library will do that work var autostartMinute string diff --git a/cli/autostart_test.go b/cli/autostart_test.go index 4ef725e516f0a..2f65bbc15d8fc 100644 --- a/cli/autostart_test.go +++ b/cli/autostart_test.go @@ -11,11 +11,43 @@ import ( "github.com/coder/coder/cli/clitest" "github.com/coder/coder/coderd/coderdtest" + "github.com/coder/coder/codersdk" ) func TestAutostart(t *testing.T) { t.Parallel() + t.Run("ShowOK", func(t *testing.T) { + t.Parallel() + + var ( + ctx = context.Background() + client = coderdtest.New(t, nil) + _ = coderdtest.NewProvisionerDaemon(t, client) + user = coderdtest.CreateFirstUser(t, client) + version = coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) + _ = coderdtest.AwaitTemplateVersionJob(t, client, version.ID) + project = coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) + workspace = coderdtest.CreateWorkspace(t, client, user.OrganizationID, project.ID) + cmdArgs = []string{"autostart", "show", workspace.Name} + sched = "CRON_TZ=Europe/Dublin 30 17 * * 1-5" + stdoutBuf = &bytes.Buffer{} + ) + + err := client.UpdateWorkspaceAutostart(ctx, workspace.ID, codersdk.UpdateWorkspaceAutostartRequest{ + Schedule: sched, + }) + require.NoError(t, err) + + cmd, root := clitest.New(t, cmdArgs...) + clitest.SetupConfig(t, client, root) + cmd.SetOut(stdoutBuf) + + err = cmd.Execute() + require.NoError(t, err, "unexpected error") + require.Contains(t, stdoutBuf.String(), "schedule: "+sched) + }) + t.Run("EnableDisableOK", func(t *testing.T) { t.Parallel() diff --git a/cli/autostop.go b/cli/autostop.go index 08923754c3989..de8faef1095ef 100644 --- a/cli/autostop.go +++ b/cli/autostop.go @@ -18,18 +18,59 @@ The default autostop schedule is at 18:00 in your local timezone (TZ env, UTC by func autostop() *cobra.Command { autostopCmd := &cobra.Command{ - Use: "autostop enable ", - Short: "schedule a workspace to automatically stop at a regular time", - Long: autostopDescriptionLong, - Example: "coder autostop enable my-workspace --minute 0 --hour 18 --days 1-5 -tz Europe/Dublin", + Annotations: workspaceCommand, + Use: "autostop enable ", + Short: "schedule a workspace to automatically stop at a regular time", + Long: autostopDescriptionLong, + Example: "coder autostop enable my-workspace --minute 0 --hour 18 --days 1-5 -tz Europe/Dublin", } + autostopCmd.AddCommand(autostopShow()) autostopCmd.AddCommand(autostopEnable()) autostopCmd.AddCommand(autostopDisable()) return autostopCmd } +func autostopShow() *cobra.Command { + cmd := &cobra.Command{ + Use: "show ", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + client, err := createClient(cmd) + if err != nil { + return err + } + organization, err := currentOrganization(cmd, client) + if err != nil { + return err + } + + workspace, err := client.WorkspaceByOwnerAndName(cmd.Context(), organization.ID, codersdk.Me, args[0]) + if err != nil { + return err + } + + if workspace.AutostopSchedule == "" { + _, _ = fmt.Fprintf(cmd.OutOrStdout(), "not enabled") + return nil + } + + validSchedule, err := schedule.Weekly(workspace.AutostopSchedule) + if err != nil { + // This should never happen. + _, _ = fmt.Fprintf(cmd.OutOrStdout(), "invalid autostop schedule %q for workspace %s: %s", workspace.AutostopSchedule, workspace.Name, err.Error()) + return nil + } + + _, _ = fmt.Fprintf(cmd.OutOrStdout(), "\nschedule: %s\nnext: %s\n", workspace.AutostopSchedule, validSchedule.Next(time.Now())) + + return nil + }, + } + return cmd +} + func autostopEnable() *cobra.Command { // yes some of these are technically numbers but the cron library will do that work var autostopMinute string diff --git a/cli/autostop_test.go b/cli/autostop_test.go index 0f3af1c2369c4..dad4f8d4ee13d 100644 --- a/cli/autostop_test.go +++ b/cli/autostop_test.go @@ -11,11 +11,43 @@ import ( "github.com/coder/coder/cli/clitest" "github.com/coder/coder/coderd/coderdtest" + "github.com/coder/coder/codersdk" ) func TestAutostop(t *testing.T) { t.Parallel() + t.Run("ShowOK", func(t *testing.T) { + t.Parallel() + + var ( + ctx = context.Background() + client = coderdtest.New(t, nil) + _ = coderdtest.NewProvisionerDaemon(t, client) + user = coderdtest.CreateFirstUser(t, client) + version = coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) + _ = coderdtest.AwaitTemplateVersionJob(t, client, version.ID) + project = coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) + workspace = coderdtest.CreateWorkspace(t, client, user.OrganizationID, project.ID) + cmdArgs = []string{"autostop", "show", workspace.Name} + sched = "CRON_TZ=Europe/Dublin 30 17 * * 1-5" + stdoutBuf = &bytes.Buffer{} + ) + + err := client.UpdateWorkspaceAutostop(ctx, workspace.ID, codersdk.UpdateWorkspaceAutostopRequest{ + Schedule: sched, + }) + require.NoError(t, err) + + cmd, root := clitest.New(t, cmdArgs...) + clitest.SetupConfig(t, client, root) + cmd.SetOut(stdoutBuf) + + err = cmd.Execute() + require.NoError(t, err, "unexpected error") + require.Contains(t, stdoutBuf.String(), "schedule: "+sched) + }) + t.Run("EnableDisableOK", func(t *testing.T) { t.Parallel() diff --git a/cli/list.go b/cli/list.go index 236d96b331bc4..d32c66ee87adc 100644 --- a/cli/list.go +++ b/cli/list.go @@ -49,7 +49,7 @@ func list() *cobra.Command { } tableWriter := cliui.Table() - header := table.Row{"workspace", "template", "status", "last built", "outdated"} + header := table.Row{"workspace", "template", "status", "last built", "outdated", "autostart", "autostop"} tableWriter.AppendHeader(header) tableWriter.SortBy([]table.SortBy{{ Name: "workspace", @@ -108,6 +108,16 @@ func list() *cobra.Command { durationDisplay = durationDisplay[:len(durationDisplay)-2] } + autostartDisplay := "not enabled" + if workspace.AutostartSchedule != "" { + autostartDisplay = workspace.AutostartSchedule + } + + autostopDisplay := "not enabled" + if workspace.AutostopSchedule != "" { + autostopDisplay = workspace.AutostopSchedule + } + user := usersByID[workspace.OwnerID] tableWriter.AppendRow(table.Row{ user.Username + "/" + workspace.Name, @@ -115,6 +125,8 @@ func list() *cobra.Command { status, durationDisplay, workspace.Outdated, + autostartDisplay, + autostopDisplay, }) } _, err = fmt.Fprintln(cmd.OutOrStdout(), tableWriter.Render()) From 4f994cb91c46097a9082ccd7b48647dce98976f2 Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Fri, 13 May 2022 18:48:25 +0000 Subject: [PATCH 2/2] fixup! feat: add autostart/autostop show, show autostart/autostop schedule in ls output --- cli/autostart.go | 6 +++--- cli/autostop.go | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/cli/autostart.go b/cli/autostart.go index 2dbfb23c41099..1e29b63982e1a 100644 --- a/cli/autostart.go +++ b/cli/autostart.go @@ -52,18 +52,18 @@ func autostartShow() *cobra.Command { } if workspace.AutostartSchedule == "" { - _, _ = fmt.Fprintf(cmd.OutOrStdout(), "not enabled") + _, _ = fmt.Fprintf(cmd.OutOrStdout(), "not enabled\n") return nil } validSchedule, err := schedule.Weekly(workspace.AutostartSchedule) if err != nil { // This should never happen. - _, _ = fmt.Fprintf(cmd.OutOrStdout(), "invalid autostart schedule %q for workspace %s: %s", workspace.AutostartSchedule, workspace.Name, err.Error()) + _, _ = fmt.Fprintf(cmd.OutOrStdout(), "invalid autostart schedule %q for workspace %s: %s\n", workspace.AutostartSchedule, workspace.Name, err.Error()) return nil } - _, _ = fmt.Fprintf(cmd.OutOrStdout(), "\nschedule: %s\nnext: %s\n", workspace.AutostartSchedule, validSchedule.Next(time.Now())) + _, _ = fmt.Fprintf(cmd.OutOrStdout(), "schedule: %s\nnext: %s\n", workspace.AutostartSchedule, validSchedule.Next(time.Now())) return nil }, diff --git a/cli/autostop.go b/cli/autostop.go index de8faef1095ef..e9520e9df04cd 100644 --- a/cli/autostop.go +++ b/cli/autostop.go @@ -52,18 +52,18 @@ func autostopShow() *cobra.Command { } if workspace.AutostopSchedule == "" { - _, _ = fmt.Fprintf(cmd.OutOrStdout(), "not enabled") + _, _ = fmt.Fprintf(cmd.OutOrStdout(), "not enabled\n") return nil } validSchedule, err := schedule.Weekly(workspace.AutostopSchedule) if err != nil { // This should never happen. - _, _ = fmt.Fprintf(cmd.OutOrStdout(), "invalid autostop schedule %q for workspace %s: %s", workspace.AutostopSchedule, workspace.Name, err.Error()) + _, _ = fmt.Fprintf(cmd.OutOrStdout(), "invalid autostop schedule %q for workspace %s: %s\n", workspace.AutostopSchedule, workspace.Name, err.Error()) return nil } - _, _ = fmt.Fprintf(cmd.OutOrStdout(), "\nschedule: %s\nnext: %s\n", workspace.AutostopSchedule, validSchedule.Next(time.Now())) + _, _ = fmt.Fprintf(cmd.OutOrStdout(), "schedule: %s\nnext: %s\n", workspace.AutostopSchedule, validSchedule.Next(time.Now())) return nil },