Skip to content

fix(nvsnap): warn when L2 fan-out is disabled at install time - #733

Closed
balajinvda wants to merge 1 commit into
mainfrom
fix/nvsnap-install-l2-warning
Closed

fix(nvsnap): warn when L2 fan-out is disabled at install time#733
balajinvda wants to merge 1 commit into
mainfrom
fix/nvsnap-install-l2-warning

Conversation

@balajinvda

@balajinvda balajinvda commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Found while validating the chart on nvcf-dgxc-k8s-aws-usw2-dev2.

Why

agent.l2.storageClass defaults to empty, which disables the L2 per-capture PVC tier. The install still succeeds and prints a clean success banner, while restore fan-out silently degrades to the L3 peer cascade. The only signal today is an info-level agent log line that scrolls past during rollout:

L2 disabled: agent.L2.StorageClass not set (cluster prerequisite missing
 -- restore fan-out will fall back to L3 peer cascade)

That is a throughput cliff that only becomes visible under multi-node fan-out, long after install. It is easy to conclude the cluster is fully configured when it is not. dev2 has six RWX-capable StorageClasses available and still came up with L2 off.

What changed

Report the condition during the existing step-5 cluster auto-detect, and list the RWX-capable StorageClasses actually present so the operator can act immediately:

WARNING: agent.l2.storageClass is unset -- L2 per-capture PVC fan-out is DISABLED.
         Restore falls back to the L3 peer cascade (slower multi-node fan-out).
         RWX-capable StorageClasses on this cluster:
           nvcf-cc-sc (nvmesh-csi.excelero.com)
           nvcf-function-storage-sc (nvmesh-csi.excelero.com)
           nvcf-sc (nvmesh-csi.excelero.com)
           nvmesh-concatenated (nvmesh-csi.excelero.com)
           nvmesh-raid0 (nvmesh-csi.excelero.com)
           nvmesh-raid1 (nvmesh-csi.excelero.com)
         Enable with: --set agent.l2.storageClass=<name>

Reported rather than auto-selected on purpose: the wrong class yields PVCs that never bind, and the right choice depends on cluster topology. RWX capability is not exposed on the StorageClass API, so candidates are matched against known RWX provisioners (smb.csi, nfs.csi, efs.csi, filestore.csi, azurefile, excelero/nvmesh, cephfs). When none match, the message points at the reference StorageClass manifest instead.

Suppressed when the operator already passed agent.l2.storageClass.

Customer Release Notes

The installer now reports when L2 restore fan-out is disabled and lists eligible StorageClasses.

Plan Summary

Not applicable.

Usage

./scripts/install-nvsnap.sh -- warning appears in step 5 when L2 is unconfigured.

Testing

On nvcf-dgxc-k8s-aws-usw2-dev2:

  • --dry-run with storageClass unset: warning plus the six nvmesh candidates above.
  • --dry-run --set agent.l2.storageClass=nvcf-sc: no warning emitted.
  • bash -n clean.

Notes

Advisory only; it does not change install behavior or exit status. Auto-selection was considered and rejected for the reason above.

References

None

Related Merge Requests/Pull Requests

#732

Dependencies

None

Summary by CodeRabbit

  • New Features
    • Added an installation-time warning when no L2 storage class is configured.
    • Detects compatible RWX storage classes and explains how to enable L2 PVC fan-out.
    • Provides guidance to provision an RWX storage class when none is available.
    • Clarifies that restores will use the slower L3 cascade when L2 fan-out is disabled.

agent.l2.storageClass defaults to empty, which disables the L2
per-capture PVC tier. The install still succeeds and prints a clean
success banner, while restore fan-out silently degrades to the L3 peer
cascade. The only signal today is an info-level agent log line that
scrolls past:

  L2 disabled: agent.L2.StorageClass not set (cluster prerequisite
  missing — restore fan-out will fall back to L3 peer cascade)

That is a throughput cliff which only shows up under multi-node fan-out,
long after install, and it is easy to conclude the cluster is fully
configured when it is not. Observed installing on
nvcf-dgxc-k8s-aws-usw2-dev2, which has six RWX-capable StorageClasses
available and still came up with L2 off.

Report the condition during the existing step-5 cluster auto-detect, and
list the RWX-capable StorageClasses actually present so the operator can
act on it immediately.

Deliberately reported rather than auto-selected: the wrong class yields
PVCs that never bind, and the right choice depends on cluster topology.
RWX capability is not exposed on the StorageClass API, so candidates are
matched against known RWX provisioners. Suppressed when the operator has
already passed agent.l2.storageClass.

Verified on dev2: unset lists the six nvmesh classes with the enabling
flag; passing --set agent.l2.storageClass=nvcf-sc emits nothing.

Co-Authored-By: Balaji Ganesan <bganesan@nvidia.com>
@balajinvda
balajinvda requested a review from a team as a code owner August 9, 2026 19:09
@balajinvda balajinvda self-assigned this Aug 9, 2026
@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The installer now warns when agent.l2.storageClass is unset. It identifies RWX-capable storage classes, reports the L3 restore fallback, and provides configuration or provisioning guidance.

Changes

NVSnap installation

Layer / File(s) Summary
Detect and report L2 storage configuration
src/compute-plane-services/nvsnap/scripts/install-nvsnap.sh
The installer skips the check when agent.l2.storageClass is present. Otherwise, it lists matching RWX provisioners or explains how to provision an RWX storage class. It reports that L2 PVC fan-out is disabled and restore uses the L3 cascade.

Estimated code review effort: 2 (Simple) | ~10 minutes

Suggested reviewers: famousdirector

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title follows Conventional Commits and accurately describes the install-time warning added for disabled L2 fan-out.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/nvsnap-install-l2-warning

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 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 `@src/compute-plane-services/nvsnap/scripts/install-nvsnap.sh`:
- Line 240: Update the guard around EXTRA_HELM_ARGS to match only an exact
agent.l2.storageClass argument, escaping the dots and anchoring the key; require
at least one non-whitespace value after the equals sign so empty assignments
still trigger the warning.
- Around line 242-252: Update the StorageClass discovery logic before the
warning so kubectl query failures are captured separately from a successful
empty result. Keep the check non-fatal, but track the command status and emit a
distinct diagnostic when the query fails; only report that no RWX-capable
StorageClass exists when the query succeeds with no candidates.
- Around line 230-241: Update the provisioner detection in the installer’s
EXTRA_HELM_ARGS validation to use the L2 backend access-mode contract rather
than an RWX-only allowlist: include the GKE Hyperdisk ML provisioner
(pd.csi.storage.gke.io) and other provisioners supported by the referenced
storage-class definitions. Revise the warning text to describe L2-compatible
RWO/ROX support instead of requiring RWX, while preserving the existing guidance
that users must explicitly select an appropriate storage class.
- Around line 242-243: Update the candidate-building command in the
storage-class discovery logic to filter exclusively on `.provisioner`, not the
combined `metadata.name (provisioner)` output. Emit the storage-class name and
provisioner as separate fields, apply `$rwx_re` only to the provisioner field,
and preserve the resulting class name for recommendations.
🪄 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: CHILL

Plan: Enterprise

Run ID: a279c243-e151-42e1-9478-5d36dbda5804

📥 Commits

Reviewing files that changed from the base of the PR and between cd51e37 and 0e88ab0.

📒 Files selected for processing (1)
  • src/compute-plane-services/nvsnap/scripts/install-nvsnap.sh

Comment on lines +230 to +241
# L2 per-capture PVC fan-out is off unless agent.l2.storageClass names an
# RWX-capable class. Left empty the install still succeeds, but restore
# fan-out silently degrades to the L3 peer cascade — a large throughput
# difference that only shows up under multi-node fan-out, long after the
# installer has printed a clean banner. Say so at install time.
#
# Reported, not auto-selected: picking the wrong class yields PVCs that
# never bind, and the right choice depends on cluster topology. RWX
# capability isn't exposed on the StorageClass API, so candidates are
# matched on known RWX provisioners.
if ! printf '%s\n' "${EXTRA_HELM_ARGS[@]}" | grep -q "agent.l2.storageClass="; then
rwx_re='smb\.csi|nfs\.csi|efs\.csi|filestore\.csi|azurefile|excelero|nvmesh|cephfs'

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Use the L2 access-mode contract instead of an RWX-only test.

The supplied manifest defines hyperdisk-ml with provisioner pd.csi.storage.gke.io. It documents RWO and ROX support for this L2 backend, so Hyperdisk ML is valid without RWX. The current regex excludes it. A cluster with the recommended class therefore receives incorrect provisioning guidance.

Detect L2-compatible provisioners and update the warning text to match the actual access modes.

This follows the storage-class contract in src/compute-plane-services/nvsnap/deploy/k8s/nvcf-cluster-prep/storage-classes.yaml.

Also applies to: 244-252

🤖 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 `@src/compute-plane-services/nvsnap/scripts/install-nvsnap.sh` around lines 230
- 241, Update the provisioner detection in the installer’s EXTRA_HELM_ARGS
validation to use the L2 backend access-mode contract rather than an RWX-only
allowlist: include the GKE Hyperdisk ML provisioner (pd.csi.storage.gke.io) and
other provisioners supported by the referenced storage-class definitions. Revise
the warning text to describe L2-compatible RWO/ROX support instead of requiring
RWX, while preserving the existing guidance that users must explicitly select an
appropriate storage class.

# never bind, and the right choice depends on cluster topology. RWX
# capability isn't exposed on the StorageClass API, so candidates are
# matched on known RWX provisioners.
if ! printf '%s\n' "${EXTRA_HELM_ARGS[@]}" | grep -q "agent.l2.storageClass="; then

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Require an exact, non-empty agent.l2.storageClass value.

The guard checks only for the substring agent.l2.storageClass=. An empty value suppresses the warning, and unescaped . characters can match unrelated keys. Parse the Helm arguments or use an escaped, anchored match that requires a non-empty value.

🤖 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 `@src/compute-plane-services/nvsnap/scripts/install-nvsnap.sh` at line 240,
Update the guard around EXTRA_HELM_ARGS to match only an exact
agent.l2.storageClass argument, escaping the dots and anchoring the key; require
at least one non-whitespace value after the equals sign so empty assignments
still trigger the warning.

Comment on lines +242 to +243
candidates=$(kubectl get storageclass -o jsonpath='{range .items[*]}{.metadata.name}{" ("}{.provisioner}{")"}{"\n"}{end}' 2>/dev/null \
| grep -iE "$rwx_re" || true)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Filter only the provisioner field.

The JSONPath emits metadata.name (provisioner), and grep scans both fields. A class named efs-backup can match even when its provisioner is not RWX-capable. The script can then recommend a class that leaves PVCs unbound. Emit separate fields and apply the regex only to .provisioner.

🤖 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 `@src/compute-plane-services/nvsnap/scripts/install-nvsnap.sh` around lines 242
- 243, Update the candidate-building command in the storage-class discovery
logic to filter exclusively on `.provisioner`, not the combined `metadata.name
(provisioner)` output. Emit the storage-class name and provisioner as separate
fields, apply `$rwx_re` only to the provisioner field, and preserve the
resulting class name for recommendations.

Comment on lines +242 to +252
candidates=$(kubectl get storageclass -o jsonpath='{range .items[*]}{.metadata.name}{" ("}{.provisioner}{")"}{"\n"}{end}' 2>/dev/null \
| grep -iE "$rwx_re" || true)
echo " WARNING: agent.l2.storageClass is unset — L2 per-capture PVC fan-out is DISABLED." >&2
echo " Restore falls back to the L3 peer cascade (slower multi-node fan-out)." >&2
if [ -n "$candidates" ]; then
echo " RWX-capable StorageClasses on this cluster:" >&2
echo "$candidates" | sed 's/^/ /' >&2
echo " Enable with: --set agent.l2.storageClass=<name>" >&2
else
echo " No RWX-capable StorageClass detected; L2 needs one provisioned first." >&2
echo " Reference: deploy/k8s/nvcf-cluster-prep/storage-classes.yaml" >&2

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Report query failures separately from an empty result.

2>/dev/null and || true convert API errors, permission errors, missing kubectl, and an empty StorageClass list into the same result. The script then tells the operator to provision a class without proving that no class exists. Keep the check non-fatal, but report query failure separately.

🤖 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 `@src/compute-plane-services/nvsnap/scripts/install-nvsnap.sh` around lines 242
- 252, Update the StorageClass discovery logic before the warning so kubectl
query failures are captured separately from a successful empty result. Keep the
check non-fatal, but track the command status and emit a distinct diagnostic
when the query fails; only report that no RWX-capable StorageClass exists when
the query succeeds with no candidates.

@balajinvda

Copy link
Copy Markdown
Contributor Author

Superseded by #737, which combines this with #732 into a single install-path PR to cut review overhead. Same commit, cherry-picked unchanged.

@balajinvda balajinvda closed this Aug 10, 2026
@balajinvda
balajinvda deleted the fix/nvsnap-install-l2-warning branch August 10, 2026 14:08
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