From b6807446c6531753b5b46ec906f8fa4d05f91770 Mon Sep 17 00:00:00 2001 From: Anton Volkov Date: Thu, 22 Feb 2024 12:42:25 +0300 Subject: [PATCH 14/14] Set autoconnect and autoconnect-priority for connections of all network devices with link in up state --- pyanaconda/modules/network/initialization.py | 53 +++++++++++++- pyanaconda/modules/network/network.py | 15 +++- .../modules/network/network_interface.py | 9 +++ pyanaconda/network.py | 69 +++++++++++++++++++ 4 files changed, 144 insertions(+), 2 deletions(-) diff --git a/pyanaconda/modules/network/initialization.py b/pyanaconda/modules/network/initialization.py index dc8035a..5530075 100644 --- a/pyanaconda/modules/network/initialization.py +++ b/pyanaconda/modules/network/initialization.py @@ -32,7 +32,7 @@ from pyanaconda.modules.network.ifcfg import get_ifcfg_file_of_device, find_ifcf from pyanaconda.modules.network.device_configuration import supported_wired_device_types, \ virtual_device_types from pyanaconda.modules.network.utils import guard_by_system_configuration -from pyanaconda.network import switch_all_network_devices +from pyanaconda.network import switch_all_network_devices, configure_connections log = get_module_logger(__name__) @@ -41,6 +41,57 @@ gi.require_version("NM", "1.0") from gi.repository import NM +class SetAutoconnectPriorityTask(Task): + """ + Task for configuring autoconnect and autoconnect-priority for connections of + all network devices with link in up state + """ + + def __init__(self, network_data, supported_devices, bootif, ifname_option_values): + """Create a new task. + + :param network_data: kickstart network data to be applied + :type: list(NetworkData) + :param supported_devices: list of names of supported network devices + :type supported_devices: list(str) + :param bootif: MAC addres of device to be used for --device=bootif specification + :type bootif: str + :param ifname_option_values: list of ifname boot option values + :type ifname_option_values: list(str) + """ + super().__init__() + self._network_data = network_data + self._supported_devices = supported_devices + self._bootif = bootif + self._ifname_option_values = ifname_option_values + + @property + def name(self): + return "Set autoconnect and autoconnect-priority for connections of network devices with link in up state" + + def for_publication(self): + """Return a DBus representation.""" + return NetworkInitializationTaskInterface(self) + + @guard_by_system_configuration(return_value=[]) + def run(self): + """ + Run nmcli utility to set autoconnect and autoconnect-priority for + connections of network devices with link in up state + :returns: names of devices + :rtype: list(str) + """ + with nm_client_in_thread() as nm_client: + return self._run(nm_client) + + def _run(self, nm_client): + settings = { + "connection.autoconnect" : "yes", + "connection.autoconnect-priority" : "-999" + } + return configure_connections(nm_client, settings) + + class SwitchNetworkDevicesTask(Task): """Task for switching all network devices ON""" diff --git a/pyanaconda/modules/network/network.py b/pyanaconda/modules/network/network.py index d436190..c196ac5 100644 --- a/pyanaconda/modules/network/network.py +++ b/pyanaconda/modules/network/network.py @@ -40,7 +40,7 @@ from pyanaconda.modules.network.ifcfg import get_kickstart_network_data, \ from pyanaconda.modules.network.installation import NetworkInstallationTask, \ ConfigureActivationOnBootTask, HostnameConfigurationTask from pyanaconda.modules.network.initialization import ApplyKickstartTask, SwitchNetworkDevicesTask, \ - ConsolidateInitramfsConnectionsTask, SetRealOnbootValuesFromKickstartTask, \ + ConsolidateInitramfsConnectionsTask, SetRealOnbootValuesFromKickstartTask, SetAutoconnectPriorityTask, \ DumpMissingIfcfgFilesTask from pyanaconda.modules.network.utils import get_default_route_iface from pyanaconda.modules.common.structures.network import NetworkDeviceInfo @@ -550,6 +550,19 @@ class NetworkService(KickstartService): self._ifname_option_values = values log.debug("ifname boot option values are set to %s", values) + def set_autoconnect_priority_with_task(self): + """ + Set autoconnect and autoconnect-priority for connections of network devices with link in up state + :returns: a task configuring autoconnect and autoconnect-priority for all network devices + """ + supported_devices = [dev_info.device_name for dev_info in self.get_supported_devices()] + task = SetAutoconnectPriorityTask(self._original_network_data, + supported_devices, + self.bootif, + self.ifname_option_values) + task.succeeded_signal.connect(lambda: self.log_task_result(task, check_result=True)) + return task + def switch_network_devices_with_task(self): """Switch all network devices ON diff --git a/pyanaconda/modules/network/network_interface.py b/pyanaconda/modules/network/network_interface.py index 27e6e3d..52b7b48 100644 --- a/pyanaconda/modules/network/network_interface.py +++ b/pyanaconda/modules/network/network_interface.py @@ -213,6 +213,15 @@ class NetworkInterface(KickstartModuleInterface): self.implementation.consolidate_initramfs_connections_with_task() ) + def SetAutoconnectPriorityWithTask(self) -> ObjPath: + """Set autoconnect and autoconnect-priority for connections of network devices with link in up state + + :returns: DBus path of the task switching network devices ON + """ + return TaskContainer.to_object_path( + self.implementation.set_autoconnect_priority_with_task() + ) + def SwitchNetworkDevicesWithTask(self) -> ObjPath: """Switch network devices ON diff --git a/pyanaconda/network.py b/pyanaconda/network.py index f7fa48c..7179c19 100644 --- a/pyanaconda/network.py +++ b/pyanaconda/network.py @@ -46,6 +46,8 @@ from pyanaconda.modules.common.structures.network import NetworkDeviceInfo from pyanaconda.modules.common.util import is_module_available from pyanaconda.anaconda_loggers import get_module_logger +import subprocess + log = get_module_logger(__name__) DEFAULT_HOSTNAME = "localhost.localdomain" @@ -274,6 +276,72 @@ def run_network_initialization_task(task_path): log.debug(msg) +def configure_connections(client, settings, check_link=True): + """ + Configure connection parameters for all wired network devices with link in up state. + Return list of device names affected + :param client: Network Manager client object + :param settings: dict(str, str) = {name:value} of the setting to configure + :param check_link: True = handle network devices with link in up state only + :rtype list(str) + """ + log.debug("start configuring autoconnect for all network devices with link in up state") + if not client: + log.debug("NM client not available") + return [] + devices = client.get_devices() + if not devices: + log.debug("No devices found") + return [] + if not settings: + log.debug("No settings passed") + return [] + changed = False + ifaces = set() + for device in devices: + if not device: + continue + switched = False + iface = device.get_iface() + if not device_type_is_supported_wired(device.get_device_type()): + log.debug("device %s is not wired, skipping", iface) + continue + # check if the link for the device is up + if check_link: + try: + carrier = device.get_carrier() + except AttributeError: + carrier = None + if carrier: + log.debug("device %s link is up", iface) + else: + log.debug("device %s link is down", iface) + # skip modifying the autoconnect.priority setting for the device if link is down + continue + connections = device.get_available_connections() + if not connections: + log.debug("No available connections for device %s", iface) + continue + for con in connections: + if not con: + continue + uuid = con.get_uuid() + cmd_line = ["nmcli", "connection", "modify", "uuid", uuid] + for setting_name in settings: + setting_value = settings[setting_name] + cmd_line.extend([setting_name, setting_value]) + p = subprocess.run(cmd_line, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, check=False, close_fds=True) + log.debug("update settings for connection %s for device %s, nmcli exit code = %s", uuid, iface, str(p.returncode)) + ifaces.add(iface) + switched = changed = True + if switched: + log.info("connection settings for device %s updated", iface) + if not changed: + log.debug("No settings for devices updated") + log.debug("finish configuring autoconnect for all network devices with link in up state") + return list(ifaces) + + def switch_all_network_devices(client, activate=True, check_link=True, wait=True): """ Switch ON (or OFF) all wired network devices with link in up state. @@ -379,6 +447,7 @@ def initialize_network(): run_network_initialization_task(network_proxy.SetRealOnbootValuesFromKickstartWithTask()) if interactive_mode: run_network_initialization_task(network_proxy.SwitchNetworkDevicesWithTask()) + run_network_initialization_task(network_proxy.SetAutoconnectPriorityWithTask()) else: log.debug("Not activating all wired network devices in non-interactive mode") -- 2.39.3