The backup examples and e2e suites no longer set passwords. They read the generated ones from <release>-credentials with jq, since a username may contain a dot that jsonpath treats as a path step, and log in as an application user after each restore, so a restore that leaves the credentials unusable fails the run. The MariaDB run also checks that an account created out of band on the source is absent from the copy. The unreachable-target restore step asserts a terminal Failed attributed to the recovery window, since the reason itself is best effort. Signed-off-by: Alexey Artamonov <aleksei.artamonov@aenix.io>
4.1 KiB
PostgreSQL backup & restore (barman-cloud plugin)
End-to-end demo of backing up a cozystack Postgres application to S3 and restoring it, using the CloudNativePG barman-cloud plugin (the native spec.backup.barmanObjectStore path is deprecated in CNPG 1.27 and removed in 1.29). Backups flow through the platform BackupClass + CNPG strategy so one strategy CR serves every Postgres instance in the tenant.
What it provisions
The numbered manifests are the documented flow; a human can read and apply them by hand, and run-all.sh drives the same files for a smoke test.
00-bucket.yaml— a cozystack-managed S3Bucketfor the backups, with abackupuser.05-postgres-src.yaml— the sourcePostgres, withbackup.enabled: truesoarchive_commandstreams WALs from helm-install onwards.10-cnpg-strategy.yaml— theCNPGstrategy templated against the live application.15-backupclass.yaml— mapsKind=Postgresto that strategy.20-plan.yaml— an optional cronPlanfor recurring backups.25-backupjob-adhoc.yaml— an ad-hocBackupJob.30-postgres-target.yaml+40-restorejob-to-copy.yaml— restore into a fresh copy, leaving the source running.35-restorejob-in-place.yaml— the destructive in-place restore variant.45-restorejob-pitr.yaml— point-in-time recovery: restore into the copy as of a specificspec.options.recoveryTime(RFC3339).
Placeholders and derived Secrets
05-postgres-src.yaml and 10-cnpg-strategy.yaml carry REPLACE_WITH_COSI_BUCKET_NAME and REPLACE_WITH_S3_ENDPOINT (the demo app user's password is chart-generated, not substituted). They also reference two Secrets, <app>-cnpg-backup-creds (the S3 credentials the barman-cloud sidecar reads) and <app>-cnpg-backup-ca (the CA it trusts for a self-signed endpoint). The strategy template renders those names against whichever application it drives, so the restore target needs its own pair too — a restore against pg-target looks up pg-target-cnpg-backup-*. run-all.sh resolves the placeholders from the provisioned Bucket's BucketInfo Secret and materialises the pair for both the source and the target; editing by hand, you copy the coordinates from kubectl -n <ns> get secret bucket-<name>-backup -o jsonpath='{.data.BucketInfo}' and the CA from the seaweedfs CA secret in tenant-root (seaweedfs-ca-cert by default; run-all.sh auto-discovers it from the cert-manager Certificate if the name differs).
Drop the endpointCA block from 05/10 (and set S3_CA_SECRET="" for run-all.sh) when the S3 endpoint is signed by a publicly-trusted CA.
Run it
# Defaults to NAMESPACE=tenant-root; override for a tenant namespace.
NAMESPACE=tenant-root examples/backups/postgres/run-all.sh
# Tear everything down afterwards (idempotent).
NAMESPACE=tenant-root examples/backups/postgres/cleanup.sh
run-all.sh writes a sentinel row into the source, waits for the BackupJob to reach Succeeded, restores to a copy, and asserts the sentinel round-tripped through S3 into the restored copy. It then runs a point-in-time recovery: it writes a before marker, captures the server timestamp, writes an after marker, and restores the copy to that timestamp (45-restorejob-pitr.yaml), asserting the before row survived and the after row did not. Finally it submits a RestoreJob with a recoveryTime an hour in the future and asserts it fails fast with status.phase: Failed and reason RecoveryTargetUnreachable (rather than hanging to the restore deadline). Set SKIP_RESTORE=1 to stop after a successful backup, or SKIP_PITR=1 to stop after the latest-point restore.
Automated e2e
The Chainsaw suite at hack/e2e-chainsaw/postgres/ drives this same run-all.sh as a second test (postgres-2-backup-roundtrip), selected by CI whenever the postgres app (or these scripts) change and on every release cut. It runs in tenant-root against the in-cluster seaweedfs endpoint — the isolated e2e tenant cannot reach it across the Cilium egress policy, and the external ingress endpoint is an unroutable placeholder in the sandbox.