Add immutable placement-target selection to Bucket #7

Merged
benvin merged 1 commits from benvin/placement-targets into main 2026-07-29 00:37:49 +10:00
Owner

Why

Buckets could not choose which RGW placement target backs them, so all data landed on the cluster default (3x replicated). The estate's radosgw exposes two targets - default-placement (3x replicated) and ec (4+1 erasure-coded) - verified live: a single zonegroup, and one bucket already sits on ec. Archival workloads want ec.

Changes

  • Validate spec.placementTarget: a DNS-ish pattern, 63-char cap, and a CEL self == oldSelf immutability rule, since RGW fixes placement at bucket creation and cannot move a bucket between targets; make spec.zonegroup immutable too.
  • Thread the target into the S3 CreateBucket LocationConstraint via the existing helper; an empty zonegroup yields :<target>, selecting the local/master zonegroup so callers need not know the zonegroup api-name.
  • Read the live placement_rule and zonegroup back from the Admin Ops bucket stats and surface them: status.placementTarget plus a Placement print column, so placement drift is visible.
  • Guard the controller: if a live bucket's placement differs from spec, set an Error phase with a PlacementImmutable reason instead of ever deleting/recreating the bucket.
  • Cover locationConstraint construction, placement readback (httptest), and the placementConflict guard with tests; document the targets and immutability in the README and add config/samples/06-bucket-ec.yaml.

Release

New Bucket field + status: cut a minor release with make minor (v0.3.1 -> v0.4.0) once merged; the v* tag builds+pushes git.unkin.net/unkin/cephrgw-operator:<tag> and :latest.

https://claude.ai/code/session_015ur3i7D2azsMAWTSVABApv

## Why Buckets could not choose which RGW placement target backs them, so all data landed on the cluster default (3x replicated). The estate's radosgw exposes two targets - `default-placement` (3x replicated) and `ec` (4+1 erasure-coded) - verified live: a single zonegroup, and one bucket already sits on `ec`. Archival workloads want `ec`. ## Changes - Validate `spec.placementTarget`: a DNS-ish pattern, 63-char cap, and a CEL `self == oldSelf` immutability rule, since RGW fixes placement at bucket creation and cannot move a bucket between targets; make `spec.zonegroup` immutable too. - Thread the target into the S3 `CreateBucket` `LocationConstraint` via the existing helper; an empty `zonegroup` yields `:<target>`, selecting the local/master zonegroup so callers need not know the zonegroup api-name. - Read the live `placement_rule` and zonegroup back from the Admin Ops bucket stats and surface them: `status.placementTarget` plus a `Placement` print column, so placement drift is visible. - Guard the controller: if a live bucket's placement differs from spec, set an `Error` phase with a `PlacementImmutable` reason instead of ever deleting/recreating the bucket. - Cover `locationConstraint` construction, placement readback (httptest), and the `placementConflict` guard with tests; document the targets and immutability in the README and add `config/samples/06-bucket-ec.yaml`. ## Release New Bucket field + status: cut a minor release with `make minor` (v0.3.1 -> v0.4.0) once merged; the `v*` tag builds+pushes `git.unkin.net/unkin/cephrgw-operator:<tag>` and `:latest`. https://claude.ai/code/session_015ur3i7D2azsMAWTSVABApv
unkinben added 1 commit 2026-07-29 00:16:56 +10:00
Add immutable placement-target selection to Bucket
ci/woodpecker/pr/build Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was successful
ci/woodpecker/pr/test Pipeline was successful
c1b3ba1c34
Buckets could not choose which RGW placement target (and thus durability
profile) backs them, so all data landed on the cluster default. The estate's
radosgw exposes two targets - default-placement (3x replicated) and ec (4+1
erasure-coded) - and archival workloads want ec.

- Validate spec.placementTarget: a DNS-ish pattern, 63-char cap, and a CEL
  self==oldSelf immutability rule (RGW fixes placement at bucket creation and
  cannot move a bucket between targets); make spec.zonegroup immutable too.
- Thread the target into the S3 CreateBucket LocationConstraint via the existing
  helper; an empty zonegroup yields ":<target>", selecting the local zonegroup
  so callers need not name the zonegroup api-name.
- Read the live placement_rule and zonegroup back from the Admin Ops bucket
  stats and surface them: status.placementTarget plus a Placement print column.
- Guard the controller: if a live bucket's placement differs from spec, set an
  Error phase with a PlacementImmutable reason instead of deleting/recreating.
- Cover locationConstraint construction, placement readback (httptest), and the
  placementConflict guard with tests; document targets and immutability in the
  README and add config/samples/06-bucket-ec.yaml.

Claude-Session: https://claude.ai/code/session_015ur3i7D2azsMAWTSVABApv
benvin merged commit 343d60cfcf into main 2026-07-29 00:37:49 +10:00
benvin deleted branch benvin/placement-targets 2026-07-29 00:37:49 +10:00
Sign in to join this conversation.