Skip to content

Guide: TimeBasedSpotSchedule provider

TimeBasedSpotSchedule is the default, first-party spot-schedule provider (ADR 0009). It is the reified former inline ScheduledMachine.spec.schedule: a declarative day-of-week / hour-of-day window in a configured timezone. It publishes a duck-typed status.active that a ScheduledMachine.spec.schedule consumes. A machine bound to it is up while the current time falls inside the window, down otherwise.

If you previously wrote an inline spec.schedule with daysOfWeek / hoursOfDay / timezone, that window now lives on a TimeBasedSpotSchedule object, and the ScheduledMachine references it by name.

How it works

The spot-schedule-time-based controller watches TimeBasedSpotSchedule objects and, for each, computes status.active from the spec window in the configured timezone, then requeues once at the next window boundary (the next open or close). It is event-driven — there is no polling interval, and it makes no network calls: the window lives entirely in spec, which operators keep current via GitOps.

Evaluation each tick:

  1. If spec.enabled is false, status.active is always false (the window is ignored — the provider's own toggle).
  2. Otherwise the instant must fall inside the window — a daysOfWeek and hoursOfDay match in spec.timezone.

Transition detection is hour-granular, so the requeue lands within an hour of the true boundary for whole-hour-offset timezones; the active value always self-corrects on the next reconcile.

Install

The TimeBasedSpotSchedule CRD ships under deploy/crds/. Install it and the provider controller:

kubectl apply -f deploy/crds/timebasedspotschedule.yaml
kubectl apply -k deploy/spot-schedule-providers/time-based/

The provider runs with a least-privilege ClusterRole: get;list;watch on timebasedspotschedules and update;patch on only their /status subresource — it never writes the spec (operators own the window) and reads nothing else.

Author a window

apiVersion: spotschedules.5spot.finos.org/v1alpha1
kind: TimeBasedSpotSchedule
metadata:
  name: business-hours
  namespace: default
spec:
  daysOfWeek: ["mon-fri"]
  hoursOfDay: ["9-17"]
  timezone: America/New_York
  enabled: true

Day format

  • Single day: mon, tue, wed, thu, fri, sat, sun
  • Range: mon-fri, sat-sun
  • Mixed: mon-wed,fri

Hour format

  • Single hour: 9, 14, 22
  • Range: 9-17 (inclusive of both start and end)
  • Mixed: 0-9,17-23

Then reference it from a machine (see examples/timebasedspotschedule.yaml and examples/scheduledmachine-basic.yaml):

spec:
  schedule:
    apiVersion: spotschedules.5spot.finos.org/v1alpha1
    kind: TimeBasedSpotSchedule
    name: business-hours   # same namespace as the ScheduledMachine

Observe

  • kubectl get timebasedspotschedule business-hours -o yaml (short name tbss) shows status.active, status.nextTransitionTime, and the Ready condition (reason WindowOpen / WindowClosed).
  • Metrics fivespot_time_based_active and fivespot_time_based_transitions_total — see monitoring.

See also