Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions cloudinit/net/network_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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)),
Expand Down Expand Up @@ -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")

Expand Down Expand Up @@ -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]
Expand All @@ -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():
Expand Down
3 changes: 2 additions & 1 deletion cloudinit/net/sysconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion tests/unittests/test_net.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down