operator: make v1alpha1 CRD lifecycle executable#136
Conversation
6262874 to
c063782
Compare
35cf631 to
9681091
Compare
wolfiesch
left a comment
There was a problem hiding this comment.
Blocking migration-safety issue: the preflight validates only curated fixture files, then applies the CRDs. Kubernetes CRD update validation does not enumerate and revalidate stored custom resources, so a live object containing an old-valid value omitted from the fixtures can be stranded by a narrowed schema. Please validate every live CR, including status/CEL/pruning behavior, before non-dry-run apply, or add a sound no-narrowing compatibility gate. I reproduced this with an enum narrowed to legacy-a: the fixture-only gate passed while a simulated persisted legacy-b object failed validation.
75d36d4 to
c228370
Compare
c228370 to
de9bf6f
Compare
|
@wolfiesch — agreed: fixture-only validation was not a sufficient migration-safety gate. This is fixed at
The tests-only red is The security-main-rebased final head is fully green: run https://github.com/LycaonLLC/t4-code/actions/runs/29890665063, cluster job https://github.com/LycaonLLC/t4-code/actions/runs/29890665063/job/88830336202, aggregate verify https://github.com/LycaonLLC/t4-code/actions/runs/29890665063/job/88830921128. This resolves the requested blocking migration-safety issue. Please re-review the exact head and clear the requested-changes state so the PR can proceed through the existing merge path. |
OP line item
OP-02 — CRD lifecycle. Depends on open blocker #135. This PR remains draft until authoritative Woodpecker proof is green.
Observable contract
cluster.t4.dev/v1alpha1CRDs, each with oneserved: true,storage: truestructural version and a status subresource.cmd/crd-preflightchecks every full compatibility fixture against the proposed structural/OpenAPI schema, Kubernetes CEL under create semantics (oldObject=nil), Kubernetes CEL under unchanged persisted-update semantics (oldObject=fixture), and pruning detection. This includes spec and status transition rules and preserves precise fixture field paths in failures.Established=Trueis insufficient: served OpenAPI must converge to the proposed schemas before admission validation, exactstatus.storedVersions == [v1alpha1], or Helm--skip-crdsmay proceed.Red/green ledger
c54ae365b8d93a0d3d3795b36469b9f0541581df(rebased equivalent21ce3611476aa9c22b2fb77f35e9b67b0682a99d), cluster proof red: https://github.com/LycaonLLC/t4-code/actions/runs/29860644569/job/88736233588baaa5b13778b6e42bf02cd5af9883271e95c54c4, cluster job: https://github.com/LycaonLLC/t4-code/actions/runs/29863767337/job/8874678872339ba01ba6c5e742cc69d8289b4062a3522aa5754: https://github.com/LycaonLLC/t4-code/actions/runs/29867015087; cluster job https://github.com/LycaonLLC/t4-code/actions/runs/29867015087/job/88757713955 failed only the new persisted spec and statusoldSelfcases as intended.35cf631c1277808be7ca7c6f6a7f39462a95179c, cleanly based on2e6a11675ec80bb3ac0f0b2f51e8d375c17dde8fafter refreshing upstreammain.35cf631c1277808be7ca7c6f6a7f39462a95179c, but an infrastructure Helm rollout terminated its assigned agent duringgit. Woodpecker still reports it running with no live task/pod or durable queue backup, so it cannot resume in place. Supported recovery requires authorization to terminalize the orphan and retrigger the same exact head. This is the only CI blocker; no duplicate run or capacity mutation was performed.MERGEABLE/CLEANfor exact head35cf631c1277808be7ca7c6f6a7f39462a95179c; independent exact-head review found no P0-P2 issue.Migration and rollback
The documented future
v1beta1procedure does not create a new API now. It keepsv1alpha1served for rollback, flips storage only after dual-version conversion proof, rewrites every object, verifies counts and reads through both served versions, and retires the old stored version only after rewrite gates pass. Current rollback remains additive and fail-closed: schema or dry-run failure leaves existing CRDs, persisted objects, and workloads untouched, with no force replacement.Residual proof
No live Kubernetes credentials were available in this worktree, so HA apiserver/load-balancer behavior remains a live-cluster proof item. Repository and GitHub CI proof is executable and fail-closed. Woodpecker 38/95 is the explicit infrastructure blocker above.
Non-goals
No
v1beta1, conversion webhook, storage-version change, product/runtime status, Helm CRD upgrades, force replacement, unrelated OP-03 behavior, or broad RBAC.Review-blocker repair
The fixture-only migration gate has been replaced with a fail-closed live-object gate. Before any server dry-run or non-dry-run mutation, the lifecycle runner reads the three exact CRD definitions, lists every installed T4 CR across namespaces, and validates complete live objects—including status—with the existing
cmd/crd-preflightOpenAPI, CEL create, CEL unchanged-update, and pruning engine. Absent CRDs remain a valid fresh-install case; definition-read denial, list denial, malformed data, incompatible live data, or cancellation stops before CRD/object/Helm mutation. Kubernetes integer values retain exactint64fidelity. Served OpenAPI convergence and exact stored-version gates are unchanged; RBAC was not broadened.eee9844c1f9a167388edc0e4a433128daefdd012— https://github.com/LycaonLLC/t4-code/actions/runs/29889342817/job/88826550288de9bf6f118476f1630b005544aefb64bc5264170