Skip to content

Commit

Permalink
net/nm: check for presence of ifcfg files when nm connection files ar…
Browse files Browse the repository at this point in the history
…e absent (canonical#4645)

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: canonicalGH-4640

Signed-off-by: Ani Sinha <anisinha@redhat.com>
  • Loading branch information
ani-sinha authored Dec 6, 2023
1 parent 1d6918b commit d1d5166
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 2 deletions.
7 changes: 7 additions & 0 deletions cloudinit/net/activators.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,13 @@ def bring_up_interface(device_name: str) -> bool:
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]
Expand Down
33 changes: 31 additions & 2 deletions cloudinit/net/network_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@
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]
Expand Down Expand Up @@ -442,7 +444,7 @@ def render_network_state(
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
Expand All @@ -452,12 +454,39 @@ def render_network_state(
)


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"
Expand Down

0 comments on commit d1d5166

Please sign in to comment.