fix(deployments): handle Docker restart races - #868
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughDocker status handling now safely reads container exit and restart data, conditionally releases GPUs for terminal missing-container states, and covers ChangesDocker status handling
Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
plugins/nemo-deployments/tests/unit/backends/docker/test_backend_mocked.py (1)
124-188: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winNo test coverage for
restart_policy="OnFailure"removed-container recovery.The new recovery logic in
backend.pytriggers for both"Never"and"OnFailure"(Line 290:if restart_policy in ("Never", "OnFailure")), but both test suites only exercise"Never".
plugins/nemo-deployments/tests/unit/backends/docker/test_backend_mocked.py#L124-L188: add a mocked test withrestart_policy="OnFailure"and a non-zero recovered exit code to verify the mapped status (and surface the backoff-bypass behavior flagged inbackend.py).plugins/nemo-deployments/tests/integration/backends/docker/test_docker_backend.py#L119-L162: add an OnFailure-policy variant of the removed-container integration test using a failing command.🤖 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 `@plugins/nemo-deployments/tests/unit/backends/docker/test_backend_mocked.py` around lines 124 - 188, Extend the mocked tests around test_read_status_recovers_removed_never_container_exit_code and test_read_status_failed_when_missing_never_has_no_exit_event in plugins/nemo-deployments/tests/unit/backends/docker/test_backend_mocked.py (lines 124-188) with an OnFailure case using a non-zero recovered Docker die-event exit code and assertions for its mapped status and exit code. Add the corresponding OnFailure removed-container integration-test variant using a failing command in plugins/nemo-deployments/tests/integration/backends/docker/test_docker_backend.py (lines 119-162).
🤖 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.
Inline comments:
In
`@plugins/nemo-deployments/src/nemo_deployments_plugin/backends/docker/backend.py`:
- Around line 399-418: The _read_removed_container_status method must preserve
OnFailure retry behavior instead of directly using map_exited_status for
non-zero exits. Apply the same restart_count/backoff_limit handling used for
in-place container exits so eligible failures return STARTING and retries
continue, while exhausted retries retain the terminal FAILED status.
- Around line 399-453: The current _latest_removed_container_exit_code method
depends on Docker’s bounded one-hour event replay and can miss recent container
exits. Capture and retain each container’s exit code when NotFound is first
detected during read_status, or maintain an equivalent live per-container
die-event cache, then have _read_removed_container_status use that recorded
value before falling back to missing_container_status; preserve existing status
mapping and recovery metadata.
---
Nitpick comments:
In `@plugins/nemo-deployments/tests/unit/backends/docker/test_backend_mocked.py`:
- Around line 124-188: Extend the mocked tests around
test_read_status_recovers_removed_never_container_exit_code and
test_read_status_failed_when_missing_never_has_no_exit_event in
plugins/nemo-deployments/tests/unit/backends/docker/test_backend_mocked.py
(lines 124-188) with an OnFailure case using a non-zero recovered Docker
die-event exit code and assertions for its mapped status and exit code. Add the
corresponding OnFailure removed-container integration-test variant using a
failing command in
plugins/nemo-deployments/tests/integration/backends/docker/test_docker_backend.py
(lines 119-162).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 2a4007df-5e5c-4fdd-a755-a09492bea6f1
📒 Files selected for processing (3)
plugins/nemo-deployments/src/nemo_deployments_plugin/backends/docker/backend.pyplugins/nemo-deployments/tests/integration/backends/docker/test_docker_backend.pyplugins/nemo-deployments/tests/unit/backends/docker/test_backend_mocked.py
|
affb68f to
fd3772a
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 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.
Inline comments:
In
`@plugins/nemo-deployments/src/nemo_deployments_plugin/backends/docker/backend.py`:
- Around line 633-682: Update _read_removed_container_status to accept a dep_key
parameter and release the GPU via self._gpu_pool.release_gpu(dep_key) whenever
recovered exit handling reaches a terminal status, including success and
non-retryable failure, while preserving the retry/STARTING path without release.
Pass deployment_key(workspace, name) from the read_status call site.
- Around line 656-671: Update the OnFailure handling in backend.py around the
restart_policy check to read RestartCount from cached inspect state or another
persisted pre-removal source rather than die-event attrs, preserving the
backoff-limit behavior. In test_backend_mocked.py lines 507-543 and 546-581,
update both unit cases to provide/assert the real persisted restart-count signal
instead of placing restartCount in event attributes.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 098f3f89-e0e0-4944-aa9a-0515eea3c3e6
📒 Files selected for processing (3)
plugins/nemo-deployments/src/nemo_deployments_plugin/backends/docker/backend.pyplugins/nemo-deployments/tests/integration/backends/docker/test_docker_backend.pyplugins/nemo-deployments/tests/unit/backends/docker/test_backend_mocked.py
🚧 Files skipped from review as they are similar to previous changes (1)
- plugins/nemo-deployments/tests/integration/backends/docker/test_docker_backend.py
fd3772a to
cfa5c61
Compare
cfa5c61 to
b22e952
Compare
b22e952 to
bbc4705
Compare
bbc4705 to
453196e
Compare
453196e to
f0f232e
Compare
f0f232e to
92cf59e
Compare
Severity: P3 · Blocking: no Summary: For Not attachable as an inline diff comment (unchanged on this head relative to main after #925). Tracking here so the restart-race gap list is complete. Agent patch snippet: |
tylersbray
left a comment
There was a problem hiding this comment.
agent (): Posted verified findings R1–R7 as inline threads (R6 already as issue comment).
dff0373 to
8353e72
Compare
b091204 to
8b6ad17
Compare
3a5997e to
7a21d4b
Compare
Update Docker deployment status reconciliation to observe Docker inspect state for exited and missing containers. Stopped one-shot containers remain observable, retryable OnFailure exits stay non-terminal until the backoff limit is exhausted, and Docker GPU allocations are released only when status handling reaches a terminal deployment result. Signed-off-by: Ryan S <267728323+ironcommit@users.noreply.github.com>
7a21d4b to
7769766
Compare
Summary
Docker deployment status reads now reconcile from Docker inspect state instead of mutating containers in the read path. This preserves one-shot and retry semantics across controller restarts and avoids releasing Docker GPU allocations before a deployment reaches a terminal status.
This PR no longer carries the Authentik/Envoy keep-alive template changes; that work has already merged into
mainvia #1101.Changes
State.ExitCodeandRestartCountfrom inspect attrs for create-time status mapping andread_status().Nevercontainers observable and report their terminal status without removing them fromread_status().OnFailuredeployments by comparing Docker's persisted restart count with the deployment backoff limit.backoffLimit/backoff_limitvalues inDeploymentConfig, the create request schema, and generated OpenAPI.on-failurerun kwargs againstMaximumRetryCount=0, and treat legacy zero-backoff Docker labels as unlimited retry and non-terminal so GPU allocations are not released while Docker would keep retrying.Alwaysstays recoverable asLOSTwhile one-shot policies report terminal failure when the backend resource is gone.OnFailureexits, missing one-shot containers, lostAlwayscontainers, foreign-container mismatch handling, zero-backoff legacy handling, API/entity validation, and GPU-release behavior.Type of Change
Quality Gates
Verification
Signed-off-by:traileruv run pre-commit run -apasses, or any blocked checks are identified belowTargeted validation:
script/generate-openapi-spec.sh— completed successfully.uv run --frozen pytest plugins/nemo-deployments/tests/unit/test_entities.py plugins/nemo-deployments/tests/unit/test_api_deployment_configs.py plugins/nemo-deployments/tests/unit/backends/docker/test_restart_policy.py plugins/nemo-deployments/tests/unit/backends/docker/test_backend_mocked.py plugins/nemo-deployments/tests/integration/backends/docker/test_docker_backend.py plugins/nemo-deployments/tests/unit/backends/k8s/test_jobs.py -v— 90 passed.uv run pre-commit run -a— blocked by local environment after all other hooks passed. Passed:ruff (legacy alias),ruff format,Run ty typechecks,Check config reference doc is up to date,Helm Docs Container,Run uv lock with platform uv,Check for uv.lock drift,Fix copyright headers,Plugins must not import from nmp-common, andcheck for merge conflicts. Blocked:studio-lint-stagedfailed becauselint-stagedis not installed.git diff --cached --check— passed before amend.git diff --check origin/main...HEAD— passed after amend.origin/main..HEAD— passed for8b6ad17a7.