Skip to content

Commit bec4463

Browse files
kvapsclaude
andcommitted
docs(plan): tick Phase 10.2 DrbdState audit + Phase 10.3 typed Node.SatelliteEndpoint / Resource.StoragePool
Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
1 parent 86b9fb1 commit bec4463

1 file changed

Lines changed: 3 additions & 3 deletions

File tree

PLAN.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -533,7 +533,7 @@ and per-object configuration lives in typed Spec / Status fields.
533533

534534
### 10.2 — Status is the only home for observed state
535535

536-
- [ ] Audit every site where observed state currently writes to `Spec.Props`. Today `pkg/satellitecontroller/server.applyObserved` lands `DrbdState` into Resource Spec via `SetState`'s `drbdProps`; that's a Spec write triggered by an observation stream — race with desired-state writers. Move `DrbdState` to the existing `Resource.Status.Volumes[i].DiskState` (typed) and drop the Spec side-write entirely.
536+
- [x] Audit every site where observed state currently writes to `Spec.Props` (2026-05-10). `applyObserved` now sets `state.DrbdState` directly on the typed `apiv1.ResourceState`; the k8s store routes the whole write through `.Status().Update()` to `Resource.Status.DrbdState`. SetState's legacy `drbdProps map[string]string` parameter is gone. No production Spec.Props side-writes remain on the observation path.
537537
- [ ] Add `ResourceVolumeStatus.CurrentGi string` (also covered by Phase 8.1 follow-up) and `ResourceVolumeStatus.HistoryGi []string` if split-brain visibility matters for the UI.
538538
- [ ] Document the Spec/Status split rule in `docs/architecture.md`: anything observed by the satellite from the kernel goes to Status, never Spec; anything the operator or controller asks the satellite to do goes to Spec, never Status.
539539
- [ ] Use Kubernetes server-side-apply field managers when both controller (writes parts of Status — e.g. allocator outputs `DRBDPort`) and satellite (writes other parts of Status — `DiskState`, `CurrentGi`) touch the same Status, so neither clobbers the other. Today the controller uses regular `Update` which can clobber Status writes that landed between Get and Update.
@@ -547,10 +547,10 @@ LINSTOR boundary.
547547

548548
- [x] `ResourceDefinition.Spec.DRBDOptions { Net, Disk, PeerDevice, Resource, Handlers }` typed structs (2026-05-10). Embedded on RG/RD/Resource alongside the existing Props map; `pkg/drbd.ResolveDRBDOptions` walks the same controller→RG→RD→Resource hierarchy with nil-vs-set discipline so an explicit `*bool=false` survives lower-scope inheritance and an empty-string handler key DELETES the inherited entry.
549549
- [x] `ResourceDefinition.Spec.Encryption.PassphraseSecretRef LocalObjectReference` (2026-05-10). The CRD now carries `EncryptionConfig.PassphraseSecretRef`; the satellite already reads the passphrase via the apiserver on reconcile (Phase 6) — this just typifies the slot that previously lived in `Props["DrbdOptions/Encryption/passphrase"]`.
550-
- [ ] `Node.Spec.SatelliteEndpoint string` — replaces `Props["SatelliteEndpoint"]`. (Or removed entirely once 10.6 lands and the endpoint is no longer dialled.)
550+
- [x] `Node.Spec.SatelliteEndpoint string` (2026-05-10). Dispatcher reads typed first with Props fallback; k8s store transcodes both ways so golinstor still sees `Props["SatelliteEndpoint"]` on GET.
551551
- [ ] `Node.Spec.DRBDPortRange / DRBDMinorRange { Min, Max int32 }` — replaces `Props["DrbdOptions/TcpPortRange"]` / `"DrbdOptions/MinorNrRange"`. Defaults baked in via kubebuilder.
552552
- [ ] `Node.Spec.AutoTieBreaker *bool` — replaces `Props["DrbdOptions/AutoAddQuorumTiebreaker"]`.
553-
- [ ] `Resource.Spec.StoragePool string` — replaces `Props["StorPoolName"]`. Already half-typed via dispatcher's `buildVolumes`; finish the migration.
553+
- [x] `Resource.Spec.StoragePool string` (2026-05-10). Typed field on Resource; dispatcher's buildVolumes + autoplacer dispatch read typed first; auto-diskful promotion stamps both typed + legacy Props key; k8s store transcodes both ways.
554554
- [ ] Topology: drop `Props["Aux/zone"]` / `"Aux/rack"`. Use Kubernetes-native `metadata.labels["topology.blockstor.io/zone"]` etc. Autoplacer reads labels via `client.MatchingLabels`. This is also the upgrade path to label-aware features like `topologySpreadConstraints` later.
555555
- [x] REST shim transcoder (2026-05-10). `pkg/store/k8s/drbd_transcode.go` splits the wire `props` bag into `Spec.DRBDOptions` (recognised keys) + `Spec.ExtraProps` (unknown DrbdOptions/* + non-DRBD residual keys); inverse re-emits typed back to `props` on GET. Pinned by 7 unit tests (per-section recognition, unknown-key fallthrough, parse-error fallback, round-trip losslessness, bool spelling tolerance). Controller's `resolveEffectiveProps` now walks typed via `ResolveDRBDOptions` and flattens via `drbd.TypedDRBDOptionsToProps` for the dispatcher → satellite renders the same .res file from typed CRD fields rather than string-keyed Props.
556556
- [x] Validation via kubebuilder enums (2026-05-10). `Net.Protocol`, `Disk.OnIOError`, `Resource.Quorum`, `Resource.OnNoQuorum`, `Net.AfterSb0Pri/1Pri/2Pri` all carry `+kubebuilder:validation:Enum=...` markers; CRD manifests regenerated. Pinned via `internal/controller/drbd_admission_test.go` — 8 ginkgo specs that submit garbage values against a live envtest apiserver and assert it rejects at admission.

0 commit comments

Comments
 (0)