diff --git a/cloudinit/net/network_manager.py b/cloudinit/net/network_manager.py index 8047f79690d..39277cc3ec0 100644 --- a/cloudinit/net/network_manager.py +++ b/cloudinit/net/network_manager.py @@ -36,7 +36,7 @@ class NMConnection: """Represents a NetworkManager connection profile.""" - def __init__(self, con_id): + def __init__(self, con_id, cloud_config=None): """ Initializes the connection with some very basic properties, notably the UUID so that the connection can be referred to. @@ -49,6 +49,8 @@ def __init__(self, con_id): # Identity option name mapping, to achieve case sensitivity self.config.optionxform = str + self.cloud_config = {} if not cloud_config else cloud_config + self.config["connection"] = { "id": f"cloud-init {con_id}", "uuid": str(uuid.uuid5(CI_NM_UUID, con_id)), @@ -105,6 +107,12 @@ def _set_ip_method(self, family, subnet_type): if self.config[family]["method"] == "auto" and method == "manual": return + flavor = self.cloud_config.get("flavor", "rhel") + if flavor == "rhel" and subnet_type == "ipv6_dhcpv6-stateful": + # set ipv4 method to 'disabled' so that dhcp4 is turned off and + # the setting aligns with sysconfig renderer + self._set_default("ipv4", "method", "disabled") + self.config[family]["method"] = method self._set_default(family, "may-fail", "false") @@ -342,6 +350,7 @@ class Renderer(renderer.Renderer): def __init__(self, config=None): self.connections = {} + self.config = config def get_conn(self, con_id): return self.connections[con_id] @@ -363,7 +372,9 @@ def render_network_state( # 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"]) + self.connections[iface["name"]] = NMConnection( + iface["name"], self.config + ) # Now render the actual interface configuration for iface in network_state.iter_interfaces(): diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py index f5fd2acfea2..ef613778afa 100644 --- a/cloudinit/net/sysconfig.py +++ b/cloudinit/net/sysconfig.py @@ -439,10 +439,11 @@ def _render_subnets(cls, iface_cfg, subnets, has_default_route, flavor): elif ( flavor == "rhel" and subnet_type == "ipv6_dhcpv6-stateful" ): - iface_cfg["BOOTPROTO"] = "dhcp" + iface_cfg["BOOTPROTO"] = "none" iface_cfg["DHCPV6C"] = True iface_cfg["IPV6INIT"] = True iface_cfg["IPV6_AUTOCONF"] = False + iface_cfg["IPV6_FAILURE_FATAL"] = True else: iface_cfg["IPV6INIT"] = True # Configure network settings using DHCPv6 diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py index da82b15a70a..959d8de36bd 100644 --- a/tests/unittests/test_net.py +++ b/tests/unittests/test_net.py @@ -2091,11 +2091,12 @@ "expected_sysconfig_rhel": { "ifcfg-iface0": textwrap.dedent( """\ - BOOTPROTO=dhcp + BOOTPROTO=none DEVICE=iface0 DHCPV6C=yes IPV6INIT=yes IPV6_AUTOCONF=no + IPV6_FAILURE_FATAL=yes IPV6_FORCE_ACCEPT_RA=yes DEVICE=iface0 NM_CONTROLLED=no