* Fri Aug 04 2023 Camilla Conte <cconte@redhat.com> - 23.1.1-9
- 0030-NM-renderer-set-default-IPv6-addr-gen-mode-for-all-i.patch [bz#2188388] - Resolves: bz#2188388
This commit is contained in:
parent
24115f699b
commit
fd633c77ed
283
0030-NM-renderer-set-default-IPv6-addr-gen-mode-for-all-i.patch
Normal file
283
0030-NM-renderer-set-default-IPv6-addr-gen-mode-for-all-i.patch
Normal file
@ -0,0 +1,283 @@
|
||||
From c720ab9703752535767691a31e4720e11674bb1f Mon Sep 17 00:00:00 2001
|
||||
From: Ani Sinha <anisinha@redhat.com>
|
||||
Date: Fri, 4 Aug 2023 08:58:26 +0530
|
||||
Subject: [PATCH] NM renderer: set default IPv6 addr-gen-mode for all
|
||||
interfaces to eui64 (#4291)
|
||||
|
||||
By default, NetworkManager renderer in cloud-init does not set any specific
|
||||
method for IPV6 addr-gen-mode in the keyfiles it writes. Hence, implicitly the
|
||||
mode is set to `eui64` in the absence of any global addr-gen-mode option in
|
||||
NetworkManager configuration.
|
||||
Later when other interfaces get added via D-Bus API or by using nmcli commands
|
||||
without explictly setting an addr-gen-mode, NM auto generates new profiles for
|
||||
those interfaces with addr-gen-mode set to `stable-privacy`. This introduces
|
||||
inconsistency of configurations between interfaces based on how they were
|
||||
added. This can cause problems for the customers.
|
||||
|
||||
In this change, cloud-init overrides NetworkManager's preferred default of
|
||||
`stable-privacy` to use EUI64 using a drop in NetworkManager configuration
|
||||
file. This setting can be overriden by using global-connection-defaults
|
||||
setting in /etc/NetworkManager/NetworkManager.conf file.
|
||||
|
||||
RHBZ: 2188388
|
||||
|
||||
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
||||
(cherry picked from commit d41264cb4297a4b143a23f3677d33b81fbfc6e8e)
|
||||
|
||||
Conflicts:
|
||||
tests/unittests/test_net.py
|
||||
---
|
||||
cloudinit/net/network_manager.py | 21 ++++++++
|
||||
tests/unittests/test_net.py | 91 +++++++++++++++++++++++++-------
|
||||
2 files changed, 94 insertions(+), 18 deletions(-)
|
||||
|
||||
diff --git a/cloudinit/net/network_manager.py b/cloudinit/net/network_manager.py
|
||||
index ca216928..8047f796 100644
|
||||
--- a/cloudinit/net/network_manager.py
|
||||
+++ b/cloudinit/net/network_manager.py
|
||||
@@ -21,6 +21,15 @@ from cloudinit.net.network_state import NetworkState
|
||||
NM_RUN_DIR = "/etc/NetworkManager"
|
||||
NM_LIB_DIR = "/usr/lib/NetworkManager"
|
||||
NM_CFG_FILE = "/etc/NetworkManager/NetworkManager.conf"
|
||||
+NM_IPV6_ADDR_GEN_CONF = """# This is generated by cloud-init. Do not edit.
|
||||
+#
|
||||
+[.config]
|
||||
+ enable=nm-version-min:1.40
|
||||
+[connection.30-cloud-init-ip6-addr-gen-mode]
|
||||
+ # Select EUI64 to be used if the profile does not specify it.
|
||||
+ ipv6.addr-gen-mode=0
|
||||
+
|
||||
+"""
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@@ -368,6 +377,12 @@ class Renderer(renderer.Renderer):
|
||||
name = 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
|
||||
+ # for use with RFC4862 IPv6 Stateless Address Autoconfiguration.
|
||||
+ util.write_file(
|
||||
+ cloud_init_nm_conf_filename(target), NM_IPV6_ADDR_GEN_CONF, 0o600
|
||||
+ )
|
||||
+
|
||||
|
||||
def conn_filename(con_id, target=None):
|
||||
target_con_dir = subp.target_path(target, NM_RUN_DIR)
|
||||
@@ -375,6 +390,12 @@ def conn_filename(con_id, target=None):
|
||||
return f"{target_con_dir}/system-connections/{con_file}"
|
||||
|
||||
|
||||
+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"
|
||||
+ return f"{target_con_dir}/conf.d/{conf_file}"
|
||||
+
|
||||
+
|
||||
def available(target=None):
|
||||
# TODO: Move `uses_systemd` to a more appropriate location
|
||||
# It is imported here to avoid circular import
|
||||
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
|
||||
index fd656a57..d49da696 100644
|
||||
--- a/tests/unittests/test_net.py
|
||||
+++ b/tests/unittests/test_net.py
|
||||
@@ -5679,9 +5679,25 @@ class TestNetworkManagerRendering(CiTestCase):
|
||||
with_logs = True
|
||||
|
||||
scripts_dir = "/etc/NetworkManager/system-connections"
|
||||
+ conf_dir = "/etc/NetworkManager/conf.d"
|
||||
|
||||
expected_name = "expected_network_manager"
|
||||
|
||||
+ expected_conf_d = {
|
||||
+ "30-cloud-init-ip6-addr-gen-mode.conf": textwrap.dedent(
|
||||
+ """\
|
||||
+ # This is generated by cloud-init. Do not edit.
|
||||
+ #
|
||||
+ [.config]
|
||||
+ enable=nm-version-min:1.40
|
||||
+ [connection.30-cloud-init-ip6-addr-gen-mode]
|
||||
+ # Select EUI64 to be used if the profile does not specify it.
|
||||
+ ipv6.addr-gen-mode=0
|
||||
+
|
||||
+ """
|
||||
+ ),
|
||||
+ }
|
||||
+
|
||||
def _get_renderer(self):
|
||||
return network_manager.Renderer()
|
||||
|
||||
@@ -5700,11 +5716,19 @@ class TestNetworkManagerRendering(CiTestCase):
|
||||
renderer.render_network_state(ns, target=dir)
|
||||
return dir2dict(dir)
|
||||
|
||||
- def _compare_files_to_expected(self, expected, found):
|
||||
+ def _compare_files_to_expected(
|
||||
+ self, expected_scripts, expected_conf, found
|
||||
+ ):
|
||||
orig_maxdiff = self.maxDiff
|
||||
- expected_d = dict(
|
||||
- (os.path.join(self.scripts_dir, k), v) for k, v in expected.items()
|
||||
+ conf_d = dict(
|
||||
+ (os.path.join(self.conf_dir, k), v)
|
||||
+ for k, v in expected_conf.items()
|
||||
+ )
|
||||
+ scripts_d = dict(
|
||||
+ (os.path.join(self.scripts_dir, k), v)
|
||||
+ for k, v in expected_scripts.items()
|
||||
)
|
||||
+ expected_d = {**conf_d, **scripts_d}
|
||||
|
||||
try:
|
||||
self.maxDiff = None
|
||||
@@ -5765,6 +5789,7 @@ class TestNetworkManagerRendering(CiTestCase):
|
||||
"""
|
||||
),
|
||||
},
|
||||
+ self.expected_conf_d,
|
||||
found,
|
||||
)
|
||||
|
||||
@@ -5820,8 +5845,9 @@ class TestNetworkManagerRendering(CiTestCase):
|
||||
gateway=10.0.2.2
|
||||
|
||||
"""
|
||||
- ),
|
||||
+ )
|
||||
},
|
||||
+ self.expected_conf_d,
|
||||
found,
|
||||
)
|
||||
|
||||
@@ -5857,33 +5883,44 @@ class TestNetworkManagerRendering(CiTestCase):
|
||||
"""
|
||||
),
|
||||
},
|
||||
+ self.expected_conf_d,
|
||||
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)
|
||||
+ self._compare_files_to_expected(
|
||||
+ entry[self.expected_name], self.expected_conf_d, 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)
|
||||
+ self._compare_files_to_expected(
|
||||
+ entry[self.expected_name], self.expected_conf_d, 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)
|
||||
+ self._compare_files_to_expected(
|
||||
+ entry[self.expected_name], self.expected_conf_d, 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)
|
||||
+ self._compare_files_to_expected(
|
||||
+ entry[self.expected_name], self.expected_conf_d, 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._compare_files_to_expected(
|
||||
+ entry[self.expected_name], self.expected_conf_d, found
|
||||
+ )
|
||||
self.assertNotIn(
|
||||
"WARNING: Network config: ignoring eth0.101 device-level mtu",
|
||||
self.logs.getvalue(),
|
||||
@@ -5892,12 +5929,16 @@ class TestNetworkManagerRendering(CiTestCase):
|
||||
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)
|
||||
+ self._compare_files_to_expected(
|
||||
+ entry[self.expected_name], self.expected_conf_d, 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)
|
||||
+ self._compare_files_to_expected(
|
||||
+ entry[self.expected_name], self.expected_conf_d, found
|
||||
+ )
|
||||
expected_msg = (
|
||||
"WARNING: Network config: ignoring iface0 device-level mtu:8999"
|
||||
" because ipv4 subnet-level mtu:9000 provided."
|
||||
@@ -5907,41 +5948,55 @@ class TestNetworkManagerRendering(CiTestCase):
|
||||
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)
|
||||
+ self._compare_files_to_expected(
|
||||
+ entry[self.expected_name], self.expected_conf_d, 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)
|
||||
+ self._compare_files_to_expected(
|
||||
+ entry[self.expected_name], self.expected_conf_d, 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)
|
||||
+ self._compare_files_to_expected(
|
||||
+ entry[self.expected_name], self.expected_conf_d, 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)
|
||||
+ self._compare_files_to_expected(
|
||||
+ entry[self.expected_name], self.expected_conf_d, 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)
|
||||
+ self._compare_files_to_expected(
|
||||
+ entry[self.expected_name], self.expected_conf_d, 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)
|
||||
+ self._compare_files_to_expected(
|
||||
+ entry[self.expected_name], self.expected_conf_d, 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)
|
||||
+ self._compare_files_to_expected(
|
||||
+ entry[self.expected_name], self.expected_conf_d, found
|
||||
+ )
|
||||
|
||||
|
||||
@mock.patch(
|
@ -1,6 +1,6 @@
|
||||
Name: cloud-init
|
||||
Version: 23.1.1
|
||||
Release: 8%{?dist}
|
||||
Release: 9%{?dist}
|
||||
Summary: Cloud instance init scripts
|
||||
License: ASL 2.0 or GPLv3
|
||||
URL: http://launchpad.net/cloud-init
|
||||
@ -37,6 +37,7 @@ Patch26: 0026-Enable-SUSE-based-distros-for-ca-handling-2036.patch
|
||||
Patch27: 0027-Handle-non-existent-ca-cert-config-situation-2073.patch
|
||||
Patch28: 0028-logging-keep-current-file-mode-of-log-file-if-its-st.patch
|
||||
Patch29: 0029-DS-VMware-modify-a-few-log-level-4284.patch
|
||||
Patch30: 0030-NM-renderer-set-default-IPv6-addr-gen-mode-for-all-i.patch
|
||||
|
||||
BuildArch: noarch
|
||||
|
||||
@ -246,6 +247,10 @@ fi
|
||||
%config(noreplace) %{_sysconfdir}/rsyslog.d/21-cloudinit.conf
|
||||
|
||||
%changelog
|
||||
* Fri Aug 04 2023 Camilla Conte <cconte@redhat.com> - 23.1.1-9
|
||||
- 0030-NM-renderer-set-default-IPv6-addr-gen-mode-for-all-i.patch [bz#2188388]
|
||||
- Resolves: bz#2188388
|
||||
|
||||
* Wed Jul 26 2023 Camilla Conte <cconte@redhat.com> - 23.1.1-8
|
||||
- 0022-test-fixes-update-tests-to-reflect-AUTOCONNECT_PRIOR.patch [bz#2217865]
|
||||
- 0023-test-fixes-remove-NM_CONTROLLED-no-from-tests.patch [bz#2217865]
|
||||
|
Loading…
Reference in New Issue
Block a user