Activate network interfaces in anaconda

i8 changed/i8/anaconda-33.16.9.4-1.el8.inferit.5
Arkady L. Shane 9 months ago
parent 88e71afeeb
commit 17216569c8
Signed by: tigro
GPG Key ID: 1EC08A25C9DB2503

@ -0,0 +1,262 @@
From a5cb6c787cd9329aa4d4825c350a45785859a01f Mon Sep 17 00:00:00 2001
From: Anton Volkov <AV.Volkov@softline.com>
Date: Tue, 20 Feb 2024 19:38:47 +0300
Subject: [PATCH 1/2] Activate all wired network devices with link in up state
when running interactive installation
---
anaconda.py | 3 +
pyanaconda/modules/network/initialization.py | 44 +++++++++
pyanaconda/modules/network/network.py | 15 ++-
.../modules/network/network_interface.py | 9 ++
pyanaconda/network.py | 91 +++++++++++++++++++
5 files changed, 161 insertions(+), 1 deletion(-)
diff --git a/anaconda.py b/anaconda.py
index bbf801b..ae282e3 100755
--- a/anaconda.py
+++ b/anaconda.py
@@ -516,6 +516,9 @@ if __name__ == "__main__":
# Initialize the network now, in case the display needs it
from pyanaconda.network import initialize_network, wait_for_connecting_NM_thread, wait_for_connected_NM
+ import pyanaconda.network # @UnusedImport
+ pyanaconda.network.interactive_mode = anaconda.interactive_mode
+
initialize_network()
# If required by user, wait for connection before starting the installation.
if opts.waitfornet:
diff --git a/pyanaconda/modules/network/initialization.py b/pyanaconda/modules/network/initialization.py
index f61b88f..dc8035a 100644
--- a/pyanaconda/modules/network/initialization.py
+++ b/pyanaconda/modules/network/initialization.py
@@ -32,6 +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
log = get_module_logger(__name__)
@@ -40,6 +41,49 @@ gi.require_version("NM", "1.0")
from gi.repository import NM
+class SwitchNetworkDevicesTask(Task):
+ """Task for switching all network devices ON"""
+
+ 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 "Switch network devices on"
+
+ def for_publication(self):
+ """Return a DBus representation."""
+ return NetworkInitializationTaskInterface(self)
+
+ @guard_by_system_configuration(return_value=[])
+ def run(self):
+ """Run the switching network devices on.
+
+ :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):
+ return switch_all_network_devices(nm_client)
+
+
class ApplyKickstartTask(Task):
"""Task for application of kickstart network configuration."""
diff --git a/pyanaconda/modules/network/network.py b/pyanaconda/modules/network/network.py
index 1e194c3..d436190 100644
--- a/pyanaconda/modules/network/network.py
+++ b/pyanaconda/modules/network/network.py
@@ -39,7 +39,7 @@ from pyanaconda.modules.network.ifcfg import get_kickstart_network_data, \
get_ifcfg_file, get_ifcfg_files_content
from pyanaconda.modules.network.installation import NetworkInstallationTask, \
ConfigureActivationOnBootTask, HostnameConfigurationTask
-from pyanaconda.modules.network.initialization import ApplyKickstartTask, \
+from pyanaconda.modules.network.initialization import ApplyKickstartTask, SwitchNetworkDevicesTask, \
ConsolidateInitramfsConnectionsTask, SetRealOnbootValuesFromKickstartTask, \
DumpMissingIfcfgFilesTask
from pyanaconda.modules.network.utils import get_default_route_iface
@@ -550,6 +550,19 @@ class NetworkService(KickstartService):
self._ifname_option_values = values
log.debug("ifname boot option values are set to %s", values)
+ def switch_network_devices_with_task(self):
+ """Switch all network devices ON
+
+ :returns: a task switching all network devices ON
+ """
+ supported_devices = [dev_info.device_name for dev_info in self.get_supported_devices()]
+ task = SwitchNetworkDevicesTask(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 apply_kickstart_with_task(self):
"""Apply kickstart configuration which has not already been applied.
diff --git a/pyanaconda/modules/network/network_interface.py b/pyanaconda/modules/network/network_interface.py
index 6e904ba..27e6e3d 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 SwitchNetworkDevicesWithTask(self) -> ObjPath:
+ """Switch network devices ON
+
+ :returns: DBus path of the task switching network devices ON
+ """
+ return TaskContainer.to_object_path(
+ self.implementation.switch_network_devices_with_task()
+ )
+
def ApplyKickstartWithTask(self) -> ObjPath:
"""Apply kickstart configuration which has not already been applied.
diff --git a/pyanaconda/network.py b/pyanaconda/network.py
index d757934..f7fa48c 100644
--- a/pyanaconda/network.py
+++ b/pyanaconda/network.py
@@ -50,6 +50,8 @@ log = get_module_logger(__name__)
DEFAULT_HOSTNAME = "localhost.localdomain"
+interactive_mode = False
+
network_connected = None
network_connected_condition = threading.Condition()
@@ -272,6 +274,91 @@ def run_network_initialization_task(task_path):
log.debug(msg)
+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.
+ Return list of device names switched ON
+ :param client: Network Manager client object
+ :param activate: True = activate (ON), False = deactivate network devices
+ :param check_link: True = activate network devices with link in up state only
+ :param wait: True = wait for network devices to become active before exiting the function
+ :rtype list(str)
+ """
+ action = "on" if activate else "off"
+ log.debug("start switching all devices %s", action)
+ if not client:
+ log.debug("NM client not available")
+ return []
+ devices = client.get_devices()
+ if not devices:
+ log.debug("No devices found")
+ return []
+ activated_ifaces = get_activated_devices(client)
+ active_connections = client.get_active_connections()
+ active_uuids = set([con.get_uuid() for con in active_connections])
+ 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
+ if activate:
+ if iface in activated_ifaces:
+ log.debug("device %s activated already, skipping", iface)
+ continue
+ elif iface not in activated_ifaces:
+ log.debug("device %s not activated already, skipping", iface)
+ continue
+ # check if the link for the device is up
+ if check_link and activate:
+ 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 activating 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()
+ if activate:
+ if uuid in active_uuids:
+ log.debug("connection %s for device %s is active already, skipping", uuid, iface)
+ continue
+ elif uuid not in active_uuids:
+ log.debug("connection %s for device %s is not active already, skipping", uuid, iface)
+ continue
+ if activate:
+ client.activate_connection_async(con, device, None, None)
+ ifaces.add(iface)
+ else:
+ device.disconnect(None)
+ switched = changed = True
+ if switched:
+ log.info("device %s switched %s", iface, action)
+ if not changed:
+ log.debug("No devices switched %s", action)
+ if wait and ifaces:
+ if wait_for_network_devices(ifaces):
+ log.debug("waiting succeeded: devices are active")
+ else:
+ log.debug("waiting timeout has expired")
+ log.debug("finish switching all devices %s", action)
+ return list(ifaces)
+
+
def initialize_network():
"""Initialize networking."""
if not conf.system.can_configure_network:
@@ -290,6 +377,10 @@ def initialize_network():
run_network_initialization_task(network_proxy.ApplyKickstartWithTask())
run_network_initialization_task(network_proxy.DumpMissingIfcfgFilesWithTask())
run_network_initialization_task(network_proxy.SetRealOnbootValuesFromKickstartWithTask())
+ if interactive_mode:
+ run_network_initialization_task(network_proxy.SwitchNetworkDevicesWithTask())
+ else:
+ log.debug("Not activating all wired network devices in non-interactive mode")
if network_proxy.Hostname == DEFAULT_HOSTNAME:
bootopts_hostname = hostname_from_cmdline(kernel_arguments)
--
2.39.3

@ -0,0 +1,234 @@
From 580c3dee53f0e374104af8d778457ebc526ca92d Mon Sep 17 00:00:00 2001
From: Anton Volkov <AV.Volkov@softline.com>
Date: Thu, 22 Feb 2024 12:42:25 +0300
Subject: [PATCH 2/2] 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

@ -1,7 +1,7 @@
Summary: Graphical system installer
Name: anaconda
Version: 33.16.9.4
Release: 1%{?dist}.inferit.4
Release: 1%{?dist}.inferit.5
License: GPLv2+ and MIT
URL: http://fedoraproject.org/wiki/Anaconda
@ -23,6 +23,8 @@ Patch9: 0009-MSVSphere-Adaptation-Patch.patch
Patch10: 0010-Fix-smt-url.patch
Patch11: 0011-Enable-administrator-by-default.patch
Patch12: 0012-Backport-bugfixes-for-keyboard-layout.patch
Patch13: 0013-Activate-all-wired-network-devices-with-link-in-up-s.patch
Patch14: 0014-Set-autoconnect-and-autoconnect-priority-for-connect.patch
# Versions of required components (done so we make sure the buildrequires
# match the requires versions of things).
@ -384,6 +386,9 @@ desktop-file-install --dir=%{buildroot}%{_datadir}/applications %{buildroot}%{_d
%{_prefix}/libexec/anaconda/dd_*
%changelog
* Fri Feb 23 2024 Arkady L. Shane <tigro@msvsphere-os.ru> - 33.16.9.4-1.inferit.5
- Activate network interfaces in anaconda
* Tue Feb 13 2024 Arkady L. Shane <tigro@msvsphere-os.ru> - 33.16.9.4-1.inferit.4
- Fix keyboard layout order

Loading…
Cancel
Save