Skip to content

feat(dpf): support BlueFieldSoftware (BF4) provisioning with per-PSID.#3361

Merged
abvarshney-nv merged 2 commits into
NVIDIA:mainfrom
abvarshney-nv:dpf_bluefield_software
Jul 10, 2026
Merged

feat(dpf): support BlueFieldSoftware (BF4) provisioning with per-PSID.#3361
abvarshney-nv merged 2 commits into
NVIDIA:mainfrom
abvarshney-nv:dpf_bluefield_software

Conversation

@abvarshney-nv

@abvarshney-nv abvarshney-nv commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Add BF4-class DPU provisioning from a BlueFieldSoftware CR (OS ISO + PLDM firmware bundle) alongside the existing BFB (BF3) path. bfb_url is now optional. A deployment uses either bfb_url (BF3) or bluefield_software (BF4).

With this change, NICO will create a separate DPUDeployment per PSID. To provision a DPU, user has to configure bf4 in following way:

[dpf.deployments.bf4_generic]
# NOTE: bfb_url must NOT be set here — BF4 uses bluefield_software instead.
flavor_name    = "dpu-flavor-bf4" 
deployment_name = "dpu-deployment-bf4"
node_label_key  = "carbide.nvidia.com/controlled.node.bf4"
 
[dpf.deployments.bf4_generic.bluefield_software]
# Shared across all PSIDs
os_iso = "https://bfb_url"
 
# PSID -> PLDM firmware bundle URL. One BlueFieldSoftware CR + DPUDeployment
# is created per entry; the sanitized PSID is appended to deployment_name and
# node_label_key (e.g. "dpu-deployment-bf4-mt-0000000884").
[dpf.deployments.bf4_generic.bluefield_software.pldm_fw_bundle]
"MT_0000000884" = "https://artifacts.example.com/bf4/mt_0000000884.pldm"

Please note only one PSID is allowed as of now in plum_fw_bundle due to DPF limitation.

Related issues

Type of Change

  • Add - New feature or capability
  • Change - Changes in existing functionality
  • Fix - Bug fixes
  • Remove - Removed features or deprecated functionality
  • Internal - Internal changes (refactoring, tests, docs, etc.)

Breaking Changes

  • This PR contains breaking changes

Testing

  • Unit tests added/updated
  • Integration tests added/updated
  • Manual testing performed
  • No testing required (docs, internal refactor, etc.)

Additional Notes

@abvarshney-nv abvarshney-nv requested a review from a team as a code owner July 10, 2026 12:11
@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: f44dfccd-dee3-47bf-916f-01e92646c6c6

📥 Commits

Reviewing files that changed from the base of the PR and between 20d9eff and d84733a.

📒 Files selected for processing (13)
  • crates/api-core/src/cfg/file.rs
  • crates/api-core/src/setup.rs
  • crates/api-core/src/tests/dpf/duplicate_events.rs
  • crates/api-core/src/tests/dpf/happy_path.rs
  • crates/api-core/src/tests/dpf/reprovisioning.rs
  • crates/api-core/src/tests/dpf/stale_labels.rs
  • crates/api-core/src/tests/dpf/waiting_for_ready.rs
  • crates/api-core/src/tests/machine_admin_force_delete.rs
  • crates/dpf/src/sdk.rs
  • crates/dpf/src/test/sdk_initialization.rs
  • crates/dpf/src/types.rs
  • crates/machine-controller/src/dpf.rs
  • crates/machine-controller/src/handler/dpf.rs
✅ Files skipped from review due to trivial changes (1)
  • crates/machine-controller/src/dpf.rs
🚧 Files skipped from review as they are similar to previous changes (11)
  • crates/api-core/src/tests/dpf/stale_labels.rs
  • crates/api-core/src/tests/machine_admin_force_delete.rs
  • crates/api-core/src/tests/dpf/happy_path.rs
  • crates/api-core/src/tests/dpf/reprovisioning.rs
  • crates/api-core/src/tests/dpf/waiting_for_ready.rs
  • crates/machine-controller/src/handler/dpf.rs
  • crates/api-core/src/tests/dpf/duplicate_events.rs
  • crates/dpf/src/test/sdk_initialization.rs
  • crates/dpf/src/types.rs
  • crates/api-core/src/cfg/file.rs
  • crates/dpf/src/sdk.rs

Summary by CodeRabbit

  • New Features

    • Added BF4 DPU provisioning through BlueField software specifications, including OS images and firmware bundles.
    • Added Kubernetes-backed management for BlueField software resources.
    • Updated deployments to support either traditional BFB provisioning or BlueField software provisioning.
  • Bug Fixes

    • Added configuration validation to prevent conflicting or incomplete provisioning sources.
    • Improved detection of outdated DPU deployments across BF3 and BF4 hardware.
  • Tests

    • Added coverage for BF4 initialization, provisioning validation, and resource management.

Walkthrough

Changes

The PR adds BF4 BlueFieldSoftware provisioning alongside BF3 BFB provisioning, validates mutually exclusive sources and PSID mappings, creates or reuses Kubernetes resources, updates deployment construction, and removes per-DPU deployment type from device registration data.

BF4 provisioning and source-aware deployment

Layer / File(s) Summary
Provisioning configuration contracts
crates/api-core/src/cfg/file.rs, crates/dpf/src/types.rs, crates/api-core/src/tests/dpf/*, crates/api-core/src/tests/machine_admin_force_delete.rs
Configuration supports optional BFB or BlueFieldSoftware sources, validates source combinations and PSID cardinality, and updates existing fixtures.
BlueFieldSoftware repository and SDK provisioning
crates/dpf/src/repository/*, crates/dpf/src/sdk.rs, crates/dpf/src/lib.rs
Repository traits and Kubernetes operations support BlueFieldSoftware resources; the SDK creates or reuses deterministic resources and writes source-specific deployment references.
Validated initialization wiring
crates/api-core/src/setup.rs, crates/dpf/src/test/sdk_initialization.rs
SDK initialization validates deployment configuration and passes BF4 OS ISO and PLDM bundle parameters into initialization objects, with mock repository coverage.
Updated device registration contracts
crates/dpf/src/types.rs, crates/dpf/src/bin/api_harness.rs, crates/dpf/src/test/sdk_device_registration.rs, crates/dpf/src/sdk.rs, crates/machine-controller/src/handler/dpf.rs, crates/machine-controller/src/dpf.rs
DpuDeviceInfo no longer carries deployment type; callers and tests adopt the revised shape, while deployment-type resolution documentation is clarified.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Config as initialize_dpf_sdk
  participant SDK as DpfSdk
  participant Repository as BlueFieldSoftwareRepository
  participant Deployment as DPUDeployment
  Config->>Config: validate_provisioning_sources
  Config->>SDK: create_initialization_objects
  SDK->>Repository: create or reuse BlueFieldSoftware
  SDK->>Deployment: set blue_field_software reference
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: BF4 BlueFieldSoftware provisioning with per-PSID support.
Description check ✅ Passed The description matches the changeset and explains the BF3/BF4 provisioning split and per-PSID behavior.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
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 unit tests (beta)
  • Create PR with unit tests

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

🧹 Nitpick comments (1)
crates/api-core/src/cfg/file.rs (1)

4953-5029: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Express the provisioning-source matrix as table-driven cases.

Use check_cases for the accepted/rejected combinations, including BF4 with BFB only. This will make the deployment/source compatibility matrix explicit and prevent omitted combinations.

As per coding guidelines, use check_cases directly when several inputs or expected fields make a macro table clearer.

🤖 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 `@crates/api-core/src/cfg/file.rs` around lines 4953 - 5029, Refactor the
provisioning-source tests around validate_provisioning_sources into table-driven
cases using check_cases. Cover accepted and rejected combinations for BF3 and
BF4, including BF4 with BFB only, BF4 with bluefield_software only, both
sources, neither source, an empty PSID map, and BF3 bluefield_software; encode
each case’s expected result in the table and remove the separate repetitive test
setup.

Source: Coding guidelines

🤖 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 `@crates/api-core/src/cfg/file.rs`:
- Around line 1219-1244: Validate every effective per-PSID identifier before
initialization, including values generated by per_psid_deployment_name and
per_psid_node_label_key: enforce Kubernetes syntax, separator rules, and length
limits, and detect collisions both among sanitized PSIDs and with existing
BF3/base identifiers. Reject invalid or ambiguous configurations with clear
errors rather than relying on lossy sanitize_psid normalization; update the
relevant configuration validation path and tests.
- Around line 1355-1367: Update the validation loop in the configuration
validation method containing the match on (&cfg.bfb_url,
&cfg.bluefield_software) to reject the (Some(_), None) case when the deployment
is bf4_generic, requiring bluefield_software and reporting a clear
deployment-specific error. Preserve the existing acceptance of BFB-only
configurations for other deployment types and keep the exactly-one validation
behavior intact.

In `@crates/dpf/src/sdk.rs`:
- Around line 465-521: Update create_bluefield_software to mirror the
terminating-object guard used by the analogous creation helper: after an
AlreadyExists/conflict error, re-fetch the BlueFieldSoftware by namespace and
name, and return an error if it is missing or has metadata.deletion_timestamp
set; only reuse the name when the fetched object exists and is not terminating.

In `@crates/dpf/src/types.rs`:
- Around line 54-62: Enforce exactly one provisioning source in
InitDpfResourcesConfig at the SDK boundary: replace the independently
optional/defaultable bfb_url and bluefield_software fields with a
compiler-enforced provisioning-source enum or otherwise require validation
before resource creation. Update all consumers and Default implementations so
neither both sources nor no source can reach resource creation, preserving the
existing BF3/BF4 behavior without silently prioritizing or accepting an empty
BFB URL.

In `@crates/machine-controller/src/handler/dpf.rs`:
- Around line 532-541: The deployment-type lookup currently waits for a PSID
before creation-capable states can register the DPUDevice. In the state dispatch
logic around the provisioning and reprovisioning handlers, create or ensure the
DPUDevice first, then perform deployment resolution and label validation; retain
the wait outcome only after registration has been attempted. Add regression
coverage proving lookup returns None before registration, registration occurs,
and lookup returns Some afterward, including safe retry behavior for partial
failures.

---

Nitpick comments:
In `@crates/api-core/src/cfg/file.rs`:
- Around line 4953-5029: Refactor the provisioning-source tests around
validate_provisioning_sources into table-driven cases using check_cases. Cover
accepted and rejected combinations for BF3 and BF4, including BF4 with BFB only,
BF4 with bluefield_software only, both sources, neither source, an empty PSID
map, and BF3 bluefield_software; encode each case’s expected result in the table
and remove the separate repetitive test setup.
🪄 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: 4317e2bb-61e8-440c-a6b3-37f81430280b

📥 Commits

Reviewing files that changed from the base of the PR and between 16d6e35 and 3374e01.

📒 Files selected for processing (19)
  • crates/api-core/src/cfg/file.rs
  • crates/api-core/src/setup.rs
  • crates/api-core/src/tests/dpf/duplicate_events.rs
  • crates/api-core/src/tests/dpf/happy_path.rs
  • crates/api-core/src/tests/dpf/reprovisioning.rs
  • crates/api-core/src/tests/dpf/stale_labels.rs
  • crates/api-core/src/tests/dpf/waiting_for_ready.rs
  • crates/api-core/src/tests/machine_admin_force_delete.rs
  • crates/dpf/src/bin/api_harness.rs
  • crates/dpf/src/flavor.rs
  • crates/dpf/src/lib.rs
  • crates/dpf/src/repository/kube.rs
  • crates/dpf/src/repository/traits.rs
  • crates/dpf/src/sdk.rs
  • crates/dpf/src/test/sdk_device_registration.rs
  • crates/dpf/src/test/sdk_initialization.rs
  • crates/dpf/src/types.rs
  • crates/machine-controller/src/dpf.rs
  • crates/machine-controller/src/handler/dpf.rs
💤 Files with no reviewable changes (2)
  • crates/dpf/src/test/sdk_device_registration.rs
  • crates/dpf/src/bin/api_harness.rs

Comment thread crates/api-core/src/cfg/file.rs Outdated
Comment thread crates/api-core/src/cfg/file.rs
Comment thread crates/dpf/src/sdk.rs
Comment thread crates/dpf/src/types.rs
Comment thread crates/machine-controller/src/handler/dpf.rs Outdated
@github-actions

github-actions Bot commented Jul 10, 2026

Copy link
Copy Markdown

🔍 Container Scan Summary

Service Total Critical High Medium Low Other
boot-artifacts-aarch64 3 0 0 3 0 0
boot-artifacts-x86_64 3 0 0 3 0 0
forge-admin-cli-x86_64 271 13 34 91 7 126
machine-validation-runner 804 40 237 296 36 195
machine_validation 804 40 237 296 36 195
machine_validation-aarch64 804 40 237 296 36 195
nvmetal-carbide 804 40 237 296 36 195
TOTAL 3493 173 982 1281 151 906

Per-CVE detail lives in the per-service grype-* artifacts (JSON + SARIF). Severity counts only — no CVE IDs published here.

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

Caution

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

⚠️ Outside diff range comments (3)
crates/api-core/src/cfg/file.rs (2)

1181-1182: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Preserve the BF3 default for partial blocks.

#[serde(default)] on Option<String> makes an omitted bfb_url deserialize to None in an explicit [dpf.deployments.bf3] block, so the new validation rejects a config that previously inherited the default BFB URL. Either keep the BF3 default during deserialization or make this a documented breaking change and add a regression test for the partial-block case.

🤖 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 `@crates/api-core/src/cfg/file.rs` around lines 1181 - 1182, Preserve the BF3
default BFB URL when an explicit partial deployment is deserialized: update the
BF3 configuration deserialization/defaulting logic around the bfb_url field
instead of allowing #[serde(default)] to produce None, and add a regression test
covering a partial [dpf.deployments.bf3] block that omits bfb_url and still
inherits the default.

1215-1222: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Remove the broken intra-doc links and state the one-entry constraint. DpfDeploymentConfig::per_psid_deployment_name and DpfDeploymentConfig::per_psid_node_label_key no longer exist, and this section should explicitly say pldm_fw_bundle is expected to contain exactly one PSID→bundle entry.

🤖 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 `@crates/api-core/src/cfg/file.rs` around lines 1215 - 1222, Update the
BlueFieldSoftware specification documentation comment by removing the broken
links to DpfDeploymentConfig::per_psid_deployment_name and
DpfDeploymentConfig::per_psid_node_label_key, and explicitly state that
pldm_fw_bundle must contain exactly one PSID-to-bundle entry.
crates/dpf/src/sdk.rs (1)

510-531: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Handle the missing-CR race in crates/dpf/src/sdk.rs:510-528. If get() returns None after an AlreadyExists/conflict, this still returns Ok(name), and create_initialization_objects will emit a DPUDeployment that points at a BlueFieldSoftware CR that no longer exists. Mirror the create_dpu_flavor guard and return InvalidState here as well.

🤖 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 `@crates/dpf/src/sdk.rs` around lines 510 - 531, Update the existing-resource
branch in the BlueFieldSoftware creation flow to handle
`BlueFieldSoftwareRepository::get` returning `None`: return
`DpfError::InvalidState` with a descriptive missing-resource message instead of
`Ok(name)`. Mirror the guard and error style used by `create_dpu_flavor`, while
preserving the deletion-timestamp check and reuse behavior.
🧹 Nitpick comments (1)
crates/api-core/src/cfg/file.rs (1)

5019-5027: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Make the validation tests table-driven and assert the failure rule.

The new cases repeat setup and only assert is_err(). Use a table of cases with targeted error-substring assertions so the tests prove the BF4-only and exactly-one-PSID rules rather than merely detecting any failure.

Also applies to: 5029-5057

🤖 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 `@crates/api-core/src/cfg/file.rs` around lines 5019 - 5027, The validation
tests around bf4_with_psids should be refactored into a table-driven set of
cases, each defining its PSID input and expected error substring. Iterate
through the cases, build the configuration with bf4_with_psids, run validation,
and assert the error both occurs and contains the targeted text proving the
BF4-only and exactly-one-PSID rules.

Source: Coding guidelines

🤖 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.

Outside diff comments:
In `@crates/api-core/src/cfg/file.rs`:
- Around line 1181-1182: Preserve the BF3 default BFB URL when an explicit
partial deployment is deserialized: update the BF3 configuration
deserialization/defaulting logic around the bfb_url field instead of allowing
#[serde(default)] to produce None, and add a regression test covering a partial
[dpf.deployments.bf3] block that omits bfb_url and still inherits the default.
- Around line 1215-1222: Update the BlueFieldSoftware specification
documentation comment by removing the broken links to
DpfDeploymentConfig::per_psid_deployment_name and
DpfDeploymentConfig::per_psid_node_label_key, and explicitly state that
pldm_fw_bundle must contain exactly one PSID-to-bundle entry.

In `@crates/dpf/src/sdk.rs`:
- Around line 510-531: Update the existing-resource branch in the
BlueFieldSoftware creation flow to handle `BlueFieldSoftwareRepository::get`
returning `None`: return `DpfError::InvalidState` with a descriptive
missing-resource message instead of `Ok(name)`. Mirror the guard and error style
used by `create_dpu_flavor`, while preserving the deletion-timestamp check and
reuse behavior.

---

Nitpick comments:
In `@crates/api-core/src/cfg/file.rs`:
- Around line 5019-5027: The validation tests around bf4_with_psids should be
refactored into a table-driven set of cases, each defining its PSID input and
expected error substring. Iterate through the cases, build the configuration
with bf4_with_psids, run validation, and assert the error both occurs and
contains the targeted text proving the BF4-only and exactly-one-PSID rules.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: ca3af771-08a2-42e0-949f-2d8ee5d9355d

📥 Commits

Reviewing files that changed from the base of the PR and between 3374e01 and 20d9eff.

📒 Files selected for processing (13)
  • crates/api-core/src/cfg/file.rs
  • crates/api-core/src/setup.rs
  • crates/api-core/src/tests/dpf/duplicate_events.rs
  • crates/api-core/src/tests/dpf/happy_path.rs
  • crates/api-core/src/tests/dpf/reprovisioning.rs
  • crates/api-core/src/tests/dpf/stale_labels.rs
  • crates/api-core/src/tests/dpf/waiting_for_ready.rs
  • crates/api-core/src/tests/machine_admin_force_delete.rs
  • crates/dpf/src/sdk.rs
  • crates/dpf/src/test/sdk_initialization.rs
  • crates/dpf/src/types.rs
  • crates/machine-controller/src/dpf.rs
  • crates/machine-controller/src/handler/dpf.rs
✅ Files skipped from review due to trivial changes (3)
  • crates/machine-controller/src/dpf.rs
  • crates/api-core/src/tests/dpf/reprovisioning.rs
  • crates/api-core/src/tests/dpf/stale_labels.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • crates/dpf/src/test/sdk_initialization.rs

@abvarshney-nv abvarshney-nv force-pushed the dpf_bluefield_software branch from 20d9eff to d84733a Compare July 10, 2026 16:16
@abvarshney-nv abvarshney-nv merged commit 70d30e9 into NVIDIA:main Jul 10, 2026
58 checks passed
@abvarshney-nv abvarshney-nv deleted the dpf_bluefield_software branch July 10, 2026 17:48
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