Skip to content

fix(operator): never resume a disabled NodeWright's suspended Jobs - #422

Open
ayuskauskas wants to merge 8 commits into
feature/package-as-jobsfrom
jobs-migration/411-disable-no-resume
Open

fix(operator): never resume a disabled NodeWright's suspended Jobs#422
ayuskauskas wants to merge 8 commits into
feature/package-as-jobsfrom
jobs-migration/411-disable-no-resume

Conversation

@ayuskauskas

@ayuskauskas ayuskauskas commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator

Refs #411 (item 5a). Does not close it. Part of #223, based on feature/package-as-jobs.

Confirmed

#411 filed this as "needs triage — one reviewer's position, confirm against the code." It holds.

resumeSuspendedJobs is called from the reconcile loop for any Skyhook that is not paused (skyhook_controller.go:463). The only IsDisabled() guard anywhere in that flow is at :556, inside processSkyhooksPerNode — a different function further down, which only stops new work being scheduled.

So this sequence restarted a NodeWright the user had just switched off:

  1. pause → every unfinished Job gets spec.suspend: true, the running stage stops
  2. user clears pause and sets disable in one edit
  3. next reconcile: IsPaused() is false → resumeSuspendedJobs runs → suspend cleared on everything, stages resume

Net effect: disable was strictly weaker than pause for in-flight work. docs/cli.md offered it as "disable completely", directly under the pause example, which is the opposite of what it did.

What this does not change

Disable still does not stop work already running. The design doc is explicit — "disable is unchanged: it skips a Skyhook from processing but has never claimed to halt in-flight work." A stage already under way runs to completion, same as before. The only change is that disable no longer restarts work that pause stopped. Re-enabling resumes them.

Where the guard went, and why

Inside resumeSuspendedJobs, not at the call site.

  • It holds for every caller, so a future call site can't reintroduce this.
  • It is testable. The existing specs call resumeSuspendedJobs directly; a call-site guard would need a full SkyhookReconciler.Reconcile spec, and this controller has none to model on — inventing that pattern to cover a one-line condition is a bad trade, and a test that re-implements the guard to check the guard proves nothing.

I also considered a pause-style continue for disabled in the loop. Rejected: that skips IntrospectSkyhook / SaveNodesAndSkyhook, and a disabled NodeWright still needs its status derived as the in-flight stages it is permitted to finish actually finish. It would have traded this bug for a status-staleness bug.

Docs

docs/cli.md now states the distinction instead of implying disable is the bigger hammer, including that the two compose safely in either order. Written as prose rather than a third stacked blockquote — MD028 rejects adjacent blockquotes separated by a blank line.

Testing

New spec: "does not resume a disabled Skyhook's suspended Jobs", with a fixture that asserts it genuinely reads as disabled before relying on it.

Verified load-bearing — removing the guard fails exactly that spec and nothing else:

[FAIL] Jobs execution swap pause suspend cascade [It] does not resume a disabled Skyhook's suspended Jobs

make unit-tests green, golangci-lint 0 issues, markdownlint-cli2 0 issues.

Closes #423 — the item-2 docs fix (f8194ea4, 19b06b1c) landed here, so that issue is fully covered by this PR.

Item 5a of #411, confirmed against the code. resumeSuspendedJobs is called
from the reconcile loop for any Skyhook that is not paused, and the only
IsDisabled guard in that flow lives in processSkyhooksPerNode, a different
function further down. So clearing the pause annotation and setting disable in
one edit un-suspended every Job pause had suspended: disabling a paused
NodeWright restarted it.

That makes disable strictly weaker than pause for in-flight work, which is the
opposite of how it reads — docs/cli.md offered it as "disable completely",
directly under the pause example.

Disable still does not stop work already running; the design doc is explicit
that it never claimed to. The fix is only that it must not RESTART work pause
stopped. Re-enabling resumes them.

The guard is inside resumeSuspendedJobs rather than at the call site so it
holds for every caller, and because that is where the existing specs already
exercise this behaviour — a call-site guard would have been untestable without
standing up a whole reconcile, and this controller has no full-Reconcile spec
to model one on.

docs/cli.md now states the distinction rather than implying disable is the
bigger hammer. Written as prose rather than a third stacked blockquote, which
MD028 rejects.

Spec verified to fail against the unguarded version.

Refs #411 (item 5a).

Signed-off-by: Alex Yuskauskas <ayuskauskas@nvidia.com>
@github-actions github-actions Bot added doc Documentation change (PR path label; doc issues use the Documentation type) component/operator Skyhook operator (controller-manager) component/ci CI workflows, GitHub Actions, and repo tooling labels Aug 7, 2026
@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It 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 reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The CLI and documentation distinguish pause from disable and describe their interaction. resumeSuspendedJobs now skips disabled Skyhooks. Tests verify that suspended Jobs remain suspended. Migration documentation describes the legacy migration hold and Jobs-only validation.

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

Possibly related PRs

Suggested labels: component/tests

Suggested reviewers: rice-riley, lockwobr

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
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.
Title check ✅ Passed The title clearly and concisely describes the primary operator fix for disabled NodeWrights with suspended Jobs.
Description check ✅ Passed The description directly explains the bug, implementation, tests, and related documentation changes.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch jobs-migration/411-disable-no-resume

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

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🤖 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 `@docs/cli.md`:
- Around line 514-522: Align the disable contract in the documentation and
NewDisableCmd: state that disable prevents new work while allowing an in-flight
stage to finish, rather than stopping all processing. Explicitly document that
removing disable does not resume jobs while the pause condition remains set,
consistent with SkyhookReconciler.Reconcile checking IsPaused() before
resumeSuspendedJobs. Clarify that pause is required to stop currently running
work.
🪄 Autofix

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: ASSERTIVE

Plan: Enterprise

Run ID: b6dafc53-f403-4fec-9f4f-20fc50466c5e

📥 Commits

Reviewing files that changed from the base of the PR and between 15a317f and 27c7fc6.

📒 Files selected for processing (3)
  • docs/cli.md
  • operator/internal/controller/skyhook_controller.go
  • operator/internal/controller/swap_test.go

Comment thread docs/cli.md Outdated
@coveralls

coveralls commented Aug 7, 2026

Copy link
Copy Markdown

Coverage Report for CI Build 31654161533

Warning

Build has drifted: This PR's base is out of sync with its target branch, so coverage data may include unrelated changes.
Quick fix: rebase this PR. Learn more →

Warning

No base build found for commit 5dd9536 on feature/package-as-jobs.
Coverage changes can't be calculated without a base build.
If a base build is processing, this comment will update automatically when it completes.

Coverage: 78.988%

Details

  • Patch coverage: 18 of 18 lines across 2 files are fully covered (100%).

Uncovered Changes

No uncovered changes found.

Coverage Regressions

Requires a base build to compare against. How to fix this →


Coverage Stats

Coverage Status
Relevant Lines: 13535
Covered Lines: 10691
Line Coverage: 78.99%
Coverage Strength: 8.14 hits per line

💛 - Coveralls

CodeRabbit review on #422; all three points were right.

My replacement for "disable completely" was "stop it being processed at all",
which oversells it just as much. It is now "prevent new work being scheduled".

NewDisableCmd still said "Disable a NodeWright completely" and "the operator
will completely stop processing". Updating docs/cli.md without it left the
CLI's own --help contradicting the page, which the repo requires to move
together. Its long help now states that a stage already under way runs to
completion, and that disable never restarts what pause stopped.

The re-enable sentence was wrong, not merely vague. Reconcile hits
`if skyhook.IsPaused() { ...; continue }` before resumeSuspendedJobs, so while
pause is set the resume never runs regardless of disable. "Re-enabling resumes
them" implied enable alone was enough; both annotations have to be cleared.

The command's short help keeps the word "Disable" because lifecycle_test.go
asserts each Short contains its verb — a convention worth conforming to rather
than loosening the test for.

Refs #411 (item 5a).

Signed-off-by: Alex Yuskauskas <ayuskauskas@nvidia.com>
@github-actions github-actions Bot added the component/cli kubectl-skyhook CLI plugin label Aug 7, 2026

@coderabbitai coderabbitai Bot 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.

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 `@docs/cli.md`:
- Line 516: Update the pause guidance in the CLI documentation to qualify its
immediate-stop guarantee by operator version, reflecting that older operators
and pre-upgrade pods may finish the current run before pausing. Keep the
emergency-stop recommendation consistent with this qualification, while
preserving the existing annotation-order behavior.

In `@operator/cmd/cli/app/lifecycle.go`:
- Around line 211-219: Update the help text in NewPauseCmd and NewEnableCmd,
plus the corresponding docs/CLI wording, to match the disable contract: pause
may suspend the current stage for Job-based operators, and enable resumes
processing only when the pause annotation is also cleared. Keep the statements
about already-running work and suspended stages consistent across all three
descriptions.
🪄 Autofix

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: ASSERTIVE

Plan: Enterprise

Run ID: 678871f1-2540-4047-843a-11c554ab567d

📥 Commits

Reviewing files that changed from the base of the PR and between 27c7fc6 and dea6dec.

📒 Files selected for processing (2)
  • docs/cli.md
  • operator/cmd/cli/app/lifecycle.go

Comment thread docs/cli.md
Comment thread operator/cmd/cli/app/lifecycle.go
…ommodations

Item 2 of #411, resolved as a docs fix now that the epic's open question has
an answer: the rename and the Jobs migration ship together.

The Upgrade section specified four in-place accommodations so Jobs and raw
pods could run side by side for a minor release — legacy-aware completion,
existence gating that ORs in raw pods, a legacy sweep in validation, and
direct deletion of legacy erroring pods on config update. None were built.
That was not an oversight; they were superseded by legacyMigrationHold, which
takes a stricter line: it runs first in Reconcile and requeues while any
pre-rename Skyhook is still rolling out, so the two execution models never
overlap rather than being taught to coexist.

Shipping the two together is what makes that work, and the section now says
so. Had the rename landed in an earlier release, the preceding operator would
already be nodewright-native, no legacy Skyhook objects would exist, the hold
would never fire, and its raw pods would carry labels the legacy sweep does
not select — and the accommodations really would have been required.

Also records the one case the hold does not cover: it treats a paused legacy
Skyhook as not-in-flight so migration does not force an unpause, but pre-Jobs
pause never stopped a running pod. Unpausing such a Skyhook on the new
operator before its pod finishes puts a Job alongside it on the same host
copyDir. Narrow, idempotent in practice via the agent's flag files, and now
written down rather than discovered later.

ValidateRunningPackages claimed a legacy raw-pod sweep ran alongside its Job
checks. It never did; the comment now says why it walks Jobs only.

Refs #411 (item 2).

Signed-off-by: Alex Yuskauskas <ayuskauskas@nvidia.com>

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🤖 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 `@docs/designs/2026-07-10-package-execution-as-jobs.md`:
- Around line 230-234: Update legacyMigrationHold to account for active raw pods
belonging to paused or disabled legacy Skyhooks, preventing NodeWright Jobs from
starting on their hosts until those pods terminate; alternatively block
NodeWright scheduling through the equivalent safeguard. Add a regression test
covering upgrade, paused legacy execution, and subsequent unpause, and revise
the documented non-overlap guarantee only if the overlap is intentionally
retained.
🪄 Autofix

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: ASSERTIVE

Plan: Enterprise

Run ID: be8553a3-bfe2-47c0-8651-5de93f8574ac

📥 Commits

Reviewing files that changed from the base of the PR and between dea6dec and f8194ea.

📒 Files selected for processing (2)
  • docs/designs/2026-07-10-package-execution-as-jobs.md
  • operator/internal/controller/skyhook_controller.go

Comment thread docs/designs/2026-07-10-package-execution-as-jobs.md Outdated
…e overlap safe

CodeRabbit review on #422. Three findings; a fourth comment was it confirming
the previous round rather than a new issue.

NewPauseCmd still said pause "will not interrupt any currently running
operations" — the pre-Jobs behaviour. NewEnableCmd said the operator "will
resume normal processing after this command", which is untrue while pause is
still set. Fixing disable's help last round and leaving its two siblings stale
was the same miss the previous review caught, one command over. Both now
describe what the Jobs path actually does, pause version-qualified because its
stop-strength depends on the operator generation.

docs/cli.md asserted pause halts running work and then, fourteen lines later,
said older operators let the current run finish. Now version-qualified inline
instead of relying on the reader following a pointer.

The design doc's paused-legacy note leaned on the agent's flag files as if they
made the overlap safe. They do not: they make re-execution idempotent, they are
not a lock, and they neither serialize two executors nor order concurrent writes
into the shared copyDir. The same overstatement is being corrected on #421. The
note now says the overlap is unguarded while the window is open, and names what
closing it would take — teaching the in-flight gate to count legacy raw pods.

Refs #411 (items 2 and 5a).

Signed-off-by: Alex Yuskauskas <ayuskauskas@nvidia.com>
@ayuskauskas

Copy link
Copy Markdown
Collaborator Author

Three findings addressed in a91634b (the fourth comment was you confirming the previous round, not a new issue).

Synchronize the pause and enable help — correct, and it's the same miss you caught last round, one command over. NewPauseCmd still said pause "will not interrupt any currently running operations", which is the pre-Jobs behaviour; NewEnableCmd said the operator "will resume normal processing after this command", which is untrue while pause is still set. I fixed disable's help and left both siblings stale. Both now describe what the Jobs path does, with pause version-qualified because its stop-strength depends on the operator generation.

Qualify the pause guarantee by version — right. I'd written "halts work already running" with a "(see the version note below)" pointer, and fourteen lines later the note contradicts the sentence. Relying on the reader following a pointer is not the same as being accurate. Now qualified inline.

The paused-legacy overlap — you're right about the safety claim, and I've fixed that: I leaned on the agent's flag files as though they made the overlap safe. They don't. They make re-execution idempotent, they are not a lock, and they neither serialize two executors nor order concurrent writes into the shared copyDir. (The same overstatement is being corrected on #421, which you also caught there.) The note now says the overlap is unguarded while the window is open.

On closing it rather than documenting it — that's a maintainer decision that has already been made, and I'm recording it rather than overriding it. The epic owner confirmed the rename and the Jobs migration ship together, and chose to document this window rather than close it. I flagged the fix at the time and have named it again in the note: teach the in-flight gate to count legacy raw pods, so a Job is not created beside one. It's one extra list call in JobExists.

For the record, two independent reviewers have now landed on this same point, which I've said on #411. If a maintainer wants it closed before merge I'll do it — but I'm not going to quietly reverse an explicit decision inside a docs commit.

make unit-tests green, golangci-lint 0 issues, markdownlint-cli2 0 issues.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
docs/designs/2026-07-10-package-execution-as-jobs.md (1)

230-234: ⚠️ Potential issue | 🟠 Major

Do not leave the legacy execution overlap unguarded.

The migration hold excludes paused and disabled legacy Skyhooks, but pre-Jobs pause does not stop a running raw pod. If the new operator unpauses or enables that Skyhook before the raw pod exits, a Job can run beside the raw pod on the same host and write to the same copyDir.

Make the hold wait for active legacy raw pods regardless of pause or disable state, or block Job scheduling until those pods terminate. Add a regression test for the upgrade and unpause/enable sequence.

🤖 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 `@docs/designs/2026-07-10-package-execution-as-jobs.md` around lines 230 - 234,
The legacy migration hold must also account for active raw pods belonging to
paused or disabled legacy Skyhooks, preventing NodeWright Jobs from starting
beside them on the same host and copyDir. Update legacyMigrationHold and its
in-flight detection to wait until those pods terminate, while preserving
existing handling for rollout, rollback, and deletion states. Add a regression
test covering upgrade followed by unpause or enable before the legacy raw pod
exits.
♻️ Duplicate comments (1)
docs/cli.md (1)

514-516: ⚠️ Potential issue | 🟠 Major

Keep the emergency-stop guidance version-qualified.

Line 514 states that older operators only block new scheduling. Line 516 then says that pause stops everything immediately. This can cause operators to expect a running stage to stop on an older operator.

Replace the final sentence with guidance that qualifies immediate suspension to Job-based operators.

🤖 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 `@docs/cli.md` around lines 514 - 516, Update the final emergency-stop sentence
in the pause/disable documentation to qualify immediate suspension as applying
only to operators that run package stages as Jobs. Preserve the existing
distinction that older operators merely block new scheduling, and avoid implying
that pause can stop an already-running stage on those versions.
🤖 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 `@operator/cmd/cli/app/lifecycle.go`:
- Around line 243-245: Update the enable help text near the NodeWright
scheduling description to replace the incomplete phrase “Stages that pause
suspended resume” with “Stages suspended by pause resume,” preserving the
surrounding explanation and behavior.

---

Outside diff comments:
In `@docs/designs/2026-07-10-package-execution-as-jobs.md`:
- Around line 230-234: The legacy migration hold must also account for active
raw pods belonging to paused or disabled legacy Skyhooks, preventing NodeWright
Jobs from starting beside them on the same host and copyDir. Update
legacyMigrationHold and its in-flight detection to wait until those pods
terminate, while preserving existing handling for rollout, rollback, and
deletion states. Add a regression test covering upgrade followed by unpause or
enable before the legacy raw pod exits.

---

Duplicate comments:
In `@docs/cli.md`:
- Around line 514-516: Update the final emergency-stop sentence in the
pause/disable documentation to qualify immediate suspension as applying only to
operators that run package stages as Jobs. Preserve the existing distinction
that older operators merely block new scheduling, and avoid implying that pause
can stop an already-running stage on those versions.
🪄 Autofix

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: ASSERTIVE

Plan: Enterprise

Run ID: 8f8fc435-e397-47dc-b8d0-762e8e44f7a1

📥 Commits

Reviewing files that changed from the base of the PR and between f8194ea and a91634b.

📒 Files selected for processing (3)
  • docs/cli.md
  • docs/designs/2026-07-10-package-execution-as-jobs.md
  • operator/cmd/cli/app/lifecycle.go

Comment thread operator/cmd/cli/app/lifecycle.go Outdated
Closes the paused-legacy overlap by contract rather than in code, per the
epic owner's call and after two reviewers raised it.

The migration guide told users that paused and disabled Skyhooks are fine to
leave as-is and need no unpausing before upgrade. That is still true for the
migration itself — they migrate in that state and do not roll out. What it did
not say is that pause on the pre-rename operator only blocked new scheduling
and never stopped a pod already running, so a Skyhook paused shortly before the
upgrade can still have one, and unpausing while it runs lets the new operator
start a stage Job beside it: the in-flight gate counts Jobs, not raw pods, and
both executors share one package directory on the host with nothing ordering
their writes.

That sequence is now documented as unsupported, with the check to run first
(list the legacy-labelled pods and wait for it to be empty) and the reassurance
that leaving it paused is safe indefinitely, since the new operator suspends
and skips it and creates no Jobs at all.

The design doc records why this is contract rather than code: guarding it would
mean teaching the in-flight gate to count legacy raw pods, and the reason the
rename and the Jobs migration ship together is precisely so the two execution
models never have to coexist. One narrow, opt-in sequence did not justify
carrying legacy-pod awareness into the gate for a release.

Refs #411 (item 2).

Signed-off-by: Alex Yuskauskas <ayuskauskas@nvidia.com>
@ayuskauskas

Copy link
Copy Markdown
Collaborator Author

Closed in 19b06b1by contract, not in code. Maintainer's call, recorded here so the reasoning isn't lost.

docs/nodewright-migration.md told users that paused and disabled Skyhooks are fine to leave as-is and need no unpausing before upgrade. That remains true for the migration itself — they migrate in that state and don't roll out. What it never said is that pause on the pre-rename operator only blocked new scheduling and never stopped a pod already running.

So the guide now carries an explicit warning: unpausing a migrated NodeWright while its pre-upgrade package pods are still running is unsupported. With the check to run first —

kubectl get pods -n skyhook -l skyhook.nvidia.com/name=<skyhook-name>

— wait for it to come back empty. And the reassurance that matters operationally: leaving it paused is safe indefinitely. The new operator suspends and skips a paused NodeWright and creates no Jobs at all, so there is no pressure to unpause quickly. Those pods finish on their own and the legacy sweep clears them once LEGACY_CLEANUP_DELAY elapses.

The design doc records why this is contract rather than a guard: closing it in code means teaching the in-flight gate to count legacy raw pods, and the reason the rename and the Jobs migration ship together is precisely so the two execution models never have to coexist. Carrying legacy-pod awareness into the gate for one narrow, opt-in sequence — for a single release — wasn't judged worth it.

To be straight about what this does and doesn't do: it removes the unwitting path. A user following the guide won't hit it. A user who ignores the warning still can, and the outcome is two executors sharing one host directory with nothing ordering their writes. That's the trade being accepted, and it's now written down in both the guide and the design doc rather than living in a PR thread.

markdownlint-cli2 0 issues.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🤖 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 `@docs/nodewright-migration.md`:
- Around line 233-241: Update docs/nodewright-migration.md lines 233-241 to
prohibit both unpausing and enabling a migrated NodeWright until all pre-upgrade
package pods are gone, while preserving the existing safety guidance. Update
docs/designs/2026-07-10-package-execution-as-jobs.md line 234 to include
enabling disabled legacy Skyhooks in the unsupported paused-pod overlap
sequence.
🪄 Autofix

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: ASSERTIVE

Plan: Enterprise

Run ID: 6e9ab481-c9d4-4c65-b645-f3438c8a3b4e

📥 Commits

Reviewing files that changed from the base of the PR and between a91634b and 19b06b1.

📒 Files selected for processing (2)
  • docs/designs/2026-07-10-package-execution-as-jobs.md
  • docs/nodewright-migration.md

Comment thread docs/nodewright-migration.md Outdated
"Stages that pause suspended resume" reads as a fragment. Say "stages
suspended by pause" so the condition is unambiguous.

Signed-off-by: Alex Yuskauskas <ayuskauskas@nvidia.com>
… pod

The overlap warning named only the pause/unpause sequence, but the
migration hold treats a paused OR disabled legacy Skyhook as
not-in-flight, and pre-Jobs disable no more stopped a running pod than
pause did: processSkyhooksPerNode skips a disabled Skyhook without
touching its pods. So enabling a disabled Skyhook over a live raw pod
puts a Job beside it exactly as unpausing does, and both transitions
need the same pre-check.

Also closes the blockquote before "The runtime hold only waits on
Skyhooks..." — the warning had swallowed the first three words of the
sentence that follows it, leaving the paragraph starting mid-clause.

Signed-off-by: Alex Yuskauskas <ayuskauskas@nvidia.com>
…bs-migration/411-disable-no-resume

Signed-off-by: Alex Yuskauskas <ayuskauskas@nvidia.com>

# Conflicts:
#	operator/internal/controller/skyhook_controller.go
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component/ci CI workflows, GitHub Actions, and repo tooling component/cli kubectl-skyhook CLI plugin component/operator Skyhook operator (controller-manager) doc Documentation change (PR path label; doc issues use the Documentation type)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants