Skip to content

feat: rename ExpectedHostNic to ExpectedInterface - #4390

Merged
chet merged 1 commit into
NVIDIA:mainfrom
chet:gh-issue-4104
Jul 30, 2026
Merged

feat: rename ExpectedHostNic to ExpectedInterface#4390
chet merged 1 commit into
NVIDIA:mainfrom
chet:gh-issue-4104

Conversation

@chet

@chet chet commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

ExpectedMachine.host_nics started as a host-only list, but now describes Host, DpuOs, DpuBmc, and HostBmc interfaces. The old name no longer matches the data.

So this makes ExpectedInterface and interfaces the Rust, configuration, and admin CLI names. Existing host_nics input and --host_nics commands keep working as aliases, while the protobuf names, field numbers, wire bytes, and physical expected_machines.host_nics column stay unchanged.

This is a no-op for existing configs and databases, and it does not change fixed_ip, role, or allocation behavior. The compatibility tests cover old, new, and mixed JSON/configuration spellings, both CLI spellings, protobuf and ProtoJSON details, and the JSONB round trip.

Related issues

This supports #4104

Part of #3491.

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

The focused compatibility tests cover canonical interfaces input, legacy host_nics input, both spellings across different machines in the same file, ambiguous same-machine duplicates, --interfaces, --host_nics, omitted-versus-present list handling, exact protobuf bytes and descriptor names, and the existing JSONB column. The full cargo make format-nightly, cargo make clippy, and cargo make carbide-lints gates pass on current main.

Additional Notes

There is no database migration or protobuf schema change. The physical expected_machines.host_nics column, protobuf ExpectedHostNic message, host_nics field numbers, and ProtoJSON names stay unchanged.

Documentation is tracked separately by #4151 so technical-writing review does not block this code change. That docs-only PR will use interfaces in current examples and call out host_nics as a supported compatibility alias.

Closes #4104

@chet
chet requested a review from a team as a code owner July 30, 2026 18:15
@coderabbitai

coderabbitai Bot commented Jul 30, 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: ab063ac2-b777-48e8-9469-b842de6adf90

📥 Commits

Reviewing files that changed from the base of the PR and between 06034f0 and 441156b.

📒 Files selected for processing (34)
  • crates/admin-cli/src/boot_interface/candidates/cmd.rs
  • crates/admin-cli/src/boot_interface/set/cmd.rs
  • crates/admin-cli/src/expected_machines/add/args.rs
  • crates/admin-cli/src/expected_machines/common.rs
  • crates/admin-cli/src/expected_machines/patch/args.rs
  • crates/admin-cli/src/expected_machines/patch/mod.rs
  • crates/admin-cli/src/expected_machines/tests.rs
  • crates/admin-cli/src/expected_machines/update/mod.rs
  • crates/admin-cli/src/rpc.rs
  • crates/api-core/src/dhcp/discover.rs
  • crates/api-core/src/handlers/bmc_endpoint_explorer.rs
  • crates/api-core/src/handlers/expected_machine.rs
  • crates/api-core/src/handlers/machine_interface_address.rs
  • crates/api-core/src/tests/expected_machine.rs
  • crates/api-core/src/tests/machine_dhcp.rs
  • crates/api-core/src/tests/sku.rs
  • crates/api-db/src/expected_machine.rs
  • crates/api-db/src/expected_machine/tests.rs
  • crates/api-db/src/machine_interface.rs
  • crates/api-db/src/machine_interface/tests.rs
  • crates/api-model/src/expected_machine.rs
  • crates/api-model/src/machine/mod.rs
  • crates/api-model/src/predicted_machine_interface.rs
  • crates/api-model/src/site_explorer/mod.rs
  • crates/machine-a-tron/src/api_client.rs
  • crates/machine-a-tron/src/machine_a_tron.rs
  • crates/rpc/build.rs
  • crates/rpc/src/model/expected_machine.rs
  • crates/rpc/src/protos/mod.rs
  • crates/site-explorer/src/lib.rs
  • crates/site-explorer/src/machine_creator.rs
  • crates/site-explorer/tests/integration/reconcile.rs
  • crates/site-explorer/tests/integration/site_explorer.rs
  • crates/site-explorer/tests/integration/zero_dpu.rs

Summary by CodeRabbit

  • New Features
    • Updated expected-machine inputs to use interfaces terminology, with host_nics accepted via compatibility aliasing (including legacy JSON key support).
    • Refreshed CLI commands to use --interfaces as the primary option, while keeping --host_nics as a visible legacy alias and updating help/examples.
  • Bug Fixes
    • Improved operator guidance and refusal/selection messaging to consistently reference interfaces[].primary.
    • Standardized interface-based matching across DHCP resolution and reconciliation, with validation rejecting payloads that specify both interfaces and host_nics.

Walkthrough

Expected-machine host NIC declarations are generalized to ExpectedInterface and interfaces. Legacy host_nics CLI, JSON, protobuf, and database representations remain compatible while DHCP, reconciliation, boot selection, and Site Explorer consumers use the new terminology and model.

Changes

Expected interface migration

Layer / File(s) Summary
Interface model and normalization
crates/api-model/..., crates/rpc/src/protos/mod.rs
Introduces ExpectedInterface, stores declarations under interfaces, preserves legacy aliases, and updates HostBmc normalization and primary selection.
RPC and CLI conversion
crates/rpc/..., crates/admin-cli/src/expected_machines/..., crates/machine-a-tron/...
Commands use --interfaces with --host_nics as an alias; RPC conversion and automatic registration map interface data to the legacy protobuf field.
Persistence and reconciliation
crates/api-db/..., crates/api-core/src/handlers/...
Database persistence, interface-MAC lookup, DHCP reconciliation, role/allocation validation, fixed-address handling, and primary selection consume ExpectedInterface.
Boot and inventory consumers
crates/api-core/src/dhcp/..., crates/site-explorer/...
DHCP discovery, boot messaging, Redfish filtering, interface preallocation, and zero-DPU MAC fallback read from interfaces.
Compatibility and regression coverage
crates/*/tests/...
Tests cover aliases, database round trips, omitted-field preservation, replacement semantics, DHCP behavior, primary validation, and interface allocation.

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

Sequence Diagram(s)

sequenceDiagram
  participant CLI
  participant RPCConversion
  participant ExpectedMachineModel
  participant Database
  participant DHCPReconciliation

  CLI->>RPCConversion: Parse --interfaces or --host_nics
  RPCConversion->>ExpectedMachineModel: Convert ExpectedInterface values
  ExpectedMachineModel->>Database: Persist interfaces in host_nics JSON column
  DHCPReconciliation->>Database: Find machine by interface MAC
  Database-->>DHCPReconciliation: Return ExpectedInterface declarations
  DHCPReconciliation->>ExpectedMachineModel: Apply role, allocation, segment, and primary settings
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: renaming ExpectedHostNic to ExpectedInterface.
Description check ✅ Passed The description matches the changeset and accurately describes the API rename and compatibility 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

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ast-grep (0.45.0)
crates/rpc/build.rs

ast-grep timed out on this file


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

@chet

chet commented Jul 30, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai full_review, thanks!

@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

@chet: Understood — I’ll perform a complete review of #4390, including the compatibility guarantees and affected API/configuration surfaces.

🐇🔎

✅ Action performed

Full review finished.

@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/rpc/build.rs (1)

634-637: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Rename-only field attribute is safe today, but only because ExpectedMachine never derives Deserialize.

#[serde(rename = "interfaces")] on ExpectedMachine.host_nics renames the JSON key outright — it does not alias the legacy "host_nics" key. This is safe right now because ExpectedMachine only derives serde::Serialize (line 633), not Deserialize, so nothing can ever feed a raw "host_nics"-keyed JSON payload into this type directly; all legacy-JSON compatibility is instead handled one layer up in ExpectedMachineJson/ExpectedMachineData via alias = "host_nics".

If Deserialize is ever added to ExpectedMachine in a future change, this rename would silently stop accepting legacy "host_nics" payloads at that layer. Consider a short comment here noting the invariant so a future contributor doesn't add Deserialize without also adding the alias.

🤖 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/rpc/build.rs` around lines 634 - 637, Add a concise comment beside the
ExpectedMachine.host_nics serde rename in the field_attribute configuration,
documenting that ExpectedMachine currently only derives Serialize and that
adding Deserialize requires an alias for the legacy "host_nics" key. Do not
change the rename behavior or the existing
ExpectedMachineJson/ExpectedMachineData compatibility handling.
🤖 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/rpc/build.rs`:
- Around line 634-637: Add a concise comment beside the
ExpectedMachine.host_nics serde rename in the field_attribute configuration,
documenting that ExpectedMachine currently only derives Serialize and that
adding Deserialize requires an alias for the legacy "host_nics" key. Do not
change the rename behavior or the existing
ExpectedMachineJson/ExpectedMachineData compatibility handling.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 4def9189-2679-4f17-b4dd-299f7995c6a2

📥 Commits

Reviewing files that changed from the base of the PR and between 49d2ee4 and 156b716.

📒 Files selected for processing (34)
  • crates/admin-cli/src/boot_interface/candidates/cmd.rs
  • crates/admin-cli/src/boot_interface/set/cmd.rs
  • crates/admin-cli/src/expected_machines/add/args.rs
  • crates/admin-cli/src/expected_machines/common.rs
  • crates/admin-cli/src/expected_machines/patch/args.rs
  • crates/admin-cli/src/expected_machines/patch/mod.rs
  • crates/admin-cli/src/expected_machines/tests.rs
  • crates/admin-cli/src/expected_machines/update/mod.rs
  • crates/admin-cli/src/rpc.rs
  • crates/api-core/src/dhcp/discover.rs
  • crates/api-core/src/handlers/bmc_endpoint_explorer.rs
  • crates/api-core/src/handlers/expected_machine.rs
  • crates/api-core/src/handlers/machine_interface_address.rs
  • crates/api-core/src/tests/expected_machine.rs
  • crates/api-core/src/tests/machine_dhcp.rs
  • crates/api-core/src/tests/sku.rs
  • crates/api-db/src/expected_machine.rs
  • crates/api-db/src/expected_machine/tests.rs
  • crates/api-db/src/machine_interface.rs
  • crates/api-db/src/machine_interface/tests.rs
  • crates/api-model/src/expected_machine.rs
  • crates/api-model/src/machine/mod.rs
  • crates/api-model/src/predicted_machine_interface.rs
  • crates/api-model/src/site_explorer/mod.rs
  • crates/machine-a-tron/src/api_client.rs
  • crates/machine-a-tron/src/machine_a_tron.rs
  • crates/rpc/build.rs
  • crates/rpc/src/model/expected_machine.rs
  • crates/rpc/src/protos/mod.rs
  • crates/site-explorer/src/lib.rs
  • crates/site-explorer/src/machine_creator.rs
  • crates/site-explorer/tests/integration/reconcile.rs
  • crates/site-explorer/tests/integration/site_explorer.rs
  • crates/site-explorer/tests/integration/zero_dpu.rs

@chet

chet commented Jul 30, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai Thanks for the eyes. Updated. PTAL. Resolve if good, thanks!

@chet

chet commented Jul 30, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai full_review, thanks!

@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

@chet: Understood. I’ll perform a complete review of the current changes, with particular attention to the compatibility guarantees across Rust, configuration, Protobuf/ProtoJSON, database persistence, and CLI aliases.

✅ Action performed

Full review finished.

@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '== Current PR diff summary =='
git diff --stat origin/main...HEAD
echo
echo '== Changed Rust files =='
git diff --name-only origin/main...HEAD -- 'crates/**/*.rs'
echo
echo '== Compatibility-sensitive diff =='
git diff --unified=80 origin/main...HEAD -- \
  crates/api-model/src/expected_machine.rs \
  crates/rpc/build.rs \
  crates/rpc/src/protos/mod.rs \
  crates/rpc/src/model/expected_machine.rs \
  crates/admin-cli/src/expected_machines/common.rs \
  crates/admin-cli/src/expected_machines/add/args.rs \
  crates/admin-cli/src/expected_machines/patch/args.rs \
  crates/admin-cli/src/rpc.rs
echo
echo '== Relevant tests and call sites =='
rg -n -C 3 --glob '*.rs' \
  'alias = "host_nics"|visible_alias = "host_nics"|interfaces\(\)|interfaces_mut\(\)|replace_interfaces|replace_host_nics|ExpectedHostNic|ExpectedInterface' \
  crates/api-model crates/rpc crates/admin-cli | head -n 900
echo
echo '== CodeRabbit review comments on PR 4390 =='
gh api repos/NVIDIA/infra-controller/pulls/4390/comments \
  --paginate \
  --jq '.[] | select(.user.login == "coderabbitai[bot]" or .user.login == "coderabbitai") | {id, node_id, path, line, body, html_url}'

Length of output: 144632


@chet: Follow-up review looks good. The compatibility boundaries are preserved: legacy JSON and CLI aliases remain accepted, while protobuf descriptor names, wire fields, and ProtoJSON names stay unchanged. I also found no outstanding CodeRabbit inline review comments on #4390.

I did not run the test suite in this sandbox, but the targeted compatibility tests and static implementation review are consistent with the stated guarantees. Resolving CodeRabbit comments.

🐇 ✅

[resolve]

You are interacting with an AI system.

@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 (1)
crates/admin-cli/src/expected_machines/patch/args.rs (1)

248-261: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Error message omits sku-id and rack-id from the list of valid selectors.

The guard checks 11 fields, but the message only names 8 of them. An operator relying on this text to understand which flags satisfy the "at least one" requirement won't see sku-id/rack-id listed, even though setting either alone passes the check.

🐛 Proposed fix to align the message with the guard
-            return Err(CarbideCliError::GenericError("One of the following options must be specified: bmc-username and bmc-password or chassis-serial-number or fallback-dpu-serial-number or bmc-ip-address or dpu-policy or bmc-ip-allocation or dpf-enabled or interfaces".to_string()));
+            return Err(CarbideCliError::GenericError("one of the following options must be specified: bmc-username and bmc-password or chassis-serial-number or fallback-dpu-serial-number or sku-id or rack-id or bmc-ip-address or dpu-policy or bmc-ip-allocation or dpf-enabled or interfaces".to_string()));
As per path instructions, "Review CLI changes for clap behavior, actionable operator-facing error messages...".
🤖 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/admin-cli/src/expected_machines/patch/args.rs` around lines 248 - 261,
Update the GenericError message in the validation guard to include the sku-id
and rack-id selectors alongside the other accepted options, matching all fields
checked by the guard while preserving the existing validation behavior.

Source: Path instructions

🤖 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/admin-cli/src/expected_machines/patch/args.rs`:
- Around line 248-261: Update the GenericError message in the validation guard
to include the sku-id and rack-id selectors alongside the other accepted
options, matching all fields checked by the guard while preserving the existing
validation behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: af85e725-6ecf-4834-aa2b-527c267291c7

📥 Commits

Reviewing files that changed from the base of the PR and between 156b716 and 7c8c1c2.

📒 Files selected for processing (34)
  • crates/admin-cli/src/boot_interface/candidates/cmd.rs
  • crates/admin-cli/src/boot_interface/set/cmd.rs
  • crates/admin-cli/src/expected_machines/add/args.rs
  • crates/admin-cli/src/expected_machines/common.rs
  • crates/admin-cli/src/expected_machines/patch/args.rs
  • crates/admin-cli/src/expected_machines/patch/mod.rs
  • crates/admin-cli/src/expected_machines/tests.rs
  • crates/admin-cli/src/expected_machines/update/mod.rs
  • crates/admin-cli/src/rpc.rs
  • crates/api-core/src/dhcp/discover.rs
  • crates/api-core/src/handlers/bmc_endpoint_explorer.rs
  • crates/api-core/src/handlers/expected_machine.rs
  • crates/api-core/src/handlers/machine_interface_address.rs
  • crates/api-core/src/tests/expected_machine.rs
  • crates/api-core/src/tests/machine_dhcp.rs
  • crates/api-core/src/tests/sku.rs
  • crates/api-db/src/expected_machine.rs
  • crates/api-db/src/expected_machine/tests.rs
  • crates/api-db/src/machine_interface.rs
  • crates/api-db/src/machine_interface/tests.rs
  • crates/api-model/src/expected_machine.rs
  • crates/api-model/src/machine/mod.rs
  • crates/api-model/src/predicted_machine_interface.rs
  • crates/api-model/src/site_explorer/mod.rs
  • crates/machine-a-tron/src/api_client.rs
  • crates/machine-a-tron/src/machine_a_tron.rs
  • crates/rpc/build.rs
  • crates/rpc/src/model/expected_machine.rs
  • crates/rpc/src/protos/mod.rs
  • crates/site-explorer/src/lib.rs
  • crates/site-explorer/src/machine_creator.rs
  • crates/site-explorer/tests/integration/reconcile.rs
  • crates/site-explorer/tests/integration/site_explorer.rs
  • crates/site-explorer/tests/integration/zero_dpu.rs
🚧 Files skipped from review as they are similar to previous changes (8)
  • crates/api-core/src/handlers/bmc_endpoint_explorer.rs
  • crates/api-model/src/machine/mod.rs
  • crates/admin-cli/src/boot_interface/candidates/cmd.rs
  • crates/api-model/src/predicted_machine_interface.rs
  • crates/admin-cli/src/boot_interface/set/cmd.rs
  • crates/api-model/src/site_explorer/mod.rs
  • crates/api-core/src/tests/sku.rs
  • crates/site-explorer/tests/integration/site_explorer.rs

@chet

chet commented Jul 30, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai Thanks for the eyes. Updated -- added sku-id and rack-id to the patch validation message. PTAL. Resolve if good, thanks!

@chet

chet commented Jul 30, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai full_review, thanks!

@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

@chet: I’ll perform a complete review of #4390, with particular focus on backward compatibility across configuration, CLI aliases, Protobuf/ProtoJSON, and persisted database data.

✅ Action performed

Full review finished.

@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '== Focused diff =='
git diff --unified=40 origin/main...HEAD -- \
  crates/admin-cli/src/expected_machines/patch/args.rs \
  crates/admin-cli/src/expected_machines/tests.rs

echo
echo '== Target file outline =='
ast-grep outline crates/admin-cli/src/expected_machines/patch/args.rs --items all

echo
echo '== Validation implementation and selector declarations =='
rg -n -C 12 --glob '*.rs' \
  'fn validate\s*\(|ArgGroup|sku-id|rack-id|interfaces|host_nics|Specify at least' \
  crates/admin-cli/src/expected_machines/patch/args.rs \
  crates/admin-cli/src/expected_machines/tests.rs

echo
echo '== Patch argument parse/validation test call sites =='
rg -n -C 5 --glob '*.rs' \
  'expected-machine.*patch|Args::validate|validate_patch|sku-id|rack-id' \
  crates/admin-cli/src/expected_machines

Length of output: 72340


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '== Patch argument declarations around SKU and rack selectors =='
sed -n '120,185p' crates/admin-cli/src/expected_machines/patch/args.rs

echo
echo '== Rack-ID patch parsing and validation coverage =='
rg -n -C 8 --glob '*.rs' \
  'rack_id|rack-id|validate_patch.*rack|patch.*rack' \
  crates/admin-cli/src/expected_machines/tests.rs \
  crates/admin-cli/src/expected_machines/patch/args.rs

echo
echo '== Full required ArgGroup selector list =='
sed -n '40,58p' crates/admin-cli/src/expected_machines/patch/args.rs

Length of output: 7877


@chet Confirmed. sku-id and rack-id are now accurately represented in the manual validation message, and rack-id is correctly included in Clap’s required patch selector group through its field-level group declaration. No issue found.

🐇 ✅

[resolve]

You are interacting with an AI system.

@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: 1

🧹 Nitpick comments (1)
crates/rpc/src/model/expected_machine.rs (1)

304-369: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Drop the needless per-interface .clone()expected_machine is already owned here.

Since this From impl consumes expected_machine by value, cloning every retained (non-HostBmc) interface before converting it is unnecessary — into_iter() moves them instead. This is a hot conversion path (invoked on every outbound ExpectedMachine read/list response), so avoiding the clone is a small but genuine win. As per coding guidelines, "Avoid needless .clone() calls; prefer borrowing, moving with into_iter, ordering struct fields to enable moves, or using Cow where values may be borrowed or owned."

♻️ Proposed refactor using owned iteration instead of cloning
 impl From<ExpectedMachine> for rpc::forge::ExpectedMachine {
     fn from(expected_machine: ExpectedMachine) -> Self {
         let has_stored_host_bmc = expected_machine
             .data
             .interfaces
             .iter()
             .any(|interface| interface.role.is_host_bmc());
         let bmc_ip_allocation = expected_machine
             .compatibility_bmc_ip_allocation()
             .map(rpc::forge::BmcIpAllocationType::from)
             .map(|allocation| allocation as i32);
-        let mut interfaces = expected_machine
-            .data
-            .interfaces
-            .iter()
-            .filter(|interface| !interface.role.is_host_bmc())
-            .map(|x| x.clone().into())
-            .collect::<Vec<_>>();
-        if has_stored_host_bmc {
-            interfaces.push(expected_machine.effective_host_bmc().into());
-        }
+        let effective_host_bmc = has_stored_host_bmc
+            .then(|| rpc::forge::ExpectedInterface::from(expected_machine.effective_host_bmc()));
+        let interfaces = expected_machine
+            .data
+            .interfaces
+            .into_iter()
+            .filter(|interface| !interface.role.is_host_bmc())
+            .map(Into::into)
+            .chain(effective_host_bmc)
+            .collect::<Vec<_>>();
         rpc::forge::ExpectedMachine {
             id: expected_machine.id.map(|u| crate::common::Uuid {
                 value: u.to_string(),
             }),
🤖 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/rpc/src/model/expected_machine.rs` around lines 304 - 369, Update the
interfaces collection in From<ExpectedMachine> for rpc::forge::ExpectedMachine
to consume expected_machine.data.interfaces with into_iter() instead of iter(),
then convert retained non-HostBmc interfaces directly without cloning. Preserve
the existing filtering and effective_host_bmc append behavior.

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/admin-cli/src/expected_machines/patch/args.rs`:
- Around line 258-260: Update the validation error returned by the argument
check in the surrounding validation method to begin with a lowercase phrase,
preserving the existing options and wording otherwise; ensure the message has no
trailing period.

---

Nitpick comments:
In `@crates/rpc/src/model/expected_machine.rs`:
- Around line 304-369: Update the interfaces collection in From<ExpectedMachine>
for rpc::forge::ExpectedMachine to consume expected_machine.data.interfaces with
into_iter() instead of iter(), then convert retained non-HostBmc interfaces
directly without cloning. Preserve the existing filtering and effective_host_bmc
append behavior.
🪄 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: 0df6fa51-2e4e-4ee2-8223-10abf9f7be66

📥 Commits

Reviewing files that changed from the base of the PR and between 262122f and 7c8c1c2.

📒 Files selected for processing (34)
  • crates/admin-cli/src/boot_interface/candidates/cmd.rs
  • crates/admin-cli/src/boot_interface/set/cmd.rs
  • crates/admin-cli/src/expected_machines/add/args.rs
  • crates/admin-cli/src/expected_machines/common.rs
  • crates/admin-cli/src/expected_machines/patch/args.rs
  • crates/admin-cli/src/expected_machines/patch/mod.rs
  • crates/admin-cli/src/expected_machines/tests.rs
  • crates/admin-cli/src/expected_machines/update/mod.rs
  • crates/admin-cli/src/rpc.rs
  • crates/api-core/src/dhcp/discover.rs
  • crates/api-core/src/handlers/bmc_endpoint_explorer.rs
  • crates/api-core/src/handlers/expected_machine.rs
  • crates/api-core/src/handlers/machine_interface_address.rs
  • crates/api-core/src/tests/expected_machine.rs
  • crates/api-core/src/tests/machine_dhcp.rs
  • crates/api-core/src/tests/sku.rs
  • crates/api-db/src/expected_machine.rs
  • crates/api-db/src/expected_machine/tests.rs
  • crates/api-db/src/machine_interface.rs
  • crates/api-db/src/machine_interface/tests.rs
  • crates/api-model/src/expected_machine.rs
  • crates/api-model/src/machine/mod.rs
  • crates/api-model/src/predicted_machine_interface.rs
  • crates/api-model/src/site_explorer/mod.rs
  • crates/machine-a-tron/src/api_client.rs
  • crates/machine-a-tron/src/machine_a_tron.rs
  • crates/rpc/build.rs
  • crates/rpc/src/model/expected_machine.rs
  • crates/rpc/src/protos/mod.rs
  • crates/site-explorer/src/lib.rs
  • crates/site-explorer/src/machine_creator.rs
  • crates/site-explorer/tests/integration/reconcile.rs
  • crates/site-explorer/tests/integration/site_explorer.rs
  • crates/site-explorer/tests/integration/zero_dpu.rs

Comment thread crates/admin-cli/src/expected_machines/patch/args.rs Outdated

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

LGTM.

`ExpectedMachine.host_nics` started as a host-only list, but now describes `Host`, `DpuOs`, `DpuBmc`, and `HostBmc` interfaces. The old name no longer matches the data.

So this makes `ExpectedInterface` and `interfaces` the Rust, configuration, and admin CLI names. Existing `host_nics` input and `--host_nics` commands keep working as aliases, while the protobuf names, field numbers, wire bytes, and physical `expected_machines.host_nics` column stay unchanged.

This is a no-op for existing configs and databases, and it does not change `fixed_ip`, role, or allocation behavior. The compatibility tests cover both JSON and CLI spellings, protobuf and ProtoJSON details, and the JSONB round trip.

This supports NVIDIA#4104

Signed-off-by: Chet Nichols III <chetn@nvidia.com>
@chet

chet commented Jul 30, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai Thanks for the eyes. Updated -- the owned conversion now consumes interfaces instead of cloning each entry. PTAL. Resolve if good, thanks!

@chet

chet commented Jul 30, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai full_review, thanks!

@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

@chet: I’ll perform a complete review of the current #4390 changes, with focused verification of the owned interfaces conversion and the Rust, configuration, CLI, protobuf/ProtoJSON, and persistence compatibility boundaries.

✅ Action performed

Full review finished.

@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '== Changed hunks for expected-machine RPC conversion =='
git diff --unified=50 origin/main...HEAD -- crates/rpc/src/model/expected_machine.rs

echo
echo '== Outline of candidate conversion module =='
ast-grep outline crates/rpc/src/model/expected_machine.rs --items all

echo
echo '== Owned ExpectedMachine conversion and interface iteration =='
rg -n -C 16 --glob '*.rs' \
  'impl From<.*ExpectedMachine.*> for rpc::forge::ExpectedMachine|impl From<ExpectedMachine|data\.interfaces|interfaces\.into_iter|interfaces\.iter\(\).*clone|host_nics' \
  crates/rpc/src/model/expected_machine.rs

echo
echo '== Focused conversion test references =='
rg -n -C 8 --glob '*.rs' \
  'canonical.*serial|interfaces.*clone|ExpectedMachine.*into|effective_host_bmc|replace_interfaces' \
  crates/rpc/src/model/expected_machine.rs

Length of output: 83987


@chet Confirmed. The owned ExpectedMachine → RPC conversion now consumes data.interfaces via into_iter() and converts each entry directly; the per-interface clone has been removed. Host BMC projection is computed before consumption, preserving the existing filtering and compatibility behavior. No issue found.

I did not run the test suite in this sandbox.

🐇 ✅

[resolve]

You are interacting with an AI system.

@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

@chet: I’ll perform a complete review of the current changes in #4390, including compatibility guarantees across configuration, CLI aliases, Protobuf/ProtoJSON, persistence, and Rust API surfaces.

✅ Action performed

Full review finished.

@chet
chet enabled auto-merge (squash) July 30, 2026 19:43
@chet
chet merged commit 9cb8d12 into NVIDIA:main Jul 30, 2026
61 checks passed
@chet
chet deleted the gh-issue-4104 branch July 30, 2026 20:37
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.

Rename ExpectedHostNic to ExpectedInterface

3 participants