# Bookstore — Part 08 ch.02 "Backup and disaster recovery": a Velero Schedule
# that takes the SAME consistent, PV-inclusive `bookstore` backup as
# velero-backup.yaml on a recurring cron — this is the actual production
# posture (a one-off Backup is for ad-hoc drills; a Schedule gives you an RPO).
#
# !!! CRD-BACKED — intrinsic dry-run behavior (the SAME documented behavior as
#     velero-backup.yaml / 18- / 51- / 70- / 80- / 83- / argocd/) !!!
#   `Schedule` is a CRD (velero.io/v1) installed by Velero. On a cluster
#   WITHOUT Velero installed:
#       kubectl apply --dry-run=client -f examples/bookstore/operators/velero-schedule.yaml
#       error: resource mapping not found ... no matches for kind "Schedule"
#       in version "velero.io/v1"
#     EXPECTED, not a defect — identical precedent to every CRD object in this
#     guide. Schema verified by reading + the official Velero API reference.
#     `Schedule.spec.template` is exactly a `Backup` spec; it is kept
#     byte-aligned with velero-backup.yaml's spec so the scheduled backup is
#     identical to the on-demand one (only the recurrence is added here).
#
# The cron-derived backup names are `bookstore-daily-<YYYYMMDDhhmmss>`; restore
# with `velero restore create --from-backup bookstore-daily-<TS>` (ch.02 DR
# runbook). RPO ≈ the schedule interval; RTO ≈ restore + app readiness time.
#
# Requires / Apply: same as velero-backup.yaml (Velero installed into its own
#   `velero` namespace + a BackupStorageLocation + the Bookstore deployed):
#   kubectl apply -f examples/bookstore/operators/velero-schedule.yaml
#   velero schedule describe bookstore-daily
#   velero backup get                       # the Schedule-created backups
apiVersion: velero.io/v1
kind: Schedule
metadata:
  name: bookstore-daily
  namespace: velero                 # Velero's own namespace (NOT bookstore)
  labels:
    app.kubernetes.io/part-of: bookstore
spec:
  # Daily at 02:00. Tighten for a smaller RPO (e.g. "0 */6 * * *" = every 6h).
  schedule: "0 2 * * *"
  # Skip a run if the previous one is still going (no overlapping backups).
  skipImmediately: false
  # `template` IS a Backup spec — kept identical to velero-backup.yaml so the
  # scheduled backup and the ad-hoc one are the same backup, just recurring.
  template:
    includedNamespaces:
      - bookstore
    snapshotVolumes: true
    defaultVolumesToFsBackup: false
    ttl: 168h0m0s                   # keep 7 days of daily backups, then GC
    storageLocation: default
    hooks:
      resources:
        - name: postgres-consistency
          includedNamespaces:
            - bookstore
          labelSelector:
            matchLabels:
              app: postgres
          pre:
            - exec:
                container: postgres
                command:
                  - /bin/sh
                  - -c
                  - >
                    PGPASSWORD="$POSTGRES_PASSWORD" psql -U "$POSTGRES_USER"
                    -d "$POSTGRES_DB" -c 'CHECKPOINT;'
                onError: Fail
                timeout: 2m0s
