Documentation
¶
Overview ¶
Package backup runs an app owner's backups (ADR-0222, F111): the BackupSchedule reconciler takes each cron slot and keeps the schedule's status and RPO alert, the Backup reconciler runs one copy with the platform's rights and deletes the record at its expireTime, and the Restore reconciler loads a Backup's members into empty stores or in place. RBAC at admission is the whole boundary (Decision 10).
Index ¶
Constants ¶
const ( ReasonMemberNotFound = "MemberNotFound" ReasonScheduleNotFound = "ScheduleNotFound" ReasonTargetUnconditional = "TargetUnconditional" ReasonCatalogUnstable = "CatalogUnstable" ReasonInterrupted = "Interrupted" ReasonNotEmpty = "NotEmpty" ReasonIntegrity = "Integrity" ReasonExportFailed = "ExportFailed" ReasonSameProvider = "SameProvider" // ReasonEngineNotReady is a run that needs a database whose engine is not Ready (ADR-0234). ReasonEngineNotReady = "EngineNotReady" // ReasonNamespaceHeld is an in-place Restore whose namespace already carries a restore marker. ReasonNamespaceHeld = "NamespaceHeld" )
The reasons a record's Ready condition names (Decisions 3 to 7).
Variables ¶
This section is empty.
Functions ¶
func RPORisk ¶
func RPORisk(t *cron.Timetable, paused bool, since, now time.Time, phase func(slot time.Time) (v1.RunPhase, bool)) bool
RPORisk is Decision 9's rule: not paused, and the slot after since (the newest Succeeded Backup's start, else the schedule's creation) has passed with its Backup Failed or absent, or a second slot has passed. phase reads a slot's Backup.
Types ¶
type BackupReconciler ¶
type BackupReconciler struct {
// contains filtered or unexported fields
}
BackupReconciler is the controller.Reconciler for KindBackup (Decision 4).
func (*BackupReconciler) Reconcile ¶
func (r *BackupReconciler) Reconcile(ctx context.Context, req controller.Request) (controller.Result, error)
Reconcile drives a Backup Pending → Running → Succeeded | Failed, one attempt. A new Backup gets its expireTime (creation + its ttl or its schedule's); a Pending one waits while the platform is held, but for a Restore's export; a Running one this process does not run was interrupted (Interrupted); a finished one is deleted at its expireTime. The run itself, with the platform's rights, is a goroutine whose end writes the record.
type Deps ¶
type Deps struct {
Store store.Store
Secrets SecretReader
// Sources are what a Backup copies; KV loads and empties a KVStore; Purger empties a Bucket; SQL loads and empties
// a SQLDatabase (nil ⇒ a Restore of one fails).
Sources workload.Sources
KV KVLoader
Purger gc.BucketPurger
SQL SQLLoader
// Hold nil is a platform never held, whose in-place Restore holds nothing.
Hold Hold
// StoreURL is the blob store's URL, blob.target or the file:// URL of blob.dir: a schedule on its provider is
// Ready with reason SameProvider (Decision 6). "" compares with nothing.
StoreURL string
// Period re-checks a schedule at the latest after it, the namespace hold's release enqueuing nothing, and paces a
// Backup waiting on the platform hold; 0 ⇒ controller.SupervisionPeriod.
Period time.Duration
Clock clock.Clock
Meter metric.Meter
Logger *slog.Logger
}
Deps are the reconcilers' dependencies; Store and Secrets are required.
type Hold ¶
type Hold interface {
hold.Gate
hold.NamespaceGate
HoldNamespace(ns v1.NamespaceName, m hold.Marker) error
ReleaseNamespaceMarker(ns v1.NamespaceName, m hold.Marker) error
}
Hold is the daemon's hold (ADR-0206): the platform gate the runs wait on, the namespace gate the slots ask, and the namespace hold an in-place Restore takes.
type KVLoader ¶
type KVLoader interface {
LoadPrefix(ctx context.Context, prefix string, next func() (snapshot.Record, error)) error
DropPrefix(prefix string) error
List(ctx context.Context, prefix string) ([]string, error)
}
KVLoader is the KV driver's per-store load, teardown and listing (ADR-0222 LoadPrefix, ADR-0072 DropPrefix).
type Reconcilers ¶
type Reconcilers struct {
Schedules *ScheduleReconciler
Backups *BackupReconciler
Restores *RestoreReconciler
}
Reconcilers are the three kinds' reconcilers, sharing one base.
func New ¶
func New(d Deps) (*Reconcilers, error)
New builds the reconcilers and registers the metrics: funcd.backup.runs and .duration_ms with stream=workload, and the gauge funcd.backup.workload_rpo_risk, the schedules at risk.
func (*Reconcilers) Wait ¶
func (r *Reconcilers) Wait()
Wait blocks until every run this process started has ended; funcd's shutdown calls it after the controller stops.
type RestoreReconciler ¶
type RestoreReconciler struct {
// contains filtered or unexported fields
}
RestoreReconciler is the controller.Reconciler for KindRestore (Decision 7).
func (*RestoreReconciler) MapBackup ¶
func (r *RestoreReconciler) MapBackup(ctx context.Context, obj v1.Object) []controller.Request
MapBackup maps a Backup to the Restores that read it or wait for it as their export.
func (*RestoreReconciler) Reconcile ¶
func (r *RestoreReconciler) Reconcile(ctx context.Context, req controller.Request) (controller.Result, error)
Reconcile drives a Restore Pending → Running → Succeeded | Failed. It waits for its Backup to succeed; an in-place Restore first runs Backup <restore>-before of the Backup's schedule and waits for it (gone ⇒ ScheduleNotFound, failed ⇒ ExportFailed, nothing written). The load is a goroutine; a Running Restore this process does not run was interrupted. Restores run while the platform is held.
type SQLLoader ¶ added in v0.13.0
type SQLLoader interface {
Load(ctx context.Context, ns v1.NamespaceName, name v1.ObjectName, file io.Reader) error
Empty(ctx context.Context, ns v1.NamespaceName, name v1.ObjectName) error
HasTables(ctx context.Context, ns v1.NamespaceName, name v1.ObjectName) (bool, error)
}
SQLLoader loads, empties and inspects a database through its engine (ADR-0234). HasTables counts tables, views, indexes and triggers.
type ScheduleReconciler ¶
type ScheduleReconciler struct {
// contains filtered or unexported fields
}
ScheduleReconciler is the controller.Reconciler for KindBackupSchedule (Decisions 3, 9).
func (*ScheduleReconciler) MapBackup ¶
func (r *ScheduleReconciler) MapBackup(_ context.Context, obj v1.Object) []controller.Request
MapBackup maps a Backup to its schedule, whose status follows its Backups.
func (*ScheduleReconciler) Reconcile ¶
func (r *ScheduleReconciler) Reconcile(ctx context.Context, req controller.Request) (controller.Result, error)
Reconcile takes the newest due slot S of a schedule (Decision 3) and writes its status (Decision 9). S is skipped, lastScheduleTime kept, while the schedule is paused or its namespace held, so the missed slots collapse into one catch-up; while one of its Backups is Pending or Running, S creates none and is taken, so no run overlaps another. Else S creates Backup <schedule>-<S in Unix minutes>, a Conflict counting as done, and lastScheduleTime becomes S. A deleted schedule leaves its Backups (they outlive it).