You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
263 lines
11 KiB
263 lines
11 KiB
8 months ago
|
From e9211745672557570dc16829489556fa58254cbd 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 13/14] 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
|
||
|
|