fix: enforce strict Sandbox-to-Pod mapping - #1337
Conversation
✅ Deploy Preview for agent-sandbox canceled.
|
|
Hi @alanhuangch. Thanks for your PR. I'm waiting for a kubernetes-sigs member to verify that this patch is reasonable to test. If it is, they should reply with Regular contributors should join the org to skip this step. Once the patch is verified, the new status will be reflected by the I understand the commands that are listed here. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
🚧 Files skipped from review as they are similar to previous changes (3)
📝 Walkthrough📝 Walkthrough🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
controllers/sandbox_controller_test.go (1)
3158-3160: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winTest preservation of an existing Service.
This test proves that reconciliation does not create a Service. It does not prove that reconciliation leaves an existing Service unchanged. Seed a Service with distinct metadata and spec, then assert it is unchanged after the ownership conflict.
As per coding guidelines, new behavior requires a unit test.
🤖 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 `@controllers/sandbox_controller_test.go` around lines 3158 - 3160, Extend the test around the ambiguous Pod mapping reconciliation to seed an existing Service with distinct metadata and spec before reconciliation, then retrieve it afterward and assert those fields remain unchanged. Preserve the existing not-found assertion only for the no-Service case, and use the relevant reconciliation/test setup symbols already present to verify ownership conflict does not modify the preexisting Service.Source: Coding guidelines
🤖 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.
Nitpick comments:
In `@controllers/sandbox_controller_test.go`:
- Around line 3158-3160: Extend the test around the ambiguous Pod mapping
reconciliation to seed an existing Service with distinct metadata and spec
before reconciliation, then retrieve it afterward and assert those fields remain
unchanged. Preserve the existing not-found assertion only for the no-Service
case, and use the relevant reconciliation/test setup symbols already present to
verify ownership conflict does not modify the preexisting Service.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 41f2b67f-a02d-471e-9b69-274481f39a03
📒 Files selected for processing (4)
api/v1beta1/sandbox_types.gocmd/agent-sandbox-controller/main.gocontrollers/sandbox_controller.gocontrollers/sandbox_controller_test.go
There was a problem hiding this comment.
Pull request overview
This PR tightens the Sandbox controller’s invariant that a Sandbox maps to at most one backing Pod by treating the tracking label as an index and using the controller ownerReference UID as the authoritative mapping. It also introduces a fail-closed behavior (Ready=False with reason MultiplePods + Warning Event) when multiple Pods are controlled by the same Sandbox UID, avoiding further Pod/Service reconciliation until the conflict is resolved.
Changes:
- Classify Pod candidates by controller owner UID, recover a unique owned Pod when the tracked pod-name annotation is stale/missing, and refuse to act when multiple owned Pods exist.
- Suppress routing Service reconciliation during Pod-mapping ambiguity and surface a stable Ready=False reason (
MultiplePods) plus a Warning Event. - Add unit tests covering owned-Pod recovery, stale adoption avoidance, terminating owned Pod handling, and multiple-owned-Pod fail-closed behavior.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| controllers/sandbox_controller.go | Adds owned-Pod filtering/recovery, fail-closed error type + Event emission, and condition handling for MultiplePods conflicts. |
| controllers/sandbox_controller_test.go | Adds regression/unit tests for owned-Pod recovery, conflict behavior, and event/condition surfacing. |
| cmd/agent-sandbox-controller/main.go | Wires an EventRecorder into the Sandbox reconciler. |
| api/v1beta1/sandbox_types.go | Introduces SandboxReasonMultiplePods for Ready condition reporting. |
GonzaloLuminary
left a comment
There was a problem hiding this comment.
I think requiring manual remediation to fix this scenario is not ideal
|
@GonzaloLuminary Thanks — I agree that requiring manual remediation as the normal recovery path would not be ideal. This PR prevents the controller from creating this state. Manual action is only required for a pre-existing or externally corrupted state with multiple non-terminating Pods. If an extra Pod is already terminating, its deletion event requeues the Sandbox and reconciliation recovers automatically. I chose fail-closed because all conflicting Pods have the current Sandbox UID as their controller owner and may be stateful. The owner UID proves membership, but neither the owner reference nor the tracking label identifies which Pod contains the canonical state. Choosing by annotation, name, readiness, or age could delete the wrong Pod in compatibility and upgrade scenarios. Would you prefer a specific deterministic cleanup rule in this PR? Issue #1297 is moving toward enforcing Pod.Name == Sandbox.Name. Once that invariant and its migration behavior are established, keeping the same-name Pod and deleting other owned Pods would be much safer. My preference is to keep this fix focused on preventing new duplicates and surfacing existing conflicts, then design automatic remediation together with #1297, unless maintainers prefer a specific deletion policy here. |
|
/lgtm |
|
/retest |
Use controller owner UIDs to recover a unique owned Pod when the pod-name annotation is stale or missing. Fail closed when multiple Pods are owned, surface a Ready condition and Warning Event, and avoid creating overlapping Pods or routing Services.
Extract the typed multipleSandboxPodsError from joined reconcile errors so transient dependency failures do not change the MultiplePods condition message. Add regression coverage for a joined PVC error.
ba105b1 to
7c48605
Compare
|
@aditya-shantanu Rebased the PR onto the latest upstream/main. Could you please take another look at the updated changes? |
|
@alanhuangch: The following test failed, say
Full PR test history. Your PR dashboard. Please help us cut down on flakes by linking to an open issue when you hit one in your PR. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here. |
|
/lgtm |
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: aditya-shantanu, alanhuangch The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
What this PR does / why we need it:
The Sandbox controller could create an additional Pod when the pod-name annotation was stale or missing even though a Pod controlled by the same Sandbox UID still existed.
This PR treats the tracking label as a candidate index and the controller owner-reference UID as the authoritative Sandbox-to-Pod mapping. It recovers a unique owned Pod instead of adopting or creating another Pod, and waits for an owned terminating Pod rather than overlapping it.
If multiple Pods are controlled by the same Sandbox UID, reconciliation now fails closed: it does not select, create, or delete a Pod; it does not create or modify the routing Service; and it reports Ready=False with reason MultiplePods plus a Warning Event. This preserves stateful Pods for operator inspection and avoids hot-loop retries while the conflict remains unchanged.
Which issue(s) this PR is related to:
Fixes #1332
Follow-up to #127.
Related to #1297.
Release Note
Summary by CodeRabbit
Bug Fixes
Tests