Repository navigation
fix(bridge): gate component deactivation on CMS dependency safety - #992
Conversation
There was a problem hiding this comment.
Code Review
This pull request implements a CMS deactivation safety handshake when disabling components (spec.enabled: false). It introduces PrepareDeactivation and CompleteDeactivation steps to prevent tearing down workloads if active dependents exist, managing blocked or incomplete deactivations via new status conditions (DeactivationBlocked and DeactivationIncomplete). Feedback on the changes highlights a potential nil pointer dereference in reportDeactivationBlocked where the result of findCondition is accessed without a nil check, which could lead to a runtime panic.
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request implements CMS deactivation safety gating in the xmc-bridge reconciler. When a component is disabled (spec.enabled: false), the reconciler now calls PrepareDeactivation to verify if other active components depend on it. If active dependents exist, deactivation is blocked, the workload continues running, and the status reports DeactivationBlocked. Otherwise, the workload is deleted, and CompleteDeactivation is called to finalize the handshake. If the handshake fails after teardown, the state is marked as DeactivationIncomplete and retried. The PR also includes updated documentation and comprehensive unit tests for these deactivation flows. I have no feedback to provide as there are no review comments.
38e8b84 to
a013c84
Compare
a013c84 to
e7dd760
Compare
e7dd760 to
637cd26
Compare
There was a problem hiding this comment.
🤖 Incremental PR Approval
PR author is a code owner and changes since last approval (4 lines) are within the 10-line grace delta.
Preserving prior approval by @janzak-dev on commit 637cd26.
b27a433 to
1549fc9
Compare
There was a problem hiding this comment.
🤖 Incremental PR Approval
PR author is a code owner and changes since last approval (4 lines) are within the 10-line grace delta.
Preserving prior approval by @janzak-dev on commit 637cd26.
Setting spec.enabled: false now runs the CMS deactivation handshake before tearing down workloads: - PrepareDeactivation (blocking mode) is called first. If CMS returns FailedPrecondition because enabled components (including gated but registered ones) depend on this one, the workload keeps running and the CR reports DeactivationBlocked=True with Ready=False reason DeactivationBlocked. CMS is re-checked at most every 30s. - Otherwise the 1P workload is deleted and CompleteDeactivation moves CMS from DISABLING to DISABLED. A handshake failure after teardown reports DeactivationIncomplete and is retried on every pass. - wasComponentPreviouslyActive no longer treats gated components (DependenciesNotReady, DependencyCycle) as having a workload. - CMSClient and the in-process adapter gain PrepareDeactivation and CompleteDeactivation. BUG=b/548435582 TAG=agy
BUG=b/548435582 TAG=agy CONV=baca6192-74d3-4579-9f73-0a3263d9a2a7
Log the PrepareDeactivation FailedPrecondition detail on each fresh CMS check (at most once per deactivation recheck interval) so operators can see which dependents block the disable. Add a TODO to split reconciler.go by responsibility as a follow-up. Comment link: #992 (comment) Comment link: #992 (comment) BUG=b/548435582 TAG=agy CONV=baca6192-74d3-4579-9f73-0a3263d9a2a7
1549fc9 to
e5d766c
Compare
There was a problem hiding this comment.
🤖 Incremental PR Approval
PR author is a code owner and changes since last approval (6 lines) are within the 10-line grace delta.
Preserving prior approval by @janzak-dev on commit 637cd26.
Summary
Setting
enabled: falseon a Component now goes through CMS deactivation safety. Disabling a component while enabled components depend on it is blocked, and its workload keeps running.Stack 4/4: CMS dependencies (0) → 1P health (B) → dependency-gated actuation (C1) → this PR.
Motivation & Context
reconcileDisableddeleted the 1P workload and reportedDISABLEDwithout consulting CMS. Soredpandacould be disabled through its CR whileingestion-gatewaydepended on it, even though the store'sEvaluateDeactivationSafetywould have rejected that.Key Changes
CMSClient, the server adapter and the fakes gainPrepareDeactivationandCompleteDeactivation.PrepareDeactivation{force:false}, then delete the Helm workload, thenCompleteDeactivation, thenUpdateObservedGeneration(DISABLED).FailedPrecondition): the workload is kept. The CR getsDeactivationBlocked=TrueandReady=False/DeactivationBlocked(Degraded=False), with a message naming the active dependents. The check re-runs at most every 30s.DeactivationIncomplete(Degraded=True) and is retried idempotently.ComponentDisabledat the current generation.wasComponentPreviouslyActiveignores never-actuated reasons (DependenciesNotReady,DependencyCycle).Assumptions
NotFound) is disabled without the handshake.Verification & Testing
bazel test //pkg/components/... //cmd/xmc_bridge/...(9/9 pass),./.githooks/pre-commit(pass). Size vs parent: 110 prod / 399 total.TestReconcileComponent_GatedDependentBlocksDeactivationInCMS, which uses the realcms.NewServer,MemoryStoreand adapter;wasComponentPreviouslyActivetable test.Live Deployment & Manual Testing (GKE
..., whole stack + #969/#974)The only action taken was
kubectl patch component <name> --type merge -p '{"spec":{"enabled":<bool>}}'.Live run (sanitized)
Related Issues / Bugs
Found while working on bug 548435582.
TAG=agy
CONV=baca6192-74d3-4579-9f73-0a3263d9a2a7