From c26453ea88c6d6e1695a18146cf5b6ccf9ce503e Mon Sep 17 00:00:00 2001 From: Brian C Date: Thu, 23 Jul 2026 16:38:48 -0400 Subject: [PATCH] fix(pxe): Make ovs port moves tolerant to OVS failures (#4029) Allow DPU provisioning to continue when a host VF representor has not materialized yet. OVS configuration and ofport_request synchronization are still attempted normally, preserving the working PF path, while expected transient failures no longer terminate cloud-init before service restart and Scout execution https://github.com/NVIDIA/infra-controller/issues/4028 - [ ] **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.) - [ ] **This PR contains breaking changes** - [x] Unit tests added/updated - [ ] Integration tests added/updated - [ ] Manual testing performed - [ ] No testing required (docs, internal refactor, etc.) Closes https://github.com/NVIDIA/infra-controller/issues/4028 (cherry picked from commit 58959fcf5eab90c93faa4df3d94da3620884ae0a) Signed-off-by: brian --- crates/pxe/src/routes/cloud_init.rs | 7 +++++++ pxe/templates/user-data | 5 +++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/crates/pxe/src/routes/cloud_init.rs b/crates/pxe/src/routes/cloud_init.rs index 0c8af5c5a5..024ad1cf42 100644 --- a/crates/pxe/src/routes/cloud_init.rs +++ b/crates/pxe/src/routes/cloud_init.rs @@ -494,6 +494,13 @@ mod tests { .unwrap(); // The loop should emit one assignment and invocation per bridge entry. + // Verify unavailable representors do not abort the remaining cloud-init work. + assert!(rendered.contains( + r#"set interface "${host_representor}" type=dpdk mtu_request=9216 external_ids='{}' || true"# + )); + assert!(rendered.contains( + r#"ofport_request=$(ovs-vsctl get interface "${host_representor}" ofport) || true"# + )); assert!(rendered.contains("ovs-vsctl get bridge br-sfc external_ids")); assert!(rendered.contains("ovs-vsctl --may-exist add-port br-sfc")); assert!(rendered.contains( diff --git a/pxe/templates/user-data b/pxe/templates/user-data index fefd264a88..6e3fe174cd 100644 --- a/pxe/templates/user-data +++ b/pxe/templates/user-data @@ -341,11 +341,12 @@ write_files: # Adjust the sfc.conf to insert our patch port where the host representor used to be sed -i "s#{{ forge_hbn_bridge }}~${host_representor}~${host_representor}_if_r~${host_representor}_if~${host_representor}_if_r#{{ forge_hbn_bridge }}~${host_intercept_hbn_port}~${host_representor}_if_r~${host_representor}_if~${host_representor}_if_r#" /etc/mellanox/sfc.conf + # Keep the OVSDB move when its backing host PF/VF is not available yet. # Now pop the host representor off of br-hbn and attach it to the host intercept bridge ovs-vsctl --if-exists del-port "${host_representor}" -- \ --may-exist add-port "${host_intercept_bridge_name}" "${host_representor}" -- \ - set interface "${host_representor}" type=dpdk mtu_request=9216 external_ids='{}' - ovs-vsctl set interface "${host_representor}" ofport_request=$(ovs-vsctl get interface "${host_representor}" ofport) + set interface "${host_representor}" type=dpdk mtu_request=9216 external_ids='{}' || true + ovs-vsctl set interface "${host_representor}" ofport_request=$(ovs-vsctl get interface "${host_representor}" ofport) || true # Add the detail about the "uplink" for this bridge to external ids for the bridge ovs-vsctl br-set-external-id "${host_intercept_bridge_name}" bridge-uplink "${host_intercept_bridge_port}"