mirror of
https://github.com/coder/coder.git
synced 2026-06-03 13:08:25 +00:00
211393a69c
## Description This PR updates the lifecycle executor to explicitly exclude prebuilt workspaces from being considered for lifecycle operations such as `autostart`, `autostop`, `dormancy`, `default TTL` and `failure TTL`. Prebuilt workspaces (i.e., those owned by the prebuild system user) are handled separately by the prebuild reconciliation loop. Including them in the lifecycle executor could lead to unintended behavior such as incorrect scheduling or state transitions. ## Changes * Updated the lifecycle executor query `GetWorkspacesEligibleForTransition` to exclude workspaces with `owner_id = 'c42fdf75-3097-471c-8c33-fb52454d81c0'` (prebuilds). * Added tests to verify prebuilt workspaces are not considered in: * Autostop * Autostart * Default TTL * Dormancy * Failure TTL Fixes: https://github.com/coder/coder/issues/18740 Related to: https://github.com/coder/coder/issues/18658
53 lines
2.0 KiB
Go
53 lines
2.0 KiB
Go
package schedule
|
|
|
|
import (
|
|
"time"
|
|
|
|
"golang.org/x/xerrors"
|
|
|
|
"github.com/coder/coder/v2/coderd/schedule/cron"
|
|
)
|
|
|
|
var ErrNoAllowedAutostart = xerrors.New("no allowed autostart")
|
|
|
|
// NextAutostart takes the workspace and template schedule and returns the next autostart schedule
|
|
// after "at". The boolean returned is if the autostart should be allowed to start based on the template
|
|
// schedule.
|
|
func NextAutostart(at time.Time, wsSchedule string, templateSchedule TemplateScheduleOptions) (time.Time, bool) {
|
|
sched, err := cron.Weekly(wsSchedule)
|
|
if err != nil {
|
|
return time.Time{}, false
|
|
}
|
|
|
|
// Round down to the nearest minute, as this is the finest granularity cron supports.
|
|
// Truncate is probably not necessary here, but doing it anyway to be sure.
|
|
nextTransition := sched.Next(at).Truncate(time.Minute)
|
|
|
|
// The nextTransition is when the auto start should kick off. If it lands on a
|
|
// forbidden day, do not allow the auto start. We use the time location of the
|
|
// schedule to determine the weekday. So if "Saturday" is disallowed, the
|
|
// definition of "Saturday" depends on the location of the schedule.
|
|
zonedTransition := nextTransition.In(sched.Location())
|
|
allowed := templateSchedule.AutostartRequirement.DaysMap()[zonedTransition.Weekday()]
|
|
|
|
return zonedTransition, allowed
|
|
}
|
|
|
|
// NextAllowedAutostart returns the next valid autostart time after 'at', based on the workspace's
|
|
// cron schedule and the template's allowed days. It searches up to 7 days ahead to find a match.
|
|
func NextAllowedAutostart(at time.Time, wsSchedule string, templateSchedule TemplateScheduleOptions) (time.Time, error) {
|
|
next := at
|
|
|
|
// Our cron schedules work on a weekly basis, so to ensure we've exhausted all
|
|
// possible autostart times we need to check up to 7 days worth of autostarts.
|
|
for next.Sub(at) < 7*24*time.Hour {
|
|
var valid bool
|
|
next, valid = NextAutostart(next, wsSchedule, templateSchedule)
|
|
if valid {
|
|
return next, nil
|
|
}
|
|
}
|
|
|
|
return time.Time{}, ErrNoAllowedAutostart
|
|
}
|