Skip to content

Fix iPXE NICo branding#2583

Merged
ajf merged 3 commits into
NVIDIA:mainfrom
osu:fix/ipxe-nico-branding
Jun 15, 2026
Merged

Fix iPXE NICo branding#2583
ajf merged 3 commits into
NVIDIA:mainfrom
osu:fix/ipxe-nico-branding

Conversation

@osu

@osu osu commented Jun 15, 2026

Copy link
Copy Markdown
Member

Summary

  • update compiled iPXE product branding from Carbide to NICo
  • update the embedded iPXE boot banner, prompt, menu, and labels to use NICo
  • make pxe/ipxe/local/embed.ipxe the single source of truth for the static iPXE menu renderer template
  • preserve the existing static template slug for compatibility
  • add a regression test for old branding and template synchronization
  • stabilize the DHCP booturl integration test against Kea startup/readiness timing seen in CI

Fixes #2541

Verification

  • git diff --check
  • docker cargo +nightly-2026-05-27 fmt --all -- --check
  • docker cargo test -p carbide-ipxe-renderer test_static_ipxe_menu_uses_nico_branding
  • python3 YAML parse/assertion for crates/ipxe-renderer/templates.yaml deferring the static menu to embed.ipxe
  • rg confirmed no Carbide/Forge hits in pxe/ipxe/local/branding.h or pxe/ipxe/local/embed.ipxe
  • docker run isolated public Rust/Kea environment: cargo test -p carbide-dhcp --test booturl -- --nocapture
  • docker rustfmt crates/dhcp/tests/booturl.rs

Note: the host PATH still does not provide cargo/cargo-make/rustfmt; the focused Rust validation above was run in Docker against an isolated copy.

@osu osu requested a review from a team as a code owner June 15, 2026 00:14
@copy-pr-bot

copy-pr-bot Bot commented Jun 15, 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 Jun 15, 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: 222119bf-b0eb-418e-b98c-9b915da69853

📥 Commits

Reviewing files that changed from the base of the PR and between 730eae8 and a7e22e4.

📒 Files selected for processing (5)
  • crates/dhcp/tests/booturl.rs
  • crates/ipxe-renderer/src/lib.rs
  • crates/ipxe-renderer/templates.yaml
  • pxe/ipxe/local/branding.h
  • pxe/ipxe/local/embed.ipxe
🚧 Files skipped from review as they are similar to previous changes (4)
  • pxe/ipxe/local/embed.ipxe
  • crates/ipxe-renderer/templates.yaml
  • crates/ipxe-renderer/src/lib.rs
  • crates/dhcp/tests/booturl.rs

Summary by CodeRabbit

  • Chores

    • Rebranded product name from "Carbide" to "NICo" (NVIDIA Infra Controller) across provisioning menu, boot flow, and branding assets.
    • Updated product descriptions and menu prompts to reflect new NICo branding.
  • Tests

    • Enhanced boot provisioning tests with deadline-based retry logic for improved timeout handling and reliability.

Walkthrough

Rebrands all iPXE-related assets from "Carbide" to "NICo": updates branding macros in branding.h, rewrites the embed.ipxe boot and menu flow to route through nico_menu, moves the static menu template body from templates.yaml to embed.ipxe (loaded at compile time via include_str!), and adds a branding assertion test. Separately refactors the DHCP booturl test suite to use deadline-based retry logic with a centralized recv_offer helper for Offer packet reception.

Changes

Carbide → NICo Rebranding

Layer / File(s) Summary
iPXE branding macros and embed boot script
pxe/ipxe/local/branding.h, pxe/ipxe/local/embed.ipxe
PRODUCT_NAME, PRODUCT_SHORT_NAME, and PRODUCT_TAG_LINE macros updated to NICo variants; entire boot entry, whoami routing, menu block, and debug return path rewritten from carbide_menu to nico_menu.
Static menu template and comment rebranding in templates.yaml
crates/ipxe-renderer/templates.yaml
Inline comments in raw-ipxe and qcow-image updated from carbide-core to NICo Core; carbide-menu-static-ipxe description changed to "NICo Menu" and its inlined iPXE script body replaced with template: "" to be populated at runtime from embed.ipxe.
Renderer constants, override logic, doc comments, and branding test
crates/ipxe-renderer/src/lib.rs
Compile-time constants STATIC_IPXE_MENU_TEMPLATE_ID and STATIC_IPXE_MENU_TEMPLATE added via include_str!; DefaultIpxeScriptRenderer::new() overrides the loaded template body on ID match; two doc comments updated to reference NICo Core; test_static_ipxe_menu_uses_nico_branding added to assert NICo presence and Carbide/Forge absence.

DHCP Booturl Test Deadline-Based Retry Refactoring

Layer / File(s) Summary
Import and recv_offer helper with deadline logic
crates/dhcp/tests/booturl.rs
Adds ErrorKind and Instant imports; introduces READ_TIMEOUT (200ms) and OFFER_TIMEOUT (10s) constants; implements private recv_offer function that repeatedly sends DHCP request and retries recv on non-fatal socket errors (would-block/timed-out/interrupted) until the offer deadline is exceeded or a DHCPv4 Offer is successfully decoded.
Test case updates using recv_offer helper
crates/dhcp/tests/booturl.rs
In test_booturl_internal_with_mtu and test_booturl_from_api, replaces inline packet send/receive/decode logic with construction of DHCP discover packet via DHCPFactory::encode and delegation to recv_offer for deadline-driven response handling.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% 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 PR title directly addresses the primary objective: updating iPXE branding from Carbide to NICo as specified in issue #2541.
Description check ✅ Passed The description comprehensively covers the changeset objectives, including branding updates, template synchronization, regression testing, and DHCP test stabilization.
Linked Issues check ✅ Passed All code changes directly address issue #2541: branding macros updated to NICo, embed script menu/labels converted to NICo, documentation references updated, and regression test added to prevent reversion [#2541].
Out of Scope Changes check ✅ Passed DHCP test improvements (recv_offer refactoring for timeout robustness) are ancillary to the stated objective but represent pragmatic CI stabilization rather than scope creep.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@osu osu force-pushed the fix/ipxe-nico-branding branch 2 times, most recently from 0c68917 to f72ef93 Compare June 15, 2026 00:18

@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 (1)
crates/ipxe-renderer/templates.yaml (1)

329-392: 🏗️ Heavy lift

Avoid drift between the static template and pxe/ipxe/local/embed.ipxe.

This block is effectively a second copy of the embedded boot menu script. This PR needed mirrored edits in both places; future changes can diverge silently. Please consider generating one from the other (or sharing a single source snippet) to keep control-flow and branding synchronized.

As per coding guidelines, "Prefer simple, explicit code over clever or heavily abstracted code. Optimize for readability and maintainability first."

🤖 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/ipxe-renderer/templates.yaml` around lines 329 - 392, The NICo Menu
template is duplicated between two locations, creating a maintenance burden
where changes must be made in both places to keep them synchronized. Consolidate
the template code by extracting the common boot menu script into a single source
of truth. Modify the template definition to generate or reference this shared
source, ensuring the control-flow and branding remain consistent across all uses
without requiring duplicate edits in the future.

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.

Nitpick comments:
In `@crates/ipxe-renderer/templates.yaml`:
- Around line 329-392: The NICo Menu template is duplicated between two
locations, creating a maintenance burden where changes must be made in both
places to keep them synchronized. Consolidate the template code by extracting
the common boot menu script into a single source of truth. Modify the template
definition to generate or reference this shared source, ensuring the
control-flow and branding remain consistent across all uses without requiring
duplicate edits in the future.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 7cc36479-b676-4029-9dc0-1c073af7a1e7

📥 Commits

Reviewing files that changed from the base of the PR and between 1070e96 and f72ef93.

📒 Files selected for processing (4)
  • crates/ipxe-renderer/src/lib.rs
  • crates/ipxe-renderer/templates.yaml
  • pxe/ipxe/local/branding.h
  • pxe/ipxe/local/embed.ipxe

@osu osu force-pushed the fix/ipxe-nico-branding branch 3 times, most recently from ef695ed to 8235236 Compare June 15, 2026 01:48

@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 (1)
crates/ipxe-renderer/src/lib.rs (1)

1061-1108: 💤 Low value

Consider consolidating redundant assertions.

The test asserts menu_template.template == STATIC_IPXE_MENU_TEMPLATE on line 1070, then checks both independently in the subsequent loops. Since equality is already established, one of them could be removed from the iteration arrays to eliminate redundant checks.

♻️ Suggested consolidation
         for (name, contents) in [
             ("embedded iPXE script", STATIC_IPXE_MENU_TEMPLATE),
             ("iPXE branding header", BRANDING_H),
-            (
-                "renderer static menu template",
-                menu_template.template.as_str(),
-            ),
             (
                 "renderer static menu description",
                 menu_template.description.as_str(),
             ),
         ] {
             assert!(contents.contains("NICo"), "{name} should mention NICo");
         }

         for (name, contents) in [
             ("embedded iPXE script", STATIC_IPXE_MENU_TEMPLATE),
             ("iPXE branding header", BRANDING_H),
-            (
-                "renderer static menu template",
-                menu_template.template.as_str(),
-            ),
             (
                 "renderer static menu description",
                 menu_template.description.as_str(),
             ),
         ] {
🤖 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/ipxe-renderer/src/lib.rs` around lines 1061 - 1108, The
test_static_ipxe_menu_uses_nico_branding function establishes equality between
menu_template.template and STATIC_IPXE_MENU_TEMPLATE with an assert_eq call,
then redundantly checks both strings independently in the subsequent iteration
loops. Since you have already verified they are equal, remove one of these
duplicate entries from the iteration arrays in both the NICo assertion loop and
the Carbide/Forge assertion loop. You can either remove the "embedded iPXE
script" entry that uses STATIC_IPXE_MENU_TEMPLATE or the "renderer static menu
template" entry that uses menu_template.template.as_str() since they represent
the same content.
🤖 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/ipxe-renderer/src/lib.rs`:
- Around line 1061-1108: The test_static_ipxe_menu_uses_nico_branding function
establishes equality between menu_template.template and
STATIC_IPXE_MENU_TEMPLATE with an assert_eq call, then redundantly checks both
strings independently in the subsequent iteration loops. Since you have already
verified they are equal, remove one of these duplicate entries from the
iteration arrays in both the NICo assertion loop and the Carbide/Forge assertion
loop. You can either remove the "embedded iPXE script" entry that uses
STATIC_IPXE_MENU_TEMPLATE or the "renderer static menu template" entry that uses
menu_template.template.as_str() since they represent the same content.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: f94c8cea-19de-433b-bba3-778048b7fc24

📥 Commits

Reviewing files that changed from the base of the PR and between f72ef93 and ef695ed.

📒 Files selected for processing (4)
  • crates/ipxe-renderer/src/lib.rs
  • crates/ipxe-renderer/templates.yaml
  • pxe/ipxe/local/branding.h
  • pxe/ipxe/local/embed.ipxe
✅ Files skipped from review due to trivial changes (1)
  • pxe/ipxe/local/branding.h
🚧 Files skipped from review as they are similar to previous changes (1)
  • pxe/ipxe/local/embed.ipxe

@osu osu force-pushed the fix/ipxe-nico-branding branch from 8235236 to 730eae8 Compare June 15, 2026 01:53
@osu

osu commented Jun 15, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@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 (1)
crates/dhcp/tests/booturl.rs (1)

31-60: 💤 Low value

Document the retransmit-on-timeout behavior.

The function intentionally retransmits the DHCP request after each socket timeout, which aligns with standard DHCP/UDP retry semantics and addresses Kea startup timing issues. However, this retry-with-retransmit strategy is not immediately apparent from the code structure. A brief comment would aid future maintainers in understanding this is deliberate behavior rather than an oversight.

📝 Suggested documentation
 fn recv_offer(socket: &UdpSocket, request: &[u8]) -> Result<v4::Message, eyre::Report> {
     let deadline = Instant::now() + OFFER_TIMEOUT;
     let mut recv_buf = [0u8; 1500]; // packet is 470 bytes, but allow for full MTU
 
+    // Retry loop: retransmit the DHCP request on each timeout to handle
+    // Kea startup timing and UDP packet loss, per standard DHCP retry behavior.
     loop {
         socket.send(request)?;
🤖 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/dhcp/tests/booturl.rs` around lines 31 - 60, The retry-with-retransmit
behavior in the recv_offer function is not documented, making it unclear whether
the loop that calls socket.send(request) before each recv attempt is
intentional. Add a comment at the start of the loop or before the socket.send
call to document that the function deliberately retransmits the DHCP request on
each timeout as part of standard DHCP/UDP retry semantics to address Kea startup
timing issues, so future maintainers understand this is deliberate behavior
rather than an oversight.
🤖 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/dhcp/tests/booturl.rs`:
- Around line 31-60: The retry-with-retransmit behavior in the recv_offer
function is not documented, making it unclear whether the loop that calls
socket.send(request) before each recv attempt is intentional. Add a comment at
the start of the loop or before the socket.send call to document that the
function deliberately retransmits the DHCP request on each timeout as part of
standard DHCP/UDP retry semantics to address Kea startup timing issues, so
future maintainers understand this is deliberate behavior rather than an
oversight.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: aedaaaf4-58ad-47d4-9957-2a64cb79aa87

📥 Commits

Reviewing files that changed from the base of the PR and between ef695ed and 730eae8.

📒 Files selected for processing (5)
  • crates/dhcp/tests/booturl.rs
  • crates/ipxe-renderer/src/lib.rs
  • crates/ipxe-renderer/templates.yaml
  • pxe/ipxe/local/branding.h
  • pxe/ipxe/local/embed.ipxe
🚧 Files skipped from review as they are similar to previous changes (4)
  • pxe/ipxe/local/branding.h
  • pxe/ipxe/local/embed.ipxe
  • crates/ipxe-renderer/src/lib.rs
  • crates/ipxe-renderer/templates.yaml

Signed-off-by: Hasan Khan <hasank@nvidia.com>
@osu osu force-pushed the fix/ipxe-nico-branding branch from 730eae8 to 29e1411 Compare June 15, 2026 02:39
@osu osu self-assigned this Jun 15, 2026
@osu osu added the bug A defect in existing software (deprecated - use issue type, but it's needed for reporting now) label Jun 15, 2026
Comment thread pxe/ipxe/local/embed.ipxe
:carbide
:nico
ifconf -c dhcp
time chain --autofree http://${next-server}:8080/api/v0/pxe/boot?buildarch=${buildarch}&platform=${platform}&manufacturer=${manufacturer}&product=${product}&serial=${serial} && exit 1 || goto error_handler

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This reminded me to file #2598

Comment thread pxe/ipxe/local/branding.h Outdated
@@ -1,11 +1,11 @@
#undef PRODUCT_NAME
#define PRODUCT_NAME "Carbide"
#define PRODUCT_NAME "NICo"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Let's make this "NVIDIA Infra Controller". This is the actual full name of NICo.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Pushed a commit to update

}

#[test]
fn test_static_ipxe_menu_uses_nico_branding() {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This test is pretty funny, I love it.

@ajf ajf enabled auto-merge (squash) June 15, 2026 15:05
@github-actions

Copy link
Copy Markdown

@ajf ajf merged commit d09de3b into NVIDIA:main Jun 15, 2026
52 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug A defect in existing software (deprecated - use issue type, but it's needed for reporting now)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: iPXE still says Carbide or Forge, should say NICo

3 participants