Skip to content

feat: add NIC name preservation check for vSphere migrations#524

Merged
myakove merged 4 commits into
RedHatQE:mainfrom
MiriSafra:feat/MTV-5007-dhcp-nic-name-preservation
Jun 1, 2026
Merged

feat: add NIC name preservation check for vSphere migrations#524
myakove merged 4 commits into
RedHatQE:mainfrom
MiriSafra:feat/MTV-5007-dhcp-nic-name-preservation

Conversation

@MiriSafra
Copy link
Copy Markdown
Member

@MiriSafra MiriSafra commented May 28, 2026

Summary

Adds automatic NIC name preservation verification for all vSphere Linux VM migrations (MTV-5007, MTV-4897).

  • New detect_guest_nic_names() in utilities/vmware_guest_operations.py — runs ip link show inside VMware guest via Guest Operations API, stores NIC name per MAC in guest_nic_name field
  • Call detect_guest_nic_names() in conftest.py prepared_plan for vSphere Linux VMs (after IP origins detection)
  • Add guest_interface_name field (from KubeVirt VMI interfaceName) to network_interfaces in libs/providers/openshift.py
  • New check_nic_name_preservation() in utilities/post_migration.py — matches by MAC address, asserts source NIC name == destination NIC name; hooked into check_vms() for vSphere migrations
  • Non-blocking: if Guest Ops fails, warning logged, check silently skips (no false failures for powered-off VMs or Windows)

Summary by CodeRabbit

  • New Features
    • Guest OS network interface names are now automatically detected during VMware migrations.
    • Post-migration validation now checks that source NIC names are preserved on the destination VM and reports discrepancies.

@qodo-code-review
Copy link
Copy Markdown

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more →

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account →

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us →

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 28, 2026

Review Change Stack

Warning

Review limit reached

@MiriSafra, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 36 minutes and 31 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: a5a63e1e-542a-49b5-bf32-2c49e49bbc68

📥 Commits

Reviewing files that changed from the base of the PR and between 4251d6e and 8c60f08.

📒 Files selected for processing (2)
  • utilities/post_migration.py
  • utilities/vmware_guest_operations.py

Walkthrough

Adds guest NIC name detection for source vSphere Linux guests via VMware Guest Operations, records destination interface names, and validates post-migration that guest NIC names were preserved by matching MAC addresses and comparing names.

Changes

Guest NIC Name Preservation Across vSphere Migration

Layer / File(s) Summary
Source NIC detection and integration
utilities/vmware_guest_operations.py, conftest.py
Adds import json and new detect_guest_nic_names() to run ip -j link show in the guest via VMware Guest Operations, parse interface name/MAC pairs, and set vm_details["network_interfaces"][...]["guest_nic_name"]; imports and invokes this in prepared_plan for VSPHERE non-Windows VMs.
Destination NIC interface capture
libs/providers/openshift.py
OCPProvider.vm_dict now includes guest_interface_name per network_interfaces entry (from VMI interfaceName or "").
Post-migration NIC name validation
utilities/post_migration.py
Adds check_nic_name_preservation(source_vm_data, destination_vm) to match NICs by normalized MAC and assert destination.guest_interface_name == source.guest_nic_name. Wires into check_vms for vSphere VMs and appends failures to per-VM validation errors.
sequenceDiagram
  participant PreparedPlan as prepared_plan
  participant Detect as detect_guest_nic_names
  participant GuestOps as run_command_in_vmware_guest
  participant VMDetails as vm_details.network_interfaces
  participant CheckVMs as check_vms
  participant CheckNIC as check_nic_name_preservation

  PreparedPlan->>Detect: invoke for VSPHERE non-Windows VM
  Detect->>GuestOps: run "ip -j link show"
  GuestOps-->>Detect: JSON interface list
  Detect->>VMDetails: set guest_nic_name by matching MACs
  CheckVMs->>CheckNIC: call with source_vm_data and destination VM
  CheckNIC->>VMDetails: compare source.guest_nic_name to dest.guest_interface_name
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • myakove
  • krcmarik
  • solenoci

CRITICAL: Verify guest Linux credentials and vCenter connectivity checks exist and are not bypassed.
HIGH: Ensure MAC normalization is consistently lowercased across source and destination before matching.
MEDIUM: Confirm logging captures failures in the prepared_plan path to aid debugging.
LOW: Consider unit tests for JSON parsing path and an integration test covering a vSphere Linux guest.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% 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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and specifically describes the main change: adding a NIC name preservation check for vSphere migrations, which is the core feature across all modified files.
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.

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

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

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@redhat-qe-bot
Copy link
Copy Markdown

Report bugs in Issues

Welcome! 🎉

This pull request will be automatically processed with the following features:

🔄 Automatic Actions

  • Reviewer Assignment: Reviewers are automatically assigned based on the OWNERS file in the repository root
  • Size Labeling: PR size labels (XS, S, M, L, XL, XXL) are automatically applied based on changes
  • Issue Creation: Disabled for this repository
  • Branch Labeling: Branch-specific labels are applied to track the target branch
  • Auto-verification: Auto-verified users have their PRs automatically marked as verified
  • Labels: All label categories are enabled (default configuration)

📋 Available Commands

PR Status Management

  • /wip - Mark PR as work in progress (adds WIP: prefix to title)
  • /wip cancel - Remove work in progress status
  • /hold - Block PR merging (approvers only)
  • /hold cancel - Unblock PR merging
  • /verified - Mark PR as verified
  • /verified cancel - Remove verification status
  • /reprocess - Trigger complete PR workflow reprocessing (useful if webhook failed or configuration changed)
  • /regenerate-welcome - Regenerate this welcome message

Review & Approval

  • /lgtm - Approve changes (looks good to me)
  • /approve - Approve PR (approvers only)
  • /automerge - Enable automatic merging when all requirements are met (maintainers and approvers only)
  • /assign-reviewers - Assign reviewers based on OWNERS file
  • /assign-reviewer @username - Assign specific reviewer
  • /check-can-merge - Check if PR meets merge requirements

Testing & Validation

  • /retest tox - Run Python test suite with tox
  • /retest build-container - Rebuild and test container image
  • /retest conventional-title - Validate commit message format
  • /retest all - Run all available tests

Container Operations

  • /build-and-push-container - Build and push container image (tagged with PR number)
    • Supports additional build arguments: /build-and-push-container --build-arg KEY=value

Cherry-pick Operations

  • /cherry-pick <branch> - Schedule cherry-pick to target branch when PR is merged
    • Multiple branches: /cherry-pick branch1 branch2 branch3

Label Management

  • /<label-name> - Add a label to the PR
  • /<label-name> cancel - Remove a label from the PR

✅ Merge Requirements

This PR will be automatically approved when the following conditions are met:

  1. Approval: /approve from at least one approver
  2. Status Checks: All required status checks must pass
  3. No Blockers: No wip, hold, has-conflicts labels and PR must be mergeable (no conflicts)
  4. Verified: PR must be marked as verified

📊 Review Process

Approvers and Reviewers

Approvers:

  • myakove
  • solenoci

Reviewers:

  • krcmarik
  • myakove
  • solenoci
Available Labels
  • hold
  • verified
  • wip
  • lgtm
  • approve
  • automerge
AI Features
  • Conventional Title: Mode: fix (claude/claude-opus-4-6[1m])
  • Cherry-Pick Conflict Resolution: Enabled (claude/claude-opus-4-6[1m])
  • Test Oracle: Triggers: approved (cursor/gpt-5.4-xhigh-fast); /test-oracle can be used anytime

💡 Tips

  • WIP Status: Use /wip when your PR is not ready for review
  • Verification: The verified label is removed on new commits unless the push is detected as a clean rebase
  • Cherry-picking: Cherry-pick labels are processed when the PR is merged
  • Container Builds: Container images are automatically tagged with the PR number
  • Permission Levels: Some commands require approver permissions
  • Auto-verified Users: Certain users have automatic verification and merge privileges

For more information, please refer to the project documentation or contact the maintainers.

@MiriSafra
Copy link
Copy Markdown
Member Author

/verified

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 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 `@conftest.py`:
- Around line 1153-1162: The try/except around detect_guest_nic_names is too
broad and hides real errors; narrow it to only catch the expected Guest Ops
runtime errors (e.g., the specific guest operations exception class your
provider raises) while allowing all other exceptions to propagate. Replace the
bare except in the block calling detect_guest_nic_names (the call using
source_provider, provider_vm_api, fixture_store["source_provider_data"],
vm_details) so it catches the provider/guest-ops specific exception type(s) and
logs via LOGGER.warning(f"Failed to detect guest NIC names for VM {vm['name']}:
{e}"), but re-raise any other Exception so regressions surface. Ensure you
import or reference the actual exception class used by the guest ops code and
only handle that here.

In `@libs/providers/openshift.py`:
- Line 254: The value assigned to "guest_interface_name" can be None when
interface["interfaceName"] exists but is null; change the expression that sets
guest_interface_name (the dict entry with key "guest_interface_name" in
libs/providers/openshift.py) to normalize falsy/None to an empty string by using
interface.get("interfaceName") or "" so downstream comparisons always see a str.

In `@utilities/post_migration.py`:
- Around line 735-746: The loop that compares source_mac to dest_nics can
silently succeed when there is no matching destination NIC; normalize MAC
formats by stripping non-hex delimiters and lowercasing both values (e.g.,
derive a normalized_source_mac from source_nic and normalize each dest_mac in
the loop) and set a found flag when a match occurs; after the loop, if not
found, raise/assert/log an error (use LOGGER.error and an AssertionError or
raise RuntimeError) indicating missing destination NIC for source_nic_name and
include normalized_source_mac so the failure is explicit; keep the existing
assertion that dest_nic_name == source_nic_name when a match is found.
- Around line 1435-1443: The NIC-name preservation check is currently nested
inside the SSH/power-state gating and thus skipped when vm_ssh_connections is
not provided; move the try/except block that calls check_nic_name_preservation
(with source_vm_data and destination_vm) out of the SSH/power-state section so
it always runs when source_vm_data is present and source_provider.type ==
Provider.ProviderType.VSPHERE, preserving the existing exception handling that
appends to res[vm_name] (using vm_name) on failure.
🪄 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: ASSERTIVE

Plan: Pro

Run ID: a267d2c8-c6ea-44fe-b595-9c5a36a5bc36

📥 Commits

Reviewing files that changed from the base of the PR and between b4c2658 and 1eef33a.

📒 Files selected for processing (4)
  • conftest.py
  • libs/providers/openshift.py
  • utilities/post_migration.py
  • utilities/vmware_guest_operations.py

Comment thread conftest.py Outdated
Comment thread libs/providers/openshift.py Outdated
Comment thread utilities/post_migration.py
Comment thread utilities/post_migration.py
@MiriSafra
Copy link
Copy Markdown
Member Author

/verified

@MiriSafra MiriSafra changed the title feat(MTV-5007): add NIC name preservation check for vSphere migrations feat: add NIC name preservation check for vSphere migrations May 28, 2026
MiriSafra added 2 commits May 31, 2026 09:50
Automatically verifies that guest OS NIC names (e.g., ens192, eth0) are
preserved after migration by comparing source names (collected via VMware
Guest Operations) against destination names (from KubeVirt guest agent).
Addresses CodeRabbit review: interface.get("interfaceName", "") can
return None when key exists with null value. Using `or ""` handles both
missing key and null value cases.
@MiriSafra MiriSafra force-pushed the feat/MTV-5007-dhcp-nic-name-preservation branch from 252457e to 3097320 Compare May 31, 2026 06:50
@redhat-qe-bot
Copy link
Copy Markdown

Clean rebase detected — no code changes compared to previous head (252457e).
The following labels were preserved: verified, commented-coderabbitai[bot], lgtm-coderabbitai[bot], commented-MiriSafra.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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 `@utilities/post_migration.py`:
- Around line 1435-1443: The NIC-name preservation check is being run even when
destination guest-agent metadata may not be available; update the logic around
check_nic_name_preservation in check_vms()/the block with source_vm_data and
destination_vm so it only runs when guest-agent data is present or forced:
either call/create destination_vm with wait_for_guest_agent=True when
source_provider.type == Provider.ProviderType.VSPHERE and source_vm_data
contains guest_interface_name, or skip the call to check_nic_name_preservation
when the destination_vm has no confirmed guest-agent metadata (e.g., empty guest
interfaces or empty guest_interface_name) or when vm["guest_agent"] is not
enabled; reference check_nic_name_preservation, destination_vm, source_vm_data
and vm["guest_agent"] to locate and implement the conditional gating or forced
wait.
🪄 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: ASSERTIVE

Plan: Pro

Run ID: 3e33627c-7af0-4fd7-94db-0732f16311be

📥 Commits

Reviewing files that changed from the base of the PR and between 1eef33a and 3097320.

📒 Files selected for processing (4)
  • conftest.py
  • libs/providers/openshift.py
  • utilities/post_migration.py
  • utilities/vmware_guest_operations.py

Comment thread utilities/post_migration.py
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 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 `@conftest.py`:
- Around line 1153-1158: Wrap the call to detect_guest_nic_names in a try/except
block mirroring the pattern used by detect_vmware_ip_origins_via_guest_ops: call
detect_guest_nic_names(...) inside try, re-raise ValueError
(configuration/credentials errors), and catch all other exceptions to log a
warning (preserving the exception message/context) and continue so NIC detection
is non-blocking; use the same logger used elsewhere in this file and keep
behavior consistent with the IP origin detection logic.

In `@utilities/post_migration.py`:
- Around line 731-734: The check that raises ValueError when dest_nics is empty
creates an implicit dependency on guest-agent data (guest_interface_name) and
can produce false negatives in post_migration NIC-name verification; update the
logic in the function that inspects source_nics/dest_nics so it either enforces
guest-agent availability (e.g., verify any nic.get("guest_interface_name")
exists on dest_nics and raise a clear ValueError referencing
guest-agent/wait_for_guest_agent) or skip the verification gracefully when
guest-agent data is missing (log/warn and return) — locate the code around the
dest_nics/source_nics checks and the use of guest_interface_name to implement
one of these two fixes consistently.

In `@utilities/vmware_guest_operations.py`:
- Line 306: The call to json.loads(output) (assigning to interfaces) can raise
JSONDecodeError on non-JSON or corrupted guest output; either document
JSONDecodeError in the function's Raises: section if fail-fast is intended, or
wrap the json.loads(output) call in a try/except JSONDecodeError and re-raise a
clearer exception (e.g., ValueError or GuestCommandError) with context including
the original error and the raw output to aid debugging; update the function
docstring accordingly to reflect the chosen 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: ASSERTIVE

Plan: Pro

Run ID: 340319a0-f0ee-4dfd-a0e2-f6338a3293e1

📥 Commits

Reviewing files that changed from the base of the PR and between 3097320 and 4251d6e.

📒 Files selected for processing (3)
  • conftest.py
  • utilities/post_migration.py
  • utilities/vmware_guest_operations.py

Comment thread conftest.py
Comment thread utilities/post_migration.py
Comment thread utilities/vmware_guest_operations.py
- Skip NIC name preservation check when guest agent is not active
  to avoid false failures from empty guest_interface_name
- Document json.JSONDecodeError in detect_guest_nic_names docstring
@MiriSafra
Copy link
Copy Markdown
Member Author

/verified

@myakove
Copy link
Copy Markdown
Collaborator

myakove commented Jun 1, 2026

/lgtm
/approve

@redhat-qe-bot
Copy link
Copy Markdown

Test Oracle server is not responding, skipping test analysis

@myakove myakove merged commit ef6bb05 into RedHatQE:main Jun 1, 2026
7 checks passed
@redhat-qe-bot
Copy link
Copy Markdown

New container for ghcr.io/redhatqe/mtv-api-tests:latest published

@prabinovRedhat
Copy link
Copy Markdown
Collaborator

Regression / flaky setup after merge — detect_guest_nic_names in prepared_plan

Seeing repeated setup failures on TestCopyoffloadThinMigration (and likely other vSphere clone tests without source_vm_power: "on") after #524 merged.

Error:

ValueError: Cannot determine guest OS for VM auto-*-xcopy-template-test-...
Ensure VMware Tools is installed and running.

Stack: prepared_plandetect_guest_nic_namesrun_command_in_vmware_guest (guestFamily is None).

What happens:

  1. VM clone completes (~10s)
  2. detect_guest_nic_names() runs immediately (~2s later)
  3. wait_for_vmware_guest_info() was never called — copy-offload config has guest_agent: True but not source_vm_power: "on", and the tools wait is only tied to explicit power-on
  4. Guest Ops fails because vm.guest.guestFamily isn't populated yet

Asymmetry with existing code:

  • detect_vmware_ip_origins_via_guest_ops → try/except, warn and continue (unless preserve_static_ips)
  • detect_guest_nic_namesunconditional, no try/except, fails setup
  • Post-migration check_nic_name_preservation is gated on guest_agent_running, but pre-migration collection is not gated the same way

Suggested fix (any of):

  1. Wrap detect_guest_nic_names in the same try/except pattern as IP origins (warn + skip NIC check if Guest Ops unavailable)
  2. Call wait_for_vmware_guest_info() before Guest Ops when guest_agent: True (not only when source_vm_power: "on")
  3. Gate collection on tools readiness / guest_agent config, matching the post-migration gate
  4. Retry/wait for guestFamily inside detect_guest_nic_names before running ip -j link show

Repro: TestCopyoffloadThinMigration on ocp-edge97 / vsphere-8.0.3-copyoffload-netapp-tlv — failed 4/4 today after merge; passed earlier the same day before #524 landed on our rebase base.

@prabinovRedhat
Copy link
Copy Markdown
Collaborator

prabinovRedhat commented Jun 1, 2026

cc @tshefi @myakove

@MiriSafra
Copy link
Copy Markdown
Member Author

@prabinovRedhat Thanks, fix in #536 , since the udev rules only run under that config

@tshefi
Copy link
Copy Markdown
Collaborator

tshefi commented Jun 2, 2026

Verified, #536 resolves offload test failure introduced by this PR.
Thanks Miri

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants