stringData with the tag in plaintext + marker. The Secret kind is kept deliberately — the controller reads it via secretKeyRef, so a ConfigMap would need a matching edit and diverge further from upstream. stringData is accepted identically by the API server.
ImageRepository + ImagePolicy for the sidecar, same filter and 0.x range as the controller, so the two cannot drift apart again. Only the controller was tracked before.
Tag aligned to v0.14.0.
Verified before pinning
Pinning a non-existent tag would put all seven Postgres clusters into ImagePullBackOff, so I confirmed the image is pullable first:
$ kubectl run sidecar-tag-check --image=...sidecar:v0.14.0 --command -- true
error during container init: exec: "true": executable file not found in $PATH
The pull succeeded — that failure is the container command, not the image.
Also verified in the render that the Secret name is unchanged (it carries a kustomize hash suffix from upstream secretGenerator but is static here), so the deployment secretKeyRef stays valid — the name still appears twice, on the Secret and its reference.
Expected impact
Changing the sidecar tag changes every Postgres pod spec, so all seven CNPG clusters roll. CNPG handles it as a normal rolling restart.
I will confirm backups still work afterwards — 113 Backup CRs exist today, newest ~3h old and completed.
Note for future re-imports
Upstream ships this Secret as base64 data with no marker, so a wholesale re-import silently reintroduces the skew. The manifest now says so inline, next to the block.
Not fixed here
This does notfix#522 — the empty lastSuccessfulBackup is a plugin feature gap (v0.6.0 added only the failed status field), not version skew. Bumping the sidecar will not enable backup-age alerting.
Fixes #535.
## The problem
An image reference is not a secret. Encoding it as base64 `data` had two concrete costs:
- **no reviewer sees a version change in a diff**
- **no `$imagepolicy` marker can attach to a base64 blob**
Result: a two-minor version skew in the component that performs every base backup and WAL archive for seven Postgres clusters.
```
controller plugin-barman-cloud:v0.14.0 <- auto-bumped by Flux
sidecar plugin-barman-cloud-sidecar:v0.12.0 <- invisible, never moved
```
Not stale pods — `ha-pg-1` was created hours ago during the recorder migration and still received v0.12.0.
Before:
```yaml
data:
SIDECAR_IMAGE: |
Z2hjci5pby9jbG91ZG5hdGl2ZS1wZy9wbHVnaW4tYmFybWFuLWNsb3VkLXNpZGVjYXI6dj
AuMTIuMA==
```
After:
```yaml
stringData:
SIDECAR_IMAGE: ghcr.io/cloudnative-pg/plugin-barman-cloud-sidecar:v0.14.0 # {"$imagepolicy": "flux-system:cnpg-barman-plugin-sidecar"}
```
## Three changes
1. **`stringData` with the tag in plaintext + marker.** The Secret *kind* is kept deliberately — the controller reads it via `secretKeyRef`, so a ConfigMap would need a matching edit and diverge further from upstream. `stringData` is accepted identically by the API server.
2. **ImageRepository + ImagePolicy for the sidecar**, same filter and `0.x` range as the controller, so the two cannot drift apart again. Only the controller was tracked before.
3. **Tag aligned to v0.14.0.**
## Verified before pinning
Pinning a non-existent tag would put **all seven Postgres clusters into ImagePullBackOff**, so I confirmed the image is pullable first:
```
$ kubectl run sidecar-tag-check --image=...sidecar:v0.14.0 --command -- true
error during container init: exec: "true": executable file not found in $PATH
```
The pull succeeded — that failure is the container *command*, not the image.
Also verified in the render that the Secret name is unchanged (it carries a kustomize hash suffix from upstream `secretGenerator` but is static here), so the deployment `secretKeyRef` stays valid — the name still appears twice, on the Secret and its reference.
## Expected impact
Changing the sidecar tag changes every Postgres pod spec, so **all seven CNPG clusters roll**. CNPG handles it as a normal rolling restart.
I will confirm backups still work afterwards — 113 Backup CRs exist today, newest ~3h old and `completed`.
## Note for future re-imports
Upstream ships this Secret as base64 `data` with no marker, so a wholesale re-import silently reintroduces the skew. The manifest now says so inline, next to the block.
## Not fixed here
This does **not** fix #522 — the empty `lastSuccessfulBackup` is a plugin feature gap (v0.6.0 added only the *failed* status field), not version skew. Bumping the sidecar will not enable backup-age alerting.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
An image reference is not a secret. Encoding it as base64 `data` had two real
costs: no reviewer sees a version change in a diff, and no $imagepolicy marker
can attach to a base64 blob.
The result was a two-minor version skew in the component that performs every
base backup and WAL archive for seven Postgres clusters (#535):
controller plugin-barman-cloud:v0.14.0 <- auto-bumped by Flux
sidecar plugin-barman-cloud-sidecar:v0.12.0 <- invisible, never moved
Not stale pods: ha-pg-1 was created hours ago during the recorder migration and
still received v0.12.0.
Three changes:
1. The Secret now uses stringData with the tag in plaintext, carrying an
$imagepolicy marker. The Secret KIND is kept because the controller reads it
via secretKeyRef; switching to a ConfigMap would need a matching edit to that
reference and diverge further from upstream. stringData is accepted
identically by the API server.
2. ImageRepository + ImagePolicy added for the sidecar image, with the same
filter and 0.x range as the controller, so the two cannot drift apart again.
Only the controller was tracked before.
3. Tag aligned to v0.14.0 to match the controller.
The Secret name carries a kustomize hash suffix from upstream's secretGenerator
but is static here, so editing the value does not change the name and the
deployment's secretKeyRef stays valid — verified in the render, which still shows
the name twice (Secret + reference).
Verified the tag EXISTS before pinning it: pulling
plugin-barman-cloud-sidecar:v0.14.0 succeeds (the pod fails later on a missing
`true` binary in that minimal image, which is the container command, not the
pull). Pinning a non-existent tag would have put all seven Postgres clusters into
ImagePullBackOff.
EXPECTED IMPACT: bumping the sidecar changes every Postgres pod spec, so all
seven CNPG clusters roll. CNPG handles this as a normal rolling restart. Backups
should be confirmed working afterwards — 113 Backup CRs exist today, newest ~3h
old and completed.
Note for future re-imports: upstream ships this Secret as base64 `data` with no
marker, so a wholesale re-import silently reintroduces the skew. The manifest now
says so inline.
Refs #535
Co-Authored-By: Claude Bot <noreply@anthropic.com>
🤖Automated review — model CLI default (complexity: complex), commit 154c933177234d59b58ed9b01cef125469545812.
Advisory review by the review-bot pipeline. It never approves; a human merges. Push new commits to get a fresh review.
Summary
This PR fixes a real, previously-invisible version-skew bug: the CNPG Barman
plugin sidecar image tag was base64-encoded inside a Secret's data, so Flux's
image-automation could never find it, and it silently trailed the controller by
two minor versions. The fix (a) switches the Secret to stringData with a
plaintext tag and $imagepolicy marker, (b) adds a matching ImageRepository
ImagePolicy pair to track the sidecar going forward, and (c) bumps the tag
to v0.14.0. I independently verified the mechanics below and found no
correctness or security issues — only a documentation gap.
🟡 Suggestions
kubernetes/infrastructure/image-automation/README.md — the "Re-import
hazard: cnpg-barman-plugin" section (lines 122–130) and the "Currently
enrolled" table row (line 56) still describe only the controller's marker
(plugin-barman-cloud on the image line) being at risk from a wholesale
upstream re-import. This PR adds a second marker in the same
upstream-imported file (the Secret's stringData.SIDECAR_IMAGE), which is
exactly as vulnerable to being clobbered by a re-import and isn't mentioned
there — even though the in-manifest comment added by this PR
(manifest.yaml:936-937) does call it out locally. A future maintainer who
goes to the README section specifically written for this hazard (rather than
reading the manifest's inline comments first) would only restore one of the
two markers. Worth a one-line addition to that section and the table.
Tests
No unit tests apply to this kind of change; the repo's relevant gate is the kustomize-build step in .woodpecker/ci-manifests-test.yml, which runs kubectl kustomize over every kustomization directory including both edited
ones (kubernetes/infrastructure/cnpg-barman-plugin and kubernetes/infrastructure/image-automation), catching YAML/wiring breakage.
I manually reviewed both files for structural correctness (see below) since I
could not execute kubectl/kustomize in this environment.
Verification performed against the checkout:
Decoded the removed base64 blob — it is exactly ghcr.io/cloudnative-pg/plugin-barman-cloud-sidecar:v0.12.0, confirming the
PR's stated before-state.
Confirmed the Secret name plugin-barman-cloud-kg5c2795f7
(manifest.yaml:943) is unchanged and is referenced via secretKeyRef.name/key: SIDECAR_IMAGE at manifest.yaml:996-1000, so the
Deployment's env var still resolves correctly under stringData.
Confirmed kubernetes/infrastructure/cnpg-barman-plugin/kustomization.yaml
has no secretGenerator/name-hash transformer, so the "name is static, not
regenerated" claim in the new comment holds.
Confirmed the controller image is already pinned to v0.14.0
(manifest.yaml:1001), so the sidecar bump to the same version does align
the two components as intended, and both now sit inside the shared 0.x
policy range.
Confirmed the new ImagePolicy name (cnpg-barman-plugin-sidecar in flux-system) matches the marker {"$imagepolicy": "flux-system:cnpg-barman-plugin-sidecar"}, and the filter
regex ^v(?P<ver>\d+\.\d+\.\d+)$ matches v0.14.0.
Confirmed cnpg-barman-plugin.yaml is already listed in image-automation/kustomization.yaml, so the two new resources (added as
extra YAML docs in an existing file) need no kustomization edit.
Recommendation
Looks reasonable — no blocking issues; the documentation-gap comment above is optional.
🤖 **Automated review** — model `CLI default` (complexity: complex), commit `154c933177234d59b58ed9b01cef125469545812`.
> Advisory review by the `review-bot` pipeline. It never approves; a human merges. Push new commits to get a fresh review.
---
## Summary
This PR fixes a real, previously-invisible version-skew bug: the CNPG Barman
plugin sidecar image tag was base64-encoded inside a Secret's `data`, so Flux's
image-automation could never find it, and it silently trailed the controller by
two minor versions. The fix (a) switches the Secret to `stringData` with a
plaintext tag and `$imagepolicy` marker, (b) adds a matching `ImageRepository`
+ `ImagePolicy` pair to track the sidecar going forward, and (c) bumps the tag
to v0.14.0. I independently verified the mechanics below and found no
correctness or security issues — only a documentation gap.
## 🟡 Suggestions
- **`kubernetes/infrastructure/image-automation/README.md`** — the "Re-import
hazard: cnpg-barman-plugin" section (lines 122–130) and the "Currently
enrolled" table row (line 56) still describe only the *controller's* marker
(`plugin-barman-cloud` on the image line) being at risk from a wholesale
upstream re-import. This PR adds a second marker in the same
upstream-imported file (the Secret's `stringData.SIDECAR_IMAGE`), which is
exactly as vulnerable to being clobbered by a re-import and isn't mentioned
there — even though the in-manifest comment added by this PR
(`manifest.yaml:936-937`) does call it out locally. A future maintainer who
goes to the README section specifically written for this hazard (rather than
reading the manifest's inline comments first) would only restore one of the
two markers. Worth a one-line addition to that section and the table.
## Tests
No unit tests apply to this kind of change; the repo's relevant gate is the
`kustomize-build` step in `.woodpecker/ci-manifests-test.yml`, which runs
`kubectl kustomize` over every kustomization directory including both edited
ones (`kubernetes/infrastructure/cnpg-barman-plugin` and
`kubernetes/infrastructure/image-automation`), catching YAML/wiring breakage.
I manually reviewed both files for structural correctness (see below) since I
could not execute `kubectl`/`kustomize` in this environment.
Verification performed against the checkout:
- Decoded the removed base64 blob — it is exactly
`ghcr.io/cloudnative-pg/plugin-barman-cloud-sidecar:v0.12.0`, confirming the
PR's stated before-state.
- Confirmed the Secret name `plugin-barman-cloud-kg5c2795f7`
(`manifest.yaml:943`) is unchanged and is referenced via
`secretKeyRef.name`/`key: SIDECAR_IMAGE` at `manifest.yaml:996-1000`, so the
Deployment's env var still resolves correctly under `stringData`.
- Confirmed `kubernetes/infrastructure/cnpg-barman-plugin/kustomization.yaml`
has no `secretGenerator`/name-hash transformer, so the "name is static, not
regenerated" claim in the new comment holds.
- Confirmed the controller image is already pinned to `v0.14.0`
(`manifest.yaml:1001`), so the sidecar bump to the same version does align
the two components as intended, and both now sit inside the shared `0.x`
policy range.
- Confirmed the new `ImagePolicy` name (`cnpg-barman-plugin-sidecar` in
`flux-system`) matches the marker
`{"$imagepolicy": "flux-system:cnpg-barman-plugin-sidecar"}`, and the filter
regex `^v(?P<ver>\d+\.\d+\.\d+)$` matches `v0.14.0`.
- Confirmed `cnpg-barman-plugin.yaml` is already listed in
`image-automation/kustomization.yaml`, so the two new resources (added as
extra YAML docs in an existing file) need no kustomization edit.
## Recommendation
Looks reasonable — no blocking issues; the documentation-gap comment above is optional.
<!-- pr-review:sha=154c933177234d59b58ed9b01cef125469545812 -->
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Fixes #535.
The problem
An image reference is not a secret. Encoding it as base64
datahad two concrete costs:$imagepolicymarker can attach to a base64 blobResult: a two-minor version skew in the component that performs every base backup and WAL archive for seven Postgres clusters.
Not stale pods —
ha-pg-1was created hours ago during the recorder migration and still received v0.12.0.Before:
After:
Three changes
stringDatawith the tag in plaintext + marker. The Secret kind is kept deliberately — the controller reads it viasecretKeyRef, so a ConfigMap would need a matching edit and diverge further from upstream.stringDatais accepted identically by the API server.0.xrange as the controller, so the two cannot drift apart again. Only the controller was tracked before.Verified before pinning
Pinning a non-existent tag would put all seven Postgres clusters into ImagePullBackOff, so I confirmed the image is pullable first:
The pull succeeded — that failure is the container command, not the image.
Also verified in the render that the Secret name is unchanged (it carries a kustomize hash suffix from upstream
secretGeneratorbut is static here), so the deploymentsecretKeyRefstays valid — the name still appears twice, on the Secret and its reference.Expected impact
Changing the sidecar tag changes every Postgres pod spec, so all seven CNPG clusters roll. CNPG handles it as a normal rolling restart.
I will confirm backups still work afterwards — 113 Backup CRs exist today, newest ~3h old and
completed.Note for future re-imports
Upstream ships this Secret as base64
datawith no marker, so a wholesale re-import silently reintroduces the skew. The manifest now says so inline, next to the block.Not fixed here
This does not fix #522 — the empty
lastSuccessfulBackupis a plugin feature gap (v0.6.0 added only the failed status field), not version skew. Bumping the sidecar will not enable backup-age alerting.🤖 Generated with Claude Code
🤖 Automated review — model
CLI default(complexity: complex), commit154c933177234d59b58ed9b01cef125469545812.Summary
This PR fixes a real, previously-invisible version-skew bug: the CNPG Barman
plugin sidecar image tag was base64-encoded inside a Secret's
data, so Flux'simage-automation could never find it, and it silently trailed the controller by
two minor versions. The fix (a) switches the Secret to
stringDatawith aplaintext tag and
$imagepolicymarker, (b) adds a matchingImageRepositoryImagePolicypair to track the sidecar going forward, and (c) bumps the tagto v0.14.0. I independently verified the mechanics below and found no
correctness or security issues — only a documentation gap.
🟡 Suggestions
kubernetes/infrastructure/image-automation/README.md— the "Re-importhazard: cnpg-barman-plugin" section (lines 122–130) and the "Currently
enrolled" table row (line 56) still describe only the controller's marker
(
plugin-barman-cloudon the image line) being at risk from a wholesaleupstream re-import. This PR adds a second marker in the same
upstream-imported file (the Secret's
stringData.SIDECAR_IMAGE), which isexactly as vulnerable to being clobbered by a re-import and isn't mentioned
there — even though the in-manifest comment added by this PR
(
manifest.yaml:936-937) does call it out locally. A future maintainer whogoes to the README section specifically written for this hazard (rather than
reading the manifest's inline comments first) would only restore one of the
two markers. Worth a one-line addition to that section and the table.
Tests
No unit tests apply to this kind of change; the repo's relevant gate is the
kustomize-buildstep in.woodpecker/ci-manifests-test.yml, which runskubectl kustomizeover every kustomization directory including both editedones (
kubernetes/infrastructure/cnpg-barman-pluginandkubernetes/infrastructure/image-automation), catching YAML/wiring breakage.I manually reviewed both files for structural correctness (see below) since I
could not execute
kubectl/kustomizein this environment.Verification performed against the checkout:
ghcr.io/cloudnative-pg/plugin-barman-cloud-sidecar:v0.12.0, confirming thePR's stated before-state.
plugin-barman-cloud-kg5c2795f7(
manifest.yaml:943) is unchanged and is referenced viasecretKeyRef.name/key: SIDECAR_IMAGEatmanifest.yaml:996-1000, so theDeployment's env var still resolves correctly under
stringData.kubernetes/infrastructure/cnpg-barman-plugin/kustomization.yamlhas no
secretGenerator/name-hash transformer, so the "name is static, notregenerated" claim in the new comment holds.
v0.14.0(
manifest.yaml:1001), so the sidecar bump to the same version does alignthe two components as intended, and both now sit inside the shared
0.xpolicy range.
ImagePolicyname (cnpg-barman-plugin-sidecarinflux-system) matches the marker{"$imagepolicy": "flux-system:cnpg-barman-plugin-sidecar"}, and the filterregex
^v(?P<ver>\d+\.\d+\.\d+)$matchesv0.14.0.cnpg-barman-plugin.yamlis already listed inimage-automation/kustomization.yaml, so the two new resources (added asextra YAML docs in an existing file) need no kustomization edit.
Recommendation
Looks reasonable — no blocking issues; the documentation-gap comment above is optional.