Files
Andrey Kolkov 647407545d fix(backupstrategy-controller): run backup clients on a package-owned image
The Altinity and RabbitMQ strategy Pods ran platform-migrations, a 349 MB
image carrying kubectl, helm and etcd-migrate whose ENTRYPOINT is the
migration runner, and whose pins were stamped from packages/core/platform
so every migration change moved the backup clients too.

Build images/backup-http-client (alpine + curl + jq + ca-certificates,
non-root) from this package's Makefile and stamp both client keys from
it. The cross-package stamp in packages/core/platform/Makefile and the
platform-migrations-specific check in hack/image-pin-consistency.bats go
away; the general one-digest-per-repository check still covers the two
keys sharing one image.

Fixes #3420

Assisted-by: LLM
Signed-off-by: Andrey Kolkov <androndo@gmail.com>
2026-10-12 09:54:52 +04:00
..

RabbitMQ backup/restore demo

This demo backs up and restores a Cozystack-managed RabbitMQ instance, proving data integrity by round-tripping a sentinel definition through object storage. It provisions its own Bucket, Rabbitmq strategy and BackupClass so the round-trip is self-contained; the platform ships an equivalent cozy-default-rabbitmq strategy that writes to the shared cozy-backups system bucket, which you can route to from your own BackupClass instead.

What is backed up

RabbitMQ's cluster operator ships no backup CRD, and RabbitMQ has no consistent online export of message payloads. This strategy therefore backs up broker definitions — vhosts, users, permissions, queues, exchanges, bindings, policies and parameters — via the management HTTP API (GET /api/definitions), and restores them with POST /api/definitions. Message payloads are out of scope, and there is no point-in-time recovery: a full-data backup would be a Velero volume snapshot, which is a different strategy.

Definitions import is additive: an in-place restore re-creates dropped definitions but does not delete objects that exist live but not in the backup.

Prerequisites

The backupstrategy-controller and the backup CRDs must be installed (the platform default backups stack). run-all.sh provisions its own Bucket, reads the S3 coordinates from its BucketInfo, projects them into a rabbitmq-backup-creds Secret, copies the endpoint's CA into rabbitmq-backup-ca, and reuses the container image the shipped cozy-default-rabbitmq strategy runs — so that strategy must be present, but this demo does not write to the system bucket.

To-copy restore imports the source's definitions into a separate broker via POST /api/definitions, which merges the source's users, permissions and vhosts into the target. It does not clobber the target's own operator-generated default user, because the cluster-operator gives each RabbitmqCluster a distinct random default username. It does, however, import the source's users (with their password hashes), so after a to-copy restore those source credentials are valid logins on the target — grant access accordingly.

Each backup is stored under a per-run key (<namespace>/<application>/<backup-name>/definitions.json), so distinct backups of one application do not overwrite each other and a restore reads the exact object its Backup recorded.

Flow

  • 00-helpers.sh — shared bash helpers (waiters, sentinel seed/check via rabbitmqctl).
  • 00-bucket.yaml — the demo Bucket backing the round-trip.
  • 03-rabbitmq-strategy.yaml — the Rabbitmq strategy (S3 coordinates filled from the Bucket by run-all.sh).
  • 04-backupclass.yaml — the rabbitmq-default BackupClass mapping RabbitMQ to that strategy.
  • 05-rabbitmq-src.yaml — the source application (no backup: block; the strategy carries the S3 coordinates).
  • 10-backupjob-adhoc.yaml — an ad-hoc BackupJob routed to rabbitmq-default.
  • 15-plan.yaml — a cron Plan for scheduled backups.
  • 20-rabbitmq-target.yaml — a separate application for restore-to-copy.
  • 25-restorejob-in-place.yaml / 30-restorejob-to-copy.yaml — the two restore flows.

Run the whole round-trip:

./run-all.sh          # backup, drop the sentinel, restore in place, then restore to a copy
./cleanup.sh          # remove this demo's objects (idempotent)

SKIP_RESTORE=1 ./run-all.sh stops after a successful backup (backup-only smoke). Override NAMESPACE (default tenant-root) to run elsewhere. BucketInfo advertises the external S3 ingress endpoint, which in-cluster Pods cannot always reach or TLS-validate; set S3_ENDPOINT=https://seaweedfs-s3.<ns>.svc:8333 to target the in-cluster SeaweedFS instead — the .svc FQDN is the name the SeaweedFS serving cert's SAN covers, so curl can verify TLS against the copied CA (the e2e harness does this).