Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitaf67280

Browse files
authored
autostart/autostop: move to traditional 5-valued cron string for compatibility (#1049)
This PR modfies the original 3-valued cron strings used in package schedule to be traditional 5-valued cron strings.- schedule.Weekly will validate that the month and dom fields are equal to *- cli autostart/autostop will attempt to detect local timezone using TZ env var, defaulting to UTC- cli autostart/autostop no longer accepts a raw schedule -- instead use the --minute, --hour, --dow, and --tz arguments.- Default schedules are provided that should suffice for most users.Fixes#993
1 parent3311c2f commitaf67280

File tree

11 files changed

+170
-150
lines changed

11 files changed

+170
-150
lines changed

‎cli/workspaceautostart.go

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package cli
22

33
import (
44
"fmt"
5+
"os"
56
"time"
67

78
"github.com/spf13/cobra"
@@ -11,20 +12,16 @@ import (
1112
)
1213

1314
constautostartDescriptionLong=`To have your workspace build automatically at a regular time you can enable autostart.
14-
When enabling autostart, provide a schedule. This schedule is in cron format except only
15-
the following fields are allowed:
16-
- minute
17-
- hour
18-
- day of week
19-
20-
For example, to start your workspace every weekday at 9.30 am, provide the schedule '30 9 1-5'.`
15+
When enabling autostart, provide the minute, hour, and day(s) of week.
16+
The default schedule is at 09:00 in your local timezone (TZ env, UTC by default).
17+
`
2118

2219
funcworkspaceAutostart()*cobra.Command {
2320
autostartCmd:=&cobra.Command{
24-
Use:"autostart enable <workspace> <schedule>",
21+
Use:"autostart enable <workspace>",
2522
Short:"schedule a workspace to automatically start at a regular time",
2623
Long:autostartDescriptionLong,
27-
Example:"coder workspaces autostart enable my-workspace'3091-5'",
24+
Example:"coder workspaces autostart enable my-workspace--minute30--hour 9 --days1-5 --tz Europe/Dublin",
2825
Hidden:true,// TODO(cian): un-hide when autostart scheduling implemented
2926
}
3027

@@ -35,22 +32,28 @@ func workspaceAutostart() *cobra.Command {
3532
}
3633

3734
funcworkspaceAutostartEnable()*cobra.Command {
38-
return&cobra.Command{
35+
// yes some of these are technically numbers but the cron library will do that work
36+
varautostartMinutestring
37+
varautostartHourstring
38+
varautostartDayOfWeekstring
39+
varautostartTimezonestring
40+
cmd:=&cobra.Command{
3941
Use:"enable <workspace_name> <schedule>",
4042
ValidArgsFunction:validArgsWorkspaceName,
41-
Args:cobra.ExactArgs(2),
43+
Args:cobra.ExactArgs(1),
4244
RunE:func(cmd*cobra.Command,args []string)error {
4345
client,err:=createClient(cmd)
4446
iferr!=nil {
4547
returnerr
4648
}
4749

48-
workspace,err:=client.WorkspaceByName(cmd.Context(),codersdk.Me,args[0])
50+
spec:=fmt.Sprintf("CRON_TZ=%s %s %s * * %s",autostartTimezone,autostartMinute,autostartHour,autostartDayOfWeek)
51+
validSchedule,err:=schedule.Weekly(spec)
4952
iferr!=nil {
5053
returnerr
5154
}
5255

53-
validSchedule,err:=schedule.Weekly(args[1])
56+
workspace,err:=client.WorkspaceByName(cmd.Context(),codersdk.Me,args[0])
5457
iferr!=nil {
5558
returnerr
5659
}
@@ -67,6 +70,16 @@ func workspaceAutostartEnable() *cobra.Command {
6770
returnnil
6871
},
6972
}
73+
74+
cmd.Flags().StringVar(&autostartMinute,"minute","0","autostart minute")
75+
cmd.Flags().StringVar(&autostartHour,"hour","9","autostart hour")
76+
cmd.Flags().StringVar(&autostartDayOfWeek,"days","1-5","autostart day(s) of week")
77+
tzEnv:=os.Getenv("TZ")
78+
iftzEnv=="" {
79+
tzEnv="UTC"
80+
}
81+
cmd.Flags().StringVar(&autostartTimezone,"tz",tzEnv,"autostart timezone")
82+
returncmd
7083
}
7184

7285
funcworkspaceAutostartDisable()*cobra.Command {

‎cli/workspaceautostart_test.go

Lines changed: 16 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package cli_test
33
import (
44
"bytes"
55
"context"
6+
"fmt"
7+
"os"
68
"testing"
79

810
"github.com/stretchr/testify/require"
@@ -27,11 +29,13 @@ func TestWorkspaceAutostart(t *testing.T) {
2729
_=coderdtest.AwaitTemplateVersionJob(t,client,version.ID)
2830
project=coderdtest.CreateTemplate(t,client,user.OrganizationID,version.ID)
2931
workspace=coderdtest.CreateWorkspace(t,client,codersdk.Me,project.ID)
30-
sched="CRON_TZ=Europe/Dublin 30 9 1-5"
32+
tz="Europe/Dublin"
33+
cmdArgs= []string{"workspaces","autostart","enable",workspace.Name,"--minute","30","--hour","9","--days","1-5","--tz",tz}
34+
sched="CRON_TZ=Europe/Dublin 30 9 * * 1-5"
3135
stdoutBuf=&bytes.Buffer{}
3236
)
3337

34-
cmd,root:=clitest.New(t,"workspaces","autostart","enable",workspace.Name,sched)
38+
cmd,root:=clitest.New(t,cmdArgs...)
3539
clitest.SetupConfig(t,client,root)
3640
cmd.SetOut(stdoutBuf)
3741

@@ -68,10 +72,9 @@ func TestWorkspaceAutostart(t *testing.T) {
6872
user=coderdtest.CreateFirstUser(t,client)
6973
version=coderdtest.CreateTemplateVersion(t,client,user.OrganizationID,nil)
7074
_=coderdtest.AwaitTemplateVersionJob(t,client,version.ID)
71-
sched="CRON_TZ=Europe/Dublin 30 9 1-5"
7275
)
7376

74-
cmd,root:=clitest.New(t,"workspaces","autostart","enable","doesnotexist",sched)
77+
cmd,root:=clitest.New(t,"workspaces","autostart","enable","doesnotexist")
7578
clitest.SetupConfig(t,client,root)
7679

7780
err:=cmd.Execute()
@@ -96,34 +99,7 @@ func TestWorkspaceAutostart(t *testing.T) {
9699
require.ErrorContains(t,err,"status code 404: no workspace found by name","unexpected error")
97100
})
98101

99-
t.Run("Enable_InvalidSchedule",func(t*testing.T) {
100-
t.Parallel()
101-
102-
var (
103-
ctx=context.Background()
104-
client=coderdtest.New(t,nil)
105-
_=coderdtest.NewProvisionerDaemon(t,client)
106-
user=coderdtest.CreateFirstUser(t,client)
107-
version=coderdtest.CreateTemplateVersion(t,client,user.OrganizationID,nil)
108-
_=coderdtest.AwaitTemplateVersionJob(t,client,version.ID)
109-
project=coderdtest.CreateTemplate(t,client,user.OrganizationID,version.ID)
110-
workspace=coderdtest.CreateWorkspace(t,client,codersdk.Me,project.ID)
111-
sched="sdfasdfasdf asdf asdf"
112-
)
113-
114-
cmd,root:=clitest.New(t,"workspaces","autostart","enable",workspace.Name,sched)
115-
clitest.SetupConfig(t,client,root)
116-
117-
err:=cmd.Execute()
118-
require.ErrorContains(t,err,"failed to parse int from sdfasdfasdf: strconv.Atoi:","unexpected error")
119-
120-
// Ensure nothing happened
121-
updated,err:=client.Workspace(ctx,workspace.ID)
122-
require.NoError(t,err,"fetch updated workspace")
123-
require.Empty(t,updated.AutostartSchedule,"expected autostart schedule to be empty")
124-
})
125-
126-
t.Run("Enable_NoSchedule",func(t*testing.T) {
102+
t.Run("Enable_DefaultSchedule",func(t*testing.T) {
127103
t.Parallel()
128104

129105
var (
@@ -137,15 +113,21 @@ func TestWorkspaceAutostart(t *testing.T) {
137113
workspace=coderdtest.CreateWorkspace(t,client,codersdk.Me,project.ID)
138114
)
139115

116+
// check current TZ env var
117+
currTz:=os.Getenv("TZ")
118+
ifcurrTz=="" {
119+
currTz="UTC"
120+
}
121+
expectedSchedule:=fmt.Sprintf("CRON_TZ=%s 0 9 * * 1-5",currTz)
140122
cmd,root:=clitest.New(t,"workspaces","autostart","enable",workspace.Name)
141123
clitest.SetupConfig(t,client,root)
142124

143125
err:=cmd.Execute()
144-
require.ErrorContains(t,err,"accepts 2 arg(s), received 1","unexpected error")
126+
require.NoError(t,err,"unexpected error")
145127

146128
// Ensure nothing happened
147129
updated,err:=client.Workspace(ctx,workspace.ID)
148130
require.NoError(t,err,"fetch updated workspace")
149-
require.Empty(t,updated.AutostartSchedule,"expected autostart schedule to be empty")
131+
require.Equal(t,expectedSchedule,updated.AutostartSchedule,"expecteddefaultautostart schedule")
150132
})
151133
}

‎cli/workspaceautostop.go

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package cli
22

33
import (
44
"fmt"
5+
"os"
56
"time"
67

78
"github.com/spf13/cobra"
@@ -11,20 +12,16 @@ import (
1112
)
1213

1314
constautostopDescriptionLong=`To have your workspace stop automatically at a regular time you can enable autostop.
14-
When enabling autostop, provide a schedule. This schedule is in cron format except only
15-
the following fields are allowed:
16-
- minute
17-
- hour
18-
- day of week
19-
20-
For example, to stop your workspace every weekday at 5.30 pm, provide the schedule '30 17 1-5'.`
15+
When enabling autostop, provide the minute, hour, and day(s) of week.
16+
The default autostop schedule is at 18:00 in your local timezone (TZ env, UTC by default).
17+
`
2118

2219
funcworkspaceAutostop()*cobra.Command {
2320
autostopCmd:=&cobra.Command{
24-
Use:"autostop enable <workspace> <schedule>",
25-
Short:"schedule a workspace to automaticallystart at a regular time",
21+
Use:"autostop enable <workspace>",
22+
Short:"schedule a workspace to automaticallystop at a regular time",
2623
Long:autostopDescriptionLong,
27-
Example:"coder workspaces autostop enable my-workspace'30 171-5'",
24+
Example:"coder workspaces autostop enable my-workspace--minute 0 --hour 18 --days1-5 -tz Europe/Dublin",
2825
Hidden:true,// TODO(cian): un-hide when autostop scheduling implemented
2926
}
3027

@@ -35,22 +32,28 @@ func workspaceAutostop() *cobra.Command {
3532
}
3633

3734
funcworkspaceAutostopEnable()*cobra.Command {
38-
return&cobra.Command{
35+
// yes some of these are technically numbers but the cron library will do that work
36+
varautostopMinutestring
37+
varautostopHourstring
38+
varautostopDayOfWeekstring
39+
varautostopTimezonestring
40+
cmd:=&cobra.Command{
3941
Use:"enable <workspace_name> <schedule>",
4042
ValidArgsFunction:validArgsWorkspaceName,
41-
Args:cobra.ExactArgs(2),
43+
Args:cobra.ExactArgs(1),
4244
RunE:func(cmd*cobra.Command,args []string)error {
4345
client,err:=createClient(cmd)
4446
iferr!=nil {
4547
returnerr
4648
}
4749

48-
workspace,err:=client.WorkspaceByName(cmd.Context(),codersdk.Me,args[0])
50+
spec:=fmt.Sprintf("CRON_TZ=%s %s %s * * %s",autostopTimezone,autostopMinute,autostopHour,autostopDayOfWeek)
51+
validSchedule,err:=schedule.Weekly(spec)
4952
iferr!=nil {
5053
returnerr
5154
}
5255

53-
validSchedule,err:=schedule.Weekly(args[1])
56+
workspace,err:=client.WorkspaceByName(cmd.Context(),codersdk.Me,args[0])
5457
iferr!=nil {
5558
returnerr
5659
}
@@ -67,6 +70,16 @@ func workspaceAutostopEnable() *cobra.Command {
6770
returnnil
6871
},
6972
}
73+
74+
cmd.Flags().StringVar(&autostopMinute,"minute","0","autostop minute")
75+
cmd.Flags().StringVar(&autostopHour,"hour","18","autostop hour")
76+
cmd.Flags().StringVar(&autostopDayOfWeek,"days","1-5","autostop day(s) of week")
77+
tzEnv:=os.Getenv("TZ")
78+
iftzEnv=="" {
79+
tzEnv="UTC"
80+
}
81+
cmd.Flags().StringVar(&autostopTimezone,"tz",tzEnv,"autostop timezone")
82+
returncmd
7083
}
7184

7285
funcworkspaceAutostopDisable()*cobra.Command {

‎cli/workspaceautostop_test.go

Lines changed: 15 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package cli_test
33
import (
44
"bytes"
55
"context"
6+
"fmt"
7+
"os"
68
"testing"
79

810
"github.com/stretchr/testify/require"
@@ -27,11 +29,12 @@ func TestWorkspaceAutostop(t *testing.T) {
2729
_=coderdtest.AwaitTemplateVersionJob(t,client,version.ID)
2830
project=coderdtest.CreateTemplate(t,client,user.OrganizationID,version.ID)
2931
workspace=coderdtest.CreateWorkspace(t,client,codersdk.Me,project.ID)
30-
sched="CRON_TZ=Europe/Dublin 30 9 1-5"
32+
cmdArgs= []string{"workspaces","autostop","enable",workspace.Name,"--minute","30","--hour","17","--days","1-5","--tz","Europe/Dublin"}
33+
sched="CRON_TZ=Europe/Dublin 30 17 * * 1-5"
3134
stdoutBuf=&bytes.Buffer{}
3235
)
3336

34-
cmd,root:=clitest.New(t,"workspaces","autostop","enable",workspace.Name,sched)
37+
cmd,root:=clitest.New(t,cmdArgs...)
3538
clitest.SetupConfig(t,client,root)
3639
cmd.SetOut(stdoutBuf)
3740

@@ -68,10 +71,9 @@ func TestWorkspaceAutostop(t *testing.T) {
6871
user=coderdtest.CreateFirstUser(t,client)
6972
version=coderdtest.CreateTemplateVersion(t,client,user.OrganizationID,nil)
7073
_=coderdtest.AwaitTemplateVersionJob(t,client,version.ID)
71-
sched="CRON_TZ=Europe/Dublin 30 9 1-5"
7274
)
7375

74-
cmd,root:=clitest.New(t,"workspaces","autostop","enable","doesnotexist",sched)
76+
cmd,root:=clitest.New(t,"workspaces","autostop","enable","doesnotexist")
7577
clitest.SetupConfig(t,client,root)
7678

7779
err:=cmd.Execute()
@@ -96,7 +98,7 @@ func TestWorkspaceAutostop(t *testing.T) {
9698
require.ErrorContains(t,err,"status code 404: no workspace found by name","unexpected error")
9799
})
98100

99-
t.Run("Enable_InvalidSchedule",func(t*testing.T) {
101+
t.Run("Enable_DefaultSchedule",func(t*testing.T) {
100102
t.Parallel()
101103

102104
var (
@@ -108,44 +110,24 @@ func TestWorkspaceAutostop(t *testing.T) {
108110
_=coderdtest.AwaitTemplateVersionJob(t,client,version.ID)
109111
project=coderdtest.CreateTemplate(t,client,user.OrganizationID,version.ID)
110112
workspace=coderdtest.CreateWorkspace(t,client,codersdk.Me,project.ID)
111-
sched="sdfasdfasdf asdf asdf"
112113
)
113114

114-
cmd,root:=clitest.New(t,"workspaces","autostop","enable",workspace.Name,sched)
115-
clitest.SetupConfig(t,client,root)
116-
117-
err:=cmd.Execute()
118-
require.ErrorContains(t,err,"failed to parse int from sdfasdfasdf: strconv.Atoi:","unexpected error")
119-
120-
// Ensure nothing happened
121-
updated,err:=client.Workspace(ctx,workspace.ID)
122-
require.NoError(t,err,"fetch updated workspace")
123-
require.Empty(t,updated.AutostopSchedule,"expected autostop schedule to be empty")
124-
})
125-
126-
t.Run("Enable_NoSchedule",func(t*testing.T) {
127-
t.Parallel()
128-
129-
var (
130-
ctx=context.Background()
131-
client=coderdtest.New(t,nil)
132-
_=coderdtest.NewProvisionerDaemon(t,client)
133-
user=coderdtest.CreateFirstUser(t,client)
134-
version=coderdtest.CreateTemplateVersion(t,client,user.OrganizationID,nil)
135-
_=coderdtest.AwaitTemplateVersionJob(t,client,version.ID)
136-
project=coderdtest.CreateTemplate(t,client,user.OrganizationID,version.ID)
137-
workspace=coderdtest.CreateWorkspace(t,client,codersdk.Me,project.ID)
138-
)
115+
// check current TZ env var
116+
currTz:=os.Getenv("TZ")
117+
ifcurrTz=="" {
118+
currTz="UTC"
119+
}
120+
expectedSchedule:=fmt.Sprintf("CRON_TZ=%s 0 18 * * 1-5",currTz)
139121

140122
cmd,root:=clitest.New(t,"workspaces","autostop","enable",workspace.Name)
141123
clitest.SetupConfig(t,client,root)
142124

143125
err:=cmd.Execute()
144-
require.ErrorContains(t,err,"accepts 2 arg(s), received 1","unexpected error")
126+
require.NoError(t,err,"unexpected error")
145127

146128
// Ensure nothing happened
147129
updated,err:=client.Workspace(ctx,workspace.ID)
148130
require.NoError(t,err,"fetch updated workspace")
149-
require.Empty(t,updated.AutostopSchedule,"expected autostop schedule to be empty")
131+
require.Equal(t,expectedSchedule,updated.AutostopSchedule,"expecteddefaultautostop schedule")
150132
})
151133
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp