Repository navigation
fix(backupstrategy-controller): run backup clients on a package-owned image - #4756
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
📝 Walkthrough
Merge Risk: ⚪ Minimal · up to The image and build flow match both backup strategies. Supported release paths stamp the image before use, and no material merge-blocking risk remains. Security Architecture Review
Pre-merge checks |
|
IvanHunters
left a comment
There was a problem hiding this comment.
LGTM.
This swaps the ClickHouse/Altinity and RabbitMQ backup strategy Pods off the reused 349 MB platform-migrations image and onto a dedicated backup-http-client (alpine + curl + jq + ca-certificates, non-root 65532, ~7 MB) built by the package's own Makefile. It also removes the cross-package stamp in platform/Makefile that had left one key with no producer, frozen at v1.4.0-rc.2 (#3420). The design is clean: a single yq writes both keys to one digest, the target chains after image-redis-backup so the three yq -i writers never race under make -j, and both strategies render against the new ref with the command: override intact and no platform-migrations reference left in the rendered output.
Verified against a merge of current origin/main: helm unittest 23/23, image-pin-consistency and build-matrix bats green, both strategies render backup-http-client:v1.6.0 with zero platform-migrations refs, and the ClickHouse and RabbitMQ chainsaw suites each drive a real BackupJob and RestoreJob round-trip, so the new image is exercised in the E2E lane once the suite runs. A throwaway probe of the pinned alpine digest confirmed curl 8.22 with --aws-sigv4, jq 1.8.2, a writable /tmp, and pipefail under busybox ash, so the uid 65532 switch and the S3 transport both hold; the scripts write only to /tmp (RabbitMQ) or nothing (Altinity).
CI
The red Unit & controller tests on this head is not from this PR. Its three failures are internal/fluxcontract/snapshot_shape_test.go, the negated-assert audit flagging find's ! in select-e2e_test.bats:34, and the flux-install workflow contract. All three are main's own contracts broken by adjacent merges, already fixed on main by #4751 and three follow-up commits that landed after this branch's base. Merging current origin/main into this head makes all three pass (ran them locally: go test ok, both bats audits OK). A rebase clears the check. E2E (in-tree) was skipped only because it gates on that stale unit job.
Findings (all non-blocking, posted inline)
- MINOR
values.yaml:12: both keys committed as a bare tag that was never released and thatmake imagewill not reproduce; contradicts the invariant this PR edits inimage-refs.md. - NIT
values.yaml:41: comment reflow left one 135-column line in an otherwise ~84-column block. - NIT
backup-http-client/Dockerfile:2: comment says both scripts parse JSON with jq, but the RabbitMQ script uses curl only.
Checked and correct
- Bare-tag introduction is consistent with
redis-backupand tolerated by the enumeration/promote suites (promote-rewrite-tags17/0). - No orphaned
platform-migrationsconsumer:platform/Makefilestill stamps.migrations.image, the only remaining reference. - The dropped
platform-migrations is pinned identicallybats test loses no real coverage: exact tag-string equality is now guaranteed by oneyqwriting both keys, and the general duplicate-digest check still holds. - The previous image ran as root (no
USERinplatform-migrations), so the uid change is a hardening, not a regression; nothing in either script depends on root.
| # release promotion (hack/image-pin-consistency.bats). They are separate keys | ||
| # so either strategy can move to its own image later. | ||
| # DO NOT hand-edit: `make image` stamps both. | ||
| chBackupClientImage: "ghcr.io/cozystack/cozystack/backup-http-client:v1.6.0" |
There was a problem hiding this comment.
[MINOR] both keys committed as a bare tag that was never released and that make image will not reproduce
Both keys are committed as the bare tag backup-http-client:v1.6.0 with no digest. Unlike backupstrategy-controller:v1.6.0@sha256:... two lines up, this tag was never released (v1.6.0 predates the image) and make image in this tree stamps the dev version derived from git describe (v1.7.0-alpha.3-...), so the committed ref is unpullable as written. Release preparation and PR CI both stamp the real tag+digest before anything consumes the ref (overlay-main-images.sh classifies the *Image: keys as refs since #4257), and redis-backup:v1.6.0 was introduced the same way, so this is not a release or install defect. It does, though, contradict the invariant this same PR edits in docs/agents/image-refs.md ("A bare tag with no digest ... must not be committed"), and a dev applying the raw tree with helm template | kubectl apply (no build first) gets ImagePullBackOff on both the Altinity and RabbitMQ strategy Pods, where the previous platform-migrations pin resolved. Either note the "first commit of a new image" exception in that doc, or publish the image first and pin the digest.
| # The Kafka metadata strategy carries no client image here: unlike the Altinity | ||
| # and RabbitMQ drivers (curl-only, so a shared platform-migrations image works), | ||
| # its driver runs the Kafka Admin-API CLI (kafka-topics / kafka-configs), which | ||
| # and RabbitMQ drivers, which need only curl and jq, its driver runs the Kafka Admin-API CLI (kafka-topics / kafka-configs), which |
There was a problem hiding this comment.
[NIT] comment reflow left one 135-column line in an otherwise ~84-column block
The Kafka comment reflow left this line at 135 columns while the rest of the block wraps at ~84. Cosmetic, but it is the only line in the file that breaks the wrap.
| @@ -0,0 +1,9 @@ | |||
| # backup-http-client runs the Altinity (ClickHouse) and RabbitMQ strategy Pods: | |||
| # both scripts only drive an HTTP API and S3 with curl, parse JSON with jq, and | |||
There was a problem hiding this comment.
[NIT] comment says both scripts parse JSON with jq, but the RabbitMQ script uses curl only
"both scripts ... parse JSON with jq" holds only for the Altinity script; the RabbitMQ script (templates/strategy-rabbitmq-default.yaml) uses curl only, with no jq call (5 jq invocations in the Altinity script, 0 in the RabbitMQ one). Harmless, since jq is installed regardless, but the comment overstates what the RabbitMQ Pod needs.
41969a8 to
8f6b7e8
Compare
Aleksei Sviridkin (lexfrei)
left a comment
There was a problem hiding this comment.
Andrey Kolkov (@androndo) NOT LGTM, but only because of the commit history. The image change itself is correct.
The second commit fixes comments that the first commit added: the Dockerfile header (only the Altinity script uses jq) and a rewrap in values.yaml. Its last paragraph walks through that diff, and with merge commits it lands in main as written. Please fold those two edits into d6b945a, so 8f6b7e8 keeps only the image-refs.md change and its first paragraph.
While there: the Kafka comment in values.yaml still says the Altinity and RabbitMQ drivers "need only curl and jq". The RabbitMQ script does not use jq, as the new Dockerfile header says.
What I checked on a trial merge with current main: helm unittest for the package, hack/image-pin-consistency.bats, hack/build-matrix_test.bats and hack/promote-rewrite-tags_test.bats pass. Both scripts already ran under busybox sh, and the date -u +FORMAT and seq calls work with busybox. The bare-tag keys are picked up by the *Image: branch in hack/overlay-main-images.sh.
The red E2E Tests is not caused by the code. clickhouse-2-backup-roundtrip failed on ImagePullBackOff: the e2e registry answers 403 Forbidden for the new backup-http-client repository. A new repository there is created private on first push, so a maintainer has to make it public before a rerun can pass. I still get the same 403 today with an anonymous pull token, while an existing repository in the same namespace accepts the same token.
… 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 <[email protected]>
docs/agents/image-refs.md forbade committing a bare tag without saying how a new image's first pin can carry a digest it does not have yet. Record the exception the backup client keys rely on: the bare tag is a placeholder the producing `make image` replaces, and an unbuilt tree pulls a tag that does not exist. Drop the securitygroup-controller example, which is pinned by digest now. Assisted-by: LLM Signed-off-by: Andrey Kolkov <[email protected]>
8f6b7e8 to
770f515
Compare
Aleksei Sviridkin (lexfrei)
left a comment
There was a problem hiding this comment.
Andrey Kolkov (@androndo) LGTM. The history and the Kafka comment are fixed. What still blocks E2E is on the maintainer side.
On a trial merge with current main (95c2d85), helm unittest for the package passes, and so do hack/image-pin-consistency.bats and hack/build-matrix_test.bats. Both keys are in packages/system/backupstrategy-controller/values.yaml, which the values.yaml glob in hack/lib/image-refs.sh covers.
The e2e registry still refuses an anonymous pull of backup-http-client. The anonymous token request is denied with "Anonymous users are only allowed read access on public repos", and the manifest fetch for this head's tag returns 403. redis-backup in the same namespace lists its tags with an anonymous token. A maintainer has to make the new repository public before the backup round-trip e2e can pass; nothing in the PR needs to change for that.
What this PR does
The Altinity (ClickHouse) and RabbitMQ backup strategy Pods ran
platform-migrations: a 349 MB image carryingkubectl,helm,git,cozyhrandetcd-migrate, whoseENTRYPOINTisrun-migrations.sh. Both pins were stamped frompackages/core/platform/Makefile, so any migration change re-digested the backup clients too, and only thecommand:override kept the Pods from running platform migrations (#3420).packages/system/backupstrategy-controller/images/backup-http-client/:alpine:3.24(digest-pinned, the same base the tree already uses) +curl+jq+ca-certificates,USER 65532:65532, noENTRYPOINT. Everything is installed at build time, so the Pods still never runapk addand keep working air-gapped.image-backup-http-clienttarget in the package's ownMakefile, chained afterimage-redis-backuplike the existing ones so only oneyq -iwritesvalues.yamlat a time. It stampschBackupClientImageandrabbitmqBackupClientImagewith the same ref.packages/core/platform/Makefile, the WORKAROUND/TODO comments in the chart and the RabbitMQ example, and the stale "live violation" line indocs/agents/image-refs.md.hack/image-pin-consistency.bats: dropped theplatform-migrations-specific test, whose subject no longer exists. The general check (no repository pinned at more than one digest, computed fromhack/promote-retag.sh --dry-run) still covers the two keys sharing one image.Why one image for both strategies rather than
ch-backup-clientas the issue named it. The RabbitMQ strategy had the same reuse and the same cross-package stamp; leaving it would have kept the stamp alive. Its script needscurl --aws-sigv4+ca-certificates, a subset of the ClickHouse one, so one image serves both. The two values keys stay separate so either strategy can move to its own image later.Initial pin. The image does not exist in ghcr until CI builds it, so both keys are committed as
backup-http-client:v1.6.0without a digest, the same wayredis-backupwas introduced. PR CI rebuilds touched packages and overlays the fresh refs for e2e; release preparation'smake imagestamps tag+digest.Image size: 6.9 MB vs 349 MB. Verified locally:
docker buildx buildforlinux/amd64,linux/arm64; in the image as uid 65532: curl 8.22 with--aws-sigv4, jq 1.8.2,date,seq, writes to/tmp(the RabbitMQ script's only write), TLS verification against the bundled CA store.helm unittest(23/23),helm templaterenders both strategies withbackup-http-clientand noplatform-migrationsreference.hack/cozytest.sh hack/image-pin-consistency.batsandhack/build-matrix_test.batspass.Not yet run end to end on a cluster; the e2e backup round-trips will exercise it.
Fixes #3420
Screenshots
N/A — no UI changes.
Downstream repositories
Walked the trigger map against the diff: it touches
packages/system/backupstrategy-controller(new image, Makefile target, values comments/pins, template comments),packages/core/platform/Makefile(stamp removal only, novalues.yamlkey change),hack/image-pin-consistency.bats,docs/agents/image-refs.mdand a comment inexamples/backups/rabbitmq. No app package, schema, CRD, variant, asset, platform values key orhack/package.mkchange. The website does not list first-party image repositories (searched forplatform-migrationsandredis-backup), so no mirror list needs the new one.Release note
Summary by CodeRabbit