diff --git a/ci-Revert-Add-native-NetworkManager-support-1224.patch b/ci-Revert-Add-native-NetworkManager-support-1224.patch new file mode 100644 index 0000000..e4e3594 --- /dev/null +++ b/ci-Revert-Add-native-NetworkManager-support-1224.patch @@ -0,0 +1,2266 @@ +From f1836e78d20ef34b05b6aba002fc10a97eceb454 Mon Sep 17 00:00:00 2001 +From: Emanuele Giuseppe Esposito +Date: Mon, 8 Aug 2022 10:08:50 +0200 +Subject: [PATCH 1/2] Revert "Add native NetworkManager support (#1224)" + +RH-Author: Emanuele Giuseppe Esposito +RH-MergeRequest: 81: Revert "Use Network-Manager and Netplan as default renderers for RHEL and Fedora (#1465)" +RH-Commit: [1/2] 5b3e51502a89c2dcfbc97dc08a86b792454fedd3 +RH-Bugzilla: 2107464 2110066 2117526 2104393 2098624 +RH-Acked-by: Eduardo Otubo +RH-Acked-by: Vitaly Kuznetsov +RH-Acked-by: Mohamed Gamal Morsy + +NM is not yet stable, so we don't want to support it for now. +This reverts commit 0d93e53fd05c44b62e3456b7580c9de8135e6b5a. + +Signed-off-by: Emanuele Giuseppe Esposito +--- + cloudinit/cmd/devel/net_convert.py | 14 +- + cloudinit/net/activators.py | 25 +- + cloudinit/net/network_manager.py | 377 ------- + cloudinit/net/renderers.py | 3 - + cloudinit/net/sysconfig.py | 37 +- + tests/unittests/test_net.py | 1268 +++--------------------- + tests/unittests/test_net_activators.py | 93 +- + 7 files changed, 193 insertions(+), 1624 deletions(-) + delete mode 100644 cloudinit/net/network_manager.py + +diff --git a/cloudinit/cmd/devel/net_convert.py b/cloudinit/cmd/devel/net_convert.py +index 647fe07b..18b1e7ff 100755 +--- a/cloudinit/cmd/devel/net_convert.py ++++ b/cloudinit/cmd/devel/net_convert.py +@@ -7,14 +7,7 @@ import os + import sys + + from cloudinit import distros, log, safeyaml +-from cloudinit.net import ( +- eni, +- netplan, +- network_manager, +- network_state, +- networkd, +- sysconfig, +-) ++from cloudinit.net import eni, netplan, network_state, networkd, sysconfig + from cloudinit.sources import DataSourceAzure as azure + from cloudinit.sources import DataSourceOVF as ovf + from cloudinit.sources.helpers import openstack +@@ -81,7 +74,7 @@ def get_parser(parser=None): + parser.add_argument( + "-O", + "--output-kind", +- choices=["eni", "netplan", "networkd", "sysconfig", "network-manager"], ++ choices=["eni", "netplan", "networkd", "sysconfig"], + required=True, + help="The network config format to emit", + ) +@@ -155,9 +148,6 @@ def handle_args(name, args): + elif args.output_kind == "sysconfig": + r_cls = sysconfig.Renderer + config = distro.renderer_configs.get("sysconfig") +- elif args.output_kind == "network-manager": +- r_cls = network_manager.Renderer +- config = distro.renderer_configs.get("network-manager") + else: + raise RuntimeError("Invalid output_kind") + +diff --git a/cloudinit/net/activators.py b/cloudinit/net/activators.py +index edbc0c06..e80c26df 100644 +--- a/cloudinit/net/activators.py ++++ b/cloudinit/net/activators.py +@@ -1,14 +1,15 @@ + # This file is part of cloud-init. See LICENSE file for license information. + import logging ++import os + from abc import ABC, abstractmethod + from typing import Iterable, List, Type + + from cloudinit import subp, util + from cloudinit.net.eni import available as eni_available + from cloudinit.net.netplan import available as netplan_available +-from cloudinit.net.network_manager import available as nm_available + from cloudinit.net.network_state import NetworkState + from cloudinit.net.networkd import available as networkd_available ++from cloudinit.net.sysconfig import NM_CFG_FILE + + LOG = logging.getLogger(__name__) + +@@ -123,24 +124,20 @@ class IfUpDownActivator(NetworkActivator): + class NetworkManagerActivator(NetworkActivator): + @staticmethod + def available(target=None) -> bool: +- """Return true if NetworkManager can be used on this system.""" +- return nm_available(target=target) ++ """Return true if network manager can be used on this system.""" ++ config_present = os.path.isfile( ++ subp.target_path(target, path=NM_CFG_FILE) ++ ) ++ nmcli_present = subp.which("nmcli", target=target) ++ return config_present and bool(nmcli_present) + + @staticmethod + def bring_up_interface(device_name: str) -> bool: +- """Bring up connection using nmcli. ++ """Bring up interface using nmcli. + + Return True is successful, otherwise return False + """ +- from cloudinit.net.network_manager import conn_filename +- +- filename = conn_filename(device_name) +- cmd = ["nmcli", "connection", "load", filename] +- if _alter_interface(cmd, device_name): +- cmd = ["nmcli", "connection", "up", "filename", filename] +- else: +- _alter_interface(["nmcli", "connection", "reload"], device_name) +- cmd = ["nmcli", "connection", "up", "ifname", device_name] ++ cmd = ["nmcli", "connection", "up", "ifname", device_name] + return _alter_interface(cmd, device_name) + + @staticmethod +@@ -149,7 +146,7 @@ class NetworkManagerActivator(NetworkActivator): + + Return True is successful, otherwise return False + """ +- cmd = ["nmcli", "device", "disconnect", device_name] ++ cmd = ["nmcli", "connection", "down", device_name] + return _alter_interface(cmd, device_name) + + +diff --git a/cloudinit/net/network_manager.py b/cloudinit/net/network_manager.py +deleted file mode 100644 +index 79b0fe0b..00000000 +--- a/cloudinit/net/network_manager.py ++++ /dev/null +@@ -1,377 +0,0 @@ +-# Copyright 2022 Red Hat, Inc. +-# +-# Author: Lubomir Rintel +-# Fixes and suggestions contributed by James Falcon, Neal Gompa, +-# Zbigniew Jędrzejewski-Szmek and Emanuele Giuseppe Esposito. +-# +-# This file is part of cloud-init. See LICENSE file for license information. +- +-import configparser +-import io +-import itertools +-import os +-import uuid +- +-from cloudinit import log as logging +-from cloudinit import subp, util +- +-from . import renderer +-from .network_state import is_ipv6_addr, subnet_is_ipv6 +- +-NM_RUN_DIR = "/etc/NetworkManager" +-NM_LIB_DIR = "/usr/lib/NetworkManager" +-LOG = logging.getLogger(__name__) +- +- +-class NMConnection: +- """Represents a NetworkManager connection profile.""" +- +- def __init__(self, con_id): +- """ +- Initializes the connection with some very basic properties, +- notably the UUID so that the connection can be referred to. +- """ +- +- # Chosen by fair dice roll +- CI_NM_UUID = uuid.UUID("a3924cb8-09e0-43e9-890b-77972a800108") +- +- self.config = configparser.ConfigParser() +- # Identity option name mapping, to achieve case sensitivity +- self.config.optionxform = str +- +- self.config["connection"] = { +- "id": f"cloud-init {con_id}", +- "uuid": str(uuid.uuid5(CI_NM_UUID, con_id)), +- } +- +- # This is not actually used anywhere, but may be useful in future +- self.config["user"] = { +- "org.freedesktop.NetworkManager.origin": "cloud-init" +- } +- +- def _set_default(self, section, option, value): +- """ +- Sets a property unless it's already set, ensuring the section +- exists. +- """ +- +- if not self.config.has_section(section): +- self.config[section] = {} +- if not self.config.has_option(section, option): +- self.config[section][option] = value +- +- def _set_ip_method(self, family, subnet_type): +- """ +- Ensures there's appropriate [ipv4]/[ipv6] for given family +- appropriate for given configuration type +- """ +- +- method_map = { +- "static": "manual", +- "dhcp6": "dhcp", +- "ipv6_slaac": "auto", +- "ipv6_dhcpv6-stateless": "auto", +- "ipv6_dhcpv6-stateful": "auto", +- "dhcp4": "auto", +- "dhcp": "auto", +- } +- +- # Ensure we got an [ipvX] section +- self._set_default(family, "method", "disabled") +- +- try: +- method = method_map[subnet_type] +- except KeyError: +- # What else can we do +- method = "auto" +- self.config[family]["may-fail"] = "true" +- +- # Make sure we don't "downgrade" the method in case +- # we got conflicting subnets (e.g. static along with dhcp) +- if self.config[family]["method"] == "dhcp": +- return +- if self.config[family]["method"] == "auto" and method == "manual": +- return +- +- self.config[family]["method"] = method +- self._set_default(family, "may-fail", "false") +- if family == "ipv6": +- self._set_default(family, "addr-gen-mode", "stable-privacy") +- +- def _add_numbered(self, section, key_prefix, value): +- """ +- Adds a numbered property, such as address or route, ensuring +- the appropriate value gets used for . +- """ +- +- for index in itertools.count(1): +- key = f"{key_prefix}{index}" +- if not self.config.has_option(section, key): +- self.config[section][key] = value +- break +- +- def _add_address(self, family, subnet): +- """ +- Adds an ipv[46]address property. +- """ +- +- value = subnet["address"] + "/" + str(subnet["prefix"]) +- self._add_numbered(family, "address", value) +- +- def _add_route(self, family, route): +- """ +- Adds a ipv[46].route property. +- """ +- +- value = route["network"] + "/" + str(route["prefix"]) +- if "gateway" in route: +- value = value + "," + route["gateway"] +- self._add_numbered(family, "route", value) +- +- def _add_nameserver(self, dns): +- """ +- Extends the ipv[46].dns property with a name server. +- """ +- +- # FIXME: the subnet contains IPv4 and IPv6 name server mixed +- # together. We might be getting an IPv6 name server while +- # we're dealing with an IPv4 subnet. Sort this out by figuring +- # out the correct family and making sure a valid section exist. +- family = "ipv6" if is_ipv6_addr(dns) else "ipv4" +- self._set_default(family, "method", "disabled") +- +- self._set_default(family, "dns", "") +- self.config[family]["dns"] = self.config[family]["dns"] + dns + ";" +- +- def _add_dns_search(self, family, dns_search): +- """ +- Extends the ipv[46].dns-search property with a name server. +- """ +- +- self._set_default(family, "dns-search", "") +- self.config[family]["dns-search"] = ( +- self.config[family]["dns-search"] + ";".join(dns_search) + ";" +- ) +- +- def con_uuid(self): +- """ +- Returns the connection UUID +- """ +- return self.config["connection"]["uuid"] +- +- def valid(self): +- """ +- Can this be serialized into a meaningful connection profile? +- """ +- return self.config.has_option("connection", "type") +- +- @staticmethod +- def mac_addr(addr): +- """ +- Sanitize a MAC address. +- """ +- return addr.replace("-", ":").upper() +- +- def render_interface(self, iface, renderer): +- """ +- Integrate information from network state interface information +- into the connection. Most of the work is done here. +- """ +- +- # Initialize type & connectivity +- _type_map = { +- "physical": "ethernet", +- "vlan": "vlan", +- "bond": "bond", +- "bridge": "bridge", +- "infiniband": "infiniband", +- "loopback": None, +- } +- +- if_type = _type_map[iface["type"]] +- if if_type is None: +- return +- if "bond-master" in iface: +- slave_type = "bond" +- else: +- slave_type = None +- +- self.config["connection"]["type"] = if_type +- if slave_type is not None: +- self.config["connection"]["slave-type"] = slave_type +- self.config["connection"]["master"] = renderer.con_ref( +- iface[slave_type + "-master"] +- ) +- +- # Add type specific-section +- self.config[if_type] = {} +- +- # These are the interface properties that map nicely +- # to NetworkManager properties +- _prop_map = { +- "bond": { +- "mode": "bond-mode", +- "miimon": "bond_miimon", +- "xmit_hash_policy": "bond-xmit-hash-policy", +- "num_grat_arp": "bond-num-grat-arp", +- "downdelay": "bond-downdelay", +- "updelay": "bond-updelay", +- "fail_over_mac": "bond-fail-over-mac", +- "primary_reselect": "bond-primary-reselect", +- "primary": "bond-primary", +- }, +- "bridge": { +- "stp": "bridge_stp", +- "priority": "bridge_bridgeprio", +- }, +- "vlan": { +- "id": "vlan_id", +- }, +- "ethernet": {}, +- "infiniband": {}, +- } +- +- device_mtu = iface["mtu"] +- ipv4_mtu = None +- +- # Deal with Layer 3 configuration +- for subnet in iface["subnets"]: +- family = "ipv6" if subnet_is_ipv6(subnet) else "ipv4" +- +- self._set_ip_method(family, subnet["type"]) +- if "address" in subnet: +- self._add_address(family, subnet) +- if "gateway" in subnet: +- self.config[family]["gateway"] = subnet["gateway"] +- for route in subnet["routes"]: +- self._add_route(family, route) +- if "dns_nameservers" in subnet: +- for nameserver in subnet["dns_nameservers"]: +- self._add_nameserver(nameserver) +- if "dns_search" in subnet: +- self._add_dns_search(family, subnet["dns_search"]) +- if family == "ipv4" and "mtu" in subnet: +- ipv4_mtu = subnet["mtu"] +- +- if ipv4_mtu is None: +- ipv4_mtu = device_mtu +- if not ipv4_mtu == device_mtu: +- LOG.warning( +- "Network config: ignoring %s device-level mtu:%s" +- " because ipv4 subnet-level mtu:%s provided.", +- iface["name"], +- device_mtu, +- ipv4_mtu, +- ) +- +- # Parse type-specific properties +- for nm_prop, key in _prop_map[if_type].items(): +- if key not in iface: +- continue +- if iface[key] is None: +- continue +- if isinstance(iface[key], bool): +- self.config[if_type][nm_prop] = ( +- "true" if iface[key] else "false" +- ) +- else: +- self.config[if_type][nm_prop] = str(iface[key]) +- +- # These ones need special treatment +- if if_type == "ethernet": +- if iface["wakeonlan"] is True: +- # NM_SETTING_WIRED_WAKE_ON_LAN_MAGIC +- self.config["ethernet"]["wake-on-lan"] = str(0x40) +- if ipv4_mtu is not None: +- self.config["ethernet"]["mtu"] = str(ipv4_mtu) +- if iface["mac_address"] is not None: +- self.config["ethernet"]["mac-address"] = self.mac_addr( +- iface["mac_address"] +- ) +- if if_type == "vlan" and "vlan-raw-device" in iface: +- self.config["vlan"]["parent"] = renderer.con_ref( +- iface["vlan-raw-device"] +- ) +- if if_type == "bridge": +- # Bridge is ass-backwards compared to bond +- for port in iface["bridge_ports"]: +- port = renderer.get_conn(port) +- port._set_default("connection", "slave-type", "bridge") +- port._set_default("connection", "master", self.con_uuid()) +- if iface["mac_address"] is not None: +- self.config["bridge"]["mac-address"] = self.mac_addr( +- iface["mac_address"] +- ) +- if if_type == "infiniband" and ipv4_mtu is not None: +- self.config["infiniband"]["transport-mode"] = "datagram" +- self.config["infiniband"]["mtu"] = str(ipv4_mtu) +- if iface["mac_address"] is not None: +- self.config["infiniband"]["mac-address"] = self.mac_addr( +- iface["mac_address"] +- ) +- +- # Finish up +- if if_type == "bridge" or not self.config.has_option( +- if_type, "mac-address" +- ): +- self.config["connection"]["interface-name"] = iface["name"] +- +- def dump(self): +- """ +- Stringify. +- """ +- +- buf = io.StringIO() +- self.config.write(buf, space_around_delimiters=False) +- header = "# Generated by cloud-init. Changes will be lost.\n\n" +- return header + buf.getvalue() +- +- +-class Renderer(renderer.Renderer): +- """Renders network information in a NetworkManager keyfile format.""" +- +- def __init__(self, config=None): +- self.connections = {} +- +- def get_conn(self, con_id): +- return self.connections[con_id] +- +- def con_ref(self, con_id): +- if con_id in self.connections: +- return self.connections[con_id].con_uuid() +- else: +- # Well, what can we do... +- return con_id +- +- def render_network_state(self, network_state, templates=None, target=None): +- # First pass makes sure there's NMConnections for all known +- # interfaces that have UUIDs that can be linked to from related +- # interfaces +- for iface in network_state.iter_interfaces(): +- self.connections[iface["name"]] = NMConnection(iface["name"]) +- +- # Now render the actual interface configuration +- for iface in network_state.iter_interfaces(): +- conn = self.connections[iface["name"]] +- conn.render_interface(iface, self) +- +- # And finally write the files +- for con_id, conn in self.connections.items(): +- if not conn.valid(): +- continue +- name = conn_filename(con_id, target) +- util.write_file(name, conn.dump(), 0o600) +- +- +-def 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 available(target=None): +- target_nm_dir = subp.target_path(target, NM_LIB_DIR) +- return os.path.exists(target_nm_dir) +- +- +-# vi: ts=4 expandtab +diff --git a/cloudinit/net/renderers.py b/cloudinit/net/renderers.py +index 7edc34b5..c755f04c 100644 +--- a/cloudinit/net/renderers.py ++++ b/cloudinit/net/renderers.py +@@ -8,7 +8,6 @@ from . import ( + freebsd, + netbsd, + netplan, +- network_manager, + networkd, + openbsd, + renderer, +@@ -20,7 +19,6 @@ NAME_TO_RENDERER = { + "freebsd": freebsd, + "netbsd": netbsd, + "netplan": netplan, +- "network-manager": network_manager, + "networkd": networkd, + "openbsd": openbsd, + "sysconfig": sysconfig, +@@ -30,7 +28,6 @@ DEFAULT_PRIORITY = [ + "eni", + "sysconfig", + "netplan", +- "network-manager", + "freebsd", + "netbsd", + "openbsd", +diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py +index c3b0c795..362e8d19 100644 +--- a/cloudinit/net/sysconfig.py ++++ b/cloudinit/net/sysconfig.py +@@ -5,6 +5,8 @@ import io + import os + import re + ++from configobj import ConfigObj ++ + from cloudinit import log as logging + from cloudinit import subp, util + from cloudinit.distros.parsers import networkmanager_conf, resolv_conf +@@ -64,6 +66,24 @@ def _quote_value(value): + return value + + ++def enable_ifcfg_rh(path): ++ """Add ifcfg-rh to NetworkManager.cfg plugins if main section is present""" ++ config = ConfigObj(path) ++ if "main" in config: ++ if "plugins" in config["main"]: ++ if "ifcfg-rh" in config["main"]["plugins"]: ++ return ++ else: ++ config["main"]["plugins"] = [] ++ ++ if isinstance(config["main"]["plugins"], list): ++ config["main"]["plugins"].append("ifcfg-rh") ++ else: ++ config["main"]["plugins"] = [config["main"]["plugins"], "ifcfg-rh"] ++ config.write() ++ LOG.debug("Enabled ifcfg-rh NetworkManager plugins") ++ ++ + class ConfigMap(object): + """Sysconfig like dictionary object.""" + +@@ -1011,6 +1031,8 @@ class Renderer(renderer.Renderer): + netrules_content = self._render_persistent_net(network_state) + netrules_path = subp.target_path(target, self.netrules_path) + util.write_file(netrules_path, netrules_content, file_mode) ++ if available_nm(target=target): ++ enable_ifcfg_rh(subp.target_path(target, path=NM_CFG_FILE)) + + sysconfig_path = subp.target_path(target, templates.get("control")) + # Distros configuring /etc/sysconfig/network as a file e.g. Centos +@@ -1049,9 +1071,14 @@ def _supported_vlan_names(rdev, vid): + + + def available(target=None): +- if not util.system_info()["variant"] in KNOWN_DISTROS: +- return False ++ sysconfig = available_sysconfig(target=target) ++ nm = available_nm(target=target) ++ return util.system_info()["variant"] in KNOWN_DISTROS and any( ++ [nm, sysconfig] ++ ) ++ + ++def available_sysconfig(target=None): + expected = ["ifup", "ifdown"] + search = ["/sbin", "/usr/sbin"] + for p in expected: +@@ -1068,4 +1095,10 @@ def available(target=None): + return False + + ++def available_nm(target=None): ++ if not os.path.isfile(subp.target_path(target, path=NM_CFG_FILE)): ++ return False ++ return True ++ ++ + # vi: ts=4 expandtab +diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py +index ef21ad76..591241b3 100644 +--- a/tests/unittests/test_net.py ++++ b/tests/unittests/test_net.py +@@ -21,7 +21,6 @@ from cloudinit.net import ( + interface_has_own_mac, + natural_sort_key, + netplan, +- network_manager, + network_state, + networkd, + renderers, +@@ -612,37 +611,6 @@ dns = none + ), + ), + ], +- "expected_network_manager": [ +- ( +- "".join( +- [ +- "etc/NetworkManager/system-connections", +- "/cloud-init-eth0.nmconnection", +- ] +- ), +- """ +-# Generated by cloud-init. Changes will be lost. +- +-[connection] +-id=cloud-init eth0 +-uuid=1dd9a779-d327-56e1-8454-c65e2556c12c +-type=ethernet +- +-[user] +-org.freedesktop.NetworkManager.origin=cloud-init +- +-[ethernet] +-mac-address=FA:16:3E:ED:9A:59 +- +-[ipv4] +-method=manual +-may-fail=false +-address1=172.19.1.34/22 +-route1=0.0.0.0/0,172.19.3.254 +- +-""".lstrip(), +- ), +- ], + }, + { + "in_data": { +@@ -1105,50 +1073,6 @@ NETWORK_CONFIGS = { + USERCTL=no""" + ), + }, +- "expected_network_manager": { +- "cloud-init-eth1.nmconnection": textwrap.dedent( +- """\ +- # Generated by cloud-init. Changes will be lost. +- +- [connection] +- id=cloud-init eth1 +- uuid=3c50eb47-7260-5a6d-801d-bd4f587d6b58 +- type=ethernet +- +- [user] +- org.freedesktop.NetworkManager.origin=cloud-init +- +- [ethernet] +- mac-address=CF:D6:AF:48:E8:80 +- +- """ +- ), +- "cloud-init-eth99.nmconnection": textwrap.dedent( +- """\ +- # Generated by cloud-init. Changes will be lost. +- +- [connection] +- id=cloud-init eth99 +- uuid=b1b88000-1f03-5360-8377-1a2205efffb4 +- type=ethernet +- +- [user] +- org.freedesktop.NetworkManager.origin=cloud-init +- +- [ethernet] +- mac-address=C0:D6:9F:2C:E8:80 +- +- [ipv4] +- method=auto +- may-fail=false +- address1=192.168.21.3/24 +- route1=0.0.0.0/0,65.61.151.37 +- dns=8.8.8.8;8.8.4.4; +- dns-search=barley.maas;sach.maas; +- +- """ +- ), +- }, + "yaml": textwrap.dedent( + """ + version: 1 +@@ -1221,34 +1145,6 @@ NETWORK_CONFIGS = { + STARTMODE=auto""" + ) + }, +- "expected_network_manager": { +- "cloud-init-iface0.nmconnection": textwrap.dedent( +- """\ +- # Generated by cloud-init. Changes will be lost. +- +- [connection] +- id=cloud-init iface0 +- uuid=8ddfba48-857c-5e86-ac09-1b43eae0bf70 +- type=ethernet +- interface-name=iface0 +- +- [user] +- org.freedesktop.NetworkManager.origin=cloud-init +- +- [ethernet] +- +- [ipv4] +- method=auto +- may-fail=false +- +- [ipv6] +- method=dhcp +- may-fail=false +- addr-gen-mode=stable-privacy +- +- """ +- ), +- }, + "yaml": textwrap.dedent( + """\ + version: 1 +@@ -1351,37 +1247,6 @@ NETWORK_CONFIGS = { + """ + ), + }, +- "expected_network_manager": { +- "cloud-init-iface0.nmconnection": textwrap.dedent( +- """\ +- # Generated by cloud-init. Changes will be lost. +- +- [connection] +- id=cloud-init iface0 +- uuid=8ddfba48-857c-5e86-ac09-1b43eae0bf70 +- type=ethernet +- interface-name=iface0 +- +- [user] +- org.freedesktop.NetworkManager.origin=cloud-init +- +- [ethernet] +- mtu=9000 +- +- [ipv4] +- method=manual +- may-fail=false +- address1=192.168.14.2/24 +- +- [ipv6] +- method=manual +- may-fail=false +- addr-gen-mode=stable-privacy +- address1=2001:1::1/64 +- +- """ +- ), +- }, + }, + "v6_and_v4": { + "expected_sysconfig_opensuse": { +@@ -1392,34 +1257,6 @@ NETWORK_CONFIGS = { + STARTMODE=auto""" + ) + }, +- "expected_network_manager": { +- "cloud-init-iface0.nmconnection": textwrap.dedent( +- """\ +- # Generated by cloud-init. Changes will be lost. +- +- [connection] +- id=cloud-init iface0 +- uuid=8ddfba48-857c-5e86-ac09-1b43eae0bf70 +- type=ethernet +- interface-name=iface0 +- +- [user] +- org.freedesktop.NetworkManager.origin=cloud-init +- +- [ethernet] +- +- [ipv6] +- method=dhcp +- may-fail=false +- addr-gen-mode=stable-privacy +- +- [ipv4] +- method=auto +- may-fail=false +- +- """ +- ), +- }, + "yaml": textwrap.dedent( + """\ + version: 1 +@@ -1493,30 +1330,6 @@ NETWORK_CONFIGS = { + """ + ), + }, +- "expected_network_manager": { +- "cloud-init-iface0.nmconnection": textwrap.dedent( +- """\ +- # Generated by cloud-init. Changes will be lost. +- +- [connection] +- id=cloud-init iface0 +- uuid=8ddfba48-857c-5e86-ac09-1b43eae0bf70 +- type=ethernet +- interface-name=iface0 +- +- [user] +- org.freedesktop.NetworkManager.origin=cloud-init +- +- [ethernet] +- +- [ipv6] +- method=dhcp +- may-fail=false +- addr-gen-mode=stable-privacy +- +- """ +- ), +- }, + }, + "dhcpv6_accept_ra": { + "expected_eni": textwrap.dedent( +@@ -1724,30 +1537,6 @@ NETWORK_CONFIGS = { + """ + ), + }, +- "expected_network_manager": { +- "cloud-init-iface0.nmconnection": textwrap.dedent( +- """\ +- # Generated by cloud-init. Changes will be lost. +- +- [connection] +- id=cloud-init iface0 +- uuid=8ddfba48-857c-5e86-ac09-1b43eae0bf70 +- type=ethernet +- interface-name=iface0 +- +- [user] +- org.freedesktop.NetworkManager.origin=cloud-init +- +- [ethernet] +- +- [ipv6] +- method=auto +- may-fail=false +- addr-gen-mode=stable-privacy +- +- """ +- ), +- }, + }, + "static6": { + "yaml": textwrap.dedent( +@@ -1836,30 +1625,6 @@ NETWORK_CONFIGS = { + """ + ), + }, +- "expected_network_manager": { +- "cloud-init-iface0.nmconnection": textwrap.dedent( +- """\ +- # Generated by cloud-init. Changes will be lost. +- +- [connection] +- id=cloud-init iface0 +- uuid=8ddfba48-857c-5e86-ac09-1b43eae0bf70 +- type=ethernet +- interface-name=iface0 +- +- [user] +- org.freedesktop.NetworkManager.origin=cloud-init +- +- [ethernet] +- +- [ipv6] +- method=auto +- may-fail=false +- addr-gen-mode=stable-privacy +- +- """ +- ), +- }, + }, + "dhcpv6_stateful": { + "expected_eni": textwrap.dedent( +@@ -1959,29 +1724,6 @@ NETWORK_CONFIGS = { + """ + ), + }, +- "expected_network_manager": { +- "cloud-init-iface0.nmconnection": textwrap.dedent( +- """\ +- # Generated by cloud-init. Changes will be lost. +- +- [connection] +- id=cloud-init iface0 +- uuid=8ddfba48-857c-5e86-ac09-1b43eae0bf70 +- type=ethernet +- interface-name=iface0 +- +- [user] +- org.freedesktop.NetworkManager.origin=cloud-init +- +- [ethernet] +- +- [ipv4] +- method=auto +- may-fail=false +- +- """ +- ), +- }, + "yaml_v2": textwrap.dedent( + """\ + version: 2 +@@ -2035,30 +1777,6 @@ NETWORK_CONFIGS = { + """ + ), + }, +- "expected_network_manager": { +- "cloud-init-iface0.nmconnection": textwrap.dedent( +- """\ +- # Generated by cloud-init. Changes will be lost. +- +- [connection] +- id=cloud-init iface0 +- uuid=8ddfba48-857c-5e86-ac09-1b43eae0bf70 +- type=ethernet +- interface-name=iface0 +- +- [user] +- org.freedesktop.NetworkManager.origin=cloud-init +- +- [ethernet] +- wake-on-lan=64 +- +- [ipv4] +- method=auto +- may-fail=false +- +- """ +- ), +- }, + "yaml_v2": textwrap.dedent( + """\ + version: 2 +@@ -2497,254 +2215,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true + USERCTL=no""" + ), + }, +- "expected_network_manager": { +- "cloud-init-eth3.nmconnection": textwrap.dedent( +- """\ +- # Generated by cloud-init. Changes will be lost. +- +- [connection] +- id=cloud-init eth3 +- uuid=b7e95dda-7746-5bf8-bf33-6e5f3c926790 +- type=ethernet +- slave-type=bridge +- master=dee46ce4-af7a-5e7c-aa08-b25533ae9213 +- +- [user] +- org.freedesktop.NetworkManager.origin=cloud-init +- +- [ethernet] +- mac-address=66:BB:9F:2C:E8:80 +- +- """ +- ), +- "cloud-init-eth5.nmconnection": textwrap.dedent( +- """\ +- # Generated by cloud-init. Changes will be lost. +- +- [connection] +- id=cloud-init eth5 +- uuid=5fda13c7-9942-5e90-a41b-1d043bd725dc +- type=ethernet +- +- [user] +- org.freedesktop.NetworkManager.origin=cloud-init +- +- [ethernet] +- mac-address=98:BB:9F:2C:E8:8A +- +- [ipv4] +- method=auto +- may-fail=false +- +- """ +- ), +- "cloud-init-ib0.nmconnection": textwrap.dedent( +- """\ +- # Generated by cloud-init. Changes will be lost. +- +- [connection] +- id=cloud-init ib0 +- uuid=11a1dda7-78b4-5529-beba-d9b5f549ad7b +- type=infiniband +- +- [user] +- org.freedesktop.NetworkManager.origin=cloud-init +- +- [infiniband] +- transport-mode=datagram +- mtu=9000 +- mac-address=A0:00:02:20:FE:80:00:00:00:00:00:00:EC:0D:9A:03:00:15:E2:C1 +- +- [ipv4] +- method=manual +- may-fail=false +- address1=192.168.200.7/24 +- +- """ +- ), +- "cloud-init-bond0.200.nmconnection": textwrap.dedent( +- """\ +- # Generated by cloud-init. Changes will be lost. +- +- [connection] +- id=cloud-init bond0.200 +- uuid=88984a9c-ff22-5233-9267-86315e0acaa7 +- type=vlan +- interface-name=bond0.200 +- +- [user] +- org.freedesktop.NetworkManager.origin=cloud-init +- +- [vlan] +- id=200 +- parent=54317911-f840-516b-a10d-82cb4c1f075c +- +- [ipv4] +- method=auto +- may-fail=false +- +- """ +- ), +- "cloud-init-eth0.nmconnection": textwrap.dedent( +- """\ +- # Generated by cloud-init. Changes will be lost. +- +- [connection] +- id=cloud-init eth0 +- uuid=1dd9a779-d327-56e1-8454-c65e2556c12c +- type=ethernet +- +- [user] +- org.freedesktop.NetworkManager.origin=cloud-init +- +- [ethernet] +- mac-address=C0:D6:9F:2C:E8:80 +- +- """ +- ), +- "cloud-init-eth4.nmconnection": textwrap.dedent( +- """\ +- # Generated by cloud-init. Changes will be lost. +- +- [connection] +- id=cloud-init eth4 +- uuid=e27e4959-fb50-5580-b9a4-2073554627b9 +- type=ethernet +- slave-type=bridge +- master=dee46ce4-af7a-5e7c-aa08-b25533ae9213 +- +- [user] +- org.freedesktop.NetworkManager.origin=cloud-init +- +- [ethernet] +- mac-address=98:BB:9F:2C:E8:80 +- +- """ +- ), +- "cloud-init-eth1.nmconnection": textwrap.dedent( +- """\ +- # Generated by cloud-init. Changes will be lost. +- +- [connection] +- id=cloud-init eth1 +- uuid=3c50eb47-7260-5a6d-801d-bd4f587d6b58 +- type=ethernet +- slave-type=bond +- master=54317911-f840-516b-a10d-82cb4c1f075c +- +- [user] +- org.freedesktop.NetworkManager.origin=cloud-init +- +- [ethernet] +- mac-address=AA:D6:9F:2C:E8:80 +- +- """ +- ), +- "cloud-init-br0.nmconnection": textwrap.dedent( +- """\ +- # Generated by cloud-init. Changes will be lost. +- +- [connection] +- id=cloud-init br0 +- uuid=dee46ce4-af7a-5e7c-aa08-b25533ae9213 +- type=bridge +- interface-name=br0 +- +- [user] +- org.freedesktop.NetworkManager.origin=cloud-init +- +- [bridge] +- stp=false +- priority=22 +- mac-address=BB:BB:BB:BB:BB:AA +- +- [ipv4] +- method=manual +- may-fail=false +- address1=192.168.14.2/24 +- +- [ipv6] +- method=manual +- may-fail=false +- addr-gen-mode=stable-privacy +- address1=2001:1::1/64 +- route1=::/0,2001:4800:78ff:1b::1 +- +- """ +- ), +- "cloud-init-eth0.101.nmconnection": textwrap.dedent( +- """\ +- # Generated by cloud-init. Changes will be lost. +- +- [connection] +- id=cloud-init eth0.101 +- uuid=b5acec5e-db80-5935-8b02-0d5619fc42bf +- type=vlan +- interface-name=eth0.101 +- +- [user] +- org.freedesktop.NetworkManager.origin=cloud-init +- +- [vlan] +- id=101 +- parent=1dd9a779-d327-56e1-8454-c65e2556c12c +- +- [ipv4] +- method=manual +- may-fail=false +- address1=192.168.0.2/24 +- gateway=192.168.0.1 +- dns=192.168.0.10;10.23.23.134; +- dns-search=barley.maas;sacchromyces.maas;brettanomyces.maas; +- address2=192.168.2.10/24 +- +- """ +- ), +- "cloud-init-bond0.nmconnection": textwrap.dedent( +- """\ +- # Generated by cloud-init. Changes will be lost. +- +- [connection] +- id=cloud-init bond0 +- uuid=54317911-f840-516b-a10d-82cb4c1f075c +- type=bond +- interface-name=bond0 +- +- [user] +- org.freedesktop.NetworkManager.origin=cloud-init +- +- [bond] +- mode=active-backup +- miimon=100 +- xmit_hash_policy=layer3+4 +- +- [ipv6] +- method=dhcp +- may-fail=false +- addr-gen-mode=stable-privacy +- +- """ +- ), +- "cloud-init-eth2.nmconnection": textwrap.dedent( +- """\ +- # Generated by cloud-init. Changes will be lost. +- +- [connection] +- id=cloud-init eth2 +- uuid=5559a242-3421-5fdd-896e-9cb8313d5804 +- type=ethernet +- slave-type=bond +- master=54317911-f840-516b-a10d-82cb4c1f075c +- +- [user] +- org.freedesktop.NetworkManager.origin=cloud-init +- +- [ethernet] +- mac-address=C0:BB:9F:2C:E8:80 +- +- """ +- ), +- }, + "yaml": textwrap.dedent( + """ + version: 1 +@@ -2933,10 +2403,10 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true + - type: static + address: 2001:1::1/92 + routes: +- - gateway: 2001:67c:1562::1 ++ - gateway: 2001:67c:1562:1 + network: 2001:67c:1 + netmask: "ffff:ffff::" +- - gateway: 3001:67c:15::1 ++ - gateway: 3001:67c:1562:1 + network: 3001:67c:1 + netmask: "ffff:ffff::" + metric: 10000 +@@ -2981,10 +2451,10 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true + - to: 10.1.3.0/24 + via: 192.168.0.3 + - to: 2001:67c:1/32 +- via: 2001:67c:1562::1 ++ via: 2001:67c:1562:1 + - metric: 10000 + to: 3001:67c:1/32 +- via: 3001:67c:15::1 ++ via: 3001:67c:1562:1 + """ + ), + "expected_eni": textwrap.dedent( +@@ -3044,11 +2514,11 @@ iface bond0 inet static + # control-alias bond0 + iface bond0 inet6 static + address 2001:1::1/92 +- post-up route add -A inet6 2001:67c:1/32 gw 2001:67c:1562::1 || true +- pre-down route del -A inet6 2001:67c:1/32 gw 2001:67c:1562::1 || true +- post-up route add -A inet6 3001:67c:1/32 gw 3001:67c:15::1 metric 10000 \ ++ post-up route add -A inet6 2001:67c:1/32 gw 2001:67c:1562:1 || true ++ pre-down route del -A inet6 2001:67c:1/32 gw 2001:67c:1562:1 || true ++ post-up route add -A inet6 3001:67c:1/32 gw 3001:67c:1562:1 metric 10000 \ + || true +- pre-down route del -A inet6 3001:67c:1/32 gw 3001:67c:15::1 metric 10000 \ ++ pre-down route del -A inet6 3001:67c:1/32 gw 3001:67c:1562:1 metric 10000 \ + || true + """ + ), +@@ -3091,8 +2561,8 @@ iface bond0 inet6 static + - to: 2001:67c:1562:8007::1/64 + via: 2001:67c:1562:8007::aac:40b2 + - metric: 10000 +- to: 3001:67c:15:8007::1/64 +- via: 3001:67c:15:8007::aac:40b2 ++ to: 3001:67c:1562:8007::1/64 ++ via: 3001:67c:1562:8007::aac:40b2 + """ + ), + "expected_netplan-v2": textwrap.dedent( +@@ -3124,8 +2594,8 @@ iface bond0 inet6 static + - to: 2001:67c:1562:8007::1/64 + via: 2001:67c:1562:8007::aac:40b2 + - metric: 10000 +- to: 3001:67c:15:8007::1/64 +- via: 3001:67c:15:8007::aac:40b2 ++ to: 3001:67c:1562:8007::1/64 ++ via: 3001:67c:1562:8007::aac:40b2 + ethernets: + eth0: + match: +@@ -3224,8 +2694,8 @@ iface bond0 inet6 static + """\ + # Created by cloud-init on instance boot automatically, do not edit. + # +- 2001:67c:1/32 via 2001:67c:1562::1 dev bond0 +- 3001:67c:1/32 via 3001:67c:15::1 metric 10000 dev bond0 ++ 2001:67c:1/32 via 2001:67c:1562:1 dev bond0 ++ 3001:67c:1/32 via 3001:67c:1562:1 metric 10000 dev bond0 + """ + ), + "route-bond0": textwrap.dedent( +@@ -3248,88 +2718,6 @@ iface bond0 inet6 static + """ + ), + }, +- "expected_network_manager": { +- "cloud-init-bond0s0.nmconnection": textwrap.dedent( +- """\ +- # Generated by cloud-init. Changes will be lost. +- +- [connection] +- id=cloud-init bond0s0 +- uuid=09d0b5b9-67e7-5577-a1af-74d1cf17a71e +- type=ethernet +- slave-type=bond +- master=54317911-f840-516b-a10d-82cb4c1f075c +- +- [user] +- org.freedesktop.NetworkManager.origin=cloud-init +- +- [ethernet] +- mac-address=AA:BB:CC:DD:E8:00 +- +- """ +- ), +- "cloud-init-bond0s1.nmconnection": textwrap.dedent( +- """\ +- # Generated by cloud-init. Changes will be lost. +- +- [connection] +- id=cloud-init bond0s1 +- uuid=4d9aca96-b515-5630-ad83-d13daac7f9d0 +- type=ethernet +- slave-type=bond +- master=54317911-f840-516b-a10d-82cb4c1f075c +- +- [user] +- org.freedesktop.NetworkManager.origin=cloud-init +- +- [ethernet] +- mac-address=AA:BB:CC:DD:E8:01 +- +- """ +- ), +- "cloud-init-bond0.nmconnection": textwrap.dedent( +- """\ +- # Generated by cloud-init. Changes will be lost. +- +- [connection] +- id=cloud-init bond0 +- uuid=54317911-f840-516b-a10d-82cb4c1f075c +- type=bond +- interface-name=bond0 +- +- [user] +- org.freedesktop.NetworkManager.origin=cloud-init +- +- [bond] +- mode=active-backup +- miimon=100 +- xmit_hash_policy=layer3+4 +- num_grat_arp=5 +- downdelay=10 +- updelay=20 +- fail_over_mac=active +- primary_reselect=always +- primary=bond0s0 +- +- [ipv4] +- method=manual +- may-fail=false +- address1=192.168.0.2/24 +- gateway=192.168.0.1 +- route1=10.1.3.0/24,192.168.0.3 +- address2=192.168.1.2/24 +- +- [ipv6] +- method=manual +- may-fail=false +- addr-gen-mode=stable-privacy +- address1=2001:1::1/92 +- route1=2001:67c:1/32,2001:67c:1562::1 +- route2=3001:67c:1/32,3001:67c:15::1 +- +- """ +- ), +- }, + }, + "vlan": { + "yaml": textwrap.dedent( +@@ -3413,58 +2801,6 @@ iface bond0 inet6 static + VLAN=yes""" + ), + }, +- "expected_network_manager": { +- "cloud-init-en0.99.nmconnection": textwrap.dedent( +- """\ +- # Generated by cloud-init. Changes will be lost. +- +- [connection] +- id=cloud-init en0.99 +- uuid=f594e2ed-f107-51df-b225-1dc530a5356b +- type=vlan +- interface-name=en0.99 +- +- [user] +- org.freedesktop.NetworkManager.origin=cloud-init +- +- [vlan] +- id=99 +- parent=e0ca478b-8d84-52ab-8fae-628482c629b5 +- +- [ipv4] +- method=manual +- may-fail=false +- address1=192.168.2.2/24 +- address2=192.168.1.2/24 +- gateway=192.168.1.1 +- +- [ipv6] +- method=manual +- may-fail=false +- addr-gen-mode=stable-privacy +- address1=2001:1::bbbb/96 +- route1=::/0,2001:1::1 +- +- """ +- ), +- "cloud-init-en0.nmconnection": textwrap.dedent( +- """\ +- # Generated by cloud-init. Changes will be lost. +- +- [connection] +- id=cloud-init en0 +- uuid=e0ca478b-8d84-52ab-8fae-628482c629b5 +- type=ethernet +- +- [user] +- org.freedesktop.NetworkManager.origin=cloud-init +- +- [ethernet] +- mac-address=AA:BB:CC:DD:E8:00 +- +- """ +- ), +- }, + }, + "bridge": { + "yaml": textwrap.dedent( +@@ -3573,82 +2909,6 @@ iface bond0 inet6 static + """ + ), + }, +- "expected_network_manager": { +- "cloud-init-br0.nmconnection": textwrap.dedent( +- """\ +- # Generated by cloud-init. Changes will be lost. +- +- [connection] +- id=cloud-init br0 +- uuid=dee46ce4-af7a-5e7c-aa08-b25533ae9213 +- type=bridge +- interface-name=br0 +- +- [user] +- org.freedesktop.NetworkManager.origin=cloud-init +- +- [bridge] +- stp=false +- priority=22 +- +- [ipv4] +- method=manual +- may-fail=false +- address1=192.168.2.2/24 +- +- """ +- ), +- "cloud-init-eth0.nmconnection": textwrap.dedent( +- """\ +- # Generated by cloud-init. Changes will be lost. +- +- [connection] +- id=cloud-init eth0 +- uuid=1dd9a779-d327-56e1-8454-c65e2556c12c +- type=ethernet +- slave-type=bridge +- master=dee46ce4-af7a-5e7c-aa08-b25533ae9213 +- +- [user] +- org.freedesktop.NetworkManager.origin=cloud-init +- +- [ethernet] +- mac-address=52:54:00:12:34:00 +- +- [ipv6] +- method=manual +- may-fail=false +- addr-gen-mode=stable-privacy +- address1=2001:1::100/96 +- +- """ +- ), +- "cloud-init-eth1.nmconnection": textwrap.dedent( +- """\ +- # Generated by cloud-init. Changes will be lost. +- +- [connection] +- id=cloud-init eth1 +- uuid=3c50eb47-7260-5a6d-801d-bd4f587d6b58 +- type=ethernet +- slave-type=bridge +- master=dee46ce4-af7a-5e7c-aa08-b25533ae9213 +- +- [user] +- org.freedesktop.NetworkManager.origin=cloud-init +- +- [ethernet] +- mac-address=52:54:00:12:34:01 +- +- [ipv6] +- method=manual +- may-fail=false +- addr-gen-mode=stable-privacy +- address1=2001:1::101/96 +- +- """ +- ), +- }, + }, + "manual": { + "yaml": textwrap.dedent( +@@ -3777,92 +3037,25 @@ iface bond0 inet6 static + """ + ), + }, +- "expected_network_manager": { +- "cloud-init-eth0.nmconnection": textwrap.dedent( +- """\ +- # Generated by cloud-init. Changes will be lost. +- +- [connection] +- id=cloud-init eth0 +- uuid=1dd9a779-d327-56e1-8454-c65e2556c12c +- type=ethernet ++ }, ++} + +- [user] +- org.freedesktop.NetworkManager.origin=cloud-init + +- [ethernet] +- mac-address=52:54:00:12:34:00 +- +- [ipv4] +- method=manual +- may-fail=false +- address1=192.168.1.2/24 +- +- """ +- ), +- "cloud-init-eth1.nmconnection": textwrap.dedent( +- """\ +- # Generated by cloud-init. Changes will be lost. +- +- [connection] +- id=cloud-init eth1 +- uuid=3c50eb47-7260-5a6d-801d-bd4f587d6b58 +- type=ethernet +- +- [user] +- org.freedesktop.NetworkManager.origin=cloud-init +- +- [ethernet] +- mtu=1480 +- mac-address=52:54:00:12:34:AA +- +- [ipv4] +- method=auto +- may-fail=true +- +- """ +- ), +- "cloud-init-eth2.nmconnection": textwrap.dedent( +- """\ +- # Generated by cloud-init. Changes will be lost. +- +- [connection] +- id=cloud-init eth2 +- uuid=5559a242-3421-5fdd-896e-9cb8313d5804 +- type=ethernet +- +- [user] +- org.freedesktop.NetworkManager.origin=cloud-init +- +- [ethernet] +- mac-address=52:54:00:12:34:FF +- +- [ipv4] +- method=auto +- may-fail=true +- +- """ +- ), +- }, +- }, +-} +- +- +-CONFIG_V1_EXPLICIT_LOOPBACK = { +- "version": 1, +- "config": [ +- { +- "name": "eth0", +- "type": "physical", +- "subnets": [{"control": "auto", "type": "dhcp"}], +- }, +- { +- "name": "lo", +- "type": "loopback", +- "subnets": [{"control": "auto", "type": "loopback"}], +- }, +- ], +-} ++CONFIG_V1_EXPLICIT_LOOPBACK = { ++ "version": 1, ++ "config": [ ++ { ++ "name": "eth0", ++ "type": "physical", ++ "subnets": [{"control": "auto", "type": "dhcp"}], ++ }, ++ { ++ "name": "lo", ++ "type": "loopback", ++ "subnets": [{"control": "auto", "type": "loopback"}], ++ }, ++ ], ++} + + + CONFIG_V1_SIMPLE_SUBNET = { +@@ -4304,6 +3497,7 @@ class TestRhelSysConfigRendering(CiTestCase): + + with_logs = True + ++ nm_cfg_file = "/etc/NetworkManager/NetworkManager.conf" + scripts_dir = "/etc/sysconfig/network-scripts" + header = ( + "# Created by cloud-init on instance boot automatically, " +@@ -4878,6 +4072,78 @@ USERCTL=no + self._compare_files_to_expected(entry[self.expected_name], found) + self._assert_headers(found) + ++ def test_check_ifcfg_rh(self): ++ """ifcfg-rh plugin is added NetworkManager.conf if conf present.""" ++ render_dir = self.tmp_dir() ++ nm_cfg = subp.target_path(render_dir, path=self.nm_cfg_file) ++ util.ensure_dir(os.path.dirname(nm_cfg)) ++ ++ # write a template nm.conf, note plugins is a list here ++ with open(nm_cfg, "w") as fh: ++ fh.write("# test_check_ifcfg_rh\n[main]\nplugins=foo,bar\n") ++ self.assertTrue(os.path.exists(nm_cfg)) ++ ++ # render and read ++ entry = NETWORK_CONFIGS["small"] ++ found = self._render_and_read( ++ network_config=yaml.load(entry["yaml"]), dir=render_dir ++ ) ++ self._compare_files_to_expected(entry[self.expected_name], found) ++ self._assert_headers(found) ++ ++ # check ifcfg-rh is in the 'plugins' list ++ config = sysconfig.ConfigObj(nm_cfg) ++ self.assertIn("ifcfg-rh", config["main"]["plugins"]) ++ ++ def test_check_ifcfg_rh_plugins_string(self): ++ """ifcfg-rh plugin is append when plugins is a string.""" ++ render_dir = self.tmp_path("render") ++ os.makedirs(render_dir) ++ nm_cfg = subp.target_path(render_dir, path=self.nm_cfg_file) ++ util.ensure_dir(os.path.dirname(nm_cfg)) ++ ++ # write a template nm.conf, note plugins is a value here ++ util.write_file(nm_cfg, "# test_check_ifcfg_rh\n[main]\nplugins=foo\n") ++ ++ # render and read ++ entry = NETWORK_CONFIGS["small"] ++ found = self._render_and_read( ++ network_config=yaml.load(entry["yaml"]), dir=render_dir ++ ) ++ self._compare_files_to_expected(entry[self.expected_name], found) ++ self._assert_headers(found) ++ ++ # check raw content has plugin ++ nm_file_content = util.load_file(nm_cfg) ++ self.assertIn("ifcfg-rh", nm_file_content) ++ ++ # check ifcfg-rh is in the 'plugins' list ++ config = sysconfig.ConfigObj(nm_cfg) ++ self.assertIn("ifcfg-rh", config["main"]["plugins"]) ++ ++ def test_check_ifcfg_rh_plugins_no_plugins(self): ++ """enable_ifcfg_plugin creates plugins value if missing.""" ++ render_dir = self.tmp_path("render") ++ os.makedirs(render_dir) ++ nm_cfg = subp.target_path(render_dir, path=self.nm_cfg_file) ++ util.ensure_dir(os.path.dirname(nm_cfg)) ++ ++ # write a template nm.conf, note plugins is missing ++ util.write_file(nm_cfg, "# test_check_ifcfg_rh\n[main]\n") ++ self.assertTrue(os.path.exists(nm_cfg)) ++ ++ # render and read ++ entry = NETWORK_CONFIGS["small"] ++ found = self._render_and_read( ++ network_config=yaml.load(entry["yaml"]), dir=render_dir ++ ) ++ self._compare_files_to_expected(entry[self.expected_name], found) ++ self._assert_headers(found) ++ ++ # check ifcfg-rh is in the 'plugins' list ++ config = sysconfig.ConfigObj(nm_cfg) ++ self.assertIn("ifcfg-rh", config["main"]["plugins"]) ++ + def test_netplan_dhcp_false_disable_dhcp_in_state(self): + """netplan config with dhcp[46]: False should not add dhcp in state""" + net_config = yaml.load(NETPLAN_DHCP_FALSE) +@@ -5433,281 +4699,6 @@ STARTMODE=auto + self._assert_headers(found) + + +-@mock.patch( +- "cloudinit.net.is_openvswitch_internal_interface", +- mock.Mock(return_value=False), +-) +-class TestNetworkManagerRendering(CiTestCase): +- +- with_logs = True +- +- scripts_dir = "/etc/NetworkManager/system-connections" +- +- expected_name = "expected_network_manager" +- +- def _get_renderer(self): +- return network_manager.Renderer() +- +- def _render_and_read(self, network_config=None, state=None, dir=None): +- if dir is None: +- dir = self.tmp_dir() +- +- if network_config: +- ns = network_state.parse_net_config_data(network_config) +- elif state: +- ns = state +- else: +- raise ValueError("Expected data or state, got neither") +- +- renderer = self._get_renderer() +- renderer.render_network_state(ns, target=dir) +- return dir2dict(dir) +- +- def _compare_files_to_expected(self, expected, found): +- orig_maxdiff = self.maxDiff +- expected_d = dict( +- (os.path.join(self.scripts_dir, k), v) for k, v in expected.items() +- ) +- +- try: +- self.maxDiff = None +- self.assertEqual(expected_d, found) +- finally: +- self.maxDiff = orig_maxdiff +- +- @mock.patch("cloudinit.net.util.get_cmdline", return_value="root=myroot") +- @mock.patch("cloudinit.net.sys_dev_path") +- @mock.patch("cloudinit.net.read_sys_net") +- @mock.patch("cloudinit.net.get_devicelist") +- def test_default_generation( +- self, +- mock_get_devicelist, +- mock_read_sys_net, +- mock_sys_dev_path, +- m_get_cmdline, +- ): +- tmp_dir = self.tmp_dir() +- _setup_test( +- tmp_dir, mock_get_devicelist, mock_read_sys_net, mock_sys_dev_path +- ) +- +- network_cfg = net.generate_fallback_config() +- ns = network_state.parse_net_config_data( +- network_cfg, skip_broken=False +- ) +- +- render_dir = os.path.join(tmp_dir, "render") +- os.makedirs(render_dir) +- +- renderer = self._get_renderer() +- renderer.render_network_state(ns, target=render_dir) +- +- found = dir2dict(render_dir) +- self._compare_files_to_expected( +- { +- "cloud-init-eth1000.nmconnection": textwrap.dedent( +- """\ +- # Generated by cloud-init. Changes will be lost. +- +- [connection] +- id=cloud-init eth1000 +- uuid=8c517500-0c95-5308-9c8a-3092eebc44eb +- type=ethernet +- +- [user] +- org.freedesktop.NetworkManager.origin=cloud-init +- +- [ethernet] +- mac-address=07:1C:C6:75:A4:BE +- +- [ipv4] +- method=auto +- may-fail=false +- +- """ +- ), +- }, +- found, +- ) +- +- def test_openstack_rendering_samples(self): +- for os_sample in OS_SAMPLES: +- render_dir = self.tmp_dir() +- ex_input = os_sample["in_data"] +- ex_mac_addrs = os_sample["in_macs"] +- network_cfg = openstack.convert_net_json( +- ex_input, known_macs=ex_mac_addrs +- ) +- ns = network_state.parse_net_config_data( +- network_cfg, skip_broken=False +- ) +- renderer = self._get_renderer() +- # render a multiple times to simulate reboots +- renderer.render_network_state(ns, target=render_dir) +- renderer.render_network_state(ns, target=render_dir) +- renderer.render_network_state(ns, target=render_dir) +- for fn, expected_content in os_sample.get(self.expected_name, []): +- with open(os.path.join(render_dir, fn)) as fh: +- self.assertEqual(expected_content, fh.read()) +- +- def test_network_config_v1_samples(self): +- ns = network_state.parse_net_config_data(CONFIG_V1_SIMPLE_SUBNET) +- render_dir = self.tmp_path("render") +- os.makedirs(render_dir) +- renderer = self._get_renderer() +- renderer.render_network_state(ns, target=render_dir) +- found = dir2dict(render_dir) +- self._compare_files_to_expected( +- { +- "cloud-init-interface0.nmconnection": textwrap.dedent( +- """\ +- # Generated by cloud-init. Changes will be lost. +- +- [connection] +- id=cloud-init interface0 +- uuid=8b6862ed-dbd6-5830-93f7-a91451c13828 +- type=ethernet +- +- [user] +- org.freedesktop.NetworkManager.origin=cloud-init +- +- [ethernet] +- mac-address=52:54:00:12:34:00 +- +- [ipv4] +- method=manual +- may-fail=false +- address1=10.0.2.15/24 +- gateway=10.0.2.2 +- +- """ +- ), +- }, +- found, +- ) +- +- def test_config_with_explicit_loopback(self): +- render_dir = self.tmp_path("render") +- os.makedirs(render_dir) +- ns = network_state.parse_net_config_data(CONFIG_V1_EXPLICIT_LOOPBACK) +- renderer = self._get_renderer() +- renderer.render_network_state(ns, target=render_dir) +- found = dir2dict(render_dir) +- self._compare_files_to_expected( +- { +- "cloud-init-eth0.nmconnection": textwrap.dedent( +- """\ +- # Generated by cloud-init. Changes will be lost. +- +- [connection] +- id=cloud-init eth0 +- uuid=1dd9a779-d327-56e1-8454-c65e2556c12c +- type=ethernet +- interface-name=eth0 +- +- [user] +- org.freedesktop.NetworkManager.origin=cloud-init +- +- [ethernet] +- +- [ipv4] +- method=auto +- may-fail=false +- +- """ +- ), +- }, +- found, +- ) +- +- def test_bond_config(self): +- entry = NETWORK_CONFIGS["bond"] +- found = self._render_and_read(network_config=yaml.load(entry["yaml"])) +- self._compare_files_to_expected(entry[self.expected_name], found) +- +- def test_vlan_config(self): +- entry = NETWORK_CONFIGS["vlan"] +- found = self._render_and_read(network_config=yaml.load(entry["yaml"])) +- self._compare_files_to_expected(entry[self.expected_name], found) +- +- def test_bridge_config(self): +- entry = NETWORK_CONFIGS["bridge"] +- found = self._render_and_read(network_config=yaml.load(entry["yaml"])) +- self._compare_files_to_expected(entry[self.expected_name], found) +- +- def test_manual_config(self): +- entry = NETWORK_CONFIGS["manual"] +- found = self._render_and_read(network_config=yaml.load(entry["yaml"])) +- self._compare_files_to_expected(entry[self.expected_name], found) +- +- def test_all_config(self): +- entry = NETWORK_CONFIGS["all"] +- found = self._render_and_read(network_config=yaml.load(entry["yaml"])) +- self._compare_files_to_expected(entry[self.expected_name], found) +- self.assertNotIn( +- "WARNING: Network config: ignoring eth0.101 device-level mtu", +- self.logs.getvalue(), +- ) +- +- def test_small_config(self): +- entry = NETWORK_CONFIGS["small"] +- found = self._render_and_read(network_config=yaml.load(entry["yaml"])) +- self._compare_files_to_expected(entry[self.expected_name], found) +- +- def test_v4_and_v6_static_config(self): +- entry = NETWORK_CONFIGS["v4_and_v6_static"] +- found = self._render_and_read(network_config=yaml.load(entry["yaml"])) +- self._compare_files_to_expected(entry[self.expected_name], found) +- expected_msg = ( +- "WARNING: Network config: ignoring iface0 device-level mtu:8999" +- " because ipv4 subnet-level mtu:9000 provided." +- ) +- self.assertIn(expected_msg, self.logs.getvalue()) +- +- def test_dhcpv6_only_config(self): +- entry = NETWORK_CONFIGS["dhcpv6_only"] +- found = self._render_and_read(network_config=yaml.load(entry["yaml"])) +- self._compare_files_to_expected(entry[self.expected_name], found) +- +- def test_simple_render_ipv6_slaac(self): +- entry = NETWORK_CONFIGS["ipv6_slaac"] +- found = self._render_and_read(network_config=yaml.load(entry["yaml"])) +- self._compare_files_to_expected(entry[self.expected_name], found) +- +- def test_dhcpv6_stateless_config(self): +- entry = NETWORK_CONFIGS["dhcpv6_stateless"] +- found = self._render_and_read(network_config=yaml.load(entry["yaml"])) +- self._compare_files_to_expected(entry[self.expected_name], found) +- +- def test_wakeonlan_disabled_config_v2(self): +- entry = NETWORK_CONFIGS["wakeonlan_disabled"] +- found = self._render_and_read( +- network_config=yaml.load(entry["yaml_v2"]) +- ) +- self._compare_files_to_expected(entry[self.expected_name], found) +- +- def test_wakeonlan_enabled_config_v2(self): +- entry = NETWORK_CONFIGS["wakeonlan_enabled"] +- found = self._render_and_read( +- network_config=yaml.load(entry["yaml_v2"]) +- ) +- self._compare_files_to_expected(entry[self.expected_name], found) +- +- def test_render_v4_and_v6(self): +- entry = NETWORK_CONFIGS["v4_and_v6"] +- found = self._render_and_read(network_config=yaml.load(entry["yaml"])) +- self._compare_files_to_expected(entry[self.expected_name], found) +- +- def test_render_v6_and_v4(self): +- entry = NETWORK_CONFIGS["v6_and_v4"] +- found = self._render_and_read(network_config=yaml.load(entry["yaml"])) +- self._compare_files_to_expected(entry[self.expected_name], found) +- +- +-@mock.patch( +- "cloudinit.net.is_openvswitch_internal_interface", +- mock.Mock(return_value=False), +-) + class TestEniNetRendering(CiTestCase): + @mock.patch("cloudinit.net.util.get_cmdline", return_value="root=myroot") + @mock.patch("cloudinit.net.sys_dev_path") +@@ -7145,9 +6136,9 @@ class TestNetworkdRoundTrip(CiTestCase): + + class TestRenderersSelect: + @pytest.mark.parametrize( +- "renderer_selected,netplan,eni,sys,network_manager,networkd", ++ "renderer_selected,netplan,eni,nm,scfg,sys,networkd", + ( +- # -netplan -ifupdown -sys -network-manager -networkd raises error ++ # -netplan -ifupdown -nm -scfg -sys raises error + ( + net.RendererNotFoundError, + False, +@@ -7155,51 +6146,52 @@ class TestRenderersSelect: + False, + False, + False, ++ False, + ), +- # -netplan +ifupdown -sys -nm -networkd selects eni +- ("eni", False, True, False, False, False), +- # +netplan +ifupdown -sys -nm -networkd selects eni +- ("eni", True, True, False, False, False), +- # +netplan -ifupdown -sys -nm -networkd selects netplan +- ("netplan", True, False, False, False, False), +- # +netplan -ifupdown -sys -nm -networkd selects netplan +- ("netplan", True, False, False, False, False), +- # -netplan -ifupdown +sys -nm -networkd selects sysconfig +- ("sysconfig", False, False, True, False, False), +- # -netplan -ifupdown +sys +nm -networkd selects sysconfig +- ("sysconfig", False, False, True, True, False), +- # -netplan -ifupdown -sys +nm -networkd selects nm +- ("network-manager", False, False, False, True, False), +- # -netplan -ifupdown -sys +nm +networkd selects nm +- ("network-manager", False, False, False, True, True), +- # -netplan -ifupdown -sys -nm +networkd selects networkd +- ("networkd", False, False, False, False, True), ++ # -netplan +ifupdown -nm -scfg -sys selects eni ++ ("eni", False, True, False, False, False, False), ++ # +netplan +ifupdown -nm -scfg -sys selects eni ++ ("eni", True, True, False, False, False, False), ++ # +netplan -ifupdown -nm -scfg -sys selects netplan ++ ("netplan", True, False, False, False, False, False), ++ # Ubuntu with Network-Manager installed ++ # +netplan -ifupdown +nm -scfg -sys selects netplan ++ ("netplan", True, False, True, False, False, False), ++ # Centos/OpenSuse with Network-Manager installed selects sysconfig ++ # -netplan -ifupdown +nm -scfg +sys selects netplan ++ ("sysconfig", False, False, True, False, True, False), ++ # -netplan -ifupdown -nm -scfg -sys +networkd selects networkd ++ ("networkd", False, False, False, False, False, True), + ), + ) + @mock.patch("cloudinit.net.renderers.networkd.available") +- @mock.patch("cloudinit.net.renderers.network_manager.available") + @mock.patch("cloudinit.net.renderers.netplan.available") + @mock.patch("cloudinit.net.renderers.sysconfig.available") ++ @mock.patch("cloudinit.net.renderers.sysconfig.available_sysconfig") ++ @mock.patch("cloudinit.net.renderers.sysconfig.available_nm") + @mock.patch("cloudinit.net.renderers.eni.available") + def test_valid_renderer_from_defaults_depending_on_availability( + self, + m_eni_avail, ++ m_nm_avail, ++ m_scfg_avail, + m_sys_avail, + m_netplan_avail, +- m_network_manager_avail, + m_networkd_avail, + renderer_selected, + netplan, + eni, ++ nm, ++ scfg, + sys, +- network_manager, + networkd, + ): + """Assert proper renderer per DEFAULT_PRIORITY given availability.""" + m_eni_avail.return_value = eni # ifupdown pkg presence ++ m_nm_avail.return_value = nm # network-manager presence ++ m_scfg_avail.return_value = scfg # sysconfig presence + m_sys_avail.return_value = sys # sysconfig/ifup/down presence + m_netplan_avail.return_value = netplan # netplan presence +- m_network_manager_avail.return_value = network_manager # NM presence + m_networkd_avail.return_value = networkd # networkd presence + if isinstance(renderer_selected, str): + (renderer_name, _rnd_class) = renderers.select( +@@ -7257,7 +6249,7 @@ class TestNetRenderers(CiTestCase): + priority=["sysconfig", "eni"], + ) + +- @mock.patch("cloudinit.net.sysconfig.available") ++ @mock.patch("cloudinit.net.sysconfig.available_sysconfig") + @mock.patch("cloudinit.util.system_info") + def test_sysconfig_available_uses_variant_mapping(self, m_info, m_avail): + m_avail.return_value = True +diff --git a/tests/unittests/test_net_activators.py b/tests/unittests/test_net_activators.py +index 4525c49c..3c29e2f7 100644 +--- a/tests/unittests/test_net_activators.py ++++ b/tests/unittests/test_net_activators.py +@@ -41,20 +41,18 @@ NETPLAN_CALL_LIST = [ + + @pytest.fixture + def available_mocks(): +- mocks = namedtuple("Mocks", "m_which, m_file, m_exists") ++ mocks = namedtuple("Mocks", "m_which, m_file") + with patch("cloudinit.subp.which", return_value=True) as m_which: + with patch("os.path.isfile", return_value=True) as m_file: +- with patch("os.path.exists", return_value=True) as m_exists: +- yield mocks(m_which, m_file, m_exists) ++ yield mocks(m_which, m_file) + + + @pytest.fixture + def unavailable_mocks(): +- mocks = namedtuple("Mocks", "m_which, m_file, m_exists") ++ mocks = namedtuple("Mocks", "m_which, m_file") + with patch("cloudinit.subp.which", return_value=False) as m_which: + with patch("os.path.isfile", return_value=False) as m_file: +- with patch("os.path.exists", return_value=False) as m_exists: +- yield mocks(m_which, m_file, m_exists) ++ yield mocks(m_which, m_file) + + + class TestSearchAndSelect: +@@ -115,6 +113,10 @@ NETPLAN_AVAILABLE_CALLS = [ + (("netplan",), {"search": ["/usr/sbin", "/sbin"], "target": None}), + ] + ++NETWORK_MANAGER_AVAILABLE_CALLS = [ ++ (("nmcli",), {"target": None}), ++] ++ + NETWORKD_AVAILABLE_CALLS = [ + (("ip",), {"search": ["/usr/sbin", "/bin"], "target": None}), + (("systemctl",), {"search": ["/usr/sbin", "/bin"], "target": None}), +@@ -126,6 +128,7 @@ NETWORKD_AVAILABLE_CALLS = [ + [ + (IfUpDownActivator, IF_UP_DOWN_AVAILABLE_CALLS), + (NetplanActivator, NETPLAN_AVAILABLE_CALLS), ++ (NetworkManagerActivator, NETWORK_MANAGER_AVAILABLE_CALLS), + (NetworkdActivator, NETWORKD_AVAILABLE_CALLS), + ], + ) +@@ -141,72 +144,8 @@ IF_UP_DOWN_BRING_UP_CALL_LIST = [ + ] + + NETWORK_MANAGER_BRING_UP_CALL_LIST = [ +- ( +- ( +- [ +- "nmcli", +- "connection", +- "load", +- "".join( +- [ +- "/etc/NetworkManager/system-connections", +- "/cloud-init-eth0.nmconnection", +- ] +- ), +- ], +- ), +- {}, +- ), +- ( +- ( +- [ +- "nmcli", +- "connection", +- "up", +- "filename", +- "".join( +- [ +- "/etc/NetworkManager/system-connections", +- "/cloud-init-eth0.nmconnection", +- ] +- ), +- ], +- ), +- {}, +- ), +- ( +- ( +- [ +- "nmcli", +- "connection", +- "load", +- "".join( +- [ +- "/etc/NetworkManager/system-connections", +- "/cloud-init-eth1.nmconnection", +- ] +- ), +- ], +- ), +- {}, +- ), +- ( +- ( +- [ +- "nmcli", +- "connection", +- "up", +- "filename", +- "".join( +- [ +- "/etc/NetworkManager/system-connections", +- "/cloud-init-eth1.nmconnection", +- ] +- ), +- ], +- ), +- {}, +- ), ++ ((["nmcli", "connection", "up", "ifname", "eth0"],), {}), ++ ((["nmcli", "connection", "up", "ifname", "eth1"],), {}), + ] + + NETWORKD_BRING_UP_CALL_LIST = [ +@@ -230,11 +169,9 @@ class TestActivatorsBringUp: + def test_bring_up_interface( + self, m_subp, activator, expected_call_list, available_mocks + ): +- index = 0 + activator.bring_up_interface("eth0") +- for call in m_subp.call_args_list: +- assert call == expected_call_list[index] +- index += 1 ++ assert len(m_subp.call_args_list) == 1 ++ assert m_subp.call_args_list[0] == expected_call_list[0] + + @patch("cloudinit.subp.subp", return_value=("", "")) + def test_bring_up_interfaces( +@@ -271,8 +208,8 @@ IF_UP_DOWN_BRING_DOWN_CALL_LIST = [ + ] + + NETWORK_MANAGER_BRING_DOWN_CALL_LIST = [ +- ((["nmcli", "device", "disconnect", "eth0"],), {}), +- ((["nmcli", "device", "disconnect", "eth1"],), {}), ++ ((["nmcli", "connection", "down", "eth0"],), {}), ++ ((["nmcli", "connection", "down", "eth1"],), {}), + ] + + NETWORKD_BRING_DOWN_CALL_LIST = [ +-- +2.27.0 + diff --git a/ci-Revert-Use-Network-Manager-and-Netplan-as-default-re.patch b/ci-Revert-Use-Network-Manager-and-Netplan-as-default-re.patch new file mode 100644 index 0000000..6532fab --- /dev/null +++ b/ci-Revert-Use-Network-Manager-and-Netplan-as-default-re.patch @@ -0,0 +1,75 @@ +From 02e7b89c157f8c3243f0d91cf5652cf27db44b72 Mon Sep 17 00:00:00 2001 +From: Emanuele Giuseppe Esposito +Date: Mon, 8 Aug 2022 10:10:26 +0200 +Subject: [PATCH 2/2] Revert "Use Network-Manager and Netplan as default + renderers for RHEL and Fedora (#1465)" + +RH-Author: Emanuele Giuseppe Esposito +RH-MergeRequest: 81: Revert "Use Network-Manager and Netplan as default renderers for RHEL and Fedora (#1465)" +RH-Commit: [2/2] 746b2e33356376e250b799261031676174e8ccc9 +RH-Bugzilla: 2107464 2110066 2117526 2104393 2098624 +RH-Acked-by: Eduardo Otubo +RH-Acked-by: Vitaly Kuznetsov +RH-Acked-by: Mohamed Gamal Morsy + +As NM is reverted, remove also documentation and any trace of it. +This reverts commit 13ded463a6a0b1b0bf0dffc0a997f006dd25c4f3. + +Signed-off-by: Emanuele Giuseppe Esposito +--- + config/cloud.cfg.tmpl | 3 --- + doc/rtd/topics/network-config.rst | 12 +----------- + 2 files changed, 1 insertion(+), 14 deletions(-) + +diff --git a/config/cloud.cfg.tmpl b/config/cloud.cfg.tmpl +index f4d2fd14..80ab4f96 100644 +--- a/config/cloud.cfg.tmpl ++++ b/config/cloud.cfg.tmpl +@@ -353,7 +353,4 @@ system_info: + {% elif variant in ["dragonfly"] %} + network: + renderers: ['freebsd'] +-{% elif variant in ["rhel", "fedora"] %} +- network: +- renderers: ['netplan', 'network-manager', 'networkd', 'sysconfig', 'eni'] + {% endif %} +diff --git a/doc/rtd/topics/network-config.rst b/doc/rtd/topics/network-config.rst +index f503caab..c461a3fe 100644 +--- a/doc/rtd/topics/network-config.rst ++++ b/doc/rtd/topics/network-config.rst +@@ -188,15 +188,6 @@ generated configuration into an internal network configuration state. From + this state `Cloud-init`_ delegates rendering of the configuration to Distro + supported formats. The following ``renderers`` are supported in cloud-init: + +-- **NetworkManager** +- +-`NetworkManager `_ is the standard Linux network +-configuration tool suite. It supports a wide range of networking setups. +-Configuration is typically stored in ``/etc/NetworkManager``. +- +-It is the default for a number of Linux distributions, notably Fedora; +-CentOS/RHEL; and derivatives. +- + - **ENI** + + /etc/network/interfaces or ``ENI`` is supported by the ``ifupdown`` package +@@ -224,7 +215,6 @@ is as follows: + - ENI + - Sysconfig + - Netplan +-- NetworkManager + + When applying the policy, `Cloud-init`_ checks if the current instance has the + correct binaries and paths to support the renderer. The first renderer that +@@ -233,7 +223,7 @@ supplying an updated configuration in cloud-config. :: + + system_info: + network: +- renderers: ['netplan', 'network-manager', 'eni', 'sysconfig', 'freebsd', 'netbsd', 'openbsd'] ++ renderers: ['netplan', 'eni', 'sysconfig', 'freebsd', 'netbsd', 'openbsd'] + + + Network Configuration Tools +-- +2.27.0 + diff --git a/cloud-init.spec b/cloud-init.spec index 137925d..58a1b58 100644 --- a/cloud-init.spec +++ b/cloud-init.spec @@ -6,7 +6,7 @@ Name: cloud-init Version: 22.1 -Release: 4%{?dist} +Release: 5%{?dist} Summary: Cloud instance init scripts Group: System Environment/Base @@ -33,6 +33,18 @@ Patch10: ci-Remove-rhel-specific-files.patch Patch11: ci-Support-EC2-tags-in-instance-metadata-1309.patch # For bz#2096269 - Adjust udev/rules default path[RHEL-8] Patch12: ci-setup.py-adjust-udev-rules-default-path-1513.patch +# For bz#2107464 - [RHEL-8.7] Cannot run sysconfig when changing the priority of network renderers +# For bz#2110066 - DNS integration with OpenStack/cloud-init/NetworkManager is not working +# For bz#2117526 - [RHEL8.7] Revert patch of configuring networking by NM keyfiles +# For bz#2104393 - [RHEL-8.7]Failed to config static IP and IPv6 according to VMware Customization Config File +# For bz#2098624 - [RHEL-8.7] IPv6 not workable when cloud-init configure network using NM keyfiles +Patch13: ci-Revert-Add-native-NetworkManager-support-1224.patch +# For bz#2107464 - [RHEL-8.7] Cannot run sysconfig when changing the priority of network renderers +# For bz#2110066 - DNS integration with OpenStack/cloud-init/NetworkManager is not working +# For bz#2117526 - [RHEL8.7] Revert patch of configuring networking by NM keyfiles +# For bz#2104393 - [RHEL-8.7]Failed to config static IP and IPv6 according to VMware Customization Config File +# For bz#2098624 - [RHEL-8.7] IPv6 not workable when cloud-init configure network using NM keyfiles +Patch14: ci-Revert-Use-Network-Manager-and-Netplan-as-default-re.patch BuildArch: noarch @@ -218,6 +230,20 @@ fi %config(noreplace) %{_sysconfdir}/rsyslog.d/21-cloudinit.conf %changelog +* Wed Aug 17 2022 Jon Maloy - 22.1-5 +- ci-Revert-Add-native-NetworkManager-support-1224.patch [bz#2107464 bz#2110066 bz#2117526 bz#2104393 bz#2098624] +- ci-Revert-Use-Network-Manager-and-Netplan-as-default-re.patch [bz#2107464 bz#2110066 bz#2117526 bz#2104393 bz#2098624] +- Resolves: bz#2107464 + ([RHEL-8.7] Cannot run sysconfig when changing the priority of network renderers) +- Resolves: bz#2110066 + (DNS integration with OpenStack/cloud-init/NetworkManager is not working) +- Resolves: bz#2117526 + ([RHEL8.7] Revert patch of configuring networking by NM keyfiles) +- Resolves: bz#2104393 + ([RHEL-8.7]Failed to config static IP and IPv6 according to VMware Customization Config File) +- Resolves: bz#2098624 + ([RHEL-8.7] IPv6 not workable when cloud-init configure network using NM keyfiles) + * Tue Jul 12 2022 Miroslav Rezanina - 22.1-4 - ci-cloud-init.spec-adjust-path-for-66-azure-ephemeral.r.patch [bz#2096269] - ci-setup.py-adjust-udev-rules-default-path-1513.patch [bz#2096269]