Skip to content

fix(pxe): seed NoCloud network-config for tenant-provided network settings#3392

Open
RajMandaliya wants to merge 4 commits into
NVIDIA:mainfrom
RajMandaliya:fix/nocloud-network-config
Open

fix(pxe): seed NoCloud network-config for tenant-provided network settings#3392
RajMandaliya wants to merge 4 commits into
NVIDIA:mainfrom
RajMandaliya:fix/nocloud-network-config

Conversation

@RajMandaliya

Copy link
Copy Markdown
Contributor

Following up on the discussion in #3303 with a working fix.

Root cause

NICo seeds NoCloud's user-data and meta-data files but never seeds the separate network-config file. A top-level network: key inside user-data is not a valid user-data format — confirmed directly against real cloud-init, whose own schema validator rejects it:

Error: Cloud config schema errors: network: Additional properties are not allowed ('network' was unexpected)

This is unrelated to #2814 specifically — that change correctly moved user-data to the canonical NoCloud seed location; the network: key was never valid there before or after, it just happened to "work" pre-#2814 because content was being written into cloud-init's own cloud.cfg.d/ config-merge directory instead of a real user-data document.

Fix

  • New /network-config PXE route that extracts an existing network: key from the tenant's custom_cloud_init (if present) and serves it as its own document.
  • One additional line in disk_imaging.sh to fetch it into the seed directory, alongside the existing user-data/meta-data fetches.

No API changes — existing network: key placement in tenant userdatakeeps working as-is.

Testing

  • Added unit tests for the extraction logic (valid key, missing key,
    invalid YAML).
  • Verified end-to-end against real cloud-init (installed locally,
    reproduced both the old and new seed-directory layouts): a populated
    network-config applies correctly (netplan reflects the custom
    config), and an empty one (the common case, no custom network
    settings) falls back cleanly to default DHCP with no errors or
    warnings.
  • cargo test -p carbide-pxe — 18/18 passing.

Addresses #3303.

RajMandaliya and others added 3 commits July 8, 2026 12:58
Keeping Pace with original repo
…tings

NICo seeds NoCloud's user-data and meta-data files, but never seeds
the separate network-config file. A top-level 'network:' key inside
user-data is not a valid user-data format (confirmed via cloud-init's
own schema validator) and is silently ignored, regardless of the
change in NVIDIA#2814 that correctly moved user-data to the canonical
NoCloud seed location.

Adds a new /network-config PXE route that extracts an existing
'network:' key from the tenant's custom_cloud_init (if present) and
serves it as its own document, plus one line in disk_imaging.sh to
fetch it into the seed directory. No API changes needed; existing
'network:' key placement keeps working as-is.

Verified end-to-end against real cloud-init: a populated
network-config applies correctly, and an empty one (the common case,
no custom network settings) falls back cleanly to default DHCP with
no errors.

Addresses NVIDIA#3303.

Signed-off-by: Raj <rajmandaliya2249@gmail.com>
@RajMandaliya RajMandaliya requested a review from a team as a code owner July 10, 2026 23:10
@copy-pr-bot

copy-pr-bot Bot commented Jul 10, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@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: 07454b78-44aa-49af-adfe-4d80d0699b70

📥 Commits

Reviewing files that changed from the base of the PR and between 0e821ad and 0a115be.

📒 Files selected for processing (1)
  • crates/pxe/src/routes/cloud_init.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • crates/pxe/src/routes/cloud_init.rs

Summary by CodeRabbit

  • New Features
    • Added support for generating and serving cloud-init network configuration through PXE.
    • Introduced a dedicated network-config endpoint that extracts network settings from custom cloud-init and renders them as YAML.
    • Updated PXE disk imaging to download network-config into the NoCloud seed directory.
  • Bug Fixes
    • Improved resilience by returning an empty network configuration when the input is missing, invalid, or lacks network.
  • Tests
    • Added unit tests to verify network extraction behavior for valid, missing, and invalid YAML inputs.

Walkthrough

Adds PXE support for serving the network section of custom cloud-init YAML and downloading it into the NoCloud seed directory during disk imaging.

Changes

Cloud-init network configuration delivery

Layer / File(s) Summary
Network-config endpoint and extraction
crates/pxe/Cargo.toml, crates/pxe/src/routes/cloud_init.rs, pxe/templates/network-config
Adds YAML parsing, extracts and serializes the top-level network value, registers the /network-config route, renders an empty value when unavailable, and tests valid, missing, and invalid YAML cases.
NoCloud seed download integration
pxe/common_files/disk_imaging.sh
Downloads /network-config into the NoCloud seed directory using the existing retry and logging behavior.

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

Sequence Diagram(s)

sequenceDiagram
  participant PXEClient
  participant network_config
  participant extract_network_config
  participant network_config_template
  PXEClient->>network_config: GET /network-config
  network_config->>extract_network_config: Parse custom_cloud_init YAML
  extract_network_config-->>network_config: Serialized network YAML or empty value
  network_config->>network_config_template: Render network_config
  network_config_template-->>PXEClient: Network configuration response
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 36.36% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the PXE NoCloud network-config seeding fix for tenant-provided network settings.
Description check ✅ Passed The description is directly aligned with the changeset and clearly explains the root cause, fix, and testing.
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.

🧹 Nitpick comments (3)
crates/pxe/src/routes/cloud_init.rs (3)

624-652: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use a table-driven test for these input variants.

These tests exercise one total operation with different inputs. Consolidate them with value_scenarios! or check_values, keeping the valid-case structural assertions explicit.

As per coding guidelines, tests covering multiple input variants should prefer table-driven scenarios.

🤖 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/pxe/src/routes/cloud_init.rs` around lines 624 - 652, The three tests
for extract_network_config should be consolidated into a table-driven test using
value_scenarios! or check_values, with cases for valid network YAML, missing
network, and invalid YAML. Keep the valid case’s explicit version and eth0
structural assertions while preserving the expected result for each scenario.

Source: Coding guidelines


272-273: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Avoid cloning the extracted network configuration.

value.get("network") already returns a reference, so cloning the full YAML tree adds unnecessary allocation before serialization.

Proposed fix
-    let network = value.get("network")?.clone();
-    serde_yaml::to_string(&network).ok()
+    serde_yaml::to_string(value.get("network")?).ok()

As per coding guidelines, avoid needless clones and prefer borrowing where ownership is not required.

🤖 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/pxe/src/routes/cloud_init.rs` around lines 272 - 273, In the network
serialization logic, avoid cloning the YAML value returned by
value.get("network"). Pass the borrowed reference directly to
serde_yaml::to_string, preserving the existing optional flow and removing the
unnecessary allocation.

Source: Coding guidelines


624-652: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Add a route-level contract test.

The current tests only validate extraction; they do not exercise network_config, template rendering, or the registered /network-config route. A focused request test should verify both rendered network YAML and the empty fallback.

🤖 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/pxe/src/routes/cloud_init.rs` around lines 624 - 652, Add a
route-level contract test covering the registered `/network-config` endpoint and
`network_config` template rendering, verifying a request with network data
returns the expected rendered YAML and a request without a network key returns
the empty fallback. Keep the existing extraction tests and use the route’s
actual test setup and handler symbols to exercise the full request path.
🤖 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.

Nitpick comments:
In `@crates/pxe/src/routes/cloud_init.rs`:
- Around line 624-652: The three tests for extract_network_config should be
consolidated into a table-driven test using value_scenarios! or check_values,
with cases for valid network YAML, missing network, and invalid YAML. Keep the
valid case’s explicit version and eth0 structural assertions while preserving
the expected result for each scenario.
- Around line 272-273: In the network serialization logic, avoid cloning the
YAML value returned by value.get("network"). Pass the borrowed reference
directly to serde_yaml::to_string, preserving the existing optional flow and
removing the unnecessary allocation.
- Around line 624-652: Add a route-level contract test covering the registered
`/network-config` endpoint and `network_config` template rendering, verifying a
request with network data returns the expected rendered YAML and a request
without a network key returns the empty fallback. Keep the existing extraction
tests and use the route’s actual test setup and handler symbols to exercise the
full request path.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 54970ee9-9f67-48f0-b908-caa27b6e8de1

📥 Commits

Reviewing files that changed from the base of the PR and between 6b42265 and 0e821ad.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (4)
  • crates/pxe/Cargo.toml
  • crates/pxe/src/routes/cloud_init.rs
  • pxe/common_files/disk_imaging.sh
  • pxe/templates/network-config

- Avoid cloning the extracted network YAML value before serializing.
- Consolidate the three extract_network_config tests into a single
  table-driven test, moved into the existing tests module.

Signed-off-by: Raj <rajmandaliya2249@gmail.com>
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.

1 participant