Schedule Exceptions¶
This guide covers creating and managing temporary schedule overrides using ScheduleException resources.
Extending Hibernation for a Weekday Holiday¶
If your base schedule already covers weekday nights (e.g., start: "20:00", end: "06:00", daysOfWeek: ["MON", "TUE", "WED", "THU", "FRI"]), weekends are already fully hibernated — wakeup only triggers on listed days. So there's no need to extend for weekends.
A practical use of extend is covering a weekday holiday. Suppose Wednesday is a public holiday and there's no reason to wake up resources in the morning. The base schedule would wake resources at 06:00 on Wednesday, but you want them to stay hibernated all day. Add an extend exception to cover the daytime gap:
apiVersion: hibernator.ardikabs.com/v1alpha1
kind: ScheduleException
metadata:
name: wednesday-holiday
namespace: hibernator-system
spec:
planRef:
name: dev-plan
type: extend
validFrom: "2026-02-11T00:00:00Z"
validUntil: "2026-02-11T23:59:59Z"
windows:
- start: "06:00"
end: "20:00"
daysOfWeek: ["WED"]
This fills the 06:00–20:00 gap on Wednesday, creating continuous hibernation from Tuesday 20:00 through Wednesday 20:00 (when the normal nightly cycle begins again). The base schedule handles the rest — no need to modify it.
Suspending Hibernation for Cross-Timezone Work¶
When a team in a different timezone needs resources to stay alive beyond the normal hibernation start time, use a suspend exception to hold off hibernation.
Scenario: Your base schedule hibernates weekday resources in Asia/Jakarta from 20:00 to 06:00. A team in Japan (UTC+9, 2 hours ahead) needs to debug an issue on Wednesday evening and expects resources to stay up past the Jakarta 20:00 cutoff until end of day:
apiVersion: hibernator.ardikabs.com/v1alpha1
kind: ScheduleException
metadata:
name: japan-team-debug
namespace: hibernator-system
spec:
planRef:
name: dev-plan
type: suspend
validFrom: "2026-02-11T00:00:00Z"
validUntil: "2026-02-11T23:59:59Z"
leadTime: "1h"
windows:
- start: "20:00"
end: "23:59"
daysOfWeek: ["WED"]
The leadTime: "1h" prevents the controller from starting a new hibernate cycle within 1 hour before the suspension window begins (i.e., no hibernation from 19:00 onward on Wednesday). Resources stay awake until 23:59 on Wednesday instead of going down at 20:00.
Emergency Incident Override¶
To keep resources awake during an active incident that may span the full day:
apiVersion: hibernator.ardikabs.com/v1alpha1
kind: ScheduleException
metadata:
name: incident-override
namespace: hibernator-system
spec:
planRef:
name: prod-plan
type: suspend
validFrom: "2026-02-03T00:00:00Z"
validUntil: "2026-02-04T23:59:59Z"
windows:
- start: "00:00"
end: "23:59"
daysOfWeek: ["MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN"]
No leadTime — the suspension takes effect immediately.
Replacing the Schedule for Holidays¶
Replace the entire schedule during a holiday period:
apiVersion: hibernator.ardikabs.com/v1alpha1
kind: ScheduleException
metadata:
name: holiday-week
namespace: hibernator-system
spec:
planRef:
name: prod-plan
type: replace
validFrom: "2026-12-24T00:00:00Z"
validUntil: "2026-12-31T23:59:59Z"
windows:
- start: "00:00"
end: "23:59"
daysOfWeek: ["MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN"]
During the holiday week, the base schedule is ignored and replaced by the exception windows.
Monitoring Exceptions¶
Check Exception State¶
kubectl get scheduleexception -n hibernator-system
# NAME PLAN TYPE STATE VALIDFROM VALIDUNTIL AGE
# wednesday-holiday dev-plan extend Active 2026-02-11T00:00:00Z 2026-02-11T23:59:59Z 2d
# japan-team-debug dev-plan suspend Pending 2026-02-11T00:00:00Z 2026-02-11T23:59:59Z 1h
Check Plan Exception History¶
kubectl get hibernateplan dev-plan -n hibernator-system \
-o jsonpath='{.status.exceptionReferences}' | jq
Up to 10 exception references are tracked, ordered by active state first, then most recent.
Composing Exceptions¶
You can apply compatible exceptions to the same plan simultaneously. For example, an extend and suspend exception can coexist — the controller merges them using mergeByType semantics.
For detailed scenarios covering all type combinations (extend + suspend, replace + extend, replace + suspend) and validation rules, see Composing Multiple Exceptions.
Execution Overrides (Advanced)¶
extend and replace exceptions can also override the execution intent for a cycle: which targets run, their parameters, the execution strategy, and failure behavior. suspend exceptions support targetOverrides only (partial wakeup subset) — executionOverride remains forbidden on suspend. Anything not listed in an override follows the base plan spec as-is.
apiVersion: hibernator.ardikabs.com/v1alpha1
kind: ScheduleException
metadata:
name: maintenance-override
namespace: hibernator-system
spec:
planRef:
name: prod-plan
type: extend
validFrom: "2026-03-15T00:00:00Z"
validUntil: "2026-03-16T23:59:59Z"
windows:
- start: "00:00"
end: "23:59"
daysOfWeek: ["SUN"]
targetOverrides:
- targetName: database
disabled: true
- targetName: compute
parameters:
instanceIds:
- i-1234567890abcdef0
executionOverride:
strategy:
type: Sequential
behavior:
mode: BestEffort
In this example:
- The
databasetarget is skipped entirely for the cycle. - The
computetarget uses overridden parameters. - Targets run sequentially, and a single failure does not stop the cycle.
Weekend subset with suspend (e.g. wake 2 of 10 while hibernated, auto-revert on expiry):
apiVersion: hibernator.ardikabs.com/v1alpha1
kind: ScheduleException
metadata:
name: weekend-dev-subset
namespace: hibernator-system
spec:
planRef:
name: rds-fleet
type: suspend
validFrom: "2026-09-06T00:00:00Z"
validUntil: "2026-09-07T23:59:00Z"
windows:
- start: "00:00"
end: "23:59"
daysOfWeek: ["SAT", "SUN"]
targetOverrides:
- targetName: db-prod-01
disabled: true
- targetName: db-prod-02
disabled: true
# unlisted targets follow base plan as-is; disabled targets stay stopped
# (disable 8 of 10 to wake only the 2 dev instances for the weekend)
Only one exception with overrides per plan
extend, replace, and suspend share a single override slot: if one exception with targetOverrides/executionOverride is active for a plan, no second exception with overrides whose validity period overlaps it can be created — even an otherwise compatible extend + suspend pair. Plain exceptions without overrides can still coexist.
Disabling on DAG plans
Disabling any target — upstream or downstream — is allowed. A disabled target is treated as instantly succeeded, so dependents proceed normally.
Execution overrides are an advanced feature
Because execution overrides change the shape of a hibernation/wakeup cycle, they are best suited for operators who understand the target resources and failure modes. Misconfigured overrides can leave resources in an unexpected state.
Operational Semantics: Retry, Resume, and Restart¶
The controller locks the resolved execution intent when a cycle starts. This locked intent is preserved for the lifetime of the cycle, including transient errors and recovery:
| Operation | What happens to the exception intent |
|---|---|
| Automatic retry after a transient error | Keeps the locked intent. The same targets, strategy, and behavior are retried. |
Manual retry (retry-now annotation) |
Keeps the locked intent. |
| Resume from suspension mid-cycle | Keeps the locked intent. |
Restart (restart=true annotation) |
Keeps the locked intent by default. Add fresh=true to start a new cycle and re-evaluate from live state. |
Manual override (override-action=true) |
Keeps the locked intent by default. Add fresh=true to start a new cycle and re-evaluate from live state. |
This means you can safely delete or modify a ScheduleException while a cycle is running:
- An in-flight cycle (including one in
PhaseErrorwaiting for retry) continues with the intent it started with. - A new cycle, triggered by
restart/override-actionwithfresh=true, picks up the current plan and exception state.
If you need to abort the locked intent and start fresh, use restart=true together with fresh=true, or wait for the cycle to complete. For detailed command examples and the complete annotation reference, see the Override Actions guide.
Cleaning Up¶
Exceptions expire automatically based on validUntil. You can delete them early: