Skip to content

Conversation

@TasmiyaNalatwad
Copy link
Contributor

@TasmiyaNalatwad TasmiyaNalatwad commented Oct 14, 2025

Few of the times it is seen that the ip address is not being fetch and the avocado runs were failed with error "ERROR: Failures occurred while postprocess:\n\n: Guest virt-tests-vm1 dmesg verification failed: Login timeout expired (output: 'exceeded 240 s timeout, last failure: No ipv4 DHCP lease for MAC aa:bb:cc:dd:ee:ff') "

To handle this error the patch has been sent. The patch helps in obtaining ip address of the guest using "virsh-net-dhcp-leases default" command. If the guest mac address is found in the command output, the mac ipv4 address is obatined and updated in the address.cache

If the ip_version is ipv6, then it raises exception VMIPAddressMissingError, and going to retry logic to try getting the ip address.

Even in case of ipv4, if the address is not found, instead of sending None, i am raising exception VMIPAddressMissingError which leads to retry menthod.

Summary by CodeRabbit

  • New Features

    • Improved VM IP discovery with an automatic IPv4 fallback that derives the guest address from the network interface and caches results.
  • Bug Fixes

    • More reliable retrieval of guest IPs, reducing missing-address cases.
    • Clearer error messages when an IP cannot be determined.
    • Note: no new IPv6 fallback was added.

@coderabbitai
Copy link

coderabbitai bot commented Oct 14, 2025

📝 Walkthrough

Walkthrough

Adds a VM._get_address override in virttest/libvirt_vm.py that, on superclass VMIPAddressMissingError, for IPv4 derives the NIC MAC and tries utils_net.obtain_guest_ip_from_domifaddr to discover, cache, and return the guest IP; adds obtain_guest_ip_from_domifaddr in virttest/utils_net.py.

Changes

Cohort / File(s) Summary of Changes
Libvirt VM address resolution
virttest/libvirt_vm.py
Added VM._get_address(self, index=0, ip_version="ipv4", session=None, timeout=60.0) override. On superclass VMIPAddressMissingError, if ip_version == "ipv4" derives the MAC, calls utils_net.obtain_guest_ip_from_domifaddr(vm_name, mac), caches the discovered IP, and returns it; otherwise raises VMIPAddressMissingError with a version- or MAC-specific message. Updated imports to include utils_net.
Networking utilities
virttest/utils_net.py
Added obtain_guest_ip_from_domifaddr(vm_name, mac) which runs and parses virsh domifaddr --full --source arp output to return the IPv4 address for the given MAC (or None if not found). Added import of virsh.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Pre-merge checks

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title clearly references the core change of retrieving the address via domifaddr and throwing VMIPAddressMissingError for both IPv4 and IPv6 when no address is found, but it is overly long and contains typos that reduce readability.
Docstring Coverage ✅ Passed Docstring coverage is 80.00% which is sufficient. The required threshold is 80.00%.

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d6279e5 and 57170c4.

📒 Files selected for processing (2)
  • virttest/libvirt_vm.py (2 hunks)
  • virttest/utils_net.py (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • virttest/utils_net.py
🧰 Additional context used
🧬 Code graph analysis (1)
virttest/libvirt_vm.py (2)
virttest/virt_vm.py (4)
  • _get_address (814-872)
  • _get_address (930-934)
  • VMIPAddressMissingError (246-253)
  • get_mac_address (767-782)
virttest/utils_net.py (2)
  • get_mac_address (3413-3420)
  • obtain_guest_ip_from_domifaddr (4899-4914)
🪛 Ruff (0.14.0)
virttest/libvirt_vm.py

393-395: Within an except clause, raise exceptions with raise ... from err or raise ... from None to distinguish them from errors in exception handling

(B904)


393-395: Avoid specifying long messages outside the exception class

(TRY003)


397-399: Within an except clause, raise exceptions with raise ... from err or raise ... from None to distinguish them from errors in exception handling

(B904)


397-399: Avoid specifying long messages outside the exception class

(TRY003)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Static checks
🔇 Additional comments (1)
virttest/libvirt_vm.py (1)

33-33: LGTM: Required import for new method.

The utils_net import is necessary for the new _get_address override that calls utils_net.obtain_guest_ip_from_domifaddr.


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.

@TasmiyaNalatwad TasmiyaNalatwad force-pushed the fixing_regression_for_ipv6_address branch from f06371d to 848dc9f Compare October 14, 2025 07:48
@TasmiyaNalatwad
Copy link
Contributor Author

@smitterl @chloerh @luckyh I have tried fixing the regression due to these changes based on PR #4250

Please have a look.

Now instead of returning None, i am raising exception VMIPAddressMissingError which allows the retry code to execute in both ipv4 and ipv6 cases.

Please let me know your inputs for this fix.

Thank you.

@TasmiyaNalatwad TasmiyaNalatwad force-pushed the fixing_regression_for_ipv6_address branch 3 times, most recently from 63c3920 to d6279e5 Compare October 14, 2025 07:55
Copy link

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

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between efccd9f and d6279e5.

📒 Files selected for processing (2)
  • virttest/libvirt_vm.py (2 hunks)
  • virttest/utils_net.py (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
virttest/libvirt_vm.py (2)
virttest/virt_vm.py (4)
  • _get_address (814-872)
  • _get_address (930-934)
  • VMIPAddressMissingError (246-253)
  • get_mac_address (767-782)
virttest/utils_net.py (2)
  • get_mac_address (3413-3420)
  • obtain_guest_ip_from_domifaddr (4899-4914)
virttest/utils_net.py (1)
virttest/virsh.py (1)
  • domifaddr (3533-3543)
🪛 Ruff (0.14.0)
virttest/libvirt_vm.py

393-395: Within an except clause, raise exceptions with raise ... from err or raise ... from None to distinguish them from errors in exception handling

(B904)


393-395: Avoid specifying long messages outside the exception class

(TRY003)


397-399: Within an except clause, raise exceptions with raise ... from err or raise ... from None to distinguish them from errors in exception handling

(B904)


397-399: Avoid specifying long messages outside the exception class

(TRY003)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)

Comment on lines 382 to 400
def _get_address(self, index=0, ip_version="ipv4", session=None, timeout=60.0):
try:
return super()._get_address(index, ip_version, session, timeout)
except virt_vm.VMIPAddressMissingError:
if ip_version == "ipv4":
mac = self.get_mac_address(index).lower()
ipaddr = utils_net.obtain_guest_ip_from_domifaddr(self.name, mac)
if ipaddr:
self.address_cache[mac] = ipaddr
return ipaddr
else:
raise virt_vm.VMIPAddressMissingError(
"IP address not found for MAC: %s", mac
)
else:
raise virt_vm.VMIPAddressMissingError(
"No IP address found for IP version: %s", ip_version
)

Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Construct VMIPAddressMissingError correctly and chain original exception

  • VMIPAddressMissingError expects (mac, ip_version). Current code passes a formatted message and mis-assigns fields, breaking error semantics and retries.
  • Also, chain the original exception per best practices (B904), and ensure MAC is available in both branches.

Apply this diff:

-    def _get_address(self, index=0, ip_version="ipv4", session=None, timeout=60.0):
-        try:
-            return super()._get_address(index, ip_version, session, timeout)
-        except virt_vm.VMIPAddressMissingError:
-            if ip_version == "ipv4":
-                mac = self.get_mac_address(index).lower()
-                ipaddr = utils_net.obtain_guest_ip_from_domifaddr(self.name, mac)
-                if ipaddr:
-                    self.address_cache[mac] = ipaddr
-                    return ipaddr
-                else:
-                    raise virt_vm.VMIPAddressMissingError(
-                        "IP address not found for MAC: %s", mac
-                    )
-            else:
-                raise virt_vm.VMIPAddressMissingError(
-                    "No IP address found for IP version: %s", ip_version
-                )
+    def _get_address(self, index=0, ip_version="ipv4", session=None, timeout=60.0):
+        try:
+            return super()._get_address(index, ip_version, session, timeout)
+        except virt_vm.VMIPAddressMissingError as err:
+            mac = self.get_mac_address(index).lower()
+            if ip_version == "ipv4":
+                ipaddr = utils_net.obtain_guest_ip_from_domifaddr(self.name, mac)
+                if ipaddr:
+                    self.address_cache[mac] = ipaddr
+                    return ipaddr
+                raise virt_vm.VMIPAddressMissingError(mac, ip_version) from err
+            raise virt_vm.VMIPAddressMissingError(mac, ip_version) from err

This corrects the constructor usage, ensures consistent error messaging, and preserves context. Based on static analysis hints.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
def _get_address(self, index=0, ip_version="ipv4", session=None, timeout=60.0):
try:
return super()._get_address(index, ip_version, session, timeout)
except virt_vm.VMIPAddressMissingError:
if ip_version == "ipv4":
mac = self.get_mac_address(index).lower()
ipaddr = utils_net.obtain_guest_ip_from_domifaddr(self.name, mac)
if ipaddr:
self.address_cache[mac] = ipaddr
return ipaddr
else:
raise virt_vm.VMIPAddressMissingError(
"IP address not found for MAC: %s", mac
)
else:
raise virt_vm.VMIPAddressMissingError(
"No IP address found for IP version: %s", ip_version
)
def _get_address(self, index=0, ip_version="ipv4", session=None, timeout=60.0):
try:
return super()._get_address(index, ip_version, session, timeout)
except virt_vm.VMIPAddressMissingError as err:
mac = self.get_mac_address(index).lower()
if ip_version == "ipv4":
ipaddr = utils_net.obtain_guest_ip_from_domifaddr(self.name, mac)
if ipaddr:
self.address_cache[mac] = ipaddr
return ipaddr
raise virt_vm.VMIPAddressMissingError(mac, ip_version) from err
raise virt_vm.VMIPAddressMissingError(mac, ip_version) from err
🧰 Tools
🪛 Ruff (0.14.0)

393-395: Within an except clause, raise exceptions with raise ... from err or raise ... from None to distinguish them from errors in exception handling

(B904)


393-395: Avoid specifying long messages outside the exception class

(TRY003)


397-399: Within an except clause, raise exceptions with raise ... from err or raise ... from None to distinguish them from errors in exception handling

(B904)


397-399: Avoid specifying long messages outside the exception class

(TRY003)

🤖 Prompt for AI Agents
In virttest/libvirt_vm.py around lines 382 to 400, fix the
VMIPAddressMissingError construction and exception chaining: capture the MAC
early (e.g., mac = self.get_mac_address(index).lower()) so it’s available in
both branches, and when re-raising use the VMIPAddressMissingError constructor
with the correct parameters (mac, ip_version) instead of a formatted message,
and chain the original exception (raise virt_vm.VMIPAddressMissingError(mac,
ip_version) from e) to preserve context.

Comment on lines +4899 to +4914
def obtain_guest_ip_from_domifaddr(vm_name, mac):
"""
Obtaining the guest ip address from virsh domifaddr command
:param: Mac address of the guest
:return: return ip-address if found for given mac in the
virsh domifaddr --full --source arp, else return None
"""
output = virsh.domifaddr(vm_name, "--full --source arp")
lines = output.stdout.splitlines()
for line in lines:
if mac in line:
parts = line.split()
for part in parts:
if "/" in part:
return part.split("/")[0]
return None
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Fix domifaddr parsing: use stdout_text, case-insensitive MAC match, and prefer IPv4

  • Use stdout_text (consistent with virsh CmdResult).
  • Match MAC case-insensitively to avoid misses.
  • Prefer IPv4 address when both IPv4/IPv6 are present.

Apply this diff:

-def obtain_guest_ip_from_domifaddr(vm_name, mac):
-    """
-    Obtaining the guest ip address from virsh domifaddr command
-    :param: Mac address of the guest
-    :return: return ip-address if found for given mac in the
-             virsh domifaddr --full --source arp, else return None
-    """
-    output = virsh.domifaddr(vm_name, "--full --source arp")
-    lines = output.stdout.splitlines()
-    for line in lines:
-        if mac in line:
-            parts = line.split()
-            for part in parts:
-                if "/" in part:
-                    return part.split("/")[0]
-    return None
+def obtain_guest_ip_from_domifaddr(vm_name, mac):
+    """
+    Obtain the guest IPv4 address from 'virsh domifaddr'.
+    :param vm_name: Domain name
+    :param mac: Guest MAC address
+    :return: IPv4 address string if found; otherwise None
+    """
+    result = virsh.domifaddr(vm_name, "--full --source arp")
+    lines = result.stdout_text.splitlines()
+    mac_l = mac.lower()
+    for line in lines:
+        if mac_l in line.lower():
+            parts = line.split()
+            for part in parts:
+                if "/" in part:
+                    addr = part.split("/", 1)[0]
+                    # Prefer IPv4 for callers expecting IPv4
+                    if "." in addr:
+                        return addr
+    return None
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
def obtain_guest_ip_from_domifaddr(vm_name, mac):
"""
Obtaining the guest ip address from virsh domifaddr command
:param: Mac address of the guest
:return: return ip-address if found for given mac in the
virsh domifaddr --full --source arp, else return None
"""
output = virsh.domifaddr(vm_name, "--full --source arp")
lines = output.stdout.splitlines()
for line in lines:
if mac in line:
parts = line.split()
for part in parts:
if "/" in part:
return part.split("/")[0]
return None
def obtain_guest_ip_from_domifaddr(vm_name, mac):
"""
Obtain the guest IPv4 address from 'virsh domifaddr'.
:param vm_name: Domain name
:param mac: Guest MAC address
:return: IPv4 address string if found; otherwise None
"""
result = virsh.domifaddr(vm_name, "--full --source arp")
lines = result.stdout_text.splitlines()
mac_l = mac.lower()
for line in lines:
if mac_l in line.lower():
parts = line.split()
for part in parts:
if "/" in part:
addr = part.split("/", 1)[0]
# Prefer IPv4 for callers expecting IPv4
if "." in addr:
return addr
return None
🤖 Prompt for AI Agents
In virttest/utils_net.py around lines 4899 to 4914, the domifaddr parsing
currently reads output.stdout and does a case-sensitive MAC search and returns
the first CIDR part it finds; change it to read output.stdout_text, perform a
case-insensitive match for the MAC (lowercase both strings), and when a matching
line contains multiple address entries (IPv4 and IPv6), prefer and return the
IPv4 address (i.e., pick the CIDR part where the IP contains dots) falling back
to the first available address if no IPv4 is present; keep returning None if no
match is found.

Few of the times it is seen that the ip address is not being fetch and the avocado runs were failed with error "ERROR: Failures occurred while postprocess:\n\n: Guest virt-tests-vm1 dmesg verification failed: Login timeout expired (output: 'exceeded 240 s timeout, last failure: No ipv4 DHCP lease for MAC aa:bb:cc:dd:ee:ff') "

To handle this error the patch has been sent. The patch helps in obtaining ip address of the guest using "virsh-net-dhcp-leases default" command. If the guest mac address is found in the command output, the mac ipv4 address is obatined and updated in the address.cache

If the ip_version is ipv6, then it raises exception VMIPAddressMissingError, and going to retry logic to try getting the ip address.
Even for ipv4 , if address is not found then it raises exception VMIPAddressMissingError and then retries will happen.

Signed-off-by: Tasmiya Nalatwad <tasmiya@linux.vnet.ibm.com>
@TasmiyaNalatwad TasmiyaNalatwad force-pushed the fixing_regression_for_ipv6_address branch from d6279e5 to 57170c4 Compare October 14, 2025 08:05
@TasmiyaNalatwad
Copy link
Contributor Author

@smitterl Would you please run your test with these changes and check if the regression issue still occurs? This will help confirm whether the fix resolves the problem effectively. Thank You in Advance.

@TasmiyaNalatwad
Copy link
Contributor Author

@smitterl @chloerh would you please look at this PR and confirm if regression is solved with this fix.

@harihare
Copy link
Contributor

harihare commented Nov 6, 2025

May I request @smitterl or @chloerh help in reviewing the patch.

@TasmiyaNalatwad
Copy link
Contributor Author

@smitterl @chloerh Would you please have a look at this PR. If regression is solved with these changes can we move forward and merge this PR.

Thank you so much for your time and support.

@TasmiyaNalatwad
Copy link
Contributor Author

@smitterl @chloerh would you please confirm and let me know with this fix the regression is addressed or not. We need this patch for our test buckets to run.

Thanks in Advance.

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.

2 participants