From a16ec1540e04a2c9e8812098f437bfb3edb60b85 Mon Sep 17 00:00:00 2001 From: Willian Galvani Date: Tue, 14 Jan 2025 09:47:32 -0300 Subject: [PATCH] cable-guy: troubleshooting dynamic ip --- core/services/cable_guy/networksetup.py | 63 +++++++++++++------------ 1 file changed, 34 insertions(+), 29 deletions(-) diff --git a/core/services/cable_guy/networksetup.py b/core/services/cable_guy/networksetup.py index 2279a70f4b..47c451c650 100755 --- a/core/services/cable_guy/networksetup.py +++ b/core/services/cable_guy/networksetup.py @@ -1,5 +1,5 @@ import os -import time +import re from typing import List import sdbus @@ -79,12 +79,18 @@ def add_static_ip(self, interface_name: str, ip: str) -> None: if any(ip in addressData.address for addressData in data.ipv4.address_data): logger.info(f"IP {ip} already exists for {interface_name}") continue + new_ip = AddressData(address=ip, prefix=24) data.ipv4.address_data.append(new_ip) settings.update_profile(data) properties = settings.get_settings() + # Keep method as manual to allow both DHCP client and server properties["ipv4"]["method"] = ("s", "manual") + # Preserve DHCP client if it was enabled + if "dhcp-enabled" not in properties["ipv4"]: + properties["ipv4"]["dhcp-enabled"] = ("b", True) + properties["ipv4"]["may-fail"] = ("b", True) settings.update(properties) settings.save() network_manager.activate_connection(connection_path) @@ -136,48 +142,47 @@ def set_interfaces_priority(self, interfaces: List[NetworkInterfaceMetricApi]) - settings.update(properties) network_manager.activate_connection(connection_path) - def _get_dhcp_address_using_dhclient(self, interface_name: str) -> str: - """Use dhclient to get a DHCP address and return it""" - import re - import subprocess + def _get_dhcp_address_using_dhclient(self, interface_name: str) -> str | None: + """Run dhclient to get a new IP address and return it. + + Args: + interface_name: Name of the interface to get IP for + Returns: + The IP address acquired from DHCP, or None if failed + """ try: # Release any existing DHCP lease - subprocess.run(["dhclient", "-r", interface_name], timeout=5) + os.system(f"dhclient -r {interface_name}") time.sleep(1) # Run dhclient and capture output - result = subprocess.run( - ["dhclient", "-1", "-v", interface_name], capture_output=True, text=True, timeout=30 - ) + dhclient_output = os.popen(f"dhclient -v {interface_name} 2>&1").read() + + bound_ip_match = re.search(r"bound to ([0-9.]+)", dhclient_output) + if bound_ip_match: + return bound_ip_match.group(1) - # Look for the bound IP in the output - match = re.search(r"bound to ([0-9.]+)", result.stderr) - if match: - return match.group(1) + logger.error(f"Could not find bound IP in dhclient output: {dhclient_output}") + return None - logger.error(f"Could not find bound IP in dhclient output: {result.stderr}") - return "" except Exception as e: logger.error(f"Failed to run dhclient: {e}") - return "" + return None def trigger_dynamic_ip_acquisition(self, interface_name: str) -> None: - """Get a new DHCP address using dhclient and add it as a static IP""" - try: - # Get a new IP using dhclient - new_ip = self._get_dhcp_address_using_dhclient(interface_name) - if not new_ip: - logger.error("Failed to get new IP from DHCP") - return - - logger.info(f"Got new IP {new_ip} from DHCP for {interface_name}") + """Get a new IP from DHCP using dhclient and store it in settings. - # Add it as a static IP - self.add_static_ip(interface_name, new_ip) + Args: + interface_name: Name of the interface to get IP for + """ + # Get new IP using dhclient + new_ip = self._get_dhcp_address_using_dhclient(interface_name) + if not new_ip: + logger.error(f"Failed to get DHCP-acquired IP for {interface_name}") + return - except Exception as e: - logger.error(f"Failed to acquire dynamic IP for {interface_name}: {e}") + logger.info(f"Got new IP {new_ip} from DHCP for {interface_name}") class DHCPCD(AbstractNetworkHandler):