Skip to content

fix(gpu): preserve customer-installed PIS drivers - #9702

Open
Ben Brady (benjamin-brady) wants to merge 26 commits into
mainfrom
bbrady/pis-preserve-customer-gpu-driver
Open

Ben Brady (benjamin-brady) wants to merge 26 commits into
mainfrom
bbrady/pis-preserve-customer-gpu-driver

Conversation

@benjamin-brady

@benjamin-brady Ben Brady (benjamin-brady) commented Oct 5, 2026 •

Copy link
Copy Markdown
Member

What this PR does / why we need it:

PIS-derived nodes skip basePrep, but their nodePrep previously deleted customer-installed GPU drivers. Clean AKS-owned artifacts before customer customization, then preserve the customer driver on derived nodes.

flowchart LR
    A[New AKS source VHD] --> B[basePrep: verify AKS GPU cleanup]
    B --> C[Customer installs driver]
    C --> D[Capture PIS image]
    D --> E[Derived node: preserve driver]
Loading
ID Change
G1 Bake the Ubuntu cleanup helper into all four Ubuntu Packer configurations, omitted from CustomData. Retain CUDA and Grace Blackwell package/BOM cleanup, ownership checks and retry handling.
G2 Fail the bake if cleanup fails; write base_prep.complete only after success. Azure Linux retains distro-specific cleanup.
G3 Run final destructive cleanup only when basePrep ran in the same execution. Ordinary-node ordering and legacy skip-tag behavior are unchanged.
G4 Six template-guard lines omit Azure Linux-only AMD code from other known distro payloads. Raw baked scripts and unknown custom-image implementations are retained.
G5 E2E: baked-script bake, customer driver installation, capture, traditional derived-node delivery, then installer/module/nvidia-smi validation. The CustomData guard uses the effective NBC flag rather than the global scriptless default.
G6 GPU pipeline accepts scenarioFilter for a targeted fresh-image run; its default remains gpu=true. Missing source images still fail.

Compatibility: all opted-out Ubuntu PIS bakes, including CPU-only pools, require a new source VHD containing the helper. This broader requirement is intentional and accepted; a missing helper fails explicitly. Ordinary and derived nodes do not require the helper. Old CSEs can still delete customer drivers; existing captures do not gain bake-time cleanup retroactively. GRID mismatch/validation paths are unchanged. No dependency on #9609 or #9753; general compression changes and the unrelated lint pin were removed.

Payload: the synthetic traditional Ubuntu 22.04/24.04 T4 fixture on base f3163c3013e5 (2026-10-22) measures 65,241 gzip bytes / 86,988 Base64 characters, leaving 294 bytes / 392 characters. Production/Packer code is unchanged by subsequent test/CI fixes. This narrow margin is not a guarantee for all customer/custom-cloud configurations.

Review scope: 884 additions / 9 deletions (893 changed lines, down from 1,423). Both GPU implementations remain. Focused preservation, fail-closed cleanup, GB ownership/retry, payload, AMD equivalence and Packer tests remain; exhaustive matrices were removed.

ID Exact validation command Result
V1 `go test ./pkg/agent -run '^(TestPISGPU TestGPUAMA)' -count=1 -v`
V2 cd e2e && go test ./scenario -count=1 Passed after E2E guard fix.
V3 cd e2e && go test ./scenario -run '^TestCreateVMSSModelHonorsScriptlessNBCOverride$' -count=1 Failed before guard fix; passed after fix and test simplification.
V4 docker run --rm -e TMPDIR=/workspace/.copilot-test-tmp -v "$PWD:/workspace" -w /workspace shellspec-docker --shell bash --format d spec/parts/linux/cloud-init/artifacts/cse_main_gpu_pis_spec.sh Passed: 4 examples.
V5 docker run --rm -e TMPDIR=/workspace/.copilot-test-tmp -v "$PWD:/workspace" -w /workspace shellspec-docker --shell bash --format d spec/parts/linux/cloud-init/artifacts/cse_install_ubuntu_gpu_pis_spec.sh Passed: 3 examples.
V6 docker run --rm -e TMPDIR=/workspace/.copilot-test-tmp -v "$PWD:/workspace" -w /workspace shellspec-docker --shell bash --format d spec/parts/linux/cloud-init/artifacts/cse_install_mariner_spec.sh Passed: 59 examples.
V7 docker run --rm -e TMPDIR=/workspace/.copilot-test-tmp -v "$PWD:/workspace" -w /workspace shellspec-docker --shell bash --format d spec/vhdbuilder/packer/pis_gpu_helper_spec.sh Passed: 2 examples.
V8 gofmt -d pkg/agent/gpu_pis_delivery_test.go; git diff --check Passed; diff check repeated before subsequent pushes.

GPU pipeline YAML parsed successfully; parameter default and missing-image failure behavior checked locally. The larger pre-slimming suites also passed in an isolated worktree at bb5b398e95 (2026-10-23 NZDT), but are not claimed as retained coverage. Independent review found no significant issues in the GPU implementation or test slimming. Repository-wide local ShellCheck previously panicked in unchanged publish-generalized-cvm-if-required.sh; scoped checks and pre-slimming CI ShellCheck passed.

Live E2E pending. GPU build 187228397 failed at the now-fixed CustomData guard and used a main image; it is not fresh-helper proof. The targeted run must use a successful branch-built 2404gen2containerd image available in westus3. Metadata is inspected externally; this GPU pipeline selects the image by VHD_BUILD_ID / gallery buildId tag, not by consuming metadata. Verify the selected resource ID equals the metadata ID, then verify the run logs before counting the result. Missing-image skips are not passes. No fresh-image preservation pass is claimed yet.

Which issue(s) this PR fixes:

Fixes AB#39923593 (Don't delete user installed GPU drivers); depends on AB#39198532.

Copilot AI balanced review requested due to automatic review settings October 5, 2026 00:28
@github-actions

github-actions Bot commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

Windows Unit Test Results

  3 files   18 suites   1m 5s ⏱️
563 tests 563 ✅ 0 💤 0 ❌
585 runs  585 ✅ 0 💤 0 ❌

Results for commit 3022615.

♻️ This comment has been updated with latest results.

Copilot AI 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.

Copilot review overview

🟡 Changes recommended

The E2E sentinel can survive destructive cleanup and incorrectly report that customer drivers were preserved.

Review effort: Balanced
Findings: 1 Medium severity

Open (1)
What changed in this PR

Preserves customer-installed GPU drivers on PIS-derived nodes by moving managed-driver cleanup to image preparation.

Changes:

  • Adds verified distro-specific bake cleanup and success-only completion markers.
  • Restricts destructive node cleanup to runs that execute basePrep.
  • Adds ShellSpec checks and a GPU VHD-caching scenario.
File Description
spec/​parts/​linux/​cloud-init/​artifacts/​cse_main_gpu_pis_spec.sh Tests cleanup across PIS phases.
spec/​parts/​linux/​cloud-init/​artifacts/​cse_install_ubuntu_spec.sh Tests Ubuntu cleanup verification.
spec/​parts/​linux/​cloud-init/​artifacts/​cse_install_mariner_spec.sh Tests cache cleanup verification.
parts/​linux/​cloud-init/​artifacts/​ubuntu/​cse_install_ubuntu.sh Verifies driver teardown before capture.
parts/​linux/​cloud-init/​artifacts/​mariner/​cse_install_mariner.sh Verifies bake-time cache removal.
parts/​linux/​cloud-init/​artifacts/​cse_start.sh Marks only successful image preparation.
parts/​linux/​cloud-init/​artifacts/​cse_main.sh Gates cleanup by provisioning phase.
e2e/​scenario/​types.go Adds a post-basePrep callback.
e2e/​scenario/​scenario.go Registers GPU driver-preservation scenario.
e2e/​scenario/​provision.go Runs callback and installs sentinel.

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread e2e/scenario/provision.go Outdated
Copilot AI balanced review requested due to automatic review settings October 5, 2026 01:57

Copilot AI 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.

Copilot review overview

🔵 Needs a closer look

Cross-distro GPU cleanup and PIS compatibility need final human review while the latest integration gates are reported as pending.

Review effort: Balanced
Findings: None

Resolved since last review (1)

Copilot AI balanced review requested due to automatic review settings October 5, 2026 03:02

Copilot AI 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.

Copilot review overview

🟡 Changes recommended

Cleanup verification rejects opted-out Grace Blackwell PIS bakes because their package-installed drivers are not removed.

Review effort: Balanced
Findings: 1 High severity

Open (1)

Comment thread parts/linux/cloud-init/artifacts/ubuntu/cse_install_ubuntu.sh Outdated
Clean AKS-owned artifacts before PIS customization and verify teardown independently of the prebake marker. Preserve customer drivers on derived nodes while retaining non-PIS cleanup.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@benjamin-brady
Ben Brady (benjamin-brady) force-pushed the bbrady/pis-preserve-customer-gpu-driver branch from 2cbf2cf to d9ddd90 Compare October 5, 2026 04:52
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings October 5, 2026 09:58

Copilot AI 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.

Copilot review overview

🔵 Needs a closer look

Cross-distro destructive GPU cleanup changes need human review while the reported CI gates remain failed or pending.

Review effort: Balanced
Findings: 1 High severity

Open (1)

Install a cached NVIDIA driver through customer RunCommand, then check
version, binary/module hashes and GPU functionality on the derived node.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings October 5, 2026 10:47
Use staged GB BOM versions to identify package ownership before PIS
customization. Support both GB200 and current layouts; retain failure
state when module teardown or initramfs rebuild cannot complete.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot AI 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.

Copilot review overview

🟡 Changes recommended

Successful legacy Grace Blackwell teardown leaves subsequent basePrep retries unable to complete after a later failure.

Review effort: Balanced
Findings: 1 High severity

Open (1)
Resolved since last review (1)

Comment thread parts/linux/cloud-init/artifacts/ubuntu/cse_install_ubuntu.sh Outdated
@aks-node-assistant

Copy link
Copy Markdown
Contributor

AgentBaker Linux gate detective

Run: 184124893
Failed job/stage/task: e2e / Run AgentBaker E2E / Run AgentBaker E2E

Detective summary: E2E finished with VHDCaching scenarios failing only in cleanup while deleting gallery image versions; ARM returned ScopeLocked for resource group abe2e-westus3 after validation had completed.

Likely cause / signature: e2e-vhdcaching-gallery-image-delete-scopelocked - VHDCaching scenario validation passed, but cleanup failed deleting SIG gallery image versions because resource group abe2e-westus3 was scope-locked.

Confidence: High for E2E cleanup/SIG resource-group lock infra flake.

Recommended owner/action: E2E/VHD infra owners should remove or avoid the abe2e-westus3 scope lock for VHDCaching cleanup, or make cleanup tolerate locked resources without failing completed validation.

Strongest alternative: PR 9702 changes E2E cleanup/provisioning code, so a cleanup regression is plausible; however, the same locked resource-group signature also appears on unrelated PR 9699.

Evidence: build run, failed timeline records, focused E2E task log, build metadata, PR changed files, and wiki tracker.

Wiki: e2e-vhdcaching-gallery-image-delete-scopelocked

Avoid Fabric Manager, which requires NVSwitch hardware. Log driver
receipts on bake and derived nodes to retain preservation evidence.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings October 5, 2026 11:14

Copilot AI 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.

Copilot review overview

🔵 Needs a closer look

Production driver teardown spans current and legacy images, while current-head CI and strengthened real-driver PIS validation remain pending.

Review effort: Balanced
Findings: 1 High severity

Open (1)

Use the CI-supported default region instead of the westus2 gallery,
where the pipeline identity cannot capture the PIS image.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings October 5, 2026 13:02
Use baked scripts for the bake unless explicitly disabled, then traditional delivery on the derived node. Document the required new source image for affected Ubuntu PIS pools.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings October 22, 2026 22:11
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot AI 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.

🔵 Needs a closer look

The revised cleanup and mixed-delivery lifecycle still needs fresh-image live GPU PIS validation and final human review.

No open issues 🎉

Review effort: Balanced

Copilot AI balanced review requested due to automatic review settings October 22, 2026 22:18

Copilot AI 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.

🔵 Needs a closer look

The destructive cross-distro cleanup changes need human review because a fresh-image GPU PIS bake, capture, and derived-node boot pass remains unestablished.

No open issues 🎉

Review effort: Balanced

Keep representative preservation, teardown failure, GB ownership and retry, payload, and E2E checks. Remove the expanded test matrices and repeated fixture setup without changing production or Packer behavior.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings October 22, 2026 23:09

Copilot AI 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.

🔵 Needs a closer look

Destructive cross-distro cleanup and the baked-helper dependency need final human review after CI and fresh-image capture-and-boot validation complete.

No open issues 🎉

Review effort: Balanced

PIS derived nodes deliberately override the global scriptless default.
Validate CustomData against the effective NBC flag instead.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings October 22, 2026 23:20
Keep the default GPU suite; allow a single fresh-image PIS scenario
without rerunning every GPU scenario.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot AI 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.

🔵 Needs a closer look

Provisioning-critical cleanup changes need human sign-off after CI and fresh-image GPU capture-and-boot validation complete.

No open issues 🎉

Review effort: Balanced

Copilot AI balanced review requested due to automatic review settings October 22, 2026 23:26
@github-actions

Copy link
Copy Markdown
Contributor

Code Coverage

Package Line Rate Health
test 0% ❌
windows 27% ❌
staging_cse_windows Package 1 65% ➖
debug 0% ❌
provisioningscripts 2% ❌
parts_windows Package 1 73% ➖
Summary 38% (1652 / 6834) ❌

@github-actions

Copy link
Copy Markdown
Contributor

Code Coverage

Package Line Rate Health
github.com/Azure/agentbaker/aks-node-controller 72% ➖
github.com/Azure/agentbaker/aks-node-controller/common 100% ✔
github.com/Azure/agentbaker/aks-node-controller/helpers 68% ➖
github.com/Azure/agentbaker/aks-node-controller/parser 88% ✔
github.com/Azure/agentbaker/aks-node-controller/pkg/gpu 100% ✔
github.com/Azure/agentbaker/aks-node-controller/pkg/nodeconfigutils 89% ✔
github.com/Azure/agentbaker/aks-node-controller/utils 0% ❌
github.com/Azure/agentbaker/apiserver 24% ❌
github.com/Azure/agentbaker/cmd 0% ❌
github.com/Azure/agentbaker/cmd/starter 0% ❌
github.com/Azure/agentbaker/fuzz/api 0% ❌
github.com/Azure/agentbaker/hotfix/render-nodecustomdata 35% ❌
github.com/Azure/agentbaker/pkg/agent 78% ➖
github.com/Azure/agentbaker/pkg/agent/datamodel 77% ➖
github.com/Azure/agentbaker/pkg/agent/toggles 0% ❌
github.com/Azure/agentbaker/pkg/vhdbuilder/datamodel 87% ✔
Summary 75% (5903 / 7864) ➖

@github-actions

Copy link
Copy Markdown
Contributor

Code Coverage

Package Line Rate Health
shellspec spec 29% ❌
Summary 29% (4678 / 16295) ❌

Copilot AI 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.

🔵 Needs a closer look

Destructive GPU cleanup across multiple image layouts requires human review and the pending fresh-image capture-to-derived-node preservation validation.

No open issues 🎉

Review effort: Balanced

@benjamin-brady

Copy link
Copy Markdown
Member Author

Tim Wright (@timmy-wright) Nishchay (@awesomenix) could you review this for today’s release cut? I’ve removed the general CustomData compression changes and slimmed the diff from 1,423 to 893 changed lines, keeping both CUDA and Grace Blackwell support.

The fix cleans AKS-owned drivers during the PIS bake, before customer scripts, and preserves customer drivers on derived nodes. Important compatibility point: opted-out Ubuntu PIS bakes, including CPU-only pools, require a new source image containing the cleanup helper.

Local regression/scenario tests pass. Fresh-image GPU PIS E2E is still pending, so this is a request to review in parallel—not a claim that it is ready to merge. The PR description has the exact validation and remaining gate.

Copilot AI 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.

🔵 Needs a closer look

Destructive GPU cleanup and the new source-image dependency need human sign-off, with fresh-image preservation E2E validation still pending.

No open issues 🎉

Review effort: Balanced

@timmy-wright

Copy link
Copy Markdown
Contributor

Review: Preserve customer-installed PIS GPU drivers

What is good

This PR fixes the ownership boundary, not just the deletion symptom. Cleaning AKS-owned artifacts before customer customization, then preserving the resulting driver on derived nodes, is the right lifecycle model.

  • Destructive operations are conservative. Grace Blackwell cleanup verifies package versions against the BOM and checks configuration ownership before removal. Unexpected state fails the bake rather than guessing what is safe to delete.
  • Recovery is considered. The pending marker preserves teardown provenance across an initramfs failure. base_prep.complete is written only after successful provisioning, so a failed bake is not marked complete.
  • Normal provisioning remains recognizable. The same-execution BASE_PREP_RAN guard retains ordinary-node cleanup while excluding PIS-derived nodes.
  • The E2E scenario models the customer journey. It installs a real driver after basePrep, captures the image, and validates the derived node. Checking the staged installer as well as the loaded module and nvidia-smi catches destructive cleanup that a working driver alone would not reveal.
  • The implementation respects operational constraints. The helper stays out of CustomData, distro-specific cleanup remains separate, and the PR explicitly documents compatibility requirements and outstanding validation.

Review outcome

Reviewed #9702 at 30226157252b762134fde7c712c06f40bfb46e9b on 2026-10-23, covering reliability, performance, readability, and software design.

No confirmed current reliability or performance defect was found. There is one blocking validation gate below. The design recommendations are non-blocking; the final readability comment is a nitpick.

The documented source-image requirement is an intentional compatibility change, not an additional finding: opted-out Ubuntu PIS bakes, including CPU-only pools, require a source VHD containing the new helper. Ordinary and derived nodes do not require it. Release sequencing must respect that requirement.

Comments, ordered by importance

1. Blocking: Verify the complete lifecycle with a fresh branch-built VHD

Where: PR validation evidence; Ubuntu2404_GPUDriverOptOut_VHDCaching in e2e/scenario/scenario.go:3109-3140.

The PR description still explicitly marks fresh-image E2E validation as pending. The local tests pass, but most destructive cleanup operations are stubbed. A green GPU pipeline check alone does not establish that the run exercised the new baked helper.

Before merge, attach a successful run using a branch-built 2404gen2containerd source image available in westus3. Confirm that the selected image resource ID matches the branch-build metadata, then verify the bake, customer installation, capture, derived-node driver checks, and cleanup in the run logs. A missing-image skip is not a pass.

Why blocking: This is the main changed lifecycle, and it combines destructive cleanup with two VM runs and an image capture. This is a verification gate, not a claim that the implementation is broken. Clear it when the evidence is available; it does not inherently require a code change.

2. Non-blocking design recommendation: Keep configuration ownership knowledge synchronized

Where: cse_install_ubuntu_gpu.sh:141-156.

The expected configuration, including comments, is copied from the authoritative files under parts/linux/cloud-init/artifacts/ubuntu/gb/. This duplicates ownership knowledge rather than merely repeating similar code.

Risk: A future template edit can leave the cleanup verifier stale. Even a comment-only edit to nvidia-peermem.conf would then make legitimate AKS configuration fail the exact comparison and block a PIS bake.

Recommendation: Keep exact ownership verification, but tie its expected content to the authoritative templates. A focused consistency test is the smallest interim safeguard. Build-time generation is an option if this duplication continues to grow.

Trade-off: A consistency test retains duplication but catches drift cheaply. Generation removes manual synchronization at the cost of additional build plumbing.

Evidence grade: Weak for the general DRY prescription, which is primarily practitioner consensus; the duplicated content is directly observable. This is not a demonstrated failure in the current revision.

3. Non-blocking design recommendation: Make the cleanup state and dependency contract explicit

Where: cse_install_ubuntu_gpu.sh:112-259.

Fresh cleanup, interrupted cleanup, and already-completed cleanup are represented through combinations of files, booleans, and missing configuration. Understanding the allowed transitions requires tracing both the orchestrator and the teardown function. The helper also relies on previously sourced distro cleanup functions and globals.

Risk: A later change can preserve one path while accidentally breaking retries or legacy-layout handling.

Recommendation: Add a concise contract describing the entry states, the pending marker's lifetime, required sourced functions/globals, and successful postconditions. Remove the unused bom parameter from cleanUpGraceBlackwellGPUDriver. Keep layout selection in the orchestrator; do not introduce a generic state-machine framework.

Trade-off: This makes the existing design easier to audit without multiplying abstractions. It does not remove the safety complexity, which is justified.

Evidence grade: Moderate for control-flow and naming guidance; its applicability to shell is indirect, not proof that a particular refactor would reduce defects.

4. Non-blocking design recommendation: Separate inspection failure from a positive result

Where: cse_install_ubuntu_gpu.sh:3-54.

The predicates return success both when artifacts remain and when inspection fails. The package predicate also accepts an allowlist, despite its name suggesting a general presence check, and writes inspection-error text to the same output channel as package names.

Risk: A future caller could interpret "could not inspect" as "found a package," or misunderstand what the allowlist excludes. The current callers remain conservative; this is an interface-design concern.

Recommendation: At minimum, document the return and output contracts. If changing the interface, distinguish found, absent, and inspection-failed outcomes, send diagnostics to stderr, and explicitly retain fail-closed behavior at every caller.

Trade-off: Distinct outcomes add some branching but make the safety policy explicit rather than hiding it inside a presence query.

Evidence grade: Moderate for aligning names and contracts with behavior. This does not justify weakening the existing failure handling.

5. Nitpick: Make the cleanup eligibility rules read like the lifecycle policy

Where: cse_main.sh:410-419, cse_main.sh:659-662, and cse_install_ubuntu_gpu.sh:5.

The compound shell conditions are valid, but nested command groups and mixed ||/&& chains take unnecessary effort to audit. The nodePrep comment also describes the old GPU conditions without explaining the new same-execution restriction.

Recommendation: Prefer explicit if blocks for these safety decisions. Initialize BASE_PREP_RAN=false beside the phase dispatcher and explain that the guard prevents deletion of customer drivers on PIS-derived nodes.

Trade-off: A few more lines in exchange for more direct control flow. No behavioral change or new helper abstraction is needed.

Evidence grade: Moderate for control-flow clarity. This is a readability preference, not a demonstrated bug, and should not delay merge.

Validation performed during review

Check Result
`go test ./pkg/agent -run '^(TestPISGPU TestGPUAMA)' -count=1 -v`
cd e2e && go test ./scenario -count=1 Passed
Focused ShellSpec: PIS phase dispatch, Ubuntu cleanup, Mariner installer, Packer helper 68 examples, 0 failures
shellcheck --shell=bash parts/linux/cloud-init/artifacts/ubuntu/cse_install_ubuntu_gpu.sh Passed
git diff --check Passed on the reviewed working tree

The selected ShellSpec suites contain 4 phase-dispatch examples, 3 Ubuntu-cleanup examples, 59 Mariner-installer examples, and 2 Packer-helper examples. These results establish local regression coverage, not a live fresh-image preservation pass or measured provisioning performance.

The inspected Linux E2E build, 187241126, reported an Azure Linux iptables validation failure rather than a GPU cleanup failure. That observation does not clear the fresh-image validation gate above.

@timmy-wright Tim Wright (timmy-wright) 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.

The lifecycle ownership boundary and conservative cleanup checks are good. Full review report: #9702 (comment)

The inline comments below are non-blocking design recommendations and one nitpick. The report separately identifies fresh branch-built VHD E2E evidence as the blocking validation gate; this review does not assert a current correctness defect.

'# stack is up, so the post-dep fails silently. systemd-modules-load.service' \
'# runs later in boot, by which point modprobe can resolve the full dep chain' \
'# (ib_core, mlx5_ib, nvidia, ...).' \
'nvidia_peermem' || return 1

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.

Non-blocking design recommendation - keep ownership knowledge synchronized. The expected configuration here duplicates the authoritative GB configuration files, including their comments. A future comment-only edit to nvidia-peermem.conf could therefore make legitimate AKS configuration fail the exact ownership check and block a PIS bake.

Please retain exact verification, but consider a focused consistency test tying this expected content to the checked-in templates. That is a smaller change than adding build-time generation now: it retains duplication but catches drift cheaply. This is a future-maintenance concern, not a failure in the current revision.

local bom="${GB_MAI_BOM_FILE:-/opt/azure/containers/gb-mai-bom.json}"
local legacy_bom="${GB200_MAI_BOM_FILE:-/opt/azure/containers/gb200-mai-bom.json}"
local pending_file="${GB_DRIVER_CLEANUP_PENDING_FILE:-/opt/azure/containers/gb-driver-cleanup.pending}"
local wave=versions-wave2 entries gb_layout=false pending_teardown=false pending_wave

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.

Non-blocking design recommendation - make the cleanup state contract explicit. Fresh cleanup, interrupted cleanup, and already-completed cleanup are encoded through the pending marker, layout files, booleans, and missing configuration. The recovery behavior is valuable, but its invariants currently require tracing both this function and cleanUpGraceBlackwellGPUDriver.

A concise contract describing the entry states, pending-marker lifetime, required sourced functions/globals, and successful postconditions would make this safer to maintain without introducing a state-machine framework. The unused bom parameter on cleanUpGraceBlackwellGPUDriver can also be removed to avoid implying a dependency that the function does not use.


graceBlackwellPackageManagedDriverRemains() {
local allowed="${1:-}" package_states
package_states=$(dpkg-query -W -f='${binary:Package}\t${db:Status-Status}\n') || {

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.

Non-blocking design recommendation - clarify inspection results versus inspection failure. This predicate returns success both when an unowned package remains and when dpkg-query fails. Its stdout can therefore contain either a package name or an inspection-error message. The current caller remains conservative, but the interface is easy for a future caller to misinterpret.

At minimum, document the return/output contract and optional allowlist. If revising the interface, distinguish found, absent, and inspection-failed outcomes, send diagnostics to stderr, and explicitly preserve fail-closed handling at every caller. The extra branching would buy a clearer safety contract; this is not a request to weaken the check.


# Clean up GPU drivers if not a GPU node or if skipping driver install
if [ "${GPU_NODE}" != "true" ] || [ "${skip_nvidia_driver_install}" = "true" ]; then
if [ "${BASE_PREP_RAN}" = "true" ] && { [ "${GPU_NODE}" != "true" ] || [ "${skip_nvidia_driver_install}" = "true" ]; }; then

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.

Nitpick - make the lifecycle policy explicit beside this guard. The comment above still describes only the old GPU conditions. The important new condition is that cleanup runs only when basePrep ran in this execution, so PIS-derived nodes retain customer-installed drivers.

Please consider updating that comment and initializing BASE_PREP_RAN=false beside the phase dispatcher. Explicit nested if blocks would also make the eligibility rules easier to scan than the compound shell grouping. This is readability-only and should not delay merge.

This branch has not been deployed

No deployments
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.

5 participants