From 6c8d0512697a422f0bd14bc70c526e9b29885e5e Mon Sep 17 00:00:00 2001 From: Tiger Kaovilai Date: Tue, 14 May 2024 16:49:41 -0400 Subject: [PATCH] Upgrade to robfig/cron/v3 to support time zone specification Breaking change (can be mitigated if needed in the future): v1 branch accepted an optional seconds field at the beginning of the cron spec. This is non-standard and has led to a lot of confusion. The new default parser conforms to the standard as described by [the Cron wikipedia page.](https://en.wikipedia.org/wiki/Cron). It is unlikely that this affects us per https://github.com/vmware-tanzu/velero/pull/31 Other notes: > CRON_TZ is now the recommended way to specify the timezone of a single schedule, which is sanctioned by the specification. The legacy "TZ=" prefix will continue to be supported since it is unambiguous and easy to do so. References: https://pkg.go.dev/github.com/robfig/cron/v3#readme-upgrading-to-v3-june-2019 Signed-off-by: Tiger Kaovilai --- changelogs/unreleased/7793-kaovilai | 1 + go.mod | 2 +- go.sum | 4 ++-- pkg/controller/schedule_controller.go | 2 +- pkg/controller/schedule_controller_test.go | 4 ++-- site/content/docs/main/backup-reference.md | 27 ++++++++++++++++++++++ 6 files changed, 34 insertions(+), 6 deletions(-) create mode 100644 changelogs/unreleased/7793-kaovilai diff --git a/changelogs/unreleased/7793-kaovilai b/changelogs/unreleased/7793-kaovilai new file mode 100644 index 0000000000..1af0dd59bd --- /dev/null +++ b/changelogs/unreleased/7793-kaovilai @@ -0,0 +1 @@ +Upgrade to robfig/cron/v3 to support time zone specification. \ No newline at end of file diff --git a/go.mod b/go.mod index 4113c1e3bc..5b7eabd2d2 100644 --- a/go.mod +++ b/go.mod @@ -32,7 +32,7 @@ require ( github.com/onsi/gomega v1.30.0 github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.19.0 - github.com/robfig/cron v1.1.0 + github.com/robfig/cron/v3 v3.0.1 github.com/sirupsen/logrus v1.9.3 github.com/spf13/afero v1.6.0 github.com/spf13/cobra v1.7.0 diff --git a/go.sum b/go.sum index 50201d5855..f44d871978 100644 --- a/go.sum +++ b/go.sum @@ -644,8 +644,8 @@ github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= -github.com/robfig/cron v1.1.0 h1:jk4/Hud3TTdcrJgUOBgsqrZBarcxl6ADIjSC2iniwLY= -github.com/robfig/cron v1.1.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k= +github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= +github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= diff --git a/pkg/controller/schedule_controller.go b/pkg/controller/schedule_controller.go index da15cdabf8..1c8267e528 100644 --- a/pkg/controller/schedule_controller.go +++ b/pkg/controller/schedule_controller.go @@ -22,7 +22,7 @@ import ( "time" "github.com/pkg/errors" - "github.com/robfig/cron" + cron "github.com/robfig/cron/v3" "github.com/sirupsen/logrus" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" diff --git a/pkg/controller/schedule_controller_test.go b/pkg/controller/schedule_controller_test.go index e7c0c25a5f..80b24e6f84 100644 --- a/pkg/controller/schedule_controller_test.go +++ b/pkg/controller/schedule_controller_test.go @@ -20,7 +20,7 @@ import ( "testing" "time" - "github.com/robfig/cron" + cron "github.com/robfig/cron/v3" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -289,7 +289,7 @@ func TestGetNextRunTime(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - cronSchedule, err := cron.Parse(test.schedule.Spec.Schedule) + cronSchedule, err := cron.ParseStandard(test.schedule.Spec.Schedule) require.NoError(t, err, "unable to parse test.schedule.Spec.Schedule: %v", err) testClock := testclocks.NewFakeClock(time.Now()) diff --git a/site/content/docs/main/backup-reference.md b/site/content/docs/main/backup-reference.md index 8b4ff57112..220d97accf 100644 --- a/site/content/docs/main/backup-reference.md +++ b/site/content/docs/main/backup-reference.md @@ -66,6 +66,33 @@ velero backup create --from-schedule example-schedule This command will immediately trigger a new backup based on your template for `example-schedule`. This will not affect the backup schedule, and another backup will trigger at the scheduled time. +### Time zone specification +Time zone can be specified in the schedule cron. The format is `CRON_TZ= `. + +Specifying timezones can reduce disputes in the case of daylight saving time changes. For example, if the schedule is set to run at 3am, and daylight saving time changes, the schedule will still run at 3am in the timezone specified. + +Be aware that jobs scheduled during daylight-savings leap-ahead transitions will not be run! + +For example, the command below creates a backup that runs every day at 3am in the timezone `America/New_York`. + +``` +velero schedule create example-schedule --schedule="CRON_TZ=America/New_York 0 3 * * *" +``` + +Another example, the command below creates a backup that runs every day at 3am in the timezone `Asia/Shanghai`. + +``` +velero schedule create example-schedule --schedule="CRON_TZ=Asia/Shanghai 0 3 * * *" +``` + +The supported timezone names are listed in the [IANA Time Zone Database](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List) under 'TZ identifier'. + ### Limitation