chore: rename template restart requirement to autostop requirement (#9295)

This commit is contained in:
Dean Sheather
2023-08-29 18:35:05 +00:00
committed by GitHub
parent fc4683d8b3
commit a572800d47
40 changed files with 925 additions and 891 deletions
+32 -32
View File
@@ -13,17 +13,17 @@ import (
)
const (
// restartRequirementLeeway is the duration of time before a restart
// autostopRequirementLeeway is the duration of time before a autostop
// requirement where we skip the requirement and fall back to the next
// scheduled restart. This avoids workspaces being restarted too soon.
// scheduled stop. This avoids workspaces being stopped too soon.
//
// E.g. If the workspace is started within an hour of the quiet hours, we
// will skip the restart requirement and use the next scheduled restart
// requirement.
restartRequirementLeeway = 1 * time.Hour
// will skip the autostop requirement and use the next scheduled
// stop time instead.
autostopRequirementLeeway = 1 * time.Hour
// restartRequirementBuffer is the duration of time we subtract from the
// time when calculating the next scheduled restart time. This avoids issues
// autostopRequirementBuffer is the duration of time we subtract from the
// time when calculating the next scheduled stop time. This avoids issues
// where autostart happens on the hour and the scheduled quiet hours are
// also on the hour.
//
@@ -37,7 +37,7 @@ const (
//
// This resolves that problem by subtracting 15 minutes from midnight
// when we check the next cron time.
restartRequirementBuffer = -15 * time.Minute
autostopRequirementBuffer = -15 * time.Minute
)
type CalculateAutostopParams struct {
@@ -68,7 +68,7 @@ type AutostopTime struct {
//
// MaxDeadline is the maximum value for deadline. The deadline cannot be bumped
// past this value, so it denotes the absolute deadline that the workspace build
// must be stopped by. MaxDeadline is calculated using the template's "restart
// must be stopped by. MaxDeadline is calculated using the template's "autostop
// requirement" settings and the user's "quiet hours" settings to pick a time
// outside of working hours.
//
@@ -113,13 +113,13 @@ func CalculateAutostop(ctx context.Context, params CalculateAutostopParams) (Aut
// Use the old algorithm for calculating max_deadline if the instance isn't
// configured or entitled to use the new feature flag yet.
// TODO(@dean): remove this once the feature flag is enabled for all
if !templateSchedule.UseRestartRequirement && templateSchedule.MaxTTL > 0 {
if !templateSchedule.UseAutostopRequirement && templateSchedule.MaxTTL > 0 {
autostop.MaxDeadline = now.Add(templateSchedule.MaxTTL)
}
// TODO(@dean): remove extra conditional
if templateSchedule.UseRestartRequirement && templateSchedule.RestartRequirement.DaysOfWeek != 0 {
// The template has a restart requirement, so determine the max deadline
if templateSchedule.UseAutostopRequirement && templateSchedule.AutostopRequirement.DaysOfWeek != 0 {
// The template has a autostop requirement, so determine the max deadline
// of this workspace build.
// First, get the user's quiet hours schedule (this will return the
@@ -137,13 +137,13 @@ func CalculateAutostop(ctx context.Context, params CalculateAutostopParams) (Aut
now := now.In(loc)
// Add the leeway here so we avoid checking today's quiet hours if
// the workspace was started <1h before midnight.
startOfStopDay := truncateMidnight(now.Add(restartRequirementLeeway))
startOfStopDay := truncateMidnight(now.Add(autostopRequirementLeeway))
// If the template schedule wants to only restart on n-th weeks then
// change the startOfDay to be the Monday of the next applicable
// week.
if templateSchedule.RestartRequirement.Weeks > 1 {
startOfStopDay, err = GetNextApplicableMondayOfNWeeks(startOfStopDay, templateSchedule.RestartRequirement.Weeks)
// If the template schedule wants to only autostop on n-th weeks
// then change the startOfDay to be the Monday of the next
// applicable week.
if templateSchedule.AutostopRequirement.Weeks > 1 {
startOfStopDay, err = GetNextApplicableMondayOfNWeeks(startOfStopDay, templateSchedule.AutostopRequirement.Weeks)
if err != nil {
return autostop, xerrors.Errorf("determine start of stop week: %w", err)
}
@@ -155,30 +155,30 @@ func CalculateAutostop(ctx context.Context, params CalculateAutostopParams) (Aut
// Allow an hour of leeway (i.e. any workspaces started within an
// hour of the scheduled stop time will always bounce to the next
// stop window).
checkSchedule := userQuietHoursSchedule.Schedule.Next(startOfStopDay.Add(restartRequirementBuffer))
if checkSchedule.Before(now.Add(restartRequirementLeeway)) {
checkSchedule := userQuietHoursSchedule.Schedule.Next(startOfStopDay.Add(autostopRequirementBuffer))
if checkSchedule.Before(now.Add(autostopRequirementLeeway)) {
// Set the first stop day we try to tomorrow because today's
// schedule is too close to now or has already passed.
startOfStopDay = nextDayMidnight(startOfStopDay)
}
// Iterate from 0 to 7, check if the current startOfDay is in the
// restart requirement. If it isn't then add a day and try again.
requirementDays := templateSchedule.RestartRequirement.DaysMap()
// autostop requirement. If it isn't then add a day and try again.
requirementDays := templateSchedule.AutostopRequirement.DaysMap()
for i := 0; i < len(DaysOfWeek)+1; i++ {
if i == len(DaysOfWeek) {
// We've wrapped, so somehow we couldn't find a day in the
// restart requirement in the next week.
// autostop requirement in the next week.
//
// This shouldn't be able to happen, as we've already
// checked that there is a day in the restart requirement
// checked that there is a day in the autostop requirement
// above with the
// `if templateSchedule.RestartRequirement.DaysOfWeek != 0`
// `if templateSchedule.AutoStopRequirement.DaysOfWeek != 0`
// check.
//
// The eighth bit shouldn't be set, as we validate the
// bitmap in the enterprise TemplateScheduleStore.
return autostop, xerrors.New("could not find suitable day for template restart requirement in the next 7 days")
return autostop, xerrors.New("could not find suitable day for template autostop requirement in the next 7 days")
}
if requirementDays[startOfStopDay.Weekday()] {
break
@@ -194,13 +194,13 @@ func CalculateAutostop(ctx context.Context, params CalculateAutostopParams) (Aut
// If it's not within an hour of now, subtract 15 minutes to
// give a little leeway. This prevents skipped stop events
// because autostart perfectly lines up with autostop.
checkTime = checkTime.Add(restartRequirementBuffer)
checkTime = checkTime.Add(autostopRequirementBuffer)
}
// Get the next occurrence of the restart schedule.
// Get the next occurrence of the schedule.
autostop.MaxDeadline = userQuietHoursSchedule.Schedule.Next(checkTime)
if autostop.MaxDeadline.IsZero() {
return autostop, xerrors.New("could not find next occurrence of template restart requirement in user quiet hours schedule")
return autostop, xerrors.Errorf("could not find next occurrence of template autostop requirement in user quiet hours schedule, checked from time %q", checkTime)
}
}
}
@@ -244,9 +244,9 @@ func nextDayMidnight(t time.Time) time.Time {
//
// The timezone embedded in the time object is used to determine the epoch.
func WeeksSinceEpoch(now time.Time) (int64, error) {
epoch := TemplateRestartRequirementEpoch(now.Location())
epoch := TemplateAutostopRequirementEpoch(now.Location())
if now.Before(epoch) {
return 0, xerrors.New("coder server system clock is incorrect, cannot calculate template restart requirement")
return 0, xerrors.New("coder server system clock is incorrect, cannot calculate template autostop requirement")
}
// This calculation needs to be done using YearDay, as dividing by the
@@ -290,7 +290,7 @@ func GetMondayOfWeek(loc *time.Location, n int64) (time.Time, error) {
if n < 0 {
return time.Time{}, xerrors.New("weeks since epoch must be positive")
}
epoch := TemplateRestartRequirementEpoch(loc)
epoch := TemplateAutostopRequirementEpoch(loc)
monday := epoch.AddDate(0, 0, int(n*7))
y, m, d := monday.Date()
+94 -94
View File
@@ -25,7 +25,7 @@ func TestCalculateAutoStop(t *testing.T) {
// Wednesday the 8th of February 2023 at midnight. This date was
// specifically chosen as it doesn't fall on a applicable week for both
// fortnightly and triweekly restart requirements.
// fortnightly and triweekly autostop requirements.
wednesdayMidnightUTC := time.Date(2023, 2, 8, 0, 0, 0, 0, time.UTC)
sydneyQuietHours := "CRON_TZ=Australia/Sydney 0 0 * * *"
@@ -73,10 +73,10 @@ func TestCalculateAutoStop(t *testing.T) {
templateAllowAutostop bool
templateDefaultTTL time.Duration
// TODO(@dean): remove max_ttl tests
useMaxTTL bool
templateMaxTTL time.Duration
templateRestartRequirement schedule.TemplateRestartRequirement
userQuietHoursSchedule string
useMaxTTL bool
templateMaxTTL time.Duration
templateAutostopRequirement schedule.TemplateAutostopRequirement
userQuietHoursSchedule string
// workspaceTTL is usually copied from the template's TTL when the
// workspace is made, so it takes precedence unless
// templateAllowAutostop is false.
@@ -88,72 +88,72 @@ func TestCalculateAutoStop(t *testing.T) {
errContains string
}{
{
name: "OK",
now: now,
templateAllowAutostop: true,
templateDefaultTTL: 0,
templateRestartRequirement: schedule.TemplateRestartRequirement{},
workspaceTTL: 0,
expectedDeadline: time.Time{},
expectedMaxDeadline: time.Time{},
name: "OK",
now: now,
templateAllowAutostop: true,
templateDefaultTTL: 0,
templateAutostopRequirement: schedule.TemplateAutostopRequirement{},
workspaceTTL: 0,
expectedDeadline: time.Time{},
expectedMaxDeadline: time.Time{},
},
{
name: "Delete",
now: now,
templateAllowAutostop: true,
templateDefaultTTL: 0,
templateRestartRequirement: schedule.TemplateRestartRequirement{},
workspaceTTL: 0,
expectedDeadline: time.Time{},
expectedMaxDeadline: time.Time{},
name: "Delete",
now: now,
templateAllowAutostop: true,
templateDefaultTTL: 0,
templateAutostopRequirement: schedule.TemplateAutostopRequirement{},
workspaceTTL: 0,
expectedDeadline: time.Time{},
expectedMaxDeadline: time.Time{},
},
{
name: "WorkspaceTTL",
now: now,
templateAllowAutostop: true,
templateDefaultTTL: 0,
templateRestartRequirement: schedule.TemplateRestartRequirement{},
workspaceTTL: time.Hour,
expectedDeadline: now.Add(time.Hour),
expectedMaxDeadline: time.Time{},
name: "WorkspaceTTL",
now: now,
templateAllowAutostop: true,
templateDefaultTTL: 0,
templateAutostopRequirement: schedule.TemplateAutostopRequirement{},
workspaceTTL: time.Hour,
expectedDeadline: now.Add(time.Hour),
expectedMaxDeadline: time.Time{},
},
{
name: "TemplateDefaultTTLIgnored",
now: now,
templateAllowAutostop: true,
templateDefaultTTL: time.Hour,
templateRestartRequirement: schedule.TemplateRestartRequirement{},
workspaceTTL: 0,
expectedDeadline: time.Time{},
expectedMaxDeadline: time.Time{},
name: "TemplateDefaultTTLIgnored",
now: now,
templateAllowAutostop: true,
templateDefaultTTL: time.Hour,
templateAutostopRequirement: schedule.TemplateAutostopRequirement{},
workspaceTTL: 0,
expectedDeadline: time.Time{},
expectedMaxDeadline: time.Time{},
},
{
name: "WorkspaceTTLOverridesTemplateDefaultTTL",
now: now,
templateAllowAutostop: true,
templateDefaultTTL: 2 * time.Hour,
templateRestartRequirement: schedule.TemplateRestartRequirement{},
workspaceTTL: time.Hour,
expectedDeadline: now.Add(time.Hour),
expectedMaxDeadline: time.Time{},
name: "WorkspaceTTLOverridesTemplateDefaultTTL",
now: now,
templateAllowAutostop: true,
templateDefaultTTL: 2 * time.Hour,
templateAutostopRequirement: schedule.TemplateAutostopRequirement{},
workspaceTTL: time.Hour,
expectedDeadline: now.Add(time.Hour),
expectedMaxDeadline: time.Time{},
},
{
name: "TemplateBlockWorkspaceTTL",
now: now,
templateAllowAutostop: false,
templateDefaultTTL: 3 * time.Hour,
templateRestartRequirement: schedule.TemplateRestartRequirement{},
workspaceTTL: 4 * time.Hour,
expectedDeadline: now.Add(3 * time.Hour),
expectedMaxDeadline: time.Time{},
name: "TemplateBlockWorkspaceTTL",
now: now,
templateAllowAutostop: false,
templateDefaultTTL: 3 * time.Hour,
templateAutostopRequirement: schedule.TemplateAutostopRequirement{},
workspaceTTL: 4 * time.Hour,
expectedDeadline: now.Add(3 * time.Hour),
expectedMaxDeadline: time.Time{},
},
{
name: "TemplateRestartRequirement",
name: "TemplateAutostopRequirement",
now: wednesdayMidnightUTC,
templateAllowAutostop: true,
templateDefaultTTL: 0,
userQuietHoursSchedule: sydneyQuietHours,
templateRestartRequirement: schedule.TemplateRestartRequirement{
templateAutostopRequirement: schedule.TemplateAutostopRequirement{
DaysOfWeek: 0b00100000, // Saturday
Weeks: 0, // weekly
},
@@ -162,12 +162,12 @@ func TestCalculateAutoStop(t *testing.T) {
expectedMaxDeadline: saturdayMidnightSydney.In(time.UTC),
},
{
name: "TemplateRestartRequirement1HourSkip",
name: "TemplateAutostopRequirement1HourSkip",
now: saturdayMidnightSydney.Add(-59 * time.Minute),
templateAllowAutostop: true,
templateDefaultTTL: 0,
userQuietHoursSchedule: sydneyQuietHours,
templateRestartRequirement: schedule.TemplateRestartRequirement{
templateAutostopRequirement: schedule.TemplateAutostopRequirement{
DaysOfWeek: 0b00100000, // Saturday
Weeks: 1, // 1 also means weekly
},
@@ -176,14 +176,14 @@ func TestCalculateAutoStop(t *testing.T) {
expectedMaxDeadline: saturdayMidnightSydney.Add(7 * 24 * time.Hour).In(time.UTC),
},
{
// The next restart requirement should be skipped if the
// The next autostop requirement should be skipped if the
// workspace is started within 1 hour of it.
name: "TemplateRestartRequirementDaily",
name: "TemplateAutostopRequirementDaily",
now: fridayEveningSydney,
templateAllowAutostop: true,
templateDefaultTTL: 0,
userQuietHoursSchedule: sydneyQuietHours,
templateRestartRequirement: schedule.TemplateRestartRequirement{
templateAutostopRequirement: schedule.TemplateAutostopRequirement{
DaysOfWeek: 0b01111111, // daily
Weeks: 0, // all weeks
},
@@ -192,12 +192,12 @@ func TestCalculateAutoStop(t *testing.T) {
expectedMaxDeadline: saturdayMidnightSydney.In(time.UTC),
},
{
name: "TemplateRestartRequirementFortnightly/Skip",
name: "TemplateAutostopRequirementFortnightly/Skip",
now: wednesdayMidnightUTC,
templateAllowAutostop: true,
templateDefaultTTL: 0,
userQuietHoursSchedule: sydneyQuietHours,
templateRestartRequirement: schedule.TemplateRestartRequirement{
templateAutostopRequirement: schedule.TemplateAutostopRequirement{
DaysOfWeek: 0b00100000, // Saturday
Weeks: 2, // every 2 weeks
},
@@ -206,12 +206,12 @@ func TestCalculateAutoStop(t *testing.T) {
expectedMaxDeadline: saturdayMidnightSydney.AddDate(0, 0, 7).In(time.UTC),
},
{
name: "TemplateRestartRequirementFortnightly/NoSkip",
name: "TemplateAutostopRequirementFortnightly/NoSkip",
now: wednesdayMidnightUTC.AddDate(0, 0, 7),
templateAllowAutostop: true,
templateDefaultTTL: 0,
userQuietHoursSchedule: sydneyQuietHours,
templateRestartRequirement: schedule.TemplateRestartRequirement{
templateAutostopRequirement: schedule.TemplateAutostopRequirement{
DaysOfWeek: 0b00100000, // Saturday
Weeks: 2, // every 2 weeks
},
@@ -220,28 +220,28 @@ func TestCalculateAutoStop(t *testing.T) {
expectedMaxDeadline: saturdayMidnightSydney.AddDate(0, 0, 7).In(time.UTC),
},
{
name: "TemplateRestartRequirementTriweekly/Skip",
name: "TemplateAutostopRequirementTriweekly/Skip",
now: wednesdayMidnightUTC,
templateAllowAutostop: true,
templateDefaultTTL: 0,
userQuietHoursSchedule: sydneyQuietHours,
templateRestartRequirement: schedule.TemplateRestartRequirement{
templateAutostopRequirement: schedule.TemplateAutostopRequirement{
DaysOfWeek: 0b00100000, // Saturday
Weeks: 3, // every 3 weeks
},
workspaceTTL: 0,
// expectedDeadline is copied from expectedMaxDeadline.
// The next triweekly restart requirement happens next week
// The next triweekly autostop requirement happens next week
// according to the epoch.
expectedMaxDeadline: saturdayMidnightSydney.AddDate(0, 0, 7).In(time.UTC),
},
{
name: "TemplateRestartRequirementTriweekly/NoSkip",
name: "TemplateAutostopRequirementTriweekly/NoSkip",
now: wednesdayMidnightUTC.AddDate(0, 0, 7),
templateAllowAutostop: true,
templateDefaultTTL: 0,
userQuietHoursSchedule: sydneyQuietHours,
templateRestartRequirement: schedule.TemplateRestartRequirement{
templateAutostopRequirement: schedule.TemplateAutostopRequirement{
DaysOfWeek: 0b00100000, // Saturday
Weeks: 3, // every 3 weeks
},
@@ -250,14 +250,14 @@ func TestCalculateAutoStop(t *testing.T) {
expectedMaxDeadline: saturdayMidnightSydney.AddDate(0, 0, 7).In(time.UTC),
},
{
name: "TemplateRestartRequirementOverridesWorkspaceTTL",
name: "TemplateAutostopRequirementOverridesWorkspaceTTL",
// now doesn't have to be UTC, but it helps us ensure that
// timezones are compared correctly in this test.
now: fridayEveningSydney.In(time.UTC),
templateAllowAutostop: true,
templateDefaultTTL: 0,
userQuietHoursSchedule: sydneyQuietHours,
templateRestartRequirement: schedule.TemplateRestartRequirement{
templateAutostopRequirement: schedule.TemplateAutostopRequirement{
DaysOfWeek: 0b00100000, // Saturday
Weeks: 0, // weekly
},
@@ -266,12 +266,12 @@ func TestCalculateAutoStop(t *testing.T) {
expectedMaxDeadline: saturdayMidnightSydney.In(time.UTC),
},
{
name: "TemplateRestartRequirementOverridesTemplateDefaultTTL",
name: "TemplateAutostopRequirementOverridesTemplateDefaultTTL",
now: fridayEveningSydney.In(time.UTC),
templateAllowAutostop: true,
templateDefaultTTL: 3 * time.Hour,
userQuietHoursSchedule: sydneyQuietHours,
templateRestartRequirement: schedule.TemplateRestartRequirement{
templateAutostopRequirement: schedule.TemplateAutostopRequirement{
DaysOfWeek: 0b00100000, // Saturday
Weeks: 0, // weekly
},
@@ -288,7 +288,7 @@ func TestCalculateAutoStop(t *testing.T) {
templateAllowAutostop: true,
templateDefaultTTL: 0,
userQuietHoursSchedule: sydneyQuietHours,
templateRestartRequirement: schedule.TemplateRestartRequirement{
templateAutostopRequirement: schedule.TemplateAutostopRequirement{
DaysOfWeek: 0b00100000, // Saturday
Weeks: 2, // every fortnight
},
@@ -301,7 +301,7 @@ func TestCalculateAutoStop(t *testing.T) {
templateAllowAutostop: true,
templateDefaultTTL: 0,
userQuietHoursSchedule: sydneyQuietHours,
templateRestartRequirement: schedule.TemplateRestartRequirement{
templateAutostopRequirement: schedule.TemplateAutostopRequirement{
DaysOfWeek: 0b00100000, // Saturday
Weeks: 1, // weekly
},
@@ -315,7 +315,7 @@ func TestCalculateAutoStop(t *testing.T) {
templateAllowAutostop: true,
templateDefaultTTL: 0,
userQuietHoursSchedule: sydneyQuietHours,
templateRestartRequirement: schedule.TemplateRestartRequirement{
templateAutostopRequirement: schedule.TemplateAutostopRequirement{
DaysOfWeek: 0b00100000, // Saturday
Weeks: 1, // weekly
},
@@ -329,7 +329,7 @@ func TestCalculateAutoStop(t *testing.T) {
templateAllowAutostop: true,
templateDefaultTTL: 0,
userQuietHoursSchedule: sydneyQuietHours,
templateRestartRequirement: schedule.TemplateRestartRequirement{
templateAutostopRequirement: schedule.TemplateAutostopRequirement{
DaysOfWeek: 0b00100000, // Saturday
Weeks: 1, // weekly
},
@@ -343,7 +343,7 @@ func TestCalculateAutoStop(t *testing.T) {
templateAllowAutostop: true,
templateDefaultTTL: 0,
userQuietHoursSchedule: dstInQuietHours,
templateRestartRequirement: schedule.TemplateRestartRequirement{
templateAutostopRequirement: schedule.TemplateAutostopRequirement{
DaysOfWeek: 0b01000000, // Sunday
Weeks: 1, // weekly
},
@@ -357,7 +357,7 @@ func TestCalculateAutoStop(t *testing.T) {
templateAllowAutostop: true,
templateDefaultTTL: 0,
userQuietHoursSchedule: dstOutQuietHours,
templateRestartRequirement: schedule.TemplateRestartRequirement{
templateAutostopRequirement: schedule.TemplateAutostopRequirement{
DaysOfWeek: 0b01000000, // Sunday
Weeks: 1, // weekly
},
@@ -368,14 +368,14 @@ func TestCalculateAutoStop(t *testing.T) {
// TODO(@dean): remove max_ttl tests
{
name: "RestartRequirementIgnoresMaxTTL",
name: "AutostopRequirementIgnoresMaxTTL",
now: fridayEveningSydney.In(time.UTC),
templateAllowAutostop: false,
templateDefaultTTL: 0,
useMaxTTL: false,
templateMaxTTL: time.Hour, // should be ignored
userQuietHoursSchedule: sydneyQuietHours,
templateRestartRequirement: schedule.TemplateRestartRequirement{
templateAutostopRequirement: schedule.TemplateAutostopRequirement{
DaysOfWeek: 0b00100000, // Saturday
Weeks: 0, // weekly
},
@@ -384,14 +384,14 @@ func TestCalculateAutoStop(t *testing.T) {
expectedMaxDeadline: saturdayMidnightSydney.In(time.UTC),
},
{
name: "MaxTTLIgnoresRestartRequirement",
name: "MaxTTLIgnoresAutostopRequirement",
now: fridayEveningSydney.In(time.UTC),
templateAllowAutostop: false,
templateDefaultTTL: 0,
useMaxTTL: true,
templateMaxTTL: time.Hour, // should NOT be ignored
userQuietHoursSchedule: sydneyQuietHours,
templateRestartRequirement: schedule.TemplateRestartRequirement{
templateAutostopRequirement: schedule.TemplateAutostopRequirement{
DaysOfWeek: 0b00100000, // Saturday
Weeks: 0, // weekly
},
@@ -413,12 +413,12 @@ func TestCalculateAutoStop(t *testing.T) {
templateScheduleStore := schedule.MockTemplateScheduleStore{
GetFn: func(_ context.Context, _ database.Store, _ uuid.UUID) (schedule.TemplateScheduleOptions, error) {
return schedule.TemplateScheduleOptions{
UserAutostartEnabled: false,
UserAutostopEnabled: c.templateAllowAutostop,
DefaultTTL: c.templateDefaultTTL,
MaxTTL: c.templateMaxTTL,
UseRestartRequirement: !c.useMaxTTL,
RestartRequirement: c.templateRestartRequirement,
UserAutostartEnabled: false,
UserAutostopEnabled: c.templateAllowAutostop,
DefaultTTL: c.templateDefaultTTL,
MaxTTL: c.templateMaxTTL,
UseAutostopRequirement: !c.useMaxTTL,
AutostopRequirement: c.templateAutostopRequirement,
}, nil
},
}
@@ -454,11 +454,11 @@ func TestCalculateAutoStop(t *testing.T) {
CreatedBy: user.ID,
})
err := db.UpdateTemplateScheduleByID(ctx, database.UpdateTemplateScheduleByIDParams{
ID: template.ID,
UpdatedAt: database.Now(),
AllowUserAutostart: c.templateAllowAutostop,
RestartRequirementDaysOfWeek: int16(c.templateRestartRequirement.DaysOfWeek),
RestartRequirementWeeks: c.templateRestartRequirement.Weeks,
ID: template.ID,
UpdatedAt: database.Now(),
AllowUserAutostart: c.templateAllowAutostop,
AutostopRequirementDaysOfWeek: int16(c.templateAutostopRequirement.DaysOfWeek),
AutostopRequirementWeeks: c.templateAutostopRequirement.Weeks,
})
require.NoError(t, err)
template, err = db.GetTemplateByID(ctx, template.ID)
+30 -30
View File
@@ -11,9 +11,9 @@ import (
"github.com/coder/coder/v2/coderd/tracing"
)
const MaxTemplateRestartRequirementWeeks = 16
const MaxTemplateAutostopRequirementWeeks = 16
func TemplateRestartRequirementEpoch(loc *time.Location) time.Time {
func TemplateAutostopRequirementEpoch(loc *time.Location) time.Time {
// The "first week" starts on January 2nd, 2023, which is the first Monday
// of 2023. All other weeks are counted using modulo arithmetic from that
// date.
@@ -34,7 +34,7 @@ var DaysOfWeek = []time.Weekday{
time.Sunday,
}
type TemplateRestartRequirement struct {
type TemplateAutostopRequirement struct {
// DaysOfWeek is a bitmap of which days of the week the workspace must be
// restarted. If fully zero, the workspace is not required to be restarted
// ever.
@@ -55,7 +55,7 @@ type TemplateRestartRequirement struct {
// DaysMap returns a map of the days of the week that the workspace must be
// restarted.
func (r TemplateRestartRequirement) DaysMap() map[time.Weekday]bool {
func (r TemplateAutostopRequirement) DaysMap() map[time.Weekday]bool {
days := make(map[time.Weekday]bool)
for i, day := range DaysOfWeek {
days[day] = r.DaysOfWeek&(1<<uint(i)) != 0
@@ -63,20 +63,20 @@ func (r TemplateRestartRequirement) DaysMap() map[time.Weekday]bool {
return days
}
// VerifyTemplateRestartRequirement returns an error if the restart requirement
// is invalid.
func VerifyTemplateRestartRequirement(days uint8, weeks int64) error {
// VerifyTemplateAutostopRequirement returns an error if the autostop
// requirement is invalid.
func VerifyTemplateAutostopRequirement(days uint8, weeks int64) error {
if days&0b10000000 != 0 {
return xerrors.New("invalid restart requirement days, last bit is set")
return xerrors.New("invalid autostop requirement days, last bit is set")
}
if days > 0b11111111 {
return xerrors.New("invalid restart requirement days, too large")
return xerrors.New("invalid autostop requirement days, too large")
}
if weeks < 0 {
return xerrors.New("invalid restart requirement weeks, negative")
return xerrors.New("invalid autostop requirement weeks, negative")
}
if weeks > MaxTemplateRestartRequirementWeeks {
return xerrors.New("invalid restart requirement weeks, too large")
if weeks > MaxTemplateAutostopRequirementWeeks {
return xerrors.New("invalid autostop requirement weeks, too large")
}
return nil
}
@@ -85,17 +85,17 @@ type TemplateScheduleOptions struct {
UserAutostartEnabled bool `json:"user_autostart_enabled"`
UserAutostopEnabled bool `json:"user_autostop_enabled"`
DefaultTTL time.Duration `json:"default_ttl"`
// TODO(@dean): remove MaxTTL once restart_requirement is matured and the
// TODO(@dean): remove MaxTTL once autostop_requirement is matured and the
// default
MaxTTL time.Duration `json:"max_ttl"`
// UseRestartRequirement dictates whether the restart requirement should be
// used instead of MaxTTL. This is governed by the feature flag and
// UseAutostopRequirement dictates whether the autostop requirement should
// be used instead of MaxTTL. This is governed by the feature flag and
// licensing.
// TODO(@dean): remove this when we remove max_tll
UseRestartRequirement bool
// RestartRequirement dictates when the workspace must be restarted. This
UseAutostopRequirement bool
// AutostopRequirement dictates when the workspace must be restarted. This
// used to be handled by MaxTTL.
RestartRequirement TemplateRestartRequirement `json:"restart_requirement"`
AutostopRequirement TemplateAutostopRequirement `json:"autostop_requirement"`
// FailureTTL dictates the duration after which failed workspaces will be
// stopped automatically.
FailureTTL time.Duration `json:"failure_ttl"`
@@ -149,11 +149,11 @@ func (*agplTemplateScheduleStore) Get(ctx context.Context, db database.Store, te
UserAutostartEnabled: true,
UserAutostopEnabled: true,
DefaultTTL: time.Duration(tpl.DefaultTTL),
// Disregard the values in the database, since RestartRequirement,
// Disregard the values in the database, since AutostopRequirement,
// FailureTTL, TimeTilDormant, and TimeTilDormantAutoDelete are enterprise features.
UseRestartRequirement: false,
MaxTTL: 0,
RestartRequirement: TemplateRestartRequirement{
UseAutostopRequirement: false,
MaxTTL: 0,
AutostopRequirement: TemplateAutostopRequirement{
DaysOfWeek: 0,
Weeks: 0,
},
@@ -180,14 +180,14 @@ func (*agplTemplateScheduleStore) Set(ctx context.Context, db database.Store, tp
DefaultTTL: int64(opts.DefaultTTL),
// Don't allow changing these settings, but keep the value in the DB (to
// avoid clearing settings if the license has an issue).
MaxTTL: tpl.MaxTTL,
RestartRequirementDaysOfWeek: tpl.RestartRequirementDaysOfWeek,
RestartRequirementWeeks: tpl.RestartRequirementWeeks,
AllowUserAutostart: tpl.AllowUserAutostart,
AllowUserAutostop: tpl.AllowUserAutostop,
FailureTTL: tpl.FailureTTL,
TimeTilDormant: tpl.TimeTilDormant,
TimeTilDormantAutoDelete: tpl.TimeTilDormantAutoDelete,
MaxTTL: tpl.MaxTTL,
AutostopRequirementDaysOfWeek: tpl.AutostopRequirementDaysOfWeek,
AutostopRequirementWeeks: tpl.AutostopRequirementWeeks,
AllowUserAutostart: tpl.AllowUserAutostart,
AllowUserAutostop: tpl.AllowUserAutostop,
FailureTTL: tpl.FailureTTL,
TimeTilDormant: tpl.TimeTilDormant,
TimeTilDormantAutoDelete: tpl.TimeTilDormantAutoDelete,
})
if err != nil {
return xerrors.Errorf("update template schedule: %w", err)