Skip to content

feat(api): publish restore outcome classifier - #130

Open
julienmancuso wants to merge 1 commit into
mainfrom
jsm/restore-outcomes
Open

feat(api): publish restore outcome classifier#130
julienmancuso wants to merge 1 commit into
mainfrom
jsm/restore-outcomes

Conversation

@julienmancuso

@julienmancuso julienmancuso commented Aug 28, 2026

Copy link
Copy Markdown

Summary

  • publish stable Pending, Succeeded, Failed, and PartiallySucceeded restore outcomes
  • classify the public nvidia.com/Restored Pod condition without requiring consumers to parse private dependency reasons
  • make the node agent use the public terminal reason constants and classifier

Part of ai-dynamo/dynamo#13919.

Validation

  • GOCACHE=/private/tmp/snapshot-outcomes-go-cache go test ./... in api/
  • make linux-test (all agent packages)
  • Linux cross-compilation of agent/internal/controller

make lint could not run locally because the installed golangci-lint binary was built with Go 1.24, below this repository's Go 1.26.6 module version.

Summary by CodeRabbit

  • New Features

    • Added standardized restore status reporting for pending, successful, failed, and partially successful restores.
    • Improved handling of restore outcomes when status conditions are missing, unknown, or incomplete.
  • Bug Fixes

    • Restore completion detection now consistently reflects the reported restore outcome.

Signed-off-by: Julien Mancuso <jmancuso@nvidia.com>
@coderabbitai

coderabbitai Bot commented Aug 28, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: d6c7e6c7-5880-42db-a2fb-1c0f524e28e1

📥 Commits

Reviewing files that changed from the base of the PR and between c1206a4 and 6c19957.

📒 Files selected for processing (4)
  • agent/internal/controller/controller.go
  • agent/internal/controller/controller_test.go
  • api/v1alpha1/restore_status.go
  • api/v1alpha1/restore_status_test.go

Included review availability: Your plan provides up to 12 included reviews per hour; 10 remain after this review.


Walkthrough

The API now defines shared restore outcomes and classifies Pod conditions. The restore controller uses these outcomes and shared reason constants. Controller tests now validate the exported constants.

Changes

Restore outcome handling

Layer / File(s) Summary
Define and test restore outcome classification
api/v1alpha1/restore_status.go, api/v1alpha1/restore_status_test.go
Adds restore outcome and reason constants. ClassifyRestoreOutcome maps conditions to pending, succeeded, failed, or partially succeeded outcomes.
Use shared restore outcomes in the controller
agent/internal/controller/controller.go
Removes local reason constants and uses shared constants and ClassifyRestoreOutcome for restore status handling.
Align controller tests with the shared contract
agent/internal/controller/controller_test.go
Updates restore fixtures and assertions to use exported API reason constants.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Merge Risk: ⚪ Minimal · up to 6c199

This change publishes restore outcome classification and updates the node agent to use the public constants and classifier; no actionable merge-blocking risk remains after normal checks and review.

Sequence Diagram(s)

sequenceDiagram
  participant RestoreController
  participant ClassifyRestoreOutcome
  participant RestoredPodConditions
  RestoreController->>ClassifyRestoreOutcome: classify conditions
  ClassifyRestoreOutcome->>RestoredPodConditions: scan Restored condition
  RestoredPodConditions-->>ClassifyRestoreOutcome: status and reason
  ClassifyRestoreOutcome-->>RestoreController: RestoreOutcome
Loading
🚥 Pre-merge checks | ✅ 6 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 12.50% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 16 functions across 4 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (6 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title uses the required conventional commit prefix feat, stays within 72 characters, and accurately describes the public restore outcome classifier added by the pull request.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Breaking Api Changes ✅ Passed No breaking API change matches the custom check. The exact pull-request diff adds only api/v1alpha1/restore_status.go and its test under api/**; it does not modify any existing API struct field, G…
Rbac Least Privilege ✅ Passed PASS — The pull request changes only controller and API status-classification code and tests. It adds no kubebuilder RBAC markers or Helm RBAC manifests. Repository RBAC markers and Helm Role/ClusterR…
Full details: Breaking Api Changes

Explanation

No breaking API change matches the custom check. The exact pull-request diff adds only api/v1alpha1/restore_status.go and its test under api/**; it does not modify any existing API struct field, Go field type, or JSON tag. The new API file contains only RestoreOutcome, constants, and ClassifyRestoreOutcome, with no exported fields. The self == oldSelf XValidation markers for both PodSnapshotSpec and PodSnapshotContentSpec are unchanged from HEAD^.

Full details: Rbac Least Privilege

Explanation

PASS — The pull request changes only controller and API status-classification code and tests. It adds no kubebuilder RBAC markers or Helm RBAC manifests. Repository RBAC markers and Helm Role/ClusterRole rules use explicit verbs and resources; no wildcard * grant appears.

  • Fix all pre-merge checks with AI

Warning

Some tools did not complete. Review the errors below.

🔧 golangci-lint (2.12.2)

Error: can't load config: unsupported version of the configuration: "" See https://golangci-lint.run/docs/product/migration-guide for migration instructions
The command is terminated due to an error: can't load config: unsupported version of the configuration: "" See https://golangci-lint.run/docs/product/migration-guide for migration instructions


Comment @coderabbitai help to get the list of available commands.

@galletas1712 galletas1712 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing to watch for when later PRs land — details on the classifier below.

return RestoreOutcomeFailed
case RestoreReasonPartiallySucceeded:
return RestoreOutcomePartiallySucceeded
default:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right now, any reason this function doesn't recognize is treated as "restore is still in progress." That's fine for "we're waiting for the snapshot."

There's a draft PR (#97) that will add a new final reason: RestoreIncompatible. That means the node looked at the checkpoint and said no. This code would call that "still in progress," and Dynamo would wait forever instead of starting a new Pod.

You don't have to change this PR for that. When #97 lands, add a case for RestoreIncompatible. A test that goes through every RestoreReason* and checks the finished ones aren't reported as Pending would keep this from happening again.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. #130 intentionally classifies only the public reasons that exist today. I am leaving it unchanged as suggested; when #97 lands, RestoreIncompatible should be added to the terminal classifier together with an exhaustive test over every exported RestoreReason* constant, so a new terminal outcome cannot silently fall back to Pending.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants