Skip to content

fix(backups): request S3 checksum only when required for barman-cloud (non-AWS S3 / Ceph RGW) - #3417

Merged
Andrey Kolkov (androndo) merged 3 commits into
mainfrom
fix/barman-cloud-s3-checksum-rgw
Jul 22, 2026
Merged

fix(backups): request S3 checksum only when required for barman-cloud (non-AWS S3 / Ceph RGW)#3417
Andrey Kolkov (androndo) merged 3 commits into
mainfrom
fix/barman-cloud-s3-checksum-rgw

Conversation

@androndo

@androndo Andrey Kolkov (androndo) commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

What this PR does

Fixes CNPG barman-cloud plugin backups to non-AWS, S3-compatible object
stores (Ceph RADOS Gateway, and some MinIO / Cloudflare R2 builds).

The plugin's sidecar uploads via boto3. Since botocore ~1.36 (early 2025)
the default RequestChecksumCalculation is when_supported, so a flexible
checksum (CRC32) plus the corresponding x-amz-content-sha256 handling is
attached to every PutObject. AWS S3 accepts it, but several S3-compatible
backends reject the request:

InvalidArgument: x-amz-content-sha256 must be UNSIGNED-PAYLOAD,
STREAMING-AWS4-HMAC-SHA256-PAYLOAD or a valid sha256 value.

so every backup / WAL-archive upload fails against them and the
ScheduledBackup never stores anything.

This sets spec.instanceSidecarConfiguration.env on the rendered
ObjectStores to carry AWS_REQUEST_CHECKSUM_CALCULATION=when_required
(botocore reads this env var from the sidecar's environment). when_required
computes a checksum only for operations that mandate one; a plain PutObject
then carries none, which both AWS S3 and the affected backends accept — a safe
default everywhere. No API/CRD change, no new value, no new dependency.

Applied to every barman-cloud ObjectStore Cozystack creates:

  • chart-renderedpackages/system/keycloak/templates/db.yaml (Keycloak
    system DB) and packages/apps/postgres/templates/db.yaml (postgres app —
    backup and bootstrap-recovery ObjectStores), via a shared cozy-lib
    helper (cozy-lib.barman.checksumSidecarConfiguration);
  • Go-constructed — the platform-managed useSystemBucket=true ObjectStore
    SSA-applied by internal/backupcontroller/cnpgstrategy_controller.go
    (barmanSidecarConfiguration), whose default system bucket is SeaweedFS.

Regression coverage: a Go unit test on the SSA-applied ObjectStore, plus
helm-unittest assertions on spec.instanceSidecarConfiguration.env for all
three rendered ObjectStores (mutation-checked — reverting the change fails
them).

Mirrors the same fix already applied to the etcd path in
cozystack/etcd-operator#342 (released in v0.5.3) for the same Ceph RGW
backend.

Verification: reproduced end-to-end against a real Ceph RGW endpoint. With
default botocore, PutObject fails with the InvalidArgument above; with
AWS_REQUEST_CHECKSUM_CALCULATION=when_required in the environment it succeeds.
Deployed the plugin + a throwaway CNPG cluster whose ObjectStore carried this
env: continuous WAL archiving reported ContinuousArchiving=True and an
on-demand Backup completed, with the base backup and WAL segments present in
the bucket. helm template renders the env on all three ObjectStores; the
packages/apps/postgres unit-test suite still passes.

Screenshots

N/A — no UI changes.

Downstream repositories

Release note

fix(backups): CNPG barman-cloud backups now work against non-AWS S3-compatible object stores (Ceph RADOS Gateway, some MinIO/Cloudflare R2). The backup sidecar requests an S3 request checksum only when required, avoiding the "x-amz-content-sha256 must be UNSIGNED-PAYLOAD, ..." error that previously broke every backup and WAL-archive upload to those backends. No change for AWS S3.

Summary by CodeRabbit

  • Bug Fixes
    • Improved compatibility with S3-compatible, non-AWS storage backends for PostgreSQL and Keycloak backups and recovery.
    • Pin the barman-cloud sidecar to compute AWS request checksums only when required (AWS_REQUEST_CHECKSUM_CALCULATION=when_required) to prevent failures with strict S3 gateways.
  • Tests
    • Updated/added assertions in controller and Helm/YAML suites to verify the checksum pin is applied to generated and recovery ObjectStores (Postgres and Keycloak).

@gemini-code-assist

Copy link
Copy Markdown
Contributor

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The change configures barman-cloud ObjectStore sidecars to set AWS_REQUEST_CHECKSUM_CALCULATION to when_required across controller-generated and Helm-managed PostgreSQL and Keycloak storage resources.

Changes

S3 checksum configuration

Layer / File(s) Summary
Configure controller-generated ObjectStores
internal/backupcontroller/cnpgtypes/types.go, internal/backupcontroller/cnpgtypes/zz_generated.deepcopy.go, internal/backupcontroller/cnpgstrategy_controller.go, internal/backupcontroller/cnpgstrategy_controller_test.go
Adds typed sidecar configuration support, applies the checksum environment variable to generated ObjectStores, deep-copies the configuration, and validates the resulting resource.
Configure Helm-managed ObjectStores
packages/library/cozy-lib/templates/_barman.tpl, packages/apps/postgres/templates/db.yaml, packages/system/keycloak/templates/db.yaml, packages/apps/postgres/tests/backup_storage_test.yaml, packages/system/keycloak/tests/db_backup_test.yaml
Adds a shared checksum configuration template, applies it to PostgreSQL backup, recovery, and Keycloak ObjectStores, and validates the rendered resources.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

Suggested labels: area/testing

Suggested reviewers: kvaps

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: pinning barman-cloud S3 request checksums to when required for non-AWS S3 backends.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/barman-cloud-s3-checksum-rgw

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added size/S This PR changes 10-29 lines, ignoring generated files area/storage Issues or PRs related to storage (linstor, seaweedfs, bucket, velero, harbor) kind/bug Categorizes issue or PR as related to a bug labels Jul 22, 2026
@androndo
Andrey Kolkov (androndo) marked this pull request as ready for review July 22, 2026 10:32
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@dosubot dosubot Bot added the area/database Issues or PRs related to managed databases (postgres, mariadb, redis, etcd, kafka, clickhouse) label Jul 22, 2026

@IvanHunters IvanHunters left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict

NOT LGTM

The fix only reaches the legacy BYO-credentials backup flow and leaves the platform's own recommended useSystemBucket=true flow (backed by the same class of non-AWS S3 gateway) unpatched, and ships with no regression test — confirmed by mutation: the full helm-unittest suite stays green with the fix fully reverted.

Findings

[MAJOR] internal/backupcontroller/cnpgstrategy_controller.go:438-441 — the fix does not cover the platform-managed default backup flow (backup.useSystemBucket=true), which the chart's own docs call "recommended for new clusters."

The PR sets spec.instanceSidecarConfiguration.env[AWS_REQUEST_CHECKSUM_CALCULATION=when_required] only on the two Helm-template-rendered barmancloud.cnpg.io/v1 ObjectStore objects (packages/apps/postgres/templates/db.yaml, packages/system/keycloak/templates/db.yaml). A third ObjectStore for the same postgres app is constructed entirely in Go by applyClusterPluginBackup (internal/backupcontroller/cnpgstrategy_controller.go:418-441) and SSA-applied under field manager cozystack-cnpg-backup-driver whenever a tenant sets backup.useSystemBucket=true — the flow packages/apps/postgres/templates/backup.yaml's own header comment and packages/apps/postgres/README.md:27 label "Platform-managed flow (recommended for new clusters)". That Go path's typed spec mirror, cnpgtypes.ObjectStoreSpec (internal/backupcontroller/cnpgtypes/types.go:206-211), has no InstanceSidecarConfiguration field at all, and objStore.Spec = cnpgtypes.ObjectStoreSpec{Configuration: ..., RetentionPolicy: ...} never sets one (grepping the file for Sidecar/EnvVar/.Env returns nothing). The platform's own default system-bucket endpoint is http://seaweedfs-s3.tenant-root.svc.cozy.local:8333 (packages/system/backupstrategy-controller/values.yaml:70) — a non-AWS S3-compatible gateway of exactly the class this PR says rejects the flexible checksum. A tenant on the recommended useSystemBucket=true flow gets none of this fix. Fix: extend the Go-side ObjectStoreSpec/buildBarmanObjectStore construction (or set the field directly on objStore.Spec before the SSA patch) to carry the same env var, with coverage in cnpgstrategy_controller_test.go.

[MAJOR] packages/apps/postgres/tests/backup_storage_test.yaml, packages/system/keycloak/tests/ — no regression test protects the fix; confirmed by mutation.

helm unittest . passes 29/29 (postgres) and 45/45 (keycloak) with the fix present. Reverting both template changes to their pre-fix content (git show aef9e201:<path>) and re-running the exact same suites still passes 29/29 and 45/45 unchanged — no assertion in either suite reads spec.instanceSidecarConfiguration. This is a bug-fix PR; the render-layer regression test (helm-unittest) required by the test-adequacy standard is missing. Without it, a future chart-split, helper refactor, or merge conflict can silently drop any of the three env blocks with nothing in CI to catch it. Add an assertion on spec.instanceSidecarConfiguration.env[0] for all three rendered ObjectStore documents (backup + recovery in postgres, the single one in keycloak).

[MINOR] packages/apps/postgres/templates/db.yaml:265-269,300-301, packages/system/keycloak/templates/db.yaml:54-58 — the same 5-line comment plus 3-line YAML block is duplicated verbatim three times across two charts.

A shared named template (in cozy-lib or a per-chart _helpers.tpl) for instanceSidecarConfiguration would make a future change (a second env var, or reusing the literal value from the Go path once Finding 1 is addressed) a one-place edit instead of three.

Claim mismatches

[PARTIAL] "Applied to every barman-cloud ObjectStore this repo renders" / release-note "CNPG barman-cloud backups now work against non-AWS S3-compatible object stores ... No change for AWS S3" — see Finding 1: the useSystemBucket=true-flow ObjectStore, SSA-applied by internal/backupcontroller/cnpgstrategy_controller.go, is untouched, so backups on that (recommended) flow against a non-AWS endpoint are not fixed by this PR despite the unqualified release-note wording.

Caveats

  • Whether SeaweedFS's S3 gateway (the platform's own default bucket backend) actually rejects the flexible-checksum header the same way Ceph RGW does was not independently reproduced here (no live cluster in scope for this review); the code-path gap in Finding 1 is verified directly from source, the real-world failure on SeaweedFS specifically is inferred by analogy to Ceph RGW, not tested end-to-end.
  • Applying this chart change via helm upgrade to an existing tenant already on backup.enabled=true (legacy flow) patches the live ObjectStore; whether that causes CNPG to roll-restart already-running instance pods to pick up the new sidecar env was not verified against CNPG operator source (out of scope for a hermetic, cluster-free review). Expected to be a normal CNPG-managed reconcile, not a hard failure, but not independently confirmed.
  • chart_lint render_errors/missing_refs on _cluster.scheduling, _namespace.host, registrySecret (from local helm template) are pre-existing harness artifacts from runtime-injected values not present outside a real cluster, located at postgres/templates/db.yaml:194 — outside the range this PR touches, not introduced by it. Verified by rendering the chart with _cluster/_namespace stubs supplied: all schema-valid corners exercised in this review (legacy backup with inline creds, bootstrap+recovery, useSystemBucket=true, keycloak backup on/off) render valid, admittable YAML including the new field.
  • Root-cause claim (botocore/boto3 defaulting to a flexible request checksum that non-AWS S3-compatible backends reject) was independently cross-checked against AWS's own S3 documentation ("for uploads, all AWS-owned clients calculate a checksum ... and send it with the upload request") and is consistent with the PR's description; not contradicted by anything found in this review.

Recommended follow-ups

  • Extend the checksum fix to the Go-driven useSystemBucket=true ObjectStore path (cnpgstrategy_controller.go / cnpgtypes.ObjectStoreSpec).
  • Add helm-unittest coverage for the new env var on all three rendered ObjectStore documents.
  • Factor the duplicated comment/env block into a shared helper.

Andrey Kolkov and others added 2 commits July 22, 2026 15:29
The barman-cloud plugin's sidecar uploads via boto3. Since botocore ~1.36
(early 2025) the default RequestChecksumCalculation is when_supported, which
attaches a flexible checksum to every PutObject. Non-AWS S3-compatible
backends (Ceph RADOS Gateway, some MinIO / Cloudflare R2 builds) reject the
accompanying header with "InvalidArgument: x-amz-content-sha256 must be
UNSIGNED-PAYLOAD, STREAMING-AWS4-HMAC-SHA256-PAYLOAD or a valid sha256
value", so every backup/WAL-archive upload fails against them.

Pin the sidecar to when_required via the ObjectStore's
spec.instanceSidecarConfiguration.env (botocore honors the
AWS_REQUEST_CHECKSUM_CALCULATION env var) on both the keycloak system DB and
the postgres app (backup + recovery ObjectStores). when_required is also
accepted by AWS S3 on a plain PutObject, so it is a safe default everywhere.

This mirrors the etcd-operator fix (cozystack/etcd-operator#342, released in
v0.5.3), which applied the same WhenRequired policy to its aws-sdk-go-v2 S3
client for the same Ceph RGW backend.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Andrey Kolkov <andrey.kolkov@aenix.io>
…hecksum helper

Address review on the S3 request-checksum fix:

- Extend the fix to the platform-managed useSystemBucket=true flow, whose
  ObjectStore is built in Go by applyClusterPluginBackup (SSA-applied), not
  chart-rendered. Add InstanceSidecarConfiguration to cnpgtypes.ObjectStoreSpec
  and set AWS_REQUEST_CHECKSUM_CALCULATION=when_required on it via
  barmanSidecarConfiguration(). The platform's own default system bucket is
  SeaweedFS, a non-AWS S3 gateway of the same class as Ceph RGW. Unit test in
  cnpgstrategy_controller_test.go asserts the applied ObjectStore carries it.

- Factor the duplicated instanceSidecarConfiguration block (3x across two
  charts) into a shared cozy-lib helper (cozy-lib.barman.checksumSidecarConfiguration).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Andrey Kolkov <andrey.kolkov@aenix.io>
@androndo
Andrey Kolkov (androndo) force-pushed the fix/barman-cloud-s3-checksum-rgw branch from 2aff9f0 to b574e21 Compare July 22, 2026 11:36
@github-actions github-actions Bot added size/M This PR changes 30-99 lines, ignoring generated files and removed size/S This PR changes 10-29 lines, ignoring generated files labels Jul 22, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@internal/backupcontroller/cnpgtypes/zz_generated.deepcopy.go`:
- Around line 242-262: Do not edit the generated DeepCopy methods directly.
Update the corresponding InstanceSidecarConfiguration definition in types.go,
then rerun the repository’s deepcopy generator to regenerate
zz_generated.deepcopy.go reproducibly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 5ecd7f9b-cdde-48ff-9687-faceb033ae5e

📥 Commits

Reviewing files that changed from the base of the PR and between 2aff9f0 and b574e21.

📒 Files selected for processing (7)
  • internal/backupcontroller/cnpgstrategy_controller.go
  • internal/backupcontroller/cnpgstrategy_controller_test.go
  • internal/backupcontroller/cnpgtypes/types.go
  • internal/backupcontroller/cnpgtypes/zz_generated.deepcopy.go
  • packages/apps/postgres/templates/db.yaml
  • packages/library/cozy-lib/templates/_barman.tpl
  • packages/system/keycloak/templates/db.yaml
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/system/keycloak/templates/db.yaml
  • packages/apps/postgres/templates/db.yaml

Comment on lines +242 to +262
if in.InstanceSidecarConfiguration != nil {
out.InstanceSidecarConfiguration = new(InstanceSidecarConfiguration)
in.InstanceSidecarConfiguration.DeepCopyInto(out.InstanceSidecarConfiguration)
}
}

func (in *InstanceSidecarConfiguration) DeepCopyInto(out *InstanceSidecarConfiguration) {
*out = *in
if in.Env != nil {
out.Env = make([]EnvVar, len(in.Env))
copy(out.Env, in.Env)
}
}

func (in *InstanceSidecarConfiguration) DeepCopy() *InstanceSidecarConfiguration {
if in == nil {
return nil
}
out := new(InstanceSidecarConfiguration)
in.DeepCopyInto(out)
return out

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Regenerate this file instead of editing it directly.

internal/backupcontroller/cnpgtypes/zz_generated.deepcopy.go matches zz_generated.*.go; keep the source change in types.go and rerun the repository’s deepcopy generator so this output remains reproducible.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/backupcontroller/cnpgtypes/zz_generated.deepcopy.go` around lines
242 - 262, Do not edit the generated DeepCopy methods directly. Update the
corresponding InstanceSidecarConfiguration definition in types.go, then rerun
the repository’s deepcopy generator to regenerate zz_generated.deepcopy.go
reproducibly.

Source: Coding guidelines

…ed ObjectStores

helm-unittest coverage for the S3 request-checksum fix (was mutation-negative
before): assert spec.instanceSidecarConfiguration.env pins
AWS_REQUEST_CHECKSUM_CALCULATION=when_required on all rendered barman-cloud
ObjectStores — postgres backup + bootstrap-recovery
(packages/apps/postgres/tests/backup_storage_test.yaml) and the Keycloak DB
(new packages/system/keycloak/tests/db_backup_test.yaml). Verified by mutation:
reverting the template change now fails these assertions.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Andrey Kolkov <andrey.kolkov@aenix.io>
@github-actions github-actions Bot added size/L This PR changes 100-499 lines, ignoring generated files and removed size/M This PR changes 30-99 lines, ignoring generated files labels Jul 22, 2026
@androndo

Copy link
Copy Markdown
Contributor Author

Thanks IvanHunters — all three findings addressed.

[MAJOR] Go-driven useSystemBucket=true flow — fixed in b574e21. Added InstanceSidecarConfiguration to cnpgtypes.ObjectStoreSpec (+ hand-written deepcopy) and set AWS_REQUEST_CHECKSUM_CALCULATION=when_required on the SSA-applied ObjectStore via barmanSidecarConfiguration() in applyClusterPluginBackup. The existing applyClusterPluginBackup test in cnpgstrategy_controller_test.go now asserts the applied ObjectStore carries it.

[MAJOR] Missing regression test — added in 80a03b1. helm-unittest now asserts spec.instanceSidecarConfiguration.env pins AWS_REQUEST_CHECKSUM_CALCULATION=when_required on all three rendered ObjectStores: postgres backup + bootstrap-recovery (packages/apps/postgres/tests/backup_storage_test.yaml) and the Keycloak DB (new packages/system/keycloak/tests/db_backup_test.yaml). Verified by the same mutation you ran — reverting the template change now fails these assertions (previously green).

[MINOR] Duplication — factored the 3× block into a shared cozy-lib helper cozy-lib.barman.checksumSidecarConfiguration (b574e21); the three call sites now include it, and the Go path documents the same intent.

[Claim mismatch] — PR description updated: the Go/useSystemBucket=true path is now covered, so the release note holds for every flow.

On the SeaweedFS caveat: I set when_required unconditionally rather than gating on the endpoint, because it's a safe default on every S3 backend (plain PutObject on AWS S3 needs no checksum either). So the platform flow is protected whether or not SeaweedFS specifically rejects the flexible-checksum header.

@IvanHunters IvanHunters left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict

LGTM

Additive fix reaching all three barman-cloud ObjectStore creation sites in the tree (the Go-driven useSystemBucket=true path plus both chart-rendered paths for postgres and keycloak), with mutation-verified regression tests at the appropriate layer and no upgrade/fresh-install/config-toggle regression identified.

Claim mismatches

[UNVERIFIABLE] "Verification: reproduced end-to-end against a real Ceph RGW endpoint... Deployed the plugin + a throwaway CNPG cluster whose ObjectStore carried this env" — this review is static and cluster-free (no live cluster available), so the live-endpoint repro could not be reproduced or checked. The underlying technical premise was instead independently verified against official documentation (see Caveats).

Caveats

  • Existing-customer upgrade (Phase 5b.A): spec.instanceSidecarConfiguration is an existing, already-vendored field on the barmancloud.cnpg.io/v1 ObjectStore CRD (packages/system/postgres-operator/charts/plugin-barman-cloud/templates/crds/crds.yaml:416-455) — not itself changed by this PR — with no immutability marker. The addition is purely additive on both the Go-SSA-applied and chart-rendered paths; no migration script or targetVersion bump is needed and none was added. One real side effect worth naming: every already-running CNPG cluster with backup.enabled: true will have this env var applied to its ObjectStore on the next reconcile after this ships — an expected CNPG-managed rolling restart, not a data-loss or availability regression, but a real fleet-wide side effect of shipping the fix.
  • Fresh install (Phase 5b.B): no new PackageSource/bundle wiring, no new values.yaml/values.schema.json field (the pin is hardcoded in the shared helper, not user-configurable), no new image reference, no new CRD or cert-manager dependency. Verified: helm template renders cleanly on a tenant-* namespace with backup.enabled=true and produces a schema-valid ObjectStore.
  • Config-combination matrix (Phase 5c): the new {{- include "cozy-lib.barman.checksumSidecarConfiguration" }} calls are unconditional additions inside three pre-existing gates ($renderBarman, .Values.bootstrap.enabled, and .Values.backup.enabled .Values.backup.destinationPath); no new toggle or branch introduced.
  • Completeness: grep -rl "barmancloud.cnpg.io/v1" / kind: ObjectStore across packages/ (excluding tests and the vendored plugin chart) return exactly the two touched chart templates; ObjectStoreSpec{ in internal/backupcontroller/*.go returns exactly the one touched Go site. All three covered; no fourth site found.
  • Test non-vacuity, verified by mutation: reverting the Go fix turns TestApplyClusterPluginBackup_PatchesExistingCluster RED; reverting the cozy-lib helper body turns both packages/apps/postgres and packages/system/keycloak helm-unittest suites RED. Both green on the actual diff. go build/go vet clean; golangci-lint findings all pre-date this PR.
  • Technical premise, independently checked: AWS SDK settings reference confirms AWS_REQUEST_CHECKSUM_CALCULATION is a real standardized env var, and when_required only skips the checksum on operations whose model does not mandate one. Cited precedent cozystack/etcd-operator#342 confirmed merged with a matching root cause.
  • Diff-artifact gap in tooling: bootstrap enumerated 8 of 9 files; internal/backupcontroller/cnpgtypes/zz_generated.deepcopy.go (+21) was missing from the supplied patch. Reviewed directly: the added DeepCopyInto for ObjectStoreSpec.InstanceSidecarConfiguration (pointer) and .Env (slice) correctly deep-copies, consistent with the file's hand-written pattern.
  • New cnpgtypes.EnvVar (minimal Name/Value, no corev1 import) mirrors the package's existing minimal-type convention — not a deviation.

Recommended follow-ups

  • The useSystemBucket=true Go path is covered by a Go unit test plus the author's manual Ceph RGW repro; there is no automated e2e/bats exercise of that path against a non-AWS backend. Not blocking, but worth considering for the shared e2e suite given this is the platform-default (SeaweedFS) backup path.

@androndo
Andrey Kolkov (androndo) merged commit c503ae2 into main Jul 22, 2026
42 checks passed
@androndo
Andrey Kolkov (androndo) deleted the fix/barman-cloud-s3-checksum-rgw branch July 22, 2026 17:02
@androndo Andrey Kolkov (androndo) added the backport Should change be backported on previous release label Aug 12, 2026
@github-actions

Copy link
Copy Markdown

@github-actions

Copy link
Copy Markdown

Created backport PR for release-1.5:

Please cherry-pick the changes locally and resolve any conflicts.

git fetch origin backport-3417-to-release-1.5
git worktree add --checkout .worktree/backport-3417-to-release-1.5 backport-3417-to-release-1.5
cd .worktree/backport-3417-to-release-1.5
git reset --hard HEAD^
git cherry-pick -x 0c586b9d72d3c3d05c25d4ed74a5039482472589 b574e2176f099305c97e5a8e4a456f463cb7aef1 80a03b1e09bac7e34b49f5016c405df913302dbb
git push --force-with-lease

myasnikovdaniil added a commit that referenced this pull request Aug 17, 2026
Since botocore ~1.36 (early 2025) the default
RequestChecksumCalculation is when_supported, so barman-cloud's boto3
attaches a flexible checksum to every PutObject. AWS S3 accepts it,
but non-AWS S3-compatible backends - Ceph RADOS Gateway, the
platform's own SeaweedFS system bucket, some MinIO / Cloudflare R2
builds - reject it with "InvalidArgument: x-amz-content-sha256 must
be UNSIGNED-PAYLOAD, ...", which fails every backup and WAL-archive
upload.

Set AWS_REQUEST_CHECKSUM_CALCULATION=when_required through the CNPG
Cluster's spec.env, which reaches the instance pods and therefore the
barman-cloud subprocess the instance manager execs.

This is a release-1.5-native equivalent of #3417 rather than a
cherry-pick of it. That change sets
spec.instanceSidecarConfiguration.env on barmancloud.cnpg.io
ObjectStore objects, and release-1.5 has no barman-cloud plugin:
there is no ObjectStore CRD on the branch and the rendered Cluster
carries no spec.plugins, so those objects would template cleanly and
then fail to apply, referenced by nothing. release-1.5 still uses
CNPG's native in-tree spec.backup.barmanObjectStore, which shells out
to the same barman-cloud client, so the bug is reachable here - the
plugin is the packaging difference, not the cause.

One spec.env covers all three paths on this branch at once: the
chart-rendered legacy barmanObjectStore, the same field SSA-patched
by the CNPG backup driver in the useSystemBucket flow, and
externalClusters recovery. No Go change is needed - the driver's
patch type carries only spec.backup and spec.bootstrap, so it cannot
express or remove the Helm-owned spec.env.

keycloak is out of scope on this branch. Its chart renders a CNPG
Cluster but configures no backup at all - no backup key in values,
no backup template - so it has no barman-cloud path to fix, and the
upstream hunk for it references values that do not exist here.

Verified against CNPG 1.27.3: spec.env is accepted by the webhook
and stored unmodified, appears in the instance manager's own
environment, and botocore inside the instance image then resolves
request_checksum_calculation as when_required instead of its
when_supported default. Adding the field to an already-running
Cluster converges back to healthy after CNPG recreates the instance
pod, which is the in-place upgrade path for existing releases with
backups enabled.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
myasnikovdaniil added a commit that referenced this pull request Aug 18, 2026
…quired for barman-cloud (non-AWS S3 / Ceph RGW) (#3767)

# Description
Backport of #3417 to `release-1.6`.
myasnikovdaniil added a commit that referenced this pull request Aug 19, 2026
…quired for barman-cloud (non-AWS S3 / Ceph RGW) (#3882)

# Description
Backport of #3417 to `release-1.5`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/database Issues or PRs related to managed databases (postgres, mariadb, redis, etcd, kafka, clickhouse) area/storage Issues or PRs related to storage (linstor, seaweedfs, bucket, velero, harbor) backport Should change be backported on previous release backport-previous Backport target — previous release line kind/bug Categorizes issue or PR as related to a bug size/L This PR changes 100-499 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants