From ffc8f3fbb4c8c14a4ef2b6a99a9ea61da4bedde7 Mon Sep 17 00:00:00 2001 From: Ani Sinha Date: Thu, 7 Dec 2023 02:39:51 +0530 Subject: [PATCH 3/3] net/nm: check for presence of ifcfg files when nm connection files are absent (#4645) RH-Author: Ani Sinha RH-MergeRequest: 120: net/nm: check for presence of ifcfg files when nm connection files are absent (#4645) RH-Jira: RHEL-17610 RH-Acked-by: Emanuele Giuseppe Esposito RH-Acked-by: Jon Maloy RH-Commit: [1/1] e0647418de8b70724a32500f26f544650d701404 On systems that use network manager to manage connections and activate network interfaces, they may also use ifcfg files for configuring interfaces using ifcfg-rh network manager plugin. When network manager is used as the activator, we need to also check for the presence of ifcfg interface config file when the network manager connection file is absent and if ifcfg-rh plugin is present. Hence, with this change, network manager activator first tries to use network manager connection files to bring up or bring down the interface. If the connection files are not present and if ifcfg-rh plugin is present, it tries to use ifcfg files for the interface. If the plugin or the ifcfg files are not present, the activator fails to activate or deactivate the interface and it bails out with warning log. Fixes: GH-4640 Signed-off-by: Ani Sinha (cherry picked from commit d1d5166895da471cff3606c70d4e8ab6eec1c006) --- cloudinit/net/activators.py | 7 +++++++ cloudinit/net/network_manager.py | 33 ++++++++++++++++++++++++++++++-- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/cloudinit/net/activators.py b/cloudinit/net/activators.py index e69da40d..dd858862 100644 --- a/cloudinit/net/activators.py +++ b/cloudinit/net/activators.py @@ -117,6 +117,13 @@ class NetworkManagerActivator(NetworkActivator): from cloudinit.net.network_manager import conn_filename filename = conn_filename(device_name) + if filename is None: + LOG.warning( + "Unable to find an interface config file. " + "Unable to bring up interface." + ) + return False + cmd = ["nmcli", "connection", "load", filename] if _alter_interface(cmd, device_name): cmd = ["nmcli", "connection", "up", "filename", filename] diff --git a/cloudinit/net/network_manager.py b/cloudinit/net/network_manager.py index 8a99eb3a..76a0ac15 100644 --- a/cloudinit/net/network_manager.py +++ b/cloudinit/net/network_manager.py @@ -17,10 +17,12 @@ from typing import Optional from cloudinit import subp, util from cloudinit.net import is_ipv6_address, renderer, subnet_is_ipv6 from cloudinit.net.network_state import NetworkState +from cloudinit.net.sysconfig import available_nm_ifcfg_rh NM_RUN_DIR = "/etc/NetworkManager" NM_LIB_DIR = "/usr/lib/NetworkManager" NM_CFG_FILE = "/etc/NetworkManager/NetworkManager.conf" +IFCFG_CFG_FILE = "/etc/sysconfig/network-scripts" NM_IPV6_ADDR_GEN_CONF = """# This is generated by cloud-init. Do not edit. # [.config] @@ -442,7 +444,7 @@ class Renderer(renderer.Renderer): for con_id, conn in self.connections.items(): if not conn.valid(): continue - name = conn_filename(con_id, target) + name = nm_conn_filename(con_id, target) util.write_file(name, conn.dump(), 0o600) # Select EUI64 to be used by default by NM for creating the address @@ -452,12 +454,39 @@ class Renderer(renderer.Renderer): ) -def conn_filename(con_id, target=None): +def nm_conn_filename(con_id, target=None): target_con_dir = subp.target_path(target, NM_RUN_DIR) con_file = f"cloud-init-{con_id}.nmconnection" return f"{target_con_dir}/system-connections/{con_file}" +def sysconfig_conn_filename(devname, target=None): + target_con_dir = subp.target_path(target, IFCFG_CFG_FILE) + con_file = f"ifcfg-{devname}" + return f"{target_con_dir}/{con_file}" + + +def conn_filename(devname): + """ + This function returns the name of the interface config file. + It first checks for presence of network manager connection file. + If absent and ifcfg-rh plugin for network manager is available, + it returns the name of the ifcfg file if it is present. If the + plugin is not present or the plugin is present but ifcfg file is + not, it returns None. + This function is called from NetworkManagerActivator class in + activators.py. + """ + conn_file = nm_conn_filename(devname) + # If the network manager connection file is absent, also check for + # presence of ifcfg files for the same interface (if nm-ifcfg-rh plugin is + # present, network manager can handle ifcfg files). If both network manager + # connection file and ifcfg files are absent, return None. + if not os.path.isfile(conn_file) and available_nm_ifcfg_rh(): + conn_file = sysconfig_conn_filename(devname) + return conn_file if os.path.isfile(conn_file) else None + + def cloud_init_nm_conf_filename(target=None): target_con_dir = subp.target_path(target, NM_RUN_DIR) conf_file = "30-cloud-init-ip6-addr-gen-mode.conf" -- 2.41.0