Compare commits

...

No commits in common. 'c9' and 'i10cs' have entirely different histories.
c9 ... i10cs

@ -1 +1 @@
e73116733f5636eb4bc1a5e47e802c3635b9bfa2 SOURCES/23.4.tar.gz
387c1d48b72cde444ab13195589deece9d1daa8c SOURCES/24.1.4.tar.gz

2
.gitignore vendored

@ -1 +1 @@
SOURCES/23.4.tar.gz
SOURCES/24.1.4.tar.gz

@ -1,12 +1,21 @@
From 03345a88b8b0008a4a81e010d46290f5ba643ebc Mon Sep 17 00:00:00 2001
From 479f1646e251e7c72c9d57589d6c72568f054fef Mon Sep 17 00:00:00 2001
From: Ani Sinha <anisinha@redhat.com>
Date: Wed, 13 Dec 2023 11:54:55 +0530
Subject: [PATCH] Add initial redhat changes
Adding minimal set of changes necessary for successful build of the package
on RHEL/CentOS 9 Stream koji.
on RHEL/CentOS 10 Stream koji.
Additional changes on top of the changes in 23.1.1 rebase:
Changes for 24.1.3 release:
- Updated version in spec file in .dist.
- Updated source tarball name in spec file in .dist/
- Removed reference to Patch0 coming from Fedora in spec file in .dist.
- Removed reference to clean.d/README from spec file in .dist/
- Updated VERSION, MARKER etc in Makefile.common in .dist.
- Updated sha512 in sources.sha512 under .dist/
- Updated TargetRelease to point to RHEL 10.0 in .dist/
Additional changes for 23.4 rebase:
- Updated VERSION, TARSHA512, MARKER and BUILD_TARGET_RHEL parameters in
Makefile.common in .dist/
- Squashed unit test fixes for the downstream changes in cloudinit/settings.py.
@ -43,16 +52,18 @@ missing rhel/ static files and "" instead of '' in setup.py
X-downstram-only: true
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
Signed-off-by: Ani Sinha <anisinha@redhat.com>
(cherry picked from commit 03345a88b8b0008a4a81e010d46290f5ba643ebc)
Signed-off-by: Ani Sinha <anisinha@redhat.com>
---
cloudinit/settings.py | 5 +++--
tests/unittests/cmd/test_main.py | 15 +++++++++------
2 files changed, 12 insertions(+), 8 deletions(-)
diff --git a/cloudinit/settings.py b/cloudinit/settings.py
index 592e144d..5ced21bd 100644
index b075682f..f749c509 100644
--- a/cloudinit/settings.py
+++ b/cloudinit/settings.py
@@ -54,13 +54,14 @@ CFG_BUILTIN = {
@@ -55,13 +55,14 @@ CFG_BUILTIN = {
],
"def_log_file": "/var/log/cloud-init.log",
"log_cfgs": [],
@ -70,10 +81,10 @@ index 592e144d..5ced21bd 100644
},
"vendor_data": {"enabled": True, "prefix": []},
diff --git a/tests/unittests/cmd/test_main.py b/tests/unittests/cmd/test_main.py
index ab427115..19d26ebe 100644
index 7f580203..19316be3 100644
--- a/tests/unittests/cmd/test_main.py
+++ b/tests/unittests/cmd/test_main.py
@@ -119,14 +119,17 @@ class TestMain(FilesystemMockingTestCase):
@@ -131,14 +131,17 @@ class TestMain(FilesystemMockingTestCase):
{
"def_log_file": "/var/log/cloud-init.log",
"log_cfgs": [],

@ -0,0 +1,268 @@
From 8effa259c803f265553b8bfc629835d88815e2dd Mon Sep 17 00:00:00 2001
From: Brett Holman <brett.holman@canonical.com>
Date: Tue, 26 Mar 2024 15:02:39 -0500
Subject: [PATCH] fix(rhel): Fix network ordering in sysconfig
NM_CONTROLLED=true allows cloud-init to wait until network devices are online.
See upstream PR: https://github.com/canonical/cloud-init/pull/5089
Conflicts:
tests/unittests/net/network_configs.py
This file was added in commit a576d11ef93d ("Cleanup test_net.py (#4840)")
This commit is not part of 24.1.2 release.
(cherry picked from commit 9a7674af70026ba77612c8f53a82573bdc350ff7)
Signed-off-by: Ani Sinha <anisinha@redhat.com>
---
cloudinit/net/sysconfig.py | 1 -
doc/rtd/reference/network-config.rst | 2 --
tests/unittests/cmd/devel/test_net_convert.py | 1 -
tests/unittests/distros/test_netconfig.py | 8 --------
tests/unittests/test_net.py | 16 ----------------
5 files changed, 28 deletions(-)
diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
index 622b8faf..3be35126 100644
--- a/cloudinit/net/sysconfig.py
+++ b/cloudinit/net/sysconfig.py
@@ -317,7 +317,6 @@ class Renderer(renderer.Renderer):
"rhel": {
"ONBOOT": True,
"USERCTL": False,
- "NM_CONTROLLED": False,
"BOOTPROTO": "none",
},
"suse": {"BOOTPROTO": "static", "STARTMODE": "auto"},
diff --git a/doc/rtd/reference/network-config.rst b/doc/rtd/reference/network-config.rst
index d9e67cf7..130b665e 100644
--- a/doc/rtd/reference/network-config.rst
+++ b/doc/rtd/reference/network-config.rst
@@ -308,7 +308,6 @@ Example output:
BOOTPROTO=static
DEVICE=eth7
IPADDR=192.168.1.5/255.255.255.0
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -316,7 +315,6 @@ Example output:
#
BOOTPROTO=dhcp
DEVICE=eth9
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
diff --git a/tests/unittests/cmd/devel/test_net_convert.py b/tests/unittests/cmd/devel/test_net_convert.py
index be2fcdd6..3e9a4f90 100644
--- a/tests/unittests/cmd/devel/test_net_convert.py
+++ b/tests/unittests/cmd/devel/test_net_convert.py
@@ -62,7 +62,6 @@ SAMPLE_SYSCONFIG_CONTENT = """\
#
BOOTPROTO=dhcp
DEVICE=eth0
-NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
diff --git a/tests/unittests/distros/test_netconfig.py b/tests/unittests/distros/test_netconfig.py
index d1e251b6..f35e5b0a 100644
--- a/tests/unittests/distros/test_netconfig.py
+++ b/tests/unittests/distros/test_netconfig.py
@@ -723,7 +723,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
GATEWAY=192.168.1.254
IPADDR=192.168.1.5
NETMASK=255.255.255.0
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -733,7 +732,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
"""\
BOOTPROTO=dhcp
DEVICE=eth1
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -764,7 +762,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
IPV6_AUTOCONF=no
IPV6_DEFAULTGW=2607:f0d0:1002:0011::1
IPV6_FORCE_ACCEPT_RA=no
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -774,7 +771,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
"""\
BOOTPROTO=dhcp
DEVICE=eth1
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -821,7 +817,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
HWADDR=00:16:3e:60:7c:df
IPADDR=192.10.1.2
NETMASK=255.255.255.0
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -833,7 +828,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
DEVICE=infra0
IPADDR=10.0.1.2
NETMASK=255.255.0.0
- NM_CONTROLLED=no
ONBOOT=yes
PHYSDEV=eth0
USERCTL=no
@@ -869,7 +863,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
DEVICE=eth0
IPADDR=192.10.1.2
NETMASK=255.255.255.0
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -881,7 +874,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
DEVICE=eth0.1001
IPADDR=10.0.1.2
NETMASK=255.255.0.0
- NM_CONTROLLED=no
ONBOOT=yes
PHYSDEV=eth0
USERCTL=no
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
index cb991938..f898543c 100644
--- a/tests/unittests/test_net.py
+++ b/tests/unittests/test_net.py
@@ -585,7 +585,6 @@ GATEWAY=172.19.3.254
HWADDR=fa:16:3e:ed:9a:59
IPADDR=172.19.1.34
NETMASK=255.255.252.0
-NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -751,7 +750,6 @@ IPADDR=172.19.1.34
IPADDR1=10.0.0.10
NETMASK=255.255.252.0
NETMASK1=255.255.255.0
-NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -913,7 +911,6 @@ IPV6_AUTOCONF=no
IPV6_DEFAULTGW=2001:DB8::1
IPV6_FORCE_ACCEPT_RA=no
NETMASK=255.255.252.0
-NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -5232,7 +5229,6 @@ DEVICE=eth1000
DHCPV6C=yes
HWADDR=07-1c-c6-75-a4-be
IPV6INIT=yes
-NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -5444,7 +5440,6 @@ GATEWAY=10.0.2.2
HWADDR=52:54:00:12:34:00
IPADDR=10.0.2.15
NETMASK=255.255.255.0
-NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -5475,7 +5470,6 @@ HWADDR=fa:16:3e:25:b4:59
IPADDR=51.68.89.122
MTU=1500
NETMASK=255.255.240.0
-NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -5489,7 +5483,6 @@ DEVICE=eth1
DHCLIENT_SET_DEFAULT_ROUTE=no
HWADDR=fa:16:3e:b1:ca:29
MTU=9000
-NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -5514,7 +5507,6 @@ USERCTL=no
#
BOOTPROTO=dhcp
DEVICE=eth0
-NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -5761,7 +5753,6 @@ USERCTL=no
IPV6_FORCE_ACCEPT_RA=no
IPV6_DEFAULTGW=2001:db8::1
NETMASK=255.255.255.0
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -5793,7 +5784,6 @@ USERCTL=no
"""\
BOOTPROTO=none
DEVICE=eno1
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -5806,7 +5796,6 @@ USERCTL=no
IPADDR=192.6.1.9
MTU=1495
NETMASK=255.255.255.0
- NM_CONTROLLED=no
ONBOOT=yes
PHYSDEV=eno1
USERCTL=no
@@ -5842,7 +5831,6 @@ USERCTL=no
IPADDR=10.101.8.65
MTU=1334
NETMASK=255.255.255.192
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Bond
USERCTL=no
@@ -5854,7 +5842,6 @@ USERCTL=no
BOOTPROTO=none
DEVICE=enp0s0
MASTER=bond0
- NM_CONTROLLED=no
ONBOOT=yes
SLAVE=yes
TYPE=Bond
@@ -5867,7 +5854,6 @@ USERCTL=no
BOOTPROTO=none
DEVICE=enp0s1
MASTER=bond0
- NM_CONTROLLED=no
ONBOOT=yes
SLAVE=yes
TYPE=Bond
@@ -5898,7 +5884,6 @@ USERCTL=no
DEVICE=eno1
HWADDR=07-1c-c6-75-a4-be
METRIC=100
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -5989,7 +5974,6 @@ USERCTL=no
IPV6_FORCE_ACCEPT_RA=no
MTU=1400
NETMASK=255.255.248.0
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no

@ -1,9 +1,16 @@
From 5129908caa1867c7f584ec8d38607cf56b20521a Mon Sep 17 00:00:00 2001
From 2d18b8b02f9de3a8ddf894241be2489de479a767 Mon Sep 17 00:00:00 2001
From: Eduardo Otubo <otubo@redhat.com>
Date: Fri, 7 May 2021 13:36:06 +0200
Subject: [PATCH] Do not write NM_CONTROLLED=no in generated interface config
files
Changes for 24.1.2:
- Renamed load_file() to load_text_file(). Please see
d27eab110 ("refactor: Replace load_file with load_binary_file to simplify typing (#4823)")
- Removed changes that are already covered by backport of the upstream commit:
9a7674af70 (" fix(rhel): Fix network ordering in sysconfig")
This change was backported with c10s commit 40f9ba8e3805e52be4 .
Conflicts 20.3:
- Not appplying patch on cloudinit/net/sysconfig.py since it now has a
mechanism to identify if cloud-init is running on RHEL, having the
@ -17,32 +24,25 @@ Signed-off-by: Eduardo Otubo <otubo@redhat.com>
Signed-off-by: Ryan McCabe <rmccabe@redhat.com>
Signed-off-by: Ani Sinha <anisinha@redhat.com>
(cherry picked from commit 5129908caa1867c7f584ec8d38607cf56b20521a)
---
cloudinit/net/sysconfig.py | 12 ++++-
tests/unittests/cmd/devel/test_net_convert.py | 1 -
tests/unittests/distros/test_netconfig.py | 8 ---
tests/unittests/test_net.py | 53 -------------------
4 files changed, 10 insertions(+), 64 deletions(-)
cloudinit/net/sysconfig.py | 13 ++++++++++++-
tests/unittests/test_net.py | 39 -------------------------------------
2 files changed, 12 insertions(+), 40 deletions(-)
diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
index 7570a5e3..f01c4236 100644
index 3be35126..b9e9593b 100644
--- a/cloudinit/net/sysconfig.py
+++ b/cloudinit/net/sysconfig.py
@@ -317,7 +317,6 @@ class Renderer(renderer.Renderer):
"rhel": {
"ONBOOT": True,
"USERCTL": False,
- "NM_CONTROLLED": False,
"BOOTPROTO": "none",
},
"suse": {"BOOTPROTO": "static", "STARTMODE": "auto"},
@@ -1030,7 +1029,16 @@ class Renderer(renderer.Renderer):
@@ -1031,7 +1031,18 @@ class Renderer(renderer.Renderer):
# Distros configuring /etc/sysconfig/network as a file e.g. Centos
if sysconfig_path.endswith("network"):
util.ensure_dir(os.path.dirname(sysconfig_path))
- netcfg = [_make_header(), "NETWORKING=yes"]
+ netcfg = []
+ for line in util.load_file(sysconfig_path, quiet=True).split("\n"):
+ for line in util.load_text_file(sysconfig_path, quiet=True).split(
+ "\n"
+ ):
+ if "cloud-init" in line:
+ break
+ if not line.startswith(
@ -54,115 +54,11 @@ index 7570a5e3..f01c4236 100644
if network_state.use_ipv6:
netcfg.append("NETWORKING_IPV6=yes")
netcfg.append("IPV6_AUTOCONF=no")
diff --git a/tests/unittests/cmd/devel/test_net_convert.py b/tests/unittests/cmd/devel/test_net_convert.py
index fb72963f..7b9121b2 100644
--- a/tests/unittests/cmd/devel/test_net_convert.py
+++ b/tests/unittests/cmd/devel/test_net_convert.py
@@ -62,7 +62,6 @@ SAMPLE_SYSCONFIG_CONTENT = """\
#
BOOTPROTO=dhcp
DEVICE=eth0
-NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
diff --git a/tests/unittests/distros/test_netconfig.py b/tests/unittests/distros/test_netconfig.py
index 7ba430f2..962ff7fb 100644
--- a/tests/unittests/distros/test_netconfig.py
+++ b/tests/unittests/distros/test_netconfig.py
@@ -723,7 +723,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
GATEWAY=192.168.1.254
IPADDR=192.168.1.5
NETMASK=255.255.255.0
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -733,7 +732,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
"""\
BOOTPROTO=dhcp
DEVICE=eth1
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -764,7 +762,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
IPV6_AUTOCONF=no
IPV6_DEFAULTGW=2607:f0d0:1002:0011::1
IPV6_FORCE_ACCEPT_RA=no
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -774,7 +771,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
"""\
BOOTPROTO=dhcp
DEVICE=eth1
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -821,7 +817,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
HWADDR=00:16:3e:60:7c:df
IPADDR=192.10.1.2
NETMASK=255.255.255.0
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -833,7 +828,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
DEVICE=infra0
IPADDR=10.0.1.2
NETMASK=255.255.0.0
- NM_CONTROLLED=no
ONBOOT=yes
PHYSDEV=eth0
USERCTL=no
@@ -869,7 +863,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
DEVICE=eth0
IPADDR=192.10.1.2
NETMASK=255.255.255.0
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -881,7 +874,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
DEVICE=eth0.1001
IPADDR=10.0.1.2
NETMASK=255.255.0.0
- NM_CONTROLLED=no
ONBOOT=yes
PHYSDEV=eth0
USERCTL=no
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
index c5509536..052b0674 100644
index f898543c..d83c52f0 100644
--- a/tests/unittests/test_net.py
+++ b/tests/unittests/test_net.py
@@ -585,7 +585,6 @@ GATEWAY=172.19.3.254
HWADDR=fa:16:3e:ed:9a:59
IPADDR=172.19.1.34
NETMASK=255.255.252.0
-NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -750,7 +749,6 @@ IPADDR=172.19.1.34
IPADDR1=10.0.0.10
NETMASK=255.255.252.0
NETMASK1=255.255.255.0
-NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -912,7 +910,6 @@ IPV6_AUTOCONF=no
IPV6_DEFAULTGW=2001:DB8::1
IPV6_FORCE_ACCEPT_RA=no
NETMASK=255.255.252.0
-NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -1143,7 +1140,6 @@ NETWORK_CONFIGS = {
@@ -1141,7 +1141,6 @@ NETWORK_CONFIGS = {
BOOTPROTO=none
DEVICE=eth1
HWADDR=cf:d6:af:48:e8:80
@ -170,7 +66,7 @@ index c5509536..052b0674 100644
ONBOOT=yes
TYPE=Ethernet
USERCTL=no"""
@@ -1162,7 +1158,6 @@ NETWORK_CONFIGS = {
@@ -1160,7 +1159,6 @@ NETWORK_CONFIGS = {
IPADDR=192.168.21.3
NETMASK=255.255.255.0
METRIC=10000
@ -178,7 +74,7 @@ index c5509536..052b0674 100644
ONBOOT=yes
TYPE=Ethernet
USERCTL=no"""
@@ -1319,7 +1314,6 @@ NETWORK_CONFIGS = {
@@ -1315,7 +1313,6 @@ NETWORK_CONFIGS = {
BOOTPROTO=none
DEVICE=eth1
HWADDR=cf:d6:af:48:e8:80
@ -186,7 +82,7 @@ index c5509536..052b0674 100644
ONBOOT=yes
TYPE=Ethernet
USERCTL=no"""
@@ -1338,7 +1332,6 @@ NETWORK_CONFIGS = {
@@ -1334,7 +1331,6 @@ NETWORK_CONFIGS = {
IPADDR=192.168.21.3
NETMASK=255.255.255.0
METRIC=10000
@ -194,7 +90,7 @@ index c5509536..052b0674 100644
ONBOOT=yes
TYPE=Ethernet
USERCTL=no"""
@@ -1581,7 +1574,6 @@ NETWORK_CONFIGS = {
@@ -1577,7 +1573,6 @@ NETWORK_CONFIGS = {
IPV6_AUTOCONF=no
IPV6_FORCE_ACCEPT_RA=no
NETMASK=255.255.255.0
@ -202,7 +98,7 @@ index c5509536..052b0674 100644
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -1725,7 +1717,6 @@ NETWORK_CONFIGS = {
@@ -1721,7 +1716,6 @@ NETWORK_CONFIGS = {
DHCPV6C=yes
IPV6INIT=yes
DEVICE=iface0
@ -210,7 +106,7 @@ index c5509536..052b0674 100644
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -1816,7 +1807,6 @@ NETWORK_CONFIGS = {
@@ -1812,7 +1806,6 @@ NETWORK_CONFIGS = {
IPV6INIT=yes
IPV6_FORCE_ACCEPT_RA=yes
DEVICE=iface0
@ -218,7 +114,7 @@ index c5509536..052b0674 100644
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -1892,7 +1882,6 @@ NETWORK_CONFIGS = {
@@ -1888,7 +1881,6 @@ NETWORK_CONFIGS = {
IPV6INIT=yes
IPV6_FORCE_ACCEPT_RA=no
DEVICE=iface0
@ -226,7 +122,7 @@ index c5509536..052b0674 100644
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -1956,7 +1945,6 @@ NETWORK_CONFIGS = {
@@ -1952,7 +1944,6 @@ NETWORK_CONFIGS = {
IPV6_AUTOCONF=yes
IPV6INIT=yes
DEVICE=iface0
@ -234,7 +130,7 @@ index c5509536..052b0674 100644
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -2014,7 +2002,6 @@ NETWORK_CONFIGS = {
@@ -2010,7 +2001,6 @@ NETWORK_CONFIGS = {
IPV6_AUTOCONF=no
IPV6_FORCE_ACCEPT_RA=no
DEVICE=iface0
@ -242,7 +138,7 @@ index c5509536..052b0674 100644
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -2071,7 +2058,6 @@ NETWORK_CONFIGS = {
@@ -2067,7 +2057,6 @@ NETWORK_CONFIGS = {
IPV6_AUTOCONF=yes
IPV6INIT=yes
DEVICE=iface0
@ -250,7 +146,7 @@ index c5509536..052b0674 100644
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -2157,7 +2143,6 @@ NETWORK_CONFIGS = {
@@ -2153,7 +2142,6 @@ NETWORK_CONFIGS = {
IPV6_FAILURE_FATAL=yes
IPV6_FORCE_ACCEPT_RA=yes
DEVICE=iface0
@ -258,7 +154,7 @@ index c5509536..052b0674 100644
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -2198,7 +2183,6 @@ NETWORK_CONFIGS = {
@@ -2194,7 +2182,6 @@ NETWORK_CONFIGS = {
"""\
BOOTPROTO=dhcp
DEVICE=iface0
@ -266,7 +162,7 @@ index c5509536..052b0674 100644
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -2275,7 +2259,6 @@ NETWORK_CONFIGS = {
@@ -2271,7 +2258,6 @@ NETWORK_CONFIGS = {
BOOTPROTO=dhcp
DEVICE=iface0
ETHTOOL_OPTS="wol g"
@ -274,7 +170,7 @@ index c5509536..052b0674 100644
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -2619,7 +2602,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
@@ -2615,7 +2601,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
DHCPV6C=yes
IPV6INIT=yes
MACADDR=aa:bb:cc:dd:ee:ff
@ -282,7 +178,7 @@ index c5509536..052b0674 100644
ONBOOT=yes
TYPE=Bond
USERCTL=no"""
@@ -2629,7 +2611,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
@@ -2625,7 +2610,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
BOOTPROTO=dhcp
DEVICE=bond0.200
DHCLIENT_SET_DEFAULT_ROUTE=no
@ -290,7 +186,7 @@ index c5509536..052b0674 100644
ONBOOT=yes
PHYSDEV=bond0
USERCTL=no
@@ -2649,7 +2630,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
@@ -2645,7 +2629,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
IPV6_DEFAULTGW=2001:4800:78ff:1b::1
MACADDR=bb:bb:bb:bb:bb:aa
NETMASK=255.255.255.0
@ -298,7 +194,7 @@ index c5509536..052b0674 100644
ONBOOT=yes
PRIO=22
STP=no
@@ -2661,7 +2641,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
@@ -2657,7 +2640,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
BOOTPROTO=none
DEVICE=eth0
HWADDR=c0:d6:9f:2c:e8:80
@ -306,7 +202,7 @@ index c5509536..052b0674 100644
ONBOOT=yes
TYPE=Ethernet
USERCTL=no"""
@@ -2680,7 +2659,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
@@ -2676,7 +2658,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
MTU=1500
NETMASK=255.255.255.0
NETMASK1=255.255.255.0
@ -314,7 +210,7 @@ index c5509536..052b0674 100644
ONBOOT=yes
PHYSDEV=eth0
USERCTL=no
@@ -2692,7 +2670,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
@@ -2688,7 +2669,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
DEVICE=eth1
HWADDR=aa:d6:9f:2c:e8:80
MASTER=bond0
@ -322,7 +218,7 @@ index c5509536..052b0674 100644
ONBOOT=yes
SLAVE=yes
TYPE=Ethernet
@@ -2704,7 +2681,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
@@ -2700,7 +2680,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
DEVICE=eth2
HWADDR=c0:bb:9f:2c:e8:80
MASTER=bond0
@ -330,7 +226,7 @@ index c5509536..052b0674 100644
ONBOOT=yes
SLAVE=yes
TYPE=Ethernet
@@ -2716,7 +2692,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
@@ -2712,7 +2691,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
BRIDGE=br0
DEVICE=eth3
HWADDR=66:bb:9f:2c:e8:80
@ -338,7 +234,7 @@ index c5509536..052b0674 100644
ONBOOT=yes
TYPE=Ethernet
USERCTL=no"""
@@ -2727,7 +2702,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
@@ -2723,7 +2701,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
BRIDGE=br0
DEVICE=eth4
HWADDR=98:bb:9f:2c:e8:80
@ -346,7 +242,7 @@ index c5509536..052b0674 100644
ONBOOT=yes
TYPE=Ethernet
USERCTL=no"""
@@ -2738,7 +2712,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
@@ -2734,7 +2711,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
DEVICE=eth5
DHCLIENT_SET_DEFAULT_ROUTE=no
HWADDR=98:bb:9f:2c:e8:8a
@ -354,7 +250,7 @@ index c5509536..052b0674 100644
ONBOOT=no
TYPE=Ethernet
USERCTL=no"""
@@ -2751,7 +2724,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
@@ -2747,7 +2723,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
IPADDR=192.168.200.7
MTU=9000
NETMASK=255.255.255.0
@ -362,7 +258,7 @@ index c5509536..052b0674 100644
ONBOOT=yes
TYPE=InfiniBand
USERCTL=no"""
@@ -3473,7 +3445,6 @@ iface bond0 inet6 static
@@ -3479,7 +3454,6 @@ iface bond0 inet6 static
MTU=9000
NETMASK=255.255.255.0
NETMASK1=255.255.255.0
@ -370,7 +266,7 @@ index c5509536..052b0674 100644
ONBOOT=yes
TYPE=Bond
USERCTL=no
@@ -3485,7 +3456,6 @@ iface bond0 inet6 static
@@ -3491,7 +3465,6 @@ iface bond0 inet6 static
DEVICE=bond0s0
HWADDR=aa:bb:cc:dd:e8:00
MASTER=bond0
@ -378,7 +274,7 @@ index c5509536..052b0674 100644
ONBOOT=yes
SLAVE=yes
TYPE=Ethernet
@@ -3513,7 +3483,6 @@ iface bond0 inet6 static
@@ -3519,7 +3492,6 @@ iface bond0 inet6 static
DEVICE=bond0s1
HWADDR=aa:bb:cc:dd:e8:01
MASTER=bond0
@ -386,7 +282,7 @@ index c5509536..052b0674 100644
ONBOOT=yes
SLAVE=yes
TYPE=Ethernet
@@ -3662,7 +3631,6 @@ iface bond0 inet6 static
@@ -3668,7 +3640,6 @@ iface bond0 inet6 static
BOOTPROTO=none
DEVICE=en0
HWADDR=aa:bb:cc:dd:e8:00
@ -394,7 +290,7 @@ index c5509536..052b0674 100644
ONBOOT=yes
TYPE=Ethernet
USERCTL=no"""
@@ -3683,7 +3651,6 @@ iface bond0 inet6 static
@@ -3689,7 +3660,6 @@ iface bond0 inet6 static
MTU=2222
NETMASK=255.255.255.0
NETMASK1=255.255.255.0
@ -402,7 +298,7 @@ index c5509536..052b0674 100644
ONBOOT=yes
PHYSDEV=en0
USERCTL=no
@@ -3811,7 +3778,6 @@ iface bond0 inet6 static
@@ -3817,7 +3787,6 @@ iface bond0 inet6 static
DEVICE=br0
IPADDR=192.168.2.2
NETMASK=255.255.255.0
@ -410,7 +306,7 @@ index c5509536..052b0674 100644
ONBOOT=yes
PRIO=22
STP=no
@@ -3829,7 +3795,6 @@ iface bond0 inet6 static
@@ -3835,7 +3804,6 @@ iface bond0 inet6 static
IPV6INIT=yes
IPV6_AUTOCONF=no
IPV6_FORCE_ACCEPT_RA=no
@ -418,7 +314,7 @@ index c5509536..052b0674 100644
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -3845,7 +3810,6 @@ iface bond0 inet6 static
@@ -3851,7 +3819,6 @@ iface bond0 inet6 static
IPV6INIT=yes
IPV6_AUTOCONF=no
IPV6_FORCE_ACCEPT_RA=no
@ -426,7 +322,7 @@ index c5509536..052b0674 100644
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -4030,7 +3994,6 @@ iface bond0 inet6 static
@@ -4036,7 +4003,6 @@ iface bond0 inet6 static
HWADDR=52:54:00:12:34:00
IPADDR=192.168.1.2
NETMASK=255.255.255.0
@ -434,7 +330,7 @@ index c5509536..052b0674 100644
ONBOOT=no
TYPE=Ethernet
USERCTL=no
@@ -4042,7 +4005,6 @@ iface bond0 inet6 static
@@ -4048,7 +4014,6 @@ iface bond0 inet6 static
DEVICE=eth1
HWADDR=52:54:00:12:34:aa
MTU=1480
@ -442,7 +338,7 @@ index c5509536..052b0674 100644
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -4053,7 +4015,6 @@ iface bond0 inet6 static
@@ -4059,7 +4024,6 @@ iface bond0 inet6 static
BOOTPROTO=none
DEVICE=eth2
HWADDR=52:54:00:12:34:ff
@ -450,114 +346,26 @@ index c5509536..052b0674 100644
ONBOOT=no
TYPE=Ethernet
USERCTL=no
@@ -4138,7 +4099,6 @@ iface bond0 inet6 static
BOOTPROTO=none
DEVICE=eth0
HWADDR=cf:d6:af:48:e8:80
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no"""
@@ -4736,7 +4696,6 @@ class TestRhelSysConfigRendering(CiTestCase):
BOOTPROTO=dhcp
DEVICE=eth1000
HWADDR=07-1c-c6-75-a4-be
-NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -4948,7 +4907,6 @@ GATEWAY=10.0.2.2
HWADDR=52:54:00:12:34:00
IPADDR=10.0.2.15
NETMASK=255.255.255.0
-NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -4979,7 +4937,6 @@ HWADDR=fa:16:3e:25:b4:59
IPADDR=51.68.89.122
MTU=1500
NETMASK=255.255.240.0
-NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -4993,7 +4950,6 @@ DEVICE=eth1
DHCLIENT_SET_DEFAULT_ROUTE=no
HWADDR=fa:16:3e:b1:ca:29
MTU=9000
-NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -5018,7 +4974,6 @@ USERCTL=no
#
BOOTPROTO=dhcp
DEVICE=eth0
-NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -5251,7 +5206,6 @@ USERCTL=no
IPV6_FORCE_ACCEPT_RA=no
IPV6_DEFAULTGW=2001:db8::1
NETMASK=255.255.255.0
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -5283,7 +5237,6 @@ USERCTL=no
"""\
BOOTPROTO=none
DEVICE=eno1
@@ -4236,7 +4200,6 @@ iface bond0 inet6 static
HWADDR=11:22:33:44:55:66
IPADDR=192.168.1.20
NETMASK=255.255.0.0
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -5296,7 +5249,6 @@ USERCTL=no
IPADDR=192.6.1.9
MTU=1495
NETMASK=255.255.255.0
- NM_CONTROLLED=no
ONBOOT=yes
PHYSDEV=eno1
USERCTL=no
@@ -5332,7 +5284,6 @@ USERCTL=no
IPADDR=10.101.8.65
MTU=1334
NETMASK=255.255.255.192
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Bond
USERCTL=no
@@ -5344,7 +5295,6 @@ USERCTL=no
@@ -4308,7 +4271,6 @@ iface bond0 inet6 static
BOOTPROTO=none
DEVICE=enp0s0
MASTER=bond0
- NM_CONTROLLED=no
ONBOOT=yes
SLAVE=yes
TYPE=Bond
@@ -5357,7 +5307,6 @@ USERCTL=no
BOOTPROTO=none
DEVICE=enp0s1
MASTER=bond0
- NM_CONTROLLED=no
ONBOOT=yes
SLAVE=yes
TYPE=Bond
@@ -5388,7 +5337,6 @@ USERCTL=no
DEVICE=eno1
HWADDR=07-1c-c6-75-a4-be
METRIC=100
DEVICE=eth0
HWADDR=cf:d6:af:48:e8:80
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -5479,7 +5427,6 @@ USERCTL=no
USERCTL=no"""
@@ -4468,7 +4430,6 @@ iface bond0 inet6 static
IPV6_AUTOCONF=no
IPV6_FORCE_ACCEPT_RA=no
MTU=1400
NETMASK=255.255.248.0
NETMASK=255.255.0.0
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet

@ -1,8 +1,13 @@
From 8a2fcbbcfdfc1df6f6c18f96588154f40083a239 Mon Sep 17 00:00:00 2001
From 4e24e6f9e786437d94ba5e2d3e084ef2a2fc534f Mon Sep 17 00:00:00 2001
From: Ani Sinha <anisinha@redhat.com>
Date: Wed, 13 Dec 2023 11:55:16 +0530
Subject: [PATCH] Setting autoconnect priority setting for network-scripts
Changes for 24.1.2 (c10s):
- Fixed additional unit tests.
Changes for 23.4 (c9s):
Squashed the following three downstream only commits from RHEL 9.3:
Commit 1:
@ -53,15 +58,16 @@ fixes: 0a2c6b6118ff ("net/sysconfig: do not use the highest autoconnect priority
fixes: c589da20eb92 ("Setting highest autoconnect priority for network-scripts")
Signed-off-by: Ani Sinha <anisinha@redhat.com>
(cherry picked from commit 8a2fcbbcfdfc1df6f6c18f96588154f40083a239)
---
cloudinit/net/sysconfig.py | 1 +
tests/unittests/cmd/devel/test_net_convert.py | 1 +
tests/unittests/distros/test_netconfig.py | 8 +++
tests/unittests/test_net.py | 53 +++++++++++++++++++
4 files changed, 63 insertions(+)
tests/unittests/test_net.py | 54 +++++++++++++++++++
4 files changed, 64 insertions(+)
diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
index f01c4236..d39f4fe3 100644
index b9e9593b..1678fcde 100644
--- a/cloudinit/net/sysconfig.py
+++ b/cloudinit/net/sysconfig.py
@@ -318,6 +318,7 @@ class Renderer(renderer.Renderer):
@ -73,7 +79,7 @@ index f01c4236..d39f4fe3 100644
"suse": {"BOOTPROTO": "static", "STARTMODE": "auto"},
}
diff --git a/tests/unittests/cmd/devel/test_net_convert.py b/tests/unittests/cmd/devel/test_net_convert.py
index 7b9121b2..288e3e37 100644
index 3e9a4f90..b6da87ca 100644
--- a/tests/unittests/cmd/devel/test_net_convert.py
+++ b/tests/unittests/cmd/devel/test_net_convert.py
@@ -60,6 +60,7 @@ DHCP=ipv4
@ -85,7 +91,7 @@ index 7b9121b2..288e3e37 100644
DEVICE=eth0
ONBOOT=yes
diff --git a/tests/unittests/distros/test_netconfig.py b/tests/unittests/distros/test_netconfig.py
index 962ff7fb..4c624079 100644
index f35e5b0a..6b4fc666 100644
--- a/tests/unittests/distros/test_netconfig.py
+++ b/tests/unittests/distros/test_netconfig.py
@@ -717,6 +717,7 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
@ -153,7 +159,7 @@ index 962ff7fb..4c624079 100644
DEVICE=eth0.1001
IPADDR=10.0.1.2
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
index 052b0674..cef4fa2d 100644
index d83c52f0..fee8e035 100644
--- a/tests/unittests/test_net.py
+++ b/tests/unittests/test_net.py
@@ -578,6 +578,7 @@ dns = none
@ -164,7 +170,7 @@ index 052b0674..cef4fa2d 100644
BOOTPROTO=none
DEFROUTE=yes
DEVICE=eth0
@@ -740,6 +741,7 @@ dns = none
@@ -741,6 +742,7 @@ dns = none
"""
# Created by cloud-init automatically, do not edit.
#
@ -172,7 +178,7 @@ index 052b0674..cef4fa2d 100644
BOOTPROTO=none
DEFROUTE=yes
DEVICE=eth0
@@ -897,6 +899,7 @@ dns = none
@@ -898,6 +900,7 @@ dns = none
"""
# Created by cloud-init automatically, do not edit.
#
@ -180,7 +186,7 @@ index 052b0674..cef4fa2d 100644
BOOTPROTO=none
DEFROUTE=yes
DEVICE=eth0
@@ -1137,6 +1140,7 @@ NETWORK_CONFIGS = {
@@ -1138,6 +1141,7 @@ NETWORK_CONFIGS = {
"expected_sysconfig_rhel": {
"ifcfg-eth1": textwrap.dedent(
"""\
@ -188,7 +194,7 @@ index 052b0674..cef4fa2d 100644
BOOTPROTO=none
DEVICE=eth1
HWADDR=cf:d6:af:48:e8:80
@@ -1146,6 +1150,7 @@ NETWORK_CONFIGS = {
@@ -1147,6 +1151,7 @@ NETWORK_CONFIGS = {
),
"ifcfg-eth99": textwrap.dedent(
"""\
@ -196,7 +202,7 @@ index 052b0674..cef4fa2d 100644
BOOTPROTO=dhcp
DEFROUTE=yes
DEVICE=eth99
@@ -1311,6 +1316,7 @@ NETWORK_CONFIGS = {
@@ -1310,6 +1315,7 @@ NETWORK_CONFIGS = {
"expected_sysconfig_rhel": {
"ifcfg-eth1": textwrap.dedent(
"""\
@ -204,7 +210,7 @@ index 052b0674..cef4fa2d 100644
BOOTPROTO=none
DEVICE=eth1
HWADDR=cf:d6:af:48:e8:80
@@ -1320,6 +1326,7 @@ NETWORK_CONFIGS = {
@@ -1319,6 +1325,7 @@ NETWORK_CONFIGS = {
),
"ifcfg-eth99": textwrap.dedent(
"""\
@ -212,7 +218,7 @@ index 052b0674..cef4fa2d 100644
BOOTPROTO=dhcp
DEFROUTE=yes
DEVICE=eth99
@@ -1566,6 +1573,7 @@ NETWORK_CONFIGS = {
@@ -1565,6 +1572,7 @@ NETWORK_CONFIGS = {
"expected_sysconfig_rhel": {
"ifcfg-iface0": textwrap.dedent(
"""\
@ -220,7 +226,7 @@ index 052b0674..cef4fa2d 100644
BOOTPROTO=none
DEVICE=iface0
IPADDR=192.168.14.2
@@ -1712,6 +1720,7 @@ NETWORK_CONFIGS = {
@@ -1711,6 +1719,7 @@ NETWORK_CONFIGS = {
"expected_sysconfig_rhel": {
"ifcfg-iface0": textwrap.dedent(
"""\
@ -228,7 +234,7 @@ index 052b0674..cef4fa2d 100644
BOOTPROTO=none
DEVICE=iface0
DHCPV6C=yes
@@ -1801,6 +1810,7 @@ NETWORK_CONFIGS = {
@@ -1800,6 +1809,7 @@ NETWORK_CONFIGS = {
"expected_sysconfig_rhel": {
"ifcfg-iface0": textwrap.dedent(
"""\
@ -236,7 +242,7 @@ index 052b0674..cef4fa2d 100644
BOOTPROTO=none
DEVICE=iface0
DHCPV6C=yes
@@ -1876,6 +1886,7 @@ NETWORK_CONFIGS = {
@@ -1875,6 +1885,7 @@ NETWORK_CONFIGS = {
"expected_sysconfig_rhel": {
"ifcfg-iface0": textwrap.dedent(
"""\
@ -244,7 +250,7 @@ index 052b0674..cef4fa2d 100644
BOOTPROTO=none
DEVICE=iface0
DHCPV6C=yes
@@ -1940,6 +1951,7 @@ NETWORK_CONFIGS = {
@@ -1939,6 +1950,7 @@ NETWORK_CONFIGS = {
"expected_sysconfig_rhel": {
"ifcfg-iface0": textwrap.dedent(
"""\
@ -252,7 +258,7 @@ index 052b0674..cef4fa2d 100644
BOOTPROTO=none
DEVICE=iface0
IPV6_AUTOCONF=yes
@@ -1995,6 +2007,7 @@ NETWORK_CONFIGS = {
@@ -1994,6 +2006,7 @@ NETWORK_CONFIGS = {
"expected_sysconfig_rhel": {
"ifcfg-iface0": textwrap.dedent(
"""\
@ -260,7 +266,7 @@ index 052b0674..cef4fa2d 100644
BOOTPROTO=none
DEVICE=iface0
IPV6ADDR=2001:1::1/64
@@ -2051,6 +2064,7 @@ NETWORK_CONFIGS = {
@@ -2050,6 +2063,7 @@ NETWORK_CONFIGS = {
"expected_sysconfig_rhel": {
"ifcfg-iface0": textwrap.dedent(
"""\
@ -268,7 +274,7 @@ index 052b0674..cef4fa2d 100644
BOOTPROTO=none
DEVICE=iface0
DHCPV6C=yes
@@ -2135,6 +2149,7 @@ NETWORK_CONFIGS = {
@@ -2134,6 +2148,7 @@ NETWORK_CONFIGS = {
"expected_sysconfig_rhel": {
"ifcfg-iface0": textwrap.dedent(
"""\
@ -276,7 +282,7 @@ index 052b0674..cef4fa2d 100644
BOOTPROTO=none
DEVICE=iface0
DHCPV6C=yes
@@ -2181,6 +2196,7 @@ NETWORK_CONFIGS = {
@@ -2180,6 +2195,7 @@ NETWORK_CONFIGS = {
"expected_sysconfig_rhel": {
"ifcfg-iface0": textwrap.dedent(
"""\
@ -284,7 +290,7 @@ index 052b0674..cef4fa2d 100644
BOOTPROTO=dhcp
DEVICE=iface0
ONBOOT=yes
@@ -2256,6 +2272,7 @@ NETWORK_CONFIGS = {
@@ -2255,6 +2271,7 @@ NETWORK_CONFIGS = {
"expected_sysconfig_rhel": {
"ifcfg-iface0": textwrap.dedent(
"""\
@ -292,7 +298,7 @@ index 052b0674..cef4fa2d 100644
BOOTPROTO=dhcp
DEVICE=iface0
ETHTOOL_OPTS="wol g"
@@ -2591,6 +2608,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
@@ -2590,6 +2607,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
"expected_sysconfig_rhel": {
"ifcfg-bond0": textwrap.dedent(
"""\
@ -300,7 +306,7 @@ index 052b0674..cef4fa2d 100644
BONDING_MASTER=yes
BONDING_OPTS="mode=active-backup """
"""xmit_hash_policy=layer3+4 """
@@ -2608,6 +2626,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
@@ -2607,6 +2625,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
),
"ifcfg-bond0.200": textwrap.dedent(
"""\
@ -308,7 +314,7 @@ index 052b0674..cef4fa2d 100644
BOOTPROTO=dhcp
DEVICE=bond0.200
DHCLIENT_SET_DEFAULT_ROUTE=no
@@ -2619,6 +2638,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
@@ -2618,6 +2637,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
"ifcfg-br0": textwrap.dedent(
"""\
AGEING=250
@ -316,7 +322,7 @@ index 052b0674..cef4fa2d 100644
BOOTPROTO=none
DEFROUTE=yes
DEVICE=br0
@@ -2638,6 +2658,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
@@ -2637,6 +2657,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
),
"ifcfg-eth0": textwrap.dedent(
"""\
@ -324,7 +330,7 @@ index 052b0674..cef4fa2d 100644
BOOTPROTO=none
DEVICE=eth0
HWADDR=c0:d6:9f:2c:e8:80
@@ -2647,6 +2668,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
@@ -2646,6 +2667,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
),
"ifcfg-eth0.101": textwrap.dedent(
"""\
@ -332,7 +338,7 @@ index 052b0674..cef4fa2d 100644
BOOTPROTO=none
DEFROUTE=yes
DEVICE=eth0.101
@@ -2666,6 +2688,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
@@ -2665,6 +2687,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
),
"ifcfg-eth1": textwrap.dedent(
"""\
@ -340,7 +346,7 @@ index 052b0674..cef4fa2d 100644
BOOTPROTO=none
DEVICE=eth1
HWADDR=aa:d6:9f:2c:e8:80
@@ -2677,6 +2700,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
@@ -2676,6 +2699,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
),
"ifcfg-eth2": textwrap.dedent(
"""\
@ -348,7 +354,7 @@ index 052b0674..cef4fa2d 100644
BOOTPROTO=none
DEVICE=eth2
HWADDR=c0:bb:9f:2c:e8:80
@@ -2688,6 +2712,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
@@ -2687,6 +2711,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
),
"ifcfg-eth3": textwrap.dedent(
"""\
@ -356,7 +362,7 @@ index 052b0674..cef4fa2d 100644
BOOTPROTO=none
BRIDGE=br0
DEVICE=eth3
@@ -2698,6 +2723,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
@@ -2697,6 +2722,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
),
"ifcfg-eth4": textwrap.dedent(
"""\
@ -364,7 +370,7 @@ index 052b0674..cef4fa2d 100644
BOOTPROTO=none
BRIDGE=br0
DEVICE=eth4
@@ -2708,6 +2734,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
@@ -2707,6 +2733,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
),
"ifcfg-eth5": textwrap.dedent(
"""\
@ -372,7 +378,7 @@ index 052b0674..cef4fa2d 100644
BOOTPROTO=dhcp
DEVICE=eth5
DHCLIENT_SET_DEFAULT_ROUTE=no
@@ -2718,6 +2745,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
@@ -2717,6 +2744,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
),
"ifcfg-ib0": textwrap.dedent(
"""\
@ -380,7 +386,7 @@ index 052b0674..cef4fa2d 100644
BOOTPROTO=none
DEVICE=ib0
HWADDR=a0:00:02:20:fe:80:00:00:00:00:00:00:ec:0d:9a:03:00:15:e2:c1
@@ -3422,6 +3450,7 @@ iface bond0 inet6 static
@@ -3431,6 +3459,7 @@ iface bond0 inet6 static
"expected_sysconfig_rhel": {
"ifcfg-bond0": textwrap.dedent(
"""\
@ -388,7 +394,7 @@ index 052b0674..cef4fa2d 100644
BONDING_MASTER=yes
BONDING_OPTS="mode=active-backup xmit_hash_policy=layer3+4 """
"""miimon=100 num_grat_arp=5 """
@@ -3452,6 +3481,7 @@ iface bond0 inet6 static
@@ -3461,6 +3490,7 @@ iface bond0 inet6 static
),
"ifcfg-bond0s0": textwrap.dedent(
"""\
@ -396,7 +402,7 @@ index 052b0674..cef4fa2d 100644
BOOTPROTO=none
DEVICE=bond0s0
HWADDR=aa:bb:cc:dd:e8:00
@@ -3479,6 +3509,7 @@ iface bond0 inet6 static
@@ -3488,6 +3518,7 @@ iface bond0 inet6 static
),
"ifcfg-bond0s1": textwrap.dedent(
"""\
@ -404,7 +410,7 @@ index 052b0674..cef4fa2d 100644
BOOTPROTO=none
DEVICE=bond0s1
HWADDR=aa:bb:cc:dd:e8:01
@@ -3628,6 +3659,7 @@ iface bond0 inet6 static
@@ -3637,6 +3668,7 @@ iface bond0 inet6 static
"expected_sysconfig_rhel": {
"ifcfg-en0": textwrap.dedent(
"""\
@ -412,7 +418,7 @@ index 052b0674..cef4fa2d 100644
BOOTPROTO=none
DEVICE=en0
HWADDR=aa:bb:cc:dd:e8:00
@@ -3637,6 +3669,7 @@ iface bond0 inet6 static
@@ -3646,6 +3678,7 @@ iface bond0 inet6 static
),
"ifcfg-en0.99": textwrap.dedent(
"""\
@ -420,7 +426,7 @@ index 052b0674..cef4fa2d 100644
BOOTPROTO=none
DEFROUTE=yes
DEVICE=en0.99
@@ -3774,6 +3807,7 @@ iface bond0 inet6 static
@@ -3783,6 +3816,7 @@ iface bond0 inet6 static
"expected_sysconfig_rhel": {
"ifcfg-br0": textwrap.dedent(
"""\
@ -428,7 +434,7 @@ index 052b0674..cef4fa2d 100644
BOOTPROTO=none
DEVICE=br0
IPADDR=192.168.2.2
@@ -3787,6 +3821,7 @@ iface bond0 inet6 static
@@ -3796,6 +3830,7 @@ iface bond0 inet6 static
),
"ifcfg-eth0": textwrap.dedent(
"""\
@ -436,7 +442,7 @@ index 052b0674..cef4fa2d 100644
BOOTPROTO=none
BRIDGE=br0
DEVICE=eth0
@@ -3802,6 +3837,7 @@ iface bond0 inet6 static
@@ -3811,6 +3846,7 @@ iface bond0 inet6 static
),
"ifcfg-eth1": textwrap.dedent(
"""\
@ -444,7 +450,7 @@ index 052b0674..cef4fa2d 100644
BOOTPROTO=none
BRIDGE=br0
DEVICE=eth1
@@ -3989,6 +4025,7 @@ iface bond0 inet6 static
@@ -3998,6 +4034,7 @@ iface bond0 inet6 static
"expected_sysconfig_rhel": {
"ifcfg-eth0": textwrap.dedent(
"""\
@ -452,7 +458,7 @@ index 052b0674..cef4fa2d 100644
BOOTPROTO=none
DEVICE=eth0
HWADDR=52:54:00:12:34:00
@@ -4001,6 +4038,7 @@ iface bond0 inet6 static
@@ -4010,6 +4047,7 @@ iface bond0 inet6 static
),
"ifcfg-eth1": textwrap.dedent(
"""\
@ -460,7 +466,7 @@ index 052b0674..cef4fa2d 100644
BOOTPROTO=none
DEVICE=eth1
HWADDR=52:54:00:12:34:aa
@@ -4012,6 +4050,7 @@ iface bond0 inet6 static
@@ -4021,6 +4059,7 @@ iface bond0 inet6 static
),
"ifcfg-eth2": textwrap.dedent(
"""\
@ -468,7 +474,7 @@ index 052b0674..cef4fa2d 100644
BOOTPROTO=none
DEVICE=eth2
HWADDR=52:54:00:12:34:ff
@@ -4096,6 +4135,7 @@ iface bond0 inet6 static
@@ -4268,6 +4307,7 @@ iface bond0 inet6 static
"expected_sysconfig_rhel": {
"ifcfg-eth0": textwrap.dedent(
"""\
@ -476,15 +482,23 @@ index 052b0674..cef4fa2d 100644
BOOTPROTO=none
DEVICE=eth0
HWADDR=cf:d6:af:48:e8:80
@@ -4693,6 +4733,7 @@ class TestRhelSysConfigRendering(CiTestCase):
@@ -4419,6 +4459,7 @@ iface bond0 inet6 static
"""\
# Created by cloud-init automatically, do not edit.
#
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEVICE=eth0
DNS1=8.8.8.8
@@ -5185,6 +5226,7 @@ class TestRhelSysConfigRendering(CiTestCase):
expected_content = """
# Created by cloud-init automatically, do not edit.
#
+AUTOCONNECT_PRIORITY=120
BOOTPROTO=dhcp
DEVICE=eth1000
HWADDR=07-1c-c6-75-a4-be
@@ -4900,6 +4941,7 @@ USERCTL=no
DHCPV6C=yes
@@ -5394,6 +5436,7 @@ USERCTL=no
expected = """\
# Created by cloud-init automatically, do not edit.
#
@ -492,7 +506,7 @@ index 052b0674..cef4fa2d 100644
BOOTPROTO=none
DEFROUTE=yes
DEVICE=interface0
@@ -4929,6 +4971,7 @@ USERCTL=no
@@ -5423,6 +5466,7 @@ USERCTL=no
expected_i1 = """\
# Created by cloud-init automatically, do not edit.
#
@ -500,7 +514,7 @@ index 052b0674..cef4fa2d 100644
BOOTPROTO=none
DEFROUTE=yes
DEVICE=eth0
@@ -4945,6 +4988,7 @@ USERCTL=no
@@ -5439,6 +5483,7 @@ USERCTL=no
expected_i2 = """\
# Created by cloud-init automatically, do not edit.
#
@ -508,7 +522,7 @@ index 052b0674..cef4fa2d 100644
BOOTPROTO=dhcp
DEVICE=eth1
DHCLIENT_SET_DEFAULT_ROUTE=no
@@ -4972,6 +5016,7 @@ USERCTL=no
@@ -5466,6 +5511,7 @@ USERCTL=no
expected = """\
# Created by cloud-init automatically, do not edit.
#
@ -516,7 +530,7 @@ index 052b0674..cef4fa2d 100644
BOOTPROTO=dhcp
DEVICE=eth0
ONBOOT=yes
@@ -5191,6 +5236,7 @@ USERCTL=no
@@ -5699,6 +5745,7 @@ USERCTL=no
"expected_sysconfig": {
"ifcfg-ens3": textwrap.dedent(
"""\
@ -524,7 +538,7 @@ index 052b0674..cef4fa2d 100644
BOOTPROTO=none
DEFROUTE=yes
DEVICE=ens3
@@ -5235,6 +5281,7 @@ USERCTL=no
@@ -5743,6 +5790,7 @@ USERCTL=no
expected = {
"ifcfg-eno1": textwrap.dedent(
"""\
@ -532,7 +546,7 @@ index 052b0674..cef4fa2d 100644
BOOTPROTO=none
DEVICE=eno1
ONBOOT=yes
@@ -5244,6 +5291,7 @@ USERCTL=no
@@ -5752,6 +5800,7 @@ USERCTL=no
),
"ifcfg-eno1.1000": textwrap.dedent(
"""\
@ -540,7 +554,7 @@ index 052b0674..cef4fa2d 100644
BOOTPROTO=none
DEVICE=eno1.1000
IPADDR=192.6.1.9
@@ -5276,6 +5324,7 @@ USERCTL=no
@@ -5784,6 +5833,7 @@ USERCTL=no
expected = {
"ifcfg-bond0": textwrap.dedent(
"""\
@ -548,7 +562,7 @@ index 052b0674..cef4fa2d 100644
BONDING_MASTER=yes
BONDING_SLAVE0=enp0s0
BONDING_SLAVE1=enp0s1
@@ -5291,6 +5340,7 @@ USERCTL=no
@@ -5799,6 +5849,7 @@ USERCTL=no
),
"ifcfg-enp0s0": textwrap.dedent(
"""\
@ -556,7 +570,7 @@ index 052b0674..cef4fa2d 100644
BONDING_MASTER=yes
BOOTPROTO=none
DEVICE=enp0s0
@@ -5303,6 +5353,7 @@ USERCTL=no
@@ -5811,6 +5862,7 @@ USERCTL=no
),
"ifcfg-enp0s1": textwrap.dedent(
"""\
@ -564,7 +578,7 @@ index 052b0674..cef4fa2d 100644
BONDING_MASTER=yes
BOOTPROTO=none
DEVICE=enp0s1
@@ -5333,6 +5384,7 @@ USERCTL=no
@@ -5841,6 +5893,7 @@ USERCTL=no
expected = {
"ifcfg-eno1": textwrap.dedent(
"""\
@ -572,7 +586,7 @@ index 052b0674..cef4fa2d 100644
BOOTPROTO=dhcp
DEVICE=eno1
HWADDR=07-1c-c6-75-a4-be
@@ -5411,6 +5463,7 @@ USERCTL=no
@@ -5919,6 +5972,7 @@ USERCTL=no
"""\
# Created by cloud-init automatically, do not edit.
#

@ -1,140 +0,0 @@
From 5fa8113a9efaa90f293b95477c4fa44e3d4b6537 Mon Sep 17 00:00:00 2001
From: Ani Sinha <anisinha@redhat.com>
Date: Thu, 23 Nov 2023 12:27:51 +0530
Subject: [PATCH] net/network_manager: do not set "may-fail" to False for both
ipv4 and ipv6 dhcp
If "may-fail" is set to False in the Network Manager keyfile for both ipv4
and ipv6 for dhcp configuration, it essentially means both ipv4 and ipv6 network
initialization using dhcp must succeed for the overall network configuration to
succeed. This means, for environments where only ipv4 or ipv6 is available but
not both and we need to configure both ipv4 and ipv6 dhcp, the overall
network configuration will fail. This is not what we want. When both ipv4
and ipv6 dhcp are configured, it is enough for the overall configuration to
succeed if any one succeeds.
Therefore, set "may-fail" to True for both ipv4 and ipv6 if and only if both
ipv4 and ipv6 are configured as dhcp in the Network Manager keyfile and
"may-fail" is set to False for both. If both ipv4 and ipv6 are configured
in the keyfile and if for any of them "may-fail" is already set to True,then
do nothing.
All other cases remain same as before.
Please see discussions in PR #4474.
Co-authored-by: James Falcon <james.falcon@canonical.com>
Signed-off-by: Ani Sinha <anisinha@redhat.com>
(cherry picked from commit 29dd5ace73ad60c7452c39b840045fb47fe0711f)
---
cloudinit/net/network_manager.py | 59 ++++++++++++++++++++++++++++++++
tests/unittests/test_net.py | 8 ++---
2 files changed, 63 insertions(+), 4 deletions(-)
diff --git a/cloudinit/net/network_manager.py b/cloudinit/net/network_manager.py
index 8374cfcc..8a99eb3a 100644
--- a/cloudinit/net/network_manager.py
+++ b/cloudinit/net/network_manager.py
@@ -71,6 +71,57 @@ class NMConnection:
if not self.config.has_option(section, option):
self.config[section][option] = value
+ def _config_option_is_set(self, section, option):
+ """
+ Checks if a config option is set. Returns True if it is,
+ else returns False.
+ """
+ return self.config.has_section(section) and self.config.has_option(
+ section, option
+ )
+
+ def _get_config_option(self, section, option):
+ """
+ Returns the value of a config option if its set,
+ else returns None.
+ """
+ if self._config_option_is_set(section, option):
+ return self.config[section][option]
+ else:
+ return None
+
+ def _change_set_config_option(self, section, option, value):
+ """
+ Overrides the value of a config option if its already set.
+ Else, if the config option is not set, it does nothing.
+ """
+ if self._config_option_is_set(section, option):
+ self.config[section][option] = value
+
+ def _set_mayfail_true_if_both_false_dhcp(self):
+ """
+ If for both ipv4 and ipv6, 'may-fail' is set to be False,
+ set it to True for both of them.
+ """
+ for family in ["ipv4", "ipv6"]:
+ if self._get_config_option(family, "may-fail") != "false":
+ # if either ipv4 or ipv6 sections are not set/configured,
+ # or if both are configured but for either ipv4 or ipv6,
+ # 'may-fail' is not 'false', do not do anything.
+ return
+ if self._get_config_option(family, "method") not in [
+ "dhcp",
+ "auto",
+ ]:
+ # if both v4 and v6 are not dhcp, do not do anything.
+ return
+
+ # If we landed here, it means both ipv4 and ipv6 are configured
+ # with dhcp/auto and both have 'may-fail' set to 'false'. So set
+ # both to 'true'.
+ for family in ["ipv4", "ipv6"]:
+ self._change_set_config_option(family, "may-fail", "true")
+
def _set_ip_method(self, family, subnet_type):
"""
Ensures there's appropriate [ipv4]/[ipv6] for given family
@@ -271,6 +322,14 @@ class NMConnection:
if family == "ipv4" and "mtu" in subnet:
ipv4_mtu = subnet["mtu"]
+ # we do not want to set may-fail to false for both ipv4 and ipv6 dhcp
+ # at the at the same time. This will make the network configuration
+ # work only when both ipv4 and ipv6 dhcp succeeds. This may not be
+ # what we want. If we have configured both ipv4 and ipv6 dhcp, any one
+ # succeeding should be enough. Therefore, if "may-fail" is set to
+ # False for both ipv4 and ipv6 dhcp, set them both to True.
+ self._set_mayfail_true_if_both_false_dhcp()
+
if ipv4_mtu is None:
ipv4_mtu = device_mtu
if not ipv4_mtu == device_mtu:
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
index cef4fa2d..fb4c863c 100644
--- a/tests/unittests/test_net.py
+++ b/tests/unittests/test_net.py
@@ -1477,11 +1477,11 @@ NETWORK_CONFIGS = {
[ipv4]
method=auto
- may-fail=false
+ may-fail=true
[ipv6]
method=auto
- may-fail=false
+ may-fail=true
"""
),
@@ -1650,11 +1650,11 @@ NETWORK_CONFIGS = {
[ipv6]
method=auto
- may-fail=false
+ may-fail=true
[ipv4]
method=auto
- may-fail=false
+ may-fail=true
"""
),

@ -0,0 +1,26 @@
From 5745b21c9e9e47478b8920e3ccf5e82afffefcdf Mon Sep 17 00:00:00 2001
From: Brett Holman <brett.holman@canonical.com>
Date: Tue, 26 Mar 2024 15:00:41 -0500
Subject: [PATCH] feat: Use NetworkManager renderer by default in RHEL family
See upstream GH: https://github.com/canonical/cloud-init/pull/5089
(cherry picked from commit 97537494d95f733fce260beb5a2d465cccf9f6c7)
Signed-off-by: Ani Sinha <anisinha@redhat.com>
---
config/cloud.cfg.tmpl | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/config/cloud.cfg.tmpl b/config/cloud.cfg.tmpl
index 0e785dbe..a4701209 100644
--- a/config/cloud.cfg.tmpl
+++ b/config/cloud.cfg.tmpl
@@ -306,7 +306,7 @@ system_info:
activators: ['netplan', 'eni', 'network-manager', 'networkd']
{% elif is_rhel %}
network:
- renderers: ['sysconfig', 'eni', 'netplan', 'network-manager', 'networkd']
+ renderers: ['eni', 'netplan', 'network-manager', 'sysconfig', 'networkd']
{% endif %}
{% if variant == "photon" %}
# If set to true, cloud-init will not use fallback network config.

@ -1,172 +0,0 @@
From 54e87eaad7841270e530beff2dcfe68292ae87ef Mon Sep 17 00:00:00 2001
From: Ani Sinha <anisinha@redhat.com>
Date: Tue, 21 Nov 2023 13:57:15 +0530
Subject: [PATCH] net: allow dhcp6 configuration from
generate_fallback_configuration()
This will make sure on Azure we can use both dhcp4 and dhcp6 when IMDS is not
used. This is useful in situations where only ipv6 network is available and
there is no dhcp4 running.
This change is mostly a reversal of commit 29ed5f5b646ee and therefore,
re-application of the commit 518047aea9 with some small changes.
The issue that caused the reversal of 518047aea9 is fixed by the earlier commit:
cab0eaf290af7 ("net/network_manager: do not set "may-fail" to False for both ipv4 and ipv6 dhcp")
Fixes GH-4439
Signed-off-by: Ani Sinha <anisinha@redhat.com>
(cherry picked from commit 0264e969166846b2f5cf87ccdb051a3a795eca15)
---
cloudinit/net/__init__.py | 7 ++++++-
tests/unittests/net/test_init.py | 4 ++++
tests/unittests/test_net.py | 24 +++++++++++++++++++++---
3 files changed, 31 insertions(+), 4 deletions(-)
diff --git a/cloudinit/net/__init__.py b/cloudinit/net/__init__.py
index bf21633b..c0888f52 100644
--- a/cloudinit/net/__init__.py
+++ b/cloudinit/net/__init__.py
@@ -571,7 +571,12 @@ def generate_fallback_config(config_driver=None):
match = {
"macaddress": read_sys_net_safe(target_name, "address").lower()
}
- cfg = {"dhcp4": True, "set-name": target_name, "match": match}
+ cfg = {
+ "dhcp4": True,
+ "dhcp6": True,
+ "set-name": target_name,
+ "match": match,
+ }
if config_driver:
driver = device_driver(target_name)
if driver:
diff --git a/tests/unittests/net/test_init.py b/tests/unittests/net/test_init.py
index 561d5151..60a44186 100644
--- a/tests/unittests/net/test_init.py
+++ b/tests/unittests/net/test_init.py
@@ -261,6 +261,7 @@ class TestGenerateFallbackConfig(CiTestCase):
"eth1": {
"match": {"macaddress": mac},
"dhcp4": True,
+ "dhcp6": True,
"set-name": "eth1",
}
},
@@ -278,6 +279,7 @@ class TestGenerateFallbackConfig(CiTestCase):
"eth0": {
"match": {"macaddress": mac},
"dhcp4": True,
+ "dhcp6": True,
"set-name": "eth0",
}
},
@@ -293,6 +295,7 @@ class TestGenerateFallbackConfig(CiTestCase):
"ethernets": {
"eth0": {
"dhcp4": True,
+ "dhcp6": True,
"match": {"macaddress": mac},
"set-name": "eth0",
}
@@ -359,6 +362,7 @@ class TestGenerateFallbackConfig(CiTestCase):
"ethernets": {
"ens3": {
"dhcp4": True,
+ "dhcp6": True,
"match": {"name": "ens3"},
"set-name": "ens3",
}
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
index fb4c863c..d9ef493b 100644
--- a/tests/unittests/test_net.py
+++ b/tests/unittests/test_net.py
@@ -4339,6 +4339,7 @@ class TestGenerateFallbackConfig(CiTestCase):
"ethernets": {
"eth0": {
"dhcp4": True,
+ "dhcp6": True,
"set-name": "eth0",
"match": {
"macaddress": "00:11:22:33:44:55",
@@ -4423,6 +4424,9 @@ iface lo inet loopback
auto eth0
iface eth0 inet dhcp
+
+# control-alias eth0
+iface eth0 inet6 dhcp
"""
self.assertEqual(expected.lstrip(), contents.lstrip())
@@ -4512,6 +4516,9 @@ iface lo inet loopback
auto eth1
iface eth1 inet dhcp
+
+# control-alias eth1
+iface eth1 inet6 dhcp
"""
self.assertEqual(expected.lstrip(), contents.lstrip())
@@ -4736,7 +4743,9 @@ class TestRhelSysConfigRendering(CiTestCase):
AUTOCONNECT_PRIORITY=120
BOOTPROTO=dhcp
DEVICE=eth1000
+DHCPV6C=yes
HWADDR=07-1c-c6-75-a4-be
+IPV6INIT=yes
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -5646,7 +5655,8 @@ class TestOpenSuseSysConfigRendering(CiTestCase):
expected_content = """
# Created by cloud-init automatically, do not edit.
#
-BOOTPROTO=dhcp4
+BOOTPROTO=dhcp
+DHCLIENT6_MODE=managed
LLADDR=07-1c-c6-75-a4-be
STARTMODE=auto
""".lstrip()
@@ -6032,7 +6042,11 @@ class TestNetworkManagerRendering(CiTestCase):
[ipv4]
method=auto
- may-fail=false
+ may-fail=true
+
+ [ipv6]
+ method=auto
+ may-fail=true
"""
),
@@ -6298,6 +6312,9 @@ iface lo inet loopback
auto eth1000
iface eth1000 inet dhcp
+
+# control-alias eth1000
+iface eth1000 inet6 dhcp
"""
self.assertEqual(expected.lstrip(), contents.lstrip())
@@ -6357,6 +6374,7 @@ class TestNetplanNetRendering:
ethernets:
eth1000:
dhcp4: true
+ dhcp6: true
match:
macaddress: 07-1c-c6-75-a4-be
set-name: eth1000
@@ -7856,7 +7874,7 @@ class TestNetworkdNetRendering(CiTestCase):
Name=eth1000
MACAddress=07-1c-c6-75-a4-be
[Network]
- DHCP=ipv4"""
+ DHCP=yes"""
).rstrip(" ")
expected = self.create_conf_dict(expected.splitlines())

@ -1,113 +0,0 @@
From c0df864e373e1e34bf23c4869acdf7d20aea7aaf Mon Sep 17 00:00:00 2001
From: Ani Sinha <anisinha@redhat.com>
Date: Thu, 7 Dec 2023 02:39:51 +0530
Subject: [PATCH] net/nm: check for presence of ifcfg files when nm connection
files are absent (#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: GH-4640
Signed-off-by: Ani Sinha <anisinha@redhat.com>
(cherry picked from commit d1d5166895da471cff3606c70d4e8ab6eec1c006)
---
cloudinit/net/activators.py | 7 +++++++
cloudinit/net/network_manager.py | 33 ++++++++++++++++++++++++++++++--
2 files changed, 38 insertions(+), 2 deletions(-)
diff --git a/cloudinit/net/activators.py b/cloudinit/net/activators.py
index e69da40d..dd858862 100644
--- a/cloudinit/net/activators.py
+++ b/cloudinit/net/activators.py
@@ -117,6 +117,13 @@ class NetworkManagerActivator(NetworkActivator):
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]
diff --git a/cloudinit/net/network_manager.py b/cloudinit/net/network_manager.py
index 8a99eb3a..76a0ac15 100644
--- a/cloudinit/net/network_manager.py
+++ b/cloudinit/net/network_manager.py
@@ -17,10 +17,12 @@ from typing import Optional
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]
@@ -442,7 +444,7 @@ class Renderer(renderer.Renderer):
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
@@ -452,12 +454,39 @@ class Renderer(renderer.Renderer):
)
-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"

@ -1,38 +0,0 @@
From e5258b60a3dbf44ef1faac91db2b45dab09de0b5 Mon Sep 17 00:00:00 2001
From: Brett Holman <brett.holman@canonical.com>
Date: Tue, 16 Jan 2024 12:43:17 -0700
Subject: [PATCH] test(jsonschema): Pin jsonschema version (#4781)
Release 4.21.0 broke tests
(cherry picked from commit 034a5cdf10582da0492321f861b2b8b42182a54e)
---
requirements.txt | 2 +-
test-requirements.txt | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/requirements.txt b/requirements.txt
index edec46a7..a095de18 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -28,7 +28,7 @@ requests
jsonpatch
# For validating cloud-config sections per schema definitions
-jsonschema
+jsonschema<=4.20.0
# Used by DataSourceVMware to inspect the host's network configuration during
# the "setup()" function.
diff --git a/test-requirements.txt b/test-requirements.txt
index 19488b94..46a98b4c 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -9,6 +9,6 @@ pytest!=7.3.2
pytest-cov
pytest-mock
setuptools
-jsonschema
+jsonschema<=4.20.0
responses
passlib

@ -1,121 +0,0 @@
From 9e8fbb736d5e8db8bcf0fbc35a76bdad9251990a Mon Sep 17 00:00:00 2001
From: d1r3ct0r <calvin.mwadime@canonical.com>
Date: Sat, 20 Jan 2024 02:11:47 +0300
Subject: [PATCH] fix(clean): stop warning when running clean command (#4761)
When the clean command is run, runparts is called and README in
/etc/cloud/clean.d is not executable which leads to a warning.
No longer deliver the README in our deb package, move content
to our online docs. Continue to deliver the /etc/cloud/clean.d
directory as it is used by installers like subiquity.
Fixes: GH-4760
(cherry picked from commit da08a260965e35fa63def1cd8b8b472f7c354ffe)
There is a downstream only change that is squashed with the upstream commit.
The spec file under .distro/ has been updated so as to not include
/etc/cloud/clean.d/README file. Otherwise, we shall see errors like the
following during the build process:
error: File not found: /builddir/build/.../etc/cloud/clean.d/README
After a rebase, we can only maintain the downstream spec file change as
the rest of it is clean cherry-pick from upstream.
X-downstream-only: true
Signed-off-by: Ani Sinha <anisinha@redhat.com>
---
config/clean.d/README | 18 ------------------
doc/rtd/reference/cli.rst | 27 +++++++++++++++++++++++++++
packages/redhat/cloud-init.spec.in | 1 -
packages/suse/cloud-init.spec.in | 1 -
4 files changed, 27 insertions(+), 20 deletions(-)
delete mode 100644 config/clean.d/README
diff --git a/config/clean.d/README b/config/clean.d/README
deleted file mode 100644
index 9b0feebe..00000000
--- a/config/clean.d/README
+++ /dev/null
@@ -1,18 +0,0 @@
--- cloud-init's clean.d run-parts directory --
-
-This directory is provided for third party applications which need
-additional configuration artifact cleanup from the filesystem when
-the command `cloud-init clean` is invoked.
-
-The `cloud-init clean` operation is typically performed by image creators
-when preparing a golden image for clone and redeployment. The clean command
-removes any cloud-init semaphores, allowing cloud-init to treat the next
-boot of this image as the "first boot". When the image is next booted
-cloud-init will performing all initial configuration based on any valid
-datasource meta-data and user-data.
-
-Any executable scripts in this subdirectory will be invoked in lexicographical
-order with run-parts by the command: sudo cloud-init clean.
-
-Typical format of such scripts would be a ##-<some-app> like the following:
- /etc/cloud/clean.d/99-live-installer
diff --git a/doc/rtd/reference/cli.rst b/doc/rtd/reference/cli.rst
index 04e05c55..c36775a8 100644
--- a/doc/rtd/reference/cli.rst
+++ b/doc/rtd/reference/cli.rst
@@ -83,6 +83,33 @@ re-run all stages as it did on first boot.
config files for ssh daemon. Argument `network` removes all generated
config files for network. `all` removes config files of all types.
+.. note::
+
+ Cloud-init provides the directory :file:`/etc/cloud/clean.d/` for third party
+ applications which need additional configuration artifact cleanup from
+ the fileystem when the `clean` command is invoked.
+
+ The :command:`clean` operation is typically performed by image creators
+ when preparing a golden image for clone and redeployment. The clean command
+ removes any cloud-init semaphores, allowing cloud-init to treat the next
+ boot of this image as the "first boot". When the image is next booted
+ cloud-init will performing all initial configuration based on any valid
+ datasource meta-data and user-data.
+
+ Any executable scripts in this subdirectory will be invoked in lexicographical
+ order with run-parts when running the :command:`clean` command.
+
+ Typical format of such scripts would be a ##-<some-app> like the following:
+ :file:`/etc/cloud/clean.d/99-live-installer`
+
+ An example of a script is:
+
+ .. code-block:: bash
+
+ sudo rm -rf /var/lib/installer_imgs/
+ sudo rm -rf /var/log/installer/
+
+
.. _cli_collect_logs:
:command:`collect-logs`
diff --git a/packages/redhat/cloud-init.spec.in b/packages/redhat/cloud-init.spec.in
index 97e95096..accfb1b6 100644
--- a/packages/redhat/cloud-init.spec.in
+++ b/packages/redhat/cloud-init.spec.in
@@ -190,7 +190,6 @@ fi
# Configs
%config(noreplace) %{_sysconfdir}/cloud/cloud.cfg
%dir %{_sysconfdir}/cloud/clean.d
-%config(noreplace) %{_sysconfdir}/cloud/clean.d/README
%dir %{_sysconfdir}/cloud/cloud.cfg.d
%config(noreplace) %{_sysconfdir}/cloud/cloud.cfg.d/*.cfg
%config(noreplace) %{_sysconfdir}/cloud/cloud.cfg.d/README
diff --git a/packages/suse/cloud-init.spec.in b/packages/suse/cloud-init.spec.in
index 62a9129b..fae3c12b 100644
--- a/packages/suse/cloud-init.spec.in
+++ b/packages/suse/cloud-init.spec.in
@@ -115,7 +115,6 @@ version_pys=$(cd "%{buildroot}" && find . -name version.py -type f)
# Configs
%dir %{_sysconfdir}/cloud/clean.d
-%config(noreplace) %{_sysconfdir}/cloud/clean.d/README
%config(noreplace) %{_sysconfdir}/cloud/cloud.cfg
%dir %{_sysconfdir}/cloud/cloud.cfg.d
%config(noreplace) %{_sysconfdir}/cloud/cloud.cfg.d/*.cfg

@ -0,0 +1,176 @@
From 86930b77ad18aa8dbad8908ddad8852447db0242 Mon Sep 17 00:00:00 2001
From: PengpengSun <40026211+PengpengSun@users.noreply.github.com>
Date: Tue, 12 Mar 2024 09:26:55 +0800
Subject: [PATCH 3/3] DS VMware: Fix ipv6 addr converter from netinfo to
netifaces (#5029)
RH-Author: Ani Sinha <anisinha@redhat.com>
RH-MergeRequest: 80: refactor: remove dependency on netifaces (#4634)
RH-Jira: RHEL-34518
RH-Acked-by: xiachen <xiachen@redhat.com>
RH-Acked-by: Cathy Avery <cavery@redhat.com>
RH-Commit: [2/2] d718522dec4c77dd153fb239d2d0a6bd9ef581a2 (anisinha/cloud-init)
Found an issue when verifying PR 4634 on vSphere platform,
which is failing to convert ipv6 addr from netinfo format to
netifaces format due to 'bcast' is not existing in ipv6.
This PR is fixing this by updating ipv4 converter function and
adding a new ipv6 converter function, also adding unit tests.
(cherry picked from commit e544a0db82caee17ee19465f8689ce02e564286f)
Signed-off-by: Ani Sinha <anisinha@redhat.com>
---
cloudinit/sources/DataSourceVMware.py | 45 ++++++++++++++++++++------
tests/unittests/sources/test_vmware.py | 33 +++++++++++++++++++
2 files changed, 68 insertions(+), 10 deletions(-)
diff --git a/cloudinit/sources/DataSourceVMware.py b/cloudinit/sources/DataSourceVMware.py
index 6ed6a6a5..888060c9 100644
--- a/cloudinit/sources/DataSourceVMware.py
+++ b/cloudinit/sources/DataSourceVMware.py
@@ -859,19 +859,18 @@ def is_valid_ip_addr(val):
)
-def convert_to_netifaces_format(addr):
+def convert_to_netifaces_ipv4_format(addr: dict) -> dict:
"""
Takes a cloudinit.netinfo formatted address and converts to netifaces
format, since this module was originally written with netifaces as the
network introspection module.
- netifaces format:
+ netifaces ipv4 format:
{
"broadcast": "10.15.255.255",
"netmask": "255.240.0.0",
"addr": "10.0.1.4"
}
-
- cloudinit.netinfo format:
+ cloudinit.netinfo ipv4 format:
{
"ip": "10.0.1.4",
"mask": "255.240.0.0",
@@ -879,10 +878,37 @@ def convert_to_netifaces_format(addr):
"scope": "global",
}
"""
+ if not addr.get("ip"):
+ return {}
+ return {
+ "broadcast": addr.get("bcast"),
+ "netmask": addr.get("mask"),
+ "addr": addr.get("ip"),
+ }
+
+
+def convert_to_netifaces_ipv6_format(addr: dict) -> dict:
+ """
+ Takes a cloudinit.netinfo formatted address and converts to netifaces
+ format, since this module was originally written with netifaces as the
+ network introspection module.
+ netifaces ipv6 format:
+ {
+ "netmask": "ffff:ffff:ffff:ffff::/64",
+ "addr": "2001:db8:abcd:1234::1"
+ }
+ cloudinit.netinfo ipv6 format:
+ {
+ "ip": "2001:db8:abcd:1234::1/64",
+ "scope6": "global",
+ }
+ """
+ if not addr.get("ip"):
+ return {}
+ ipv6 = ipaddress.IPv6Interface(addr.get("ip"))
return {
- "broadcast": addr["bcast"],
- "netmask": addr["mask"],
- "addr": addr["ip"],
+ "netmask": f"{ipv6.netmask}/{ipv6.network.prefixlen}",
+ "addr": str(ipv6.ip),
}
@@ -890,7 +916,6 @@ def get_host_info():
"""
Returns host information such as the host name and network interfaces.
"""
- # TODO(look to promote netifices use up in cloud-init netinfo funcs)
host_info = {
"network": {
"interfaces": {
@@ -921,9 +946,9 @@ def get_host_info():
af_inet4 = []
af_inet6 = []
for addr in ifaces[dev_name]["ipv4"]:
- af_inet4.append(convert_to_netifaces_format(addr))
+ af_inet4.append(convert_to_netifaces_ipv4_format(addr))
for addr in ifaces[dev_name]["ipv6"]:
- af_inet6.append(convert_to_netifaces_format(addr))
+ af_inet6.append(convert_to_netifaces_ipv6_format(addr))
mac = ifaces[dev_name].get("hwaddr")
diff --git a/tests/unittests/sources/test_vmware.py b/tests/unittests/sources/test_vmware.py
index 33193f89..cfeff6d5 100644
--- a/tests/unittests/sources/test_vmware.py
+++ b/tests/unittests/sources/test_vmware.py
@@ -77,6 +77,11 @@ VMW_IPV4_NETDEV_ADDR = {
"mask": "255.255.255.0",
"scope": "global",
}
+VMW_IPV4_NETIFACES_ADDR = {
+ "broadcast": "10.85.130.255",
+ "netmask": "255.255.255.0",
+ "addr": "10.85.130.116",
+}
VMW_IPV6_ROUTEINFO = {
"destination": "::/0",
"flags": "UG",
@@ -88,6 +93,18 @@ VMW_IPV6_NETDEV_ADDR = {
"ip": "fd42:baa2:3dd:17a:216:3eff:fe16:db54/64",
"scope6": "global",
}
+VMW_IPV6_NETIFACES_ADDR = {
+ "netmask": "ffff:ffff:ffff:ffff::/64",
+ "addr": "fd42:baa2:3dd:17a:216:3eff:fe16:db54",
+}
+VMW_IPV6_NETDEV_PEER_ADDR = {
+ "ip": "fd42:baa2:3dd:17a:216:3eff:fe16:db54",
+ "scope6": "global",
+}
+VMW_IPV6_NETIFACES_PEER_ADDR = {
+ "netmask": "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128",
+ "addr": "fd42:baa2:3dd:17a:216:3eff:fe16:db54",
+}
def generate_test_netdev_data(ipv4=None, ipv6=None):
@@ -147,6 +164,22 @@ class TestDataSourceVMware(CiTestCase):
ret = ds.get_data()
self.assertFalse(ret)
+ def test_convert_to_netifaces_ipv4_format(self):
+ netifaces_format = DataSourceVMware.convert_to_netifaces_ipv4_format(
+ VMW_IPV4_NETDEV_ADDR
+ )
+ self.assertEqual(netifaces_format, VMW_IPV4_NETIFACES_ADDR)
+
+ def test_convert_to_netifaces_ipv6_format(self):
+ netifaces_format = DataSourceVMware.convert_to_netifaces_ipv6_format(
+ VMW_IPV6_NETDEV_ADDR
+ )
+ self.assertEqual(netifaces_format, VMW_IPV6_NETIFACES_ADDR)
+ netifaces_format = DataSourceVMware.convert_to_netifaces_ipv6_format(
+ VMW_IPV6_NETDEV_PEER_ADDR
+ )
+ self.assertEqual(netifaces_format, VMW_IPV6_NETIFACES_PEER_ADDR)
+
@mock.patch("cloudinit.sources.DataSourceVMware.get_default_ip_addrs")
def test_get_host_info_ipv4(self, m_fn_ipaddr):
m_fn_ipaddr.return_value = ("10.10.10.1", None)
--
2.39.3

@ -1,4 +1,4 @@
From 808cd6f434a4ede1441cc1f5781abf59f53c4153 Mon Sep 17 00:00:00 2001
From 50c4b5575d9f8d93f1d55448dd59b2fce827e4b9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Anders=20Bj=C3=B6rklund?= <anders.f.bjorklund@gmail.com>
Date: Mon, 22 Apr 2024 17:52:44 +0200
Subject: [PATCH 1/3] Deprecate the users ssh-authorized-keys property (#5162)
@ -7,11 +7,11 @@ Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Ani Sinha <anisinha@redhat.com>
RH-MergeRequest: 95: Deprecate the users ssh-authorized-keys property (#5162)
RH-Jira: RHEL-45262
RH-MergeRequest: 94: Deprecate the users ssh-authorized-keys property (#5162)
RH-Jira: RHEL-45263
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [1/3] 27d6f99519a28ae91037fe47f9ef654b7fbd6236 (anisinha/cloud-init)
RH-Commit: [1/3] 79e1b116a8c60ebe7e70a9670ff7626fb204d6a1 (anisinha/cloud-init)
Deprecate the users ssh-authorized-keys property
@ -24,10 +24,10 @@ Signed-off-by: Anders F Björklund <anders.f.bjorklund@gmail.com>
3 files changed, 47 insertions(+)
diff --git a/cloudinit/config/schemas/schema-cloud-config-v1.json b/cloudinit/config/schemas/schema-cloud-config-v1.json
index 8b10fe70..670ef4c2 100644
index c47e7c4f..24b6c4bd 100644
--- a/cloudinit/config/schemas/schema-cloud-config-v1.json
+++ b/cloudinit/config/schemas/schema-cloud-config-v1.json
@@ -272,6 +272,22 @@
@@ -361,6 +361,22 @@
},
"minItems": 1
},
@ -48,7 +48,7 @@ index 8b10fe70..670ef4c2 100644
+ ]
+ },
"ssh_import_id": {
"description": "List of SSH IDs to import for user. Can not be combined with ``ssh_redirect_user``.",
"description": "List of ssh ids to import for user. Can not be combined with ``ssh_redirect_user``. See the man page[1] for more details. [1] https://manpages.ubuntu.com/manpages/noble/en/man1/ssh-import-id.1.html",
"type": "array",
diff --git a/tests/unittests/config/test_cc_users_groups.py b/tests/unittests/config/test_cc_users_groups.py
index 3300b77b..53e231e1 100644
@ -92,7 +92,7 @@ index 3300b77b..53e231e1 100644
)
@skipUnlessJsonSchema()
diff --git a/tools/.github-cla-signers b/tools/.github-cla-signers
index f4da0989..8b119025 100644
index bd50dc84..8da1e3a3 100644
--- a/tools/.github-cla-signers
+++ b/tools/.github-cla-signers
@@ -3,6 +3,7 @@ aciba90

@ -1,14 +1,15 @@
From 94c0cd9c656877250f7e5cfe05325a42bbdec182 Mon Sep 17 00:00:00 2001
From 2da948152c4b7b2f30dc6189d0072f7562df1ad5 Mon Sep 17 00:00:00 2001
From: Ani Sinha <anisinha@redhat.com>
Date: Fri, 4 Oct 2024 02:38:23 +0530
Subject: [PATCH 1/2] Fix metric setting for ifcfg network connections for rhel
Subject: [PATCH 1/3] Fix metric setting for ifcfg network connections for rhel
(#5777)
RH-Author: xiachen <xiachen@redhat.com>
RH-MergeRequest: 145: Fix metric setting for ifcfg network connections for rhel (#5777)
RH-Jira: RHEL-65018
RH-MergeRequest: 112: Fix metric setting for ifcfg network connections for rhel (#5777)
RH-Jira: RHEL-65016
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
RH-Acked-by: Ani Sinha <anisinha@redhat.com>
RH-Commit: [1/2] a18205f1ffa455a2ccd836ba6baa12b7da0afbde (xiachen/cloud-init)
RH-Commit: [1/1] ee573dfb2dccc59f2c9b74ca3f95026f96c49998 (xiachen/cloud-init-centos)
Most RHEL systems use Network manager to bring up manage network connections.
Network manager does not recognize "METRIC" option for network connections.
@ -30,7 +31,7 @@ Signed-off-by: Amy Chen <xiachen@redhat.com>
2 files changed, 38 insertions(+), 20 deletions(-)
diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
index 7eb430ed1..b50a6a8a0 100644
index 32ee7901..503b6993 100644
--- a/cloudinit/net/sysconfig.py
+++ b/cloudinit/net/sysconfig.py
@@ -205,7 +205,7 @@ class Route(ConfigMap):
@ -76,7 +77,7 @@ index 7eb430ed1..b50a6a8a0 100644
else:
# add default routes only to ifcfg files, not
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
index 2d716f4b5..4673e4eaf 100644
index de149f5e..00198232 100644
--- a/tests/unittests/test_net.py
+++ b/tests/unittests/test_net.py
@@ -1345,7 +1345,7 @@ NETWORK_CONFIGS = {
@ -88,7 +89,7 @@ index 2d716f4b5..4673e4eaf 100644
ONBOOT=yes
TYPE=Ethernet
USERCTL=no"""
@@ -1521,7 +1521,7 @@ NETWORK_CONFIGS = {
@@ -1519,7 +1519,7 @@ NETWORK_CONFIGS = {
HWADDR=c0:d6:9f:2c:e8:80
IPADDR=192.168.21.3
NETMASK=255.255.255.0
@ -97,7 +98,7 @@ index 2d716f4b5..4673e4eaf 100644
ONBOOT=yes
TYPE=Ethernet
USERCTL=no"""
@@ -5725,24 +5725,27 @@ USERCTL=no
@@ -6072,24 +6072,27 @@ USERCTL=no
}
},
}

@ -0,0 +1,175 @@
From f1fdff22c356fcfb6ef546633e7872313dca36d1 Mon Sep 17 00:00:00 2001
From: Vitaly Kuznetsov <vkuznets@redhat.com>
Date: Wed, 7 Aug 2024 16:47:52 +0200
Subject: [PATCH 2/2] Get rid of gdisk dependency
RH-Author: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-MergeRequest: 106: Get rid of gdisk dependency
RH-Jira: RHEL-36093
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
RH-Acked-by: Cathy Avery <cavery@redhat.com>
RH-Commit: [2/2] 7814ff343d4f8e7db95ca1853ea0079fe577354a (vkuznets/cloud-init)
gdisk is not going to be shipped in RHEL10 as sfdisk is perfectly capable
of dealing with GPT partition tables. cloud-init's upstream still relies on
sgdisk for GPT and is reluctant to do the switch, do this downstream only
for now.
X-downstream-only: true
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
---
.distro/cloud-init.spec | 1 -
cloudinit/config/cc_disk_setup.py | 98 +++++++++++++------------------
2 files changed, 42 insertions(+), 57 deletions(-)
diff --git a/cloudinit/config/cc_disk_setup.py b/cloudinit/config/cc_disk_setup.py
index fa6a52d3..7638b425 100644
--- a/cloudinit/config/cc_disk_setup.py
+++ b/cloudinit/config/cc_disk_setup.py
@@ -10,6 +10,7 @@
import logging
import os
import shlex
+import json
from textwrap import dedent
from cloudinit import subp, util
@@ -21,7 +22,6 @@ from cloudinit.settings import PER_INSTANCE
# Define the commands to use
SFDISK_CMD = subp.which("sfdisk")
-SGDISK_CMD = subp.which("sgdisk")
LSBLK_CMD = subp.which("lsblk")
BLKID_CMD = subp.which("blkid")
BLKDEV_CMD = subp.which("blockdev")
@@ -856,44 +856,32 @@ sgdisk_to_gpt_id = {
gpt_id_to_sgdisk = {v: k for k, v in reversed(sgdisk_to_gpt_id.items())}
def check_partition_gpt_layout(device, layout):
- prt_cmd = [SGDISK_CMD, "-p", device]
+ # Use sfdisk's JSON output for reliability
+ prt_cmd = [SFDISK_CMD, "-l", "-J", device]
try:
out, _err = subp.subp(prt_cmd, update_env=LANG_C_ENV)
+ ptable = json.loads(out)["partitiontable"]
+ if "partitions" in ptable:
+ partitions = ptable["partitions"]
+ else:
+ partitions = []
+
except Exception as e:
raise RuntimeError(
"Error running partition command on %s\n%s" % (device, e)
) from e
- out_lines = iter(out.splitlines())
- # Skip header. Output looks like:
- # ***************************************************************
- # Found invalid GPT and valid MBR; converting MBR to GPT format
- # in memory.
- # ***************************************************************
- #
- # Disk /dev/vdb: 83886080 sectors, 40.0 GiB
- # Logical sector size: 512 bytes
- # Disk identifier (GUID): 8A7F11AD-3953-491B-8051-077E01C8E9A7
- # Partition table holds up to 128 entries
- # First usable sector is 34, last usable sector is 83886046
- # Partitions will be aligned on 2048-sector boundaries
- # Total free space is 83476413 sectors (39.8 GiB)
- #
- # Number Start (sector) End (sector) Size Code Name
- # 1 2048 206847 100.0 MiB 0700 Microsoft basic data
- for line in out_lines:
- if line.strip().startswith("Number"):
- break
-
- codes = [line.strip().split()[5] for line in out_lines]
- cleaned = []
-
- # user would expect a code '83' to be Linux, but sgdisk outputs 8300.
- for code in codes:
- if len(code) == 4 and code.endswith("00"):
- code = code[0:2]
- cleaned.append(code)
- return cleaned
+ found_layout = []
+ for part in partitions:
+ if part["type"] in gpt_id_to_sgdisk:
+ ptype = gpt_id_to_sgdisk[part["type"]]
+ if len(ptype) == 4 and ptype[-2:] == "00":
+ ptype = ptype[0:2]
+ found_layout.append(ptype)
+ else:
+ # Unknown GPT UUID, using standard Linux
+ found_layout.append("83")
+ return found_layout
def check_partition_layout(table_type, device, layout):
@@ -1066,11 +1054,11 @@ def get_partition_layout(table_type, size, layout):
This is a future proofing function. To add support for
other layouts, simply add a "get_partition_%s_layout"
function.
+
+ RHEL-only: sfdisk is used both for GPT and MBR
"""
- if "mbr" == table_type:
+ if table_type in ["gpt", "mbr"]:
return get_partition_mbr_layout(size, layout)
- elif "gpt" == table_type:
- return get_partition_gpt_layout(size, layout)
raise RuntimeError("Unable to determine table type")
@@ -1110,28 +1098,26 @@ def exec_mkpart_mbr(device, layout):
def exec_mkpart_gpt(device, layout):
+ prt_cmd = [SFDISK_CMD, "-X", "gpt", "--force", device]
try:
- subp.subp([SGDISK_CMD, "-Z", device])
- for index, (partition_type, (start, end)) in enumerate(layout):
- index += 1
- subp.subp(
- [
- SGDISK_CMD,
- "-n",
- "{}:{}:{}".format(index, start, end),
- device,
- ]
- )
- if partition_type is not None:
- # convert to a 4 char (or more) string right padded with 0
- # 82 -> 8200. 'Linux' -> 'Linux'
- pinput = str(partition_type).ljust(4, "0")
- subp.subp(
- [SGDISK_CMD, "-t", "{}:{}".format(index, pinput), device]
- )
- except Exception:
- LOG.warning("Failed to partition device %s", device)
- raise
+ layout_fixed = []
+ # convert partition UUIDs to GPT UUIDs
+ for part in layout.split('\n'):
+ (pstart, psize, ptype) = part.split(',')
+ if len(ptype) == 2:
+ ptype = ptype + "00"
+ if ptype.upper() in sgdisk_to_gpt_id:
+ ptype = sgdisk_to_gpt_id[ptype]
+ else:
+ # Use standard Linux for unknown ids
+ ptype = "0FC63DAF-8483-4772-8E79-3D69D8477DE4"
+ layout_fixed.append(','.join([pstart, psize, ptype]))
+ layout = '\n'.join(layout_fixed)
+ subp.subp(prt_cmd, data="%s\n" % layout)
+ except Exception as e:
+ raise RuntimeError(
+ "Failed to partition device %s\n%s" % (device, e)
+ ) from e
read_parttbl(device)
--
2.39.3

@ -1,44 +0,0 @@
From 7f3b0ff968409a880596e04aece4e4c504fb9c64 Mon Sep 17 00:00:00 2001
From: Brett Holman <brett.holman@canonical.com>
Date: Mon, 29 Jan 2024 12:03:36 -0700
Subject: [PATCH] ci: Pin pytest<8.0.0. (#4816)
The latest pytest release broke some tests in non-obvious ways. Pin
the version for now so that CI passes.
(cherry picked from commit 7c96c9cd9318e816ce4564b58a2c98271363c447)
Signed-off-by: Ani Sinha <anisinha@redhat.com>
---
integration-requirements.txt | 2 +-
test-requirements.txt | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/integration-requirements.txt b/integration-requirements.txt
index 1f8b54a5..c0792d63 100644
--- a/integration-requirements.txt
+++ b/integration-requirements.txt
@@ -7,7 +7,7 @@ pycloudlib>=5.10.0,<1!6
# test/unittests/conftest.py to be loaded by our integration-tests tox env
# resulting in an unmet dependency issue:
# https://github.com/pytest-dev/pytest/issues/11104
-pytest!=7.3.2
+pytest!=7.3.2,<8.0.0
packaging
passlib
diff --git a/test-requirements.txt b/test-requirements.txt
index 46a98b4c..3d2480fd 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -4,7 +4,7 @@
# test/unittests/conftest.py to be loaded by our integration-tests tox env
# resulting in an unmet dependency issue:
# https://github.com/pytest-dev/pytest/issues/11104
-pytest!=7.3.2
+pytest!=7.3.2,<8.0.0
pytest-cov
pytest-mock
--
2.39.3

@ -1,15 +1,15 @@
From 038a391b7016f16a7336d67965762a7dbf3ba662 Mon Sep 17 00:00:00 2001
From ab36aacfb2f98d865d9e03df81f9102b04d307dd Mon Sep 17 00:00:00 2001
From: Ani Sinha <anisinha@redhat.com>
Date: Tue, 5 Nov 2024 04:07:36 +0530
Subject: [PATCH] Prevent NM from handling DNS when network interfaces have DNS
config (#5846)
RH-Author: Ani Sinha <anisinha@redhat.com>
RH-MergeRequest: 150: Prevent NM from handling DNS when network interfaces have DNS config (#5846)
RH-Jira: RHEL-65778
RH-MergeRequest: 117: Prevent NM from handling DNS when network interfaces have DNS config (#5846)
RH-Jira: RHEL-65769
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [1/1] b464ef219eba1a0c718dda5ed96b6f88e1273f99
RH-Commit: [1/1] cc175ec567ba5500f2a69d7943e8d5ee5c3822c8 (anisinha/cloud-init)
In the change under PR #5401, we use global DNS configuration as well as
DNS and search domain information from interface config and use it to populate
@ -25,24 +25,20 @@ Fixes bug added in 1b8030e0 .
Signed-off-by: Ani Sinha <anisinha@redhat.com>
(cherry picked from commit 2df49b652471999434f06d9d83ed9db8b4055895)
---
cloudinit/net/sysconfig.py | 28 +++++--
cloudinit/net/sysconfig.py | 26 +++++-
tests/unittests/test_net.py | 158 ++++++++++++++++++++++++++++++++++++
2 files changed, 181 insertions(+), 5 deletions(-)
2 files changed, 180 insertions(+), 4 deletions(-)
diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
index e4a65187f..4898a2fd1 100644
index 96652e15..363d052a 100644
--- a/cloudinit/net/sysconfig.py
+++ b/cloudinit/net/sysconfig.py
@@ -905,17 +905,35 @@ class Renderer(renderer.Renderer):
@@ -907,17 +907,35 @@ class Renderer(renderer.Renderer):
@staticmethod
def _render_networkmanager_conf(network_state, templates=None):
+ iface_dns = False
content = networkmanager_conf.NetworkManagerConf("")
-
- # If DNS server information is provided, configure
- # NetworkManager to not manage dns, so that /etc/resolv.conf
- # does not get clobbered.
+ # check if there is interface specific DNS information configured
+ for iface in network_state.iter_interfaces():
+ for subnet in iface["subnets"]:
@ -56,7 +52,10 @@ index e4a65187f..4898a2fd1 100644
+ ):
+ iface_dns = True
+ break
+
- # If DNS server information is provided, configure
- # NetworkManager to not manage dns, so that /etc/resolv.conf
- # does not get clobbered.
+ # If DNS server and/or dns search information is provided either
+ # globally or per interface basis, configure NetworkManager to
+ # not manage dns, so that /etc/resolv.conf does not get clobbered.
@ -75,7 +74,7 @@ index e4a65187f..4898a2fd1 100644
if len(content) == 0:
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
index ddb45dc69..47b36d052 100644
index 8a75c42b..215807ba 100644
--- a/tests/unittests/test_net.py
+++ b/tests/unittests/test_net.py
@@ -967,6 +967,164 @@ dns = none

@ -0,0 +1,54 @@
From bb5f9a5e4ad5225ce9f380812a9ec04828702e76 Mon Sep 17 00:00:00 2001
From: Ani Sinha <anisinha@redhat.com>
Date: Tue, 22 Oct 2024 11:49:47 +0530
Subject: [PATCH] Remove python3-jsonschema dependency
RH-Author: Ani Sinha <anisinha@redhat.com>
RH-MergeRequest: 115: Remove python3-jsonschema dependency
RH-Jira: RHEL-65849
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [1/1] b2c16e5e07d12eeb05a6d86ccb5e988220afafa3 (anisinha/cloud-init)
Cloud-init is the only package in RHEL-10 that still needs it. It is used by the
schema validator. When python3-jsonschema is not present, the schema validator
does not run and fails gracefully with the log message:
schema.py[DEBUG]: Ignoring schema validation. jsonschema is not present
There seems to be no other major regressions if we remove the dependency.
Please see RHEL-61183 for test cases and test results.
Removing the dependency enables us to not support jsonschema package for
the lifetime of RHEL-10 release.
python3-jsonschema can be replaced with fastjsonschema but the replacement is
not trivial and upstream has not committed to doing the work yet. When
support for fastjsonschema is implemented, we will incorporate the fix either
through backport or a rebase and then the schema validator will hopefully
be enabled again.
Remove the dependency from the spec file and requirements.txt file. This
change is downstream only for now.
X-downstream-only: true
Signed-off-by: Ani Sinha <anisinha@redhat.com>
---
.distro/cloud-init.spec | 1 -
requirements.txt | 2 +-
2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/requirements.txt b/requirements.txt
index eabd7a22..84211e80 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -28,4 +28,4 @@ requests
jsonpatch
# For validating cloud-config sections per schema definitions
-jsonschema
+# jsonschema
--
2.39.3

@ -1,65 +0,0 @@
From cc31dc321ae35995ceff93e67aaf0b0c660aa890 Mon Sep 17 00:00:00 2001
From: Ani Sinha <anisinha@redhat.com>
Date: Tue, 12 Mar 2024 12:52:10 +0530
Subject: [PATCH] Retain exit code in cloud-init status for recoverable errors
RH-Author: Ani Sinha <None>
RH-MergeRequest: 71: Retain exit code in cloud-init status for recoverable errors
RH-Jira: RHEL-28549
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
RH-Acked-by: Cathy Avery <cavery@redhat.com>
RH-Commit: [1/1] 00934ade88c481c012bc1947fa44e5ed59f82858 (anisinha/cloud-init)
Version 23.4 of cloud-init changed the status code reported by cloud-init for
recoverable errors from 0 to 2. Please see the commit
70acb7f2a30d58 ("Add support for cloud-init "degraded" state (#4500)")
This change has the potential to break customers who are expecting a 0 status
and where warnings can be expected. Hence, revert the status code from 2 to 0
even in case of recoverable errors. This retains the old behavior and hence
avoids breaking scripts and software stack that expects 0 on the end user side.
Cannonical has made a similar change downstream for similar reasons. Please see
https://bugs.launchpad.net/ubuntu/+source/cloud-init/+bug/2048522
and the corresponding downstream patch:
https://github.com/canonical/cloud-init/pull/4747/commits/adce34bfd214e4eecdf87329486f30f0898dd303
This patch has limited risk as it narrowly only restores the old status
code for recoverable errors and does not modify anything else.
X-downstream-only: true
Signed-off-by: Ani Sinha <anisinha@redhat.com>
---
cloudinit/cmd/status.py | 2 +-
tests/unittests/cmd/test_status.py | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/cloudinit/cmd/status.py b/cloudinit/cmd/status.py
index f5ee9c11..849c80bc 100644
--- a/cloudinit/cmd/status.py
+++ b/cloudinit/cmd/status.py
@@ -225,7 +225,7 @@ def handle_status_args(name, args) -> int:
return 1
# Recoverable error
elif details.status in UXAppStatusDegradedMap.values():
- return 2
+ return 0
return 0
diff --git a/tests/unittests/cmd/test_status.py b/tests/unittests/cmd/test_status.py
index 6c85a59a..567b517a 100644
--- a/tests/unittests/cmd/test_status.py
+++ b/tests/unittests/cmd/test_status.py
@@ -636,7 +636,7 @@ PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin
},
None,
MyArgs(long=False, wait=False, format="json"),
- 2,
+ 0,
{
"boot_status_code": "enabled-by-kernel-cmdline",
"datasource": "nocloud",
--
2.39.3

@ -1,242 +0,0 @@
From 72b2deeafd9276d15f20831f01b2f8c44616f33d Mon Sep 17 00:00:00 2001
From: Brett Holman <brett.holman@canonical.com>
Date: Tue, 23 Jan 2024 11:47:35 -0700
Subject: [PATCH] Revert "Use grep for faster parsing of cloud config in
ds-identify (#4327)"
RH-Author: Ani Sinha <None>
RH-MergeRequest: 67: Revert "Use grep for faster parsing of cloud config in ds-identify (#4327)"
RH-Jira: RHEL-22255
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [1/1] 5997598254cd16ea7f26d87212b0f09920fcdf50 (anisinha/cloud-init)
This reverts commit 816e05d4830f5e789f1f85ef926e2849156bff3a.
Reopens LP: 2030729
Fixes GH-4794
(cherry picked from commit 8ff94fe9493ad88344eb8bbf2f023c6ba2db5206)
Signed-off-by: Ani Sinha <anisinha@redhat.com>
---
tests/unittests/test_ds_identify.py | 146 +---------------------------
tools/ds-identify | 31 +++---
2 files changed, 15 insertions(+), 162 deletions(-)
diff --git a/tests/unittests/test_ds_identify.py b/tests/unittests/test_ds_identify.py
index ca206fb5..ba0bf779 100644
--- a/tests/unittests/test_ds_identify.py
+++ b/tests/unittests/test_ds_identify.py
@@ -57,146 +57,6 @@ BLKID_UEFI_UBUNTU = [
]
-DEFAULT_CLOUD_CONFIG = """\
-# The top level settings are used as module
-# and base configuration.
-# A set of users which may be applied and/or used by various modules
-# when a 'default' entry is found it will reference the 'default_user'
-# from the distro configuration specified below
-users:
- - default
-
-# If this is set, 'root' will not be able to ssh in and they
-# will get a message to login instead as the default $user
-disable_root: true
-
-# This will cause the set+update hostname module to not operate (if true)
-preserve_hostname: false
-
-# If you use datasource_list array, keep array items in a single line.
-# If you use multi line array, ds-identify script won't read array items.
-# Example datasource config
-# datasource:
-# Ec2:
-# metadata_urls: [ 'blah.com' ]
-# timeout: 5 # (defaults to 50 seconds)
-# max_wait: 10 # (defaults to 120 seconds)
-
-# The modules that run in the 'init' stage
-cloud_init_modules:
- - migrator
- - seed_random
- - bootcmd
- - write-files
- - growpart
- - resizefs
- - disk_setup
- - mounts
- - set_hostname
- - update_hostname
- - update_etc_hosts
- - ca-certs
- - rsyslog
- - users-groups
- - ssh
-
-# The modules that run in the 'config' stage
-cloud_config_modules:
- - wireguard
- - snap
- - ubuntu_autoinstall
- - ssh-import-id
- - keyboard
- - locale
- - set-passwords
- - grub-dpkg
- - apt-pipelining
- - apt-configure
- - ubuntu-advantage
- - ntp
- - timezone
- - disable-ec2-metadata
- - runcmd
- - byobu
-
-# The modules that run in the 'final' stage
-cloud_final_modules:
- - package-update-upgrade-install
- - fan
- - landscape
- - lxd
- - ubuntu-drivers
- - write-files-deferred
- - puppet
- - chef
- - ansible
- - mcollective
- - salt-minion
- - reset_rmc
- - refresh_rmc_and_interface
- - rightscale_userdata
- - scripts-vendor
- - scripts-per-once
- - scripts-per-boot
- - scripts-per-instance
- - scripts-user
- - ssh-authkey-fingerprints
- - keys-to-console
- - install-hotplug
- - phone-home
- - final-message
- - power-state-change
-
-# System and/or distro specific settings
-# (not accessible to handlers/transforms)
-system_info:
- # This will affect which distro class gets used
- distro: ubuntu
- # Default user name + that default users groups (if added/used)
- default_user:
- name: ubuntu
- lock_passwd: True
- gecos: Ubuntu
- groups: [adm, audio, cdrom, floppy, lxd, netdev, plugdev, sudo, video]
- sudo: ["ALL=(ALL) NOPASSWD:ALL"]
- shell: /bin/bash
- network:
- renderers: ['netplan', 'eni', 'sysconfig']
- activators: ['netplan', 'eni', 'network-manager', 'networkd']
- # Automatically discover the best ntp_client
- ntp_client: auto
- # Other config here will be given to the distro class and/or path classes
- paths:
- cloud_dir: /var/lib/cloud/
- templates_dir: /etc/cloud/templates/
- package_mirrors:
- - arches: [i386, amd64]
- failsafe:
- primary: http://archive.ubuntu.com/ubuntu
- security: http://security.ubuntu.com/ubuntu
- search:
- primary:
- - http://%(ec2_region)s.ec2.archive.ubuntu.com/ubuntu/
- - http://%(availability_zone)s.clouds.archive.ubuntu.com/ubuntu/
- - http://%(region)s.clouds.archive.ubuntu.com/ubuntu/
- security: []
- - arches: [arm64, armel, armhf]
- failsafe:
- primary: http://ports.ubuntu.com/ubuntu-ports
- security: http://ports.ubuntu.com/ubuntu-ports
- search:
- primary:
- - http://%(ec2_region)s.ec2.ports.ubuntu.com/ubuntu-ports/
- - http://%(availability_zone)s.clouds.ports.ubuntu.com/ubuntu-ports/
- - http://%(region)s.clouds.ports.ubuntu.com/ubuntu-ports/
- security: []
- - arches: [default]
- failsafe:
- primary: http://ports.ubuntu.com/ubuntu-ports
- security: http://ports.ubuntu.com/ubuntu-ports
- ssh_svcname: ssh
-"""
-
POLICY_FOUND_ONLY = "search,found=all,maybe=none,notfound=disabled"
POLICY_FOUND_OR_MAYBE = "search,found=all,maybe=all,notfound=disabled"
DI_DEFAULT_POLICY = "search,found=all,maybe=all,notfound=disabled"
@@ -279,10 +139,6 @@ class DsIdentifyBase(CiTestCase):
if files is None:
files = {}
- cloudcfg = "etc/cloud/cloud.cfg"
- if cloudcfg not in files:
- files[cloudcfg] = DEFAULT_CLOUD_CONFIG
-
if rootd is None:
rootd = self.tmp_dir()
@@ -1305,7 +1161,7 @@ VALID_CFG = {
# Also include a datasource list of more than just
# [NoCloud, None], because that would automatically select
# NoCloud without checking
- "etc/cloud/cloud.cfg": dedent(
+ "/etc/cloud/cloud.cfg": dedent(
"""\
datasource_list: [ Azure, Openstack, NoCloud, None ]
datasource:
diff --git a/tools/ds-identify b/tools/ds-identify
index 7a537278..ec2cc18a 100755
--- a/tools/ds-identify
+++ b/tools/ds-identify
@@ -777,24 +777,21 @@ check_config() {
if [ "$1" = "$files" -a ! -f "$1" ]; then
return 1
fi
- local line="" ret="" found=0 found_fn="" oifs="$IFS" out=""
- out=$(grep "$key\"\?:" "$@" 2>/dev/null)
- IFS=${CR}
- for line in $out; do
- # drop '# comment'
- line=${line%%#*}
- # if more than one file was 'grep'ed, then grep will output filename:
- # but if only one file, line will not be prefixed.
- if [ $# -eq 1 ]; then
- found_fn="$1"
- else
- found_fn="${line%%:*}"
- line=${line#*:}
- fi
- ret=${line#*: };
- found=$((found+1))
+ local fname="" line="" ret="" found=0 found_fn=""
+ # shellcheck disable=2094
+ for fname in "$@"; do
+ [ -f "$fname" ] || continue
+ while read line; do
+ line=${line%%#*}
+ case "$line" in
+ $key:\ *|"${key}":)
+ ret=${line#*:};
+ ret=${ret# };
+ found=$((found+1))
+ found_fn="$fname";;
+ esac
+ done <"$fname"
done
- IFS="$oifs"
if [ $found -ne 0 ]; then
_RET="$ret"
_RET_fname="$found_fn"
--
2.39.3

@ -1,15 +1,15 @@
From 87db4f8680222d2579d0ffb5fe507231f88d8aa5 Mon Sep 17 00:00:00 2001
From f8aff06e81da87383a0ae62a01b8488f4f2f98e0 Mon Sep 17 00:00:00 2001
From: PengpengSun <40026211+PengpengSun@users.noreply.github.com>
Date: Sat, 10 Aug 2024 03:32:40 +0800
Subject: [PATCH] Revert "fix(vmware): Set IPv6 to dhcp when there is no IPv6
addr (#5471)" (#5596)
RH-Author: xiachen <xiachen@redhat.com>
RH-MergeRequest: 108: Revert "fix(vmware): Set IPv6 to dhcp when there is no IPv6 addr (#5471)" (#5596)
RH-Jira: RHEL-54373
RH-MergeRequest: 107: Revert "fix(vmware): Set IPv6 to dhcp when there is no IPv6 addr (#5471)" (#5596)
RH-Jira: RHEL-54372
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [1/1] 96cccfca3d29c95d9c491d5995b7aa96adec4621 (xiachen/cloud-init-centos)
RH-Commit: [1/1] ac9414d2f1ee605d70bb94277d48ce97c21ea4b8 (xiachen/cloud-init-centos)
This reverts commit 2b6fe6403db769de14f7c7b7e4aa65f5bea8f3e0.
@ -40,10 +40,10 @@ index 254518af..b07214a2 100644
subnet_list = []
# Static Ipv6
diff --git a/tests/unittests/sources/vmware/test_vmware_config_file.py b/tests/unittests/sources/vmware/test_vmware_config_file.py
index 25d3b093..b53ea96c 100644
index c1415934..fd4bb481 100644
--- a/tests/unittests/sources/vmware/test_vmware_config_file.py
+++ b/tests/unittests/sources/vmware/test_vmware_config_file.py
@@ -240,45 +240,27 @@ class TestVmwareConfigFile(CiTestCase):
@@ -241,45 +241,27 @@ class TestVmwareConfigFile(CiTestCase):
elif cfg.get("name") == nic2.get("name"):
nic2.update(cfg)
@ -97,7 +97,7 @@ index 25d3b093..b53ea96c 100644
def test_get_nics_list_static(self):
"""Tests if NicConfigurator properly calculates network subnets
@@ -303,7 +285,6 @@ class TestVmwareConfigFile(CiTestCase):
@@ -304,7 +286,6 @@ class TestVmwareConfigFile(CiTestCase):
elif cfg.get("name") == nic2.get("name"):
nic2.update(cfg)
@ -105,7 +105,7 @@ index 25d3b093..b53ea96c 100644
self.assertEqual("physical", nic1.get("type"), "type of NIC1")
self.assertEqual("NIC1", nic1.get("name"), "name of NIC1")
self.assertEqual(
@@ -363,7 +344,6 @@ class TestVmwareConfigFile(CiTestCase):
@@ -364,7 +345,6 @@ class TestVmwareConfigFile(CiTestCase):
else:
self.assertEqual(True, False, "invalid gateway %s" % (gateway))
@ -113,7 +113,7 @@ index 25d3b093..b53ea96c 100644
self.assertEqual("physical", nic2.get("type"), "type of NIC2")
self.assertEqual("NIC2", nic2.get("name"), "name of NIC2")
self.assertEqual(
@@ -371,18 +351,16 @@ class TestVmwareConfigFile(CiTestCase):
@@ -372,18 +352,16 @@ class TestVmwareConfigFile(CiTestCase):
)
subnets = nic2.get("subnets")
@ -137,7 +137,7 @@ index 25d3b093..b53ea96c 100644
def test_custom_script(self):
cf = ConfigFile("tests/data/vmware/cust-dhcp-2nic.cfg")
@@ -469,10 +447,7 @@ class TestVmwareNetConfig(CiTestCase):
@@ -470,10 +448,7 @@ class TestVmwareNetConfig(CiTestCase):
"type": "static",
"address": "10.20.87.154",
"netmask": "255.255.252.0",
@ -149,7 +149,7 @@ index 25d3b093..b53ea96c 100644
],
}
],
@@ -523,10 +498,7 @@ class TestVmwareNetConfig(CiTestCase):
@@ -524,10 +499,7 @@ class TestVmwareNetConfig(CiTestCase):
"metric": 10000,
}
],
@ -161,7 +161,7 @@ index 25d3b093..b53ea96c 100644
],
}
],
@@ -586,10 +558,7 @@ class TestVmwareNetConfig(CiTestCase):
@@ -587,10 +559,7 @@ class TestVmwareNetConfig(CiTestCase):
"metric": 10000,
}
],
@ -173,7 +173,7 @@ index 25d3b093..b53ea96c 100644
],
}
],
@@ -634,10 +603,7 @@ class TestVmwareNetConfig(CiTestCase):
@@ -635,10 +604,7 @@ class TestVmwareNetConfig(CiTestCase):
"address": "10.20.87.154",
"netmask": "255.255.252.0",
"gateway": "10.20.87.253",

@ -1,14 +1,14 @@
From 96b10adc942f5117e35584d28ba88071849e8e29 Mon Sep 17 00:00:00 2001
From fc7ef10d5ca56af69eeef6d5d66a757dc01352ee Mon Sep 17 00:00:00 2001
From: Ani Sinha <anisinha@redhat.com>
Date: Thu, 27 Jun 2024 18:38:22 +0530
Date: Tue, 2 Jul 2024 13:58:56 +0800
Subject: [PATCH 1/2] Support metalink in yum repository config (#5444)
RH-Author: xiachen <xiachen@redhat.com>
RH-MergeRequest: 97: Support metalink in yum repository config (#5444)
RH-Jira: RHEL-44916
RH-MergeRequest: 96: Support metalink in yum repository config (#5444)
RH-Jira: RHEL-44918
RH-Acked-by: Ani Sinha <anisinha@redhat.com>
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
RH-Commit: [1/1] 4671fd3a3f6842f1f590d5a89a429facd0d8bb4d (xiachen/cloud-init-centos)
RH-Commit: [1/1] ff6d688b0ddfe31bbf42067a4107e56aa68395f0 (xiachen/cloud-init-centos)
'metalink' config can be specified instead or along with 'baseurl' in the yum
repository config. Add support for specifying metalink instead of 'baseurl'.
@ -80,7 +80,7 @@ index e8f2bbb4..6a4037e2 100644
failovermethod: priority
gpgcheck: true
diff --git a/tests/unittests/config/test_cc_yum_add_repo.py b/tests/unittests/config/test_cc_yum_add_repo.py
index d2c2912f..1f27d1fb 100644
index 1707860a..e6a9109e 100644
--- a/tests/unittests/config/test_cc_yum_add_repo.py
+++ b/tests/unittests/config/test_cc_yum_add_repo.py
@@ -31,6 +31,7 @@ class TestConfig(helpers.FilesystemMockingTestCase):
@ -92,7 +92,7 @@ index d2c2912f..1f27d1fb 100644
# 'baseurl': 'http://blah.org/pub/epel/testing/5/$barch',
"enabled": False,
@@ -46,6 +47,43 @@ class TestConfig(helpers.FilesystemMockingTestCase):
IOError, util.load_file, "/etc/yum.repos.d/epel_testing.repo"
IOError, util.load_text_file, "/etc/yum.repos.d/epel_testing.repo"
)
+ def test_metalink_config(self):
@ -111,7 +111,7 @@ index d2c2912f..1f27d1fb 100644
+ self.patchUtils(self.tmp)
+ self.patchOS(self.tmp)
+ cc_yum_add_repo.handle("yum_add_repo", cfg, None, [])
+ contents = util.load_file("/etc/yum.repos.d/epel-testing.repo")
+ contents = util.load_text_file("/etc/yum.repos.d/epel-testing.repo")
+ parser = configparser.ConfigParser()
+ parser.read_string(contents)
+ expected = {

@ -1,15 +1,15 @@
From d27ac077dac3474fea3c7bb1a19afe50ecbcc64d Mon Sep 17 00:00:00 2001
From 6ed8ff9885cddbbf87a63c13eedcbfed8440f626 Mon Sep 17 00:00:00 2001
From: Ani Sinha <anisinha@redhat.com>
Date: Thu, 18 Jul 2024 13:36:39 +0530
Subject: [PATCH 2/2] Support setting mirrorlist in yum repository config
(#5522)
RH-Author: xiachen <xiachen@redhat.com>
RH-MergeRequest: 104: Support setting mirrorlist in yum repository config (#5522)
RH-Jira: RHEL-49674
RH-MergeRequest: 105: Support setting mirrorlist in yum repository config (#5522)
RH-Jira: RHEL-49739
RH-Acked-by: Ani Sinha <anisinha@redhat.com>
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
RH-Commit: [1/1] 4605a0304c6bed6614990b7194465230afa79778 (xiachen/cloud-init-centos)
RH-Commit: [1/1] 497b813a26d27085703318ab22118f3824511f39 (xiachen/cloud-init-centos)
'mirrorlist' config can be specified instead or along with 'baseurl' in the yum
repository config. Add support for specifying mirrorlist instead of 'baseurl'.
@ -39,10 +39,10 @@ index 4fd66250..3870d24e 100644
if req_field not in repo_config:
missing_required += 1
diff --git a/cloudinit/config/schemas/schema-cloud-config-v1.json b/cloudinit/config/schemas/schema-cloud-config-v1.json
index 4fb7fd93..c5f46f37 100644
index 5758777a..6e0e7db9 100644
--- a/cloudinit/config/schemas/schema-cloud-config-v1.json
+++ b/cloudinit/config/schemas/schema-cloud-config-v1.json
@@ -3447,6 +3447,11 @@
@@ -3439,6 +3439,11 @@
"format": "uri",
"description": "Specifies a URL to a metalink file for the repomd.xml"
},
@ -54,7 +54,7 @@ index 4fb7fd93..c5f46f37 100644
"name": {
"type": "string",
"description": "Optional human-readable name of the yum repo."
@@ -3484,6 +3489,11 @@
@@ -3476,6 +3481,11 @@
"required": [
"metalink"
]
@ -83,7 +83,7 @@ index 6a4037e2..cee26677 100644
failovermethod: priority
gpgcheck: true
diff --git a/tests/unittests/config/test_cc_yum_add_repo.py b/tests/unittests/config/test_cc_yum_add_repo.py
index 1f27d1fb..000792b4 100644
index e6a9109e..c77262f5 100644
--- a/tests/unittests/config/test_cc_yum_add_repo.py
+++ b/tests/unittests/config/test_cc_yum_add_repo.py
@@ -31,7 +31,8 @@ class TestConfig(helpers.FilesystemMockingTestCase):
@ -116,7 +116,7 @@ index 1f27d1fb..000792b4 100644
+ self.patchUtils(self.tmp)
+ self.patchOS(self.tmp)
+ cc_yum_add_repo.handle("yum_add_repo", cfg, None, [])
+ contents = util.load_file("/etc/yum.repos.d/epel-testing.repo")
+ contents = util.load_text_file("/etc/yum.repos.d/epel-testing.repo")
+ parser = configparser.ConfigParser()
+ parser.read_string(contents)
+ expected = {

@ -1,14 +1,14 @@
From c34f5c4275c3ef7bee9a99e87bf6e37c5886b160 Mon Sep 17 00:00:00 2001
From 2865a3c52e72bcf70ef95c8f9787b650addeec51 Mon Sep 17 00:00:00 2001
From: Ani Sinha <anisinha@redhat.com>
Date: Wed, 29 May 2024 03:34:38 +0530
Subject: [PATCH 6/6] Update pylint version to support python 3.12 (#5338)
Subject: [PATCH 4/4] Update pylint version to support python 3.12 (#5338)
RH-Author: Ani Sinha <anisinha@redhat.com>
RH-MergeRequest: 92: Update pylint version to support python 3.12
RH-Jira: RHEL-44598
RH-MergeRequest: 93: Update pylint version to support python 3.12 (#5338)
RH-Jira: RHEL-44599
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [3/3] d6185e0a126e1589260ee59709fe933b5a780b78 (anisinha/cloud-init)
RH-Commit: [1/1] 979ef05888d5d9c0fd81a84249eb86410846ef33 (anisinha/cloud-init)
Fedora 39 and above comes with python version 3.12. When running `tox -e pylint`
on cloud-init, we may experience issue such as the one reported here:
@ -21,10 +21,6 @@ cloud-init. Update tox.ini in order to use this pylint version.
Signed-off-by: Ani Sinha <anisinha@redhat.com>
(cherry picked from commit 5ad609ffdf4bb76c5665e12e34e1867b72bd4435)
Conflicts:
cloudinit/sources/DataSourceWSL.py (does not exist)
cloudinit/util.py (doc added upstream)
---
cloudinit/config/cc_mounts.py | 4 ++++
cloudinit/distros/bsd.py | 2 ++
@ -41,7 +37,7 @@ Signed-off-by: Ani Sinha <anisinha@redhat.com>
12 files changed, 21 insertions(+), 9 deletions(-)
diff --git a/cloudinit/config/cc_mounts.py b/cloudinit/config/cc_mounts.py
index 4efa2a29..d445b440 100644
index 4cc32be5..3f690d06 100644
--- a/cloudinit/config/cc_mounts.py
+++ b/cloudinit/config/cc_mounts.py
@@ -304,6 +304,10 @@ def create_swapfile(fname: str, size: str) -> None:
@ -56,7 +52,7 @@ index 4efa2a29..d445b440 100644
try:
subp.subp(cmd, capture=True)
diff --git a/cloudinit/distros/bsd.py b/cloudinit/distros/bsd.py
index 761cf5c4..77e0385f 100644
index 995a1ba2..b0e63964 100644
--- a/cloudinit/distros/bsd.py
+++ b/cloudinit/distros/bsd.py
@@ -120,6 +120,8 @@ class BSD(distros.Distro):
@ -69,7 +65,7 @@ index 761cf5c4..77e0385f 100644
if args and isinstance(args, str):
cmd.append(args)
diff --git a/cloudinit/distros/netbsd.py b/cloudinit/distros/netbsd.py
index a5678907..b7f3f3d8 100644
index e8b9bcd5..972528c6 100644
--- a/cloudinit/distros/netbsd.py
+++ b/cloudinit/distros/netbsd.py
@@ -12,7 +12,7 @@ import cloudinit.distros.bsd
@ -82,10 +78,10 @@ index a5678907..b7f3f3d8 100644
salt = crypt.METHOD_BLOWFISH # pylint: disable=E1101
blowfish_hash: Any = functools.partial(
diff --git a/cloudinit/sources/DataSourceAzure.py b/cloudinit/sources/DataSourceAzure.py
index 11c14e20..eb0304c3 100644
index bd654cc0..11dc6686 100644
--- a/cloudinit/sources/DataSourceAzure.py
+++ b/cloudinit/sources/DataSourceAzure.py
@@ -51,7 +51,7 @@ from cloudinit.sources.helpers.azure import (
@@ -49,7 +49,7 @@ from cloudinit.sources.helpers.azure import (
from cloudinit.url_helper import UrlError
try:
@ -95,10 +91,10 @@ index 11c14e20..eb0304c3 100644
blowfish_hash: Any = functools.partial(
crypt.crypt, salt=f"$6${util.rand_str(strlen=16)}"
diff --git a/cloudinit/sources/DataSourceEc2.py b/cloudinit/sources/DataSourceEc2.py
index 9e6bfbd1..384e4074 100644
index 1b81b21f..28822e37 100644
--- a/cloudinit/sources/DataSourceEc2.py
+++ b/cloudinit/sources/DataSourceEc2.py
@@ -312,6 +312,8 @@ class DataSourceEc2(sources.DataSource):
@@ -333,6 +333,8 @@ class DataSourceEc2(sources.DataSource):
return None
def wait_for_metadata_service(self):
@ -107,7 +103,7 @@ index 9e6bfbd1..384e4074 100644
mcfg = self.ds_cfg
url_params = self.get_url_params()
@@ -345,7 +347,6 @@ class DataSourceEc2(sources.DataSource):
@@ -366,7 +368,6 @@ class DataSourceEc2(sources.DataSource):
and self.cloud_name not in IDMSV2_SUPPORTED_CLOUD_PLATFORMS
):
# if we can't get a token, use instance-id path
@ -129,10 +125,10 @@ index cd316101..4c95b907 100644
class _MetaDataReader:
diff --git a/tests/integration_tests/conftest.py b/tests/integration_tests/conftest.py
index fa729b7d..ec211a00 100644
index ccbf6a71..58133815 100644
--- a/tests/integration_tests/conftest.py
+++ b/tests/integration_tests/conftest.py
@@ -241,7 +241,7 @@ def _client(
@@ -273,7 +273,7 @@ def _client(
@pytest.fixture
@ -141,7 +137,7 @@ index fa729b7d..ec211a00 100644
request, fixture_utils, session_cloud, setup_image
) -> Iterator[IntegrationInstance]:
"""Provide a client that runs for every test."""
@@ -250,7 +250,7 @@ def client(
@@ -282,7 +282,7 @@ def client(
@pytest.fixture(scope="module")
@ -150,7 +146,7 @@ index fa729b7d..ec211a00 100644
request, fixture_utils, session_cloud, setup_image
) -> Iterator[IntegrationInstance]:
"""Provide a client that runs once per module."""
@@ -259,7 +259,7 @@ def module_client(
@@ -291,7 +291,7 @@ def module_client(
@pytest.fixture(scope="class")
@ -160,10 +156,10 @@ index fa729b7d..ec211a00 100644
) -> Iterator[IntegrationInstance]:
"""Provide a client that runs once per class."""
diff --git a/tests/integration_tests/util.py b/tests/integration_tests/util.py
index 0a15203c..e26e466c 100644
index 8ee3631d..cbe00c83 100644
--- a/tests/integration_tests/util.py
+++ b/tests/integration_tests/util.py
@@ -182,7 +182,7 @@ def wait_for_cloud_init(client: IntegrationInstance, num_retries: int = 30):
@@ -187,7 +187,7 @@ def wait_for_cloud_init(client: "IntegrationInstance", num_retries: int = 30):
except Exception as e:
last_exception = e
time.sleep(1)
@ -173,10 +169,10 @@ index 0a15203c..e26e466c 100644
) from last_exception
diff --git a/tests/unittests/config/test_cc_ntp.py b/tests/unittests/config/test_cc_ntp.py
index a9444ec5..c9ce5daa 100644
index 74ccf2de..6f6c3360 100644
--- a/tests/unittests/config/test_cc_ntp.py
+++ b/tests/unittests/config/test_cc_ntp.py
@@ -248,6 +248,7 @@ class TestNtp(FilesystemMockingTestCase):
@@ -249,6 +249,7 @@ class TestNtp(FilesystemMockingTestCase):
)
def _get_expected_pools(self, pools, distro, client):
@ -184,7 +180,7 @@ index a9444ec5..c9ce5daa 100644
if client in ["ntp", "chrony"]:
if client == "ntp" and distro == "alpine":
# NTP for Alpine Linux is Busybox's ntp which does not
@@ -263,6 +264,7 @@ class TestNtp(FilesystemMockingTestCase):
@@ -264,6 +265,7 @@ class TestNtp(FilesystemMockingTestCase):
return expected_pools
def _get_expected_servers(self, servers, distro, client):
@ -193,7 +189,7 @@ index a9444ec5..c9ce5daa 100644
if client == "ntp" and distro == "alpine":
# NTP for Alpine Linux is Busybox's ntp which only supports
diff --git a/tests/unittests/sources/test_gce.py b/tests/unittests/sources/test_gce.py
index c0b19d3c..30a50236 100644
index 6fc31ddc..1617f694 100644
--- a/tests/unittests/sources/test_gce.py
+++ b/tests/unittests/sources/test_gce.py
@@ -101,6 +101,7 @@ class TestDataSourceGCE(test_helpers.ResponsesTestCase):
@ -205,10 +201,10 @@ index c0b19d3c..30a50236 100644
if url_path.startswith("/computeMetadata/v1/"):
path = url_path.split("/computeMetadata/v1/")[1:][0]
diff --git a/tests/unittests/test_util.py b/tests/unittests/test_util.py
index 519ef63c..de1326d4 100644
index 70edb40b..b534a1a7 100644
--- a/tests/unittests/test_util.py
+++ b/tests/unittests/test_util.py
@@ -1677,6 +1677,8 @@ class TestRedirectOutputPreexecFn:
@@ -1700,6 +1700,8 @@ class TestRedirectOutputPreexecFn:
args = (test_string, None)
elif request.param == "errfmt":
args = (None, test_string)
@ -218,7 +214,7 @@ index 519ef63c..de1326d4 100644
util.redirect_output(*args)
diff --git a/tox.ini b/tox.ini
index 5f01a9a8..5199ca13 100644
index 473e937c..85af1a14 100644
--- a/tox.ini
+++ b/tox.ini
@@ -25,7 +25,7 @@ hypothesis==6.31.6

@ -0,0 +1,409 @@
From f370030e178c928592e6c359cc528b7033956d79 Mon Sep 17 00:00:00 2001
From: Vitaly Kuznetsov <vkuznets@redhat.com>
Date: Wed, 7 Aug 2024 16:43:55 +0200
Subject: [PATCH 1/2] cc_disk_setup: add sgdisk to sfdisk convertion
dictionaries
RH-Author: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-MergeRequest: 106: Get rid of gdisk dependency
RH-Jira: RHEL-36093
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
RH-Acked-by: Cathy Avery <cavery@redhat.com>
RH-Commit: [1/2] c6a6eca2b1496bccfe404e902417f02f828682aa (vkuznets/cloud-init)
In preparation to using sfdisk instead of sgdisk, make it possible to
convert between sgdisk-invented ids and standard GPT UUIDs.
No functional change.
X-downstream-only: true
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
---
cloudinit/config/cc_disk_setup.py | 370 ++++++++++++++++++++++++++++++
1 file changed, 370 insertions(+)
diff --git a/cloudinit/config/cc_disk_setup.py b/cloudinit/config/cc_disk_setup.py
index 0ccf6a35..fa6a52d3 100644
--- a/cloudinit/config/cc_disk_setup.py
+++ b/cloudinit/config/cc_disk_setup.py
@@ -484,6 +484,376 @@ def check_partition_mbr_layout(device, layout):
found_layout.append(type_label)
return found_layout
+SFDISK_CMD="sfdisk"
+
+# gdisk uses its own invented ids, convert them to standard GPT ones. From gdisk sources:
+# grep " AddType" parttypes.cc | sed -e 's,AddType(,,' -e 's,"\,.*$,"\,,' -e 's,0x,",' -e 's,\,,":,' | tr "[a-z]" "[A-Z]"
+sgdisk_to_gpt_id = {
+ "0000": "00000000-0000-0000-0000-000000000000",
+ "0100": "EBD0A0A2-B9E5-4433-87C0-68B6B72699C7",
+ "0400": "EBD0A0A2-B9E5-4433-87C0-68B6B72699C7",
+ "0600": "EBD0A0A2-B9E5-4433-87C0-68B6B72699C7",
+ "0700": "EBD0A0A2-B9E5-4433-87C0-68B6B72699C7",
+ "0701": "558D43C5-A1AC-43C0-AAC8-D1472B2923D1",
+ "0702": "90B6FF38-B98F-4358-A21F-48F35B4A8AD3",
+ "0B00": "EBD0A0A2-B9E5-4433-87C0-68B6B72699C7",
+ "0C00": "EBD0A0A2-B9E5-4433-87C0-68B6B72699C7",
+ "0C01": "E3C9E316-0B5C-4DB8-817D-F92DF00215AE",
+ "0E00": "EBD0A0A2-B9E5-4433-87C0-68B6B72699C7",
+ "1100": "EBD0A0A2-B9E5-4433-87C0-68B6B72699C7",
+ "1400": "EBD0A0A2-B9E5-4433-87C0-68B6B72699C7",
+ "1600": "EBD0A0A2-B9E5-4433-87C0-68B6B72699C7",
+ "1700": "EBD0A0A2-B9E5-4433-87C0-68B6B72699C7",
+ "1B00": "EBD0A0A2-B9E5-4433-87C0-68B6B72699C7",
+ "1C00": "EBD0A0A2-B9E5-4433-87C0-68B6B72699C7",
+ "1E00": "EBD0A0A2-B9E5-4433-87C0-68B6B72699C7",
+ "2700": "DE94BBA4-06D1-4D40-A16A-BFD50179D6AC",
+ "3000": "7412F7D5-A156-4B13-81DC-867174929325",
+ "3001": "D4E6E2CD-4469-46F3-B5CB-1BFF57AFC149",
+ "3900": "C91818F9-8025-47AF-89D2-F030D7000C2C",
+ "4100": "9E1A2D38-C612-4316-AA26-8B49521E5A8B",
+ "4200": "AF9B60A0-1431-4F62-BC68-3311714A69AD",
+ "4201": "5808C8AA-7E8F-42E0-85D2-E1E90434CFB3",
+ "4202": "E75CAF8F-F680-4CEE-AFA3-B001E56EFC2D",
+ "7501": "37AFFC90-EF7D-4E96-91C3-2D7AE055B174",
+ "7F00": "FE3A2A5D-4F32-41A7-B725-ACCC3285A309",
+ "7F01": "3CB8E202-3B7E-47DD-8A3C-7FF2A13CFCEC",
+ "7F02": "2E0A753D-9E48-43B0-8337-B15192CB1B5E",
+ "7F03": "CAB6E88E-ABF3-4102-A07A-D4BB9BE3C1D3",
+ "7F04": "09845860-705F-4BB5-B16C-8A8A099CAF52",
+ "7F05": "3F0F8318-F146-4E6B-8222-C28C8F02E0D5",
+ "8200": "0657FD6D-A4AB-43C4-84E5-0933C84B4F4F",
+ "8300": "0FC63DAF-8483-4772-8E79-3D69D8477DE4",
+ "8301": "8DA63339-0007-60C0-C436-083AC8230908",
+ "8302": "933AC7E1-2EB4-4F13-B844-0E14E2AEF915",
+ "8303": "44479540-F297-41B2-9AF7-D131D5F0458A",
+ "8304": "4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709",
+ "8305": "B921B045-1DF0-41C3-AF44-4C6F280D3FAE",
+ "8306": "3B8F8425-20E0-4F3B-907F-1A25A76F98E8",
+ "8307": "69DAD710-2CE4-4E3C-B16C-21A1D49ABED3",
+ "8308": "7FFEC5C9-2D00-49B7-8941-3EA10A5586B7",
+ "8309": "CA7D7CCB-63ED-4C53-861C-1742536059CC",
+ "830A": "993D8D3D-F80E-4225-855A-9DAF8ED7EA97",
+ "830B": "D13C5D3B-B5D1-422A-B29F-9454FDC89D76",
+ "830C": "2C7357ED-EBD2-46D9-AEC1-23D437EC2BF5",
+ "830D": "7386CDF2-203C-47A9-A498-F2ECCE45A2D6",
+ "830E": "DF3300CE-D69F-4C92-978C-9BFB0F38D820",
+ "830F": "86ED10D5-B607-45BB-8957-D350F23D0571",
+ "8310": "4D21B016-B534-45C2-A9FB-5C16E091FD2D",
+ "8311": "7EC6F557-3BC5-4ACA-B293-16EF5DF639D1",
+ "8312": "773F91EF-66D4-49B5-BD83-D683BF40AD16",
+ "8313": "75250D76-8CC6-458E-BD66-BD47CC81A812",
+ "8314": "8484680C-9521-48C6-9C11-B0720656F69E",
+ "8315": "7D0359A3-02B3-4F0A-865C-654403E70625",
+ "8316": "B0E01050-EE5F-4390-949A-9101B17104E9",
+ "8317": "4301D2A6-4E3B-4B2A-BB94-9E0B2C4225EA",
+ "8318": "8F461B0D-14EE-4E81-9AA9-049B6FB97ABD",
+ "8319": "77FF5F63-E7B6-4633-ACF4-1565B864C0E6",
+ "831A": "C215D751-7BCD-4649-BE90-6627490A4C05",
+ "831B": "6E11A4E7-FBCA-4DED-B9E9-E1A512BB664E",
+ "831C": "6A491E03-3BE7-4545-8E38-83320E0EA880",
+ "831D": "6523F8AE-3EB1-4E2A-A05A-18B695AE656F",
+ "831E": "D27F46ED-2919-4CB8-BD25-9531F3C16534",
+ "831F": "77055800-792C-4F94-B39A-98C91B762BB6",
+ "8320": "E9434544-6E2C-47CC-BAE2-12D6DEAFB44C",
+ "8321": "D113AF76-80EF-41B4-BDB6-0CFF4D3D4A25",
+ "8322": "37C58C8A-D913-4156-A25F-48B1B64E07F0",
+ "8323": "700BDA43-7A34-4507-B179-EEB93D7A7CA3",
+ "8324": "1AACDB3B-5444-4138-BD9E-E5C2239B2346",
+ "8325": "1DE3F1EF-FA98-47B5-8DCD-4A860A654D78",
+ "8326": "912ADE1D-A839-4913-8964-A10EEE08FBD2",
+ "8327": "C31C45E6-3F39-412E-80FB-4809C4980599",
+ "8328": "60D5A7FE-8E7D-435C-B714-3DD8162144E1",
+ "8329": "72EC70A6-CF74-40E6-BD49-4BDA08E8F224",
+ "832A": "08A7ACEA-624C-4A20-91E8-6E0FA67D23F9",
+ "832B": "5EEAD9A9-FE09-4A1E-A1D7-520D00531306",
+ "832C": "C50CDD70-3862-4CC3-90E1-809A8C93EE2C",
+ "832D": "E18CF08C-33EC-4C0D-8246-C6C6FB3DA024",
+ "832E": "7978A683-6316-4922-BBEE-38BFF5A2FECC",
+ "832F": "E611C702-575C-4CBE-9A46-434FA0BF7E3F",
+ "8330": "773B2ABC-2A99-4398-8BF5-03BAAC40D02B",
+ "8331": "57E13958-7331-4365-8E6E-35EEEE17C61B",
+ "8332": "0F4868E9-9952-4706-979F-3ED3A473E947",
+ "8333": "C97C1F32-BA06-40B4-9F22-236061B08AA8",
+ "8334": "DC4A4480-6917-4262-A4EC-DB9384949F25",
+ "8335": "7D14FEC5-CC71-415D-9D6C-06BF0B3C3EAF",
+ "8336": "2C9739E2-F068-46B3-9FD0-01C5A9AFBCCA",
+ "8337": "15BB03AF-77E7-4D4A-B12B-C0D084F7491C",
+ "8338": "B933FB22-5C3F-4F91-AF90-E2BB0FA50702",
+ "8339": "BEAEC34B-8442-439B-A40B-984381ED097D",
+ "833A": "CD0F869B-D0FB-4CA0-B141-9EA87CC78D66",
+ "833B": "8A4F5770-50AA-4ED3-874A-99B710DB6FEA",
+ "833C": "55497029-C7C1-44CC-AA39-815ED1558630",
+ "833D": "FC56D9E9-E6E5-4C06-BE32-E74407CE09A5",
+ "833E": "24B2D975-0F97-4521-AFA1-CD531E421B8D",
+ "833F": "F3393B22-E9AF-4613-A948-9D3BFBD0C535",
+ "8340": "7A430799-F711-4C7E-8E5B-1D685BD48607",
+ "8341": "579536F8-6A33-4055-A95A-DF2D5E2C42A8",
+ "8342": "D7D150D2-2A04-4A33-8F12-16651205FF7B",
+ "8343": "16B417F8-3E06-4F57-8DD2-9B5232F41AA6",
+ "8344": "D212A430-FBC5-49F9-A983-A7FEEF2B8D0E",
+ "8345": "906BD944-4589-4AAE-A4E4-DD983917446A",
+ "8346": "9225A9A3-3C19-4D89-B4F6-EEFF88F17631",
+ "8347": "98CFE649-1588-46DC-B2F0-ADD147424925",
+ "8348": "AE0253BE-1167-4007-AC68-43926C14C5DE",
+ "8349": "B6ED5582-440B-4209-B8DA-5FF7C419EA3D",
+ "834A": "7AC63B47-B25C-463B-8DF8-B4A94E6C90E1",
+ "834B": "B325BFBE-C7BE-4AB8-8357-139E652D2F6B",
+ "834C": "966061EC-28E4-4B2E-B4A5-1F0A825A1D84",
+ "834D": "8CCE0D25-C0D0-4A44-BD87-46331BF1DF67",
+ "834E": "FCA0598C-D880-4591-8C16-4EDA05C7347C",
+ "834F": "F46B2C26-59AE-48F0-9106-C50ED47F673D",
+ "8350": "6E5A1BC8-D223-49B7-BCA8-37A5FCCEB996",
+ "8351": "81CF9D90-7458-4DF4-8DCF-C8A3A404F09B",
+ "8352": "46B98D8D-B55C-4E8F-AAB3-37FCA7F80752",
+ "8353": "3C3D61FE-B5F3-414D-BB71-8739A694A4EF",
+ "8354": "5843D618-EC37-48D7-9F12-CEA8E08768B2",
+ "8355": "EE2B9983-21E8-4153-86D9-B6901A54D1CE",
+ "8356": "BDB528A5-A259-475F-A87D-DA53FA736A07",
+ "8357": "DF765D00-270E-49E5-BC75-F47BB2118B09",
+ "8358": "CB1EE4E3-8CD0-4136-A0A4-AA61A32E8730",
+ "8359": "8F1056BE-9B05-47C4-81D6-BE53128E5B54",
+ "835A": "B663C618-E7BC-4D6D-90AA-11B756BB1797",
+ "835B": "31741CC4-1A2A-4111-A581-E00B447D2D06",
+ "835C": "2FB4BF56-07FA-42DA-8132-6B139F2026AE",
+ "835D": "D46495B7-A053-414F-80F7-700C99921EF8",
+ "835E": "143A70BA-CBD3-4F06-919F-6C05683A78BC",
+ "835F": "42B0455F-EB11-491D-98D3-56145BA9D037",
+ "8360": "6DB69DE6-29F4-4758-A7A5-962190F00CE3",
+ "8361": "E98B36EE-32BA-4882-9B12-0CE14655F46A",
+ "8362": "5AFB67EB-ECC8-4F85-AE8E-AC1E7C50E7D0",
+ "8363": "BBA210A2-9C5D-45EE-9E87-FF2CCBD002D0",
+ "8364": "43CE94D4-0F3D-4999-8250-B9DEAFD98E6E",
+ "8365": "C919CC1F-4456-4EFF-918C-F75E94525CA5",
+ "8366": "904E58EF-5C65-4A31-9C57-6AF5FC7C5DE7",
+ "8367": "15DE6170-65D3-431C-916E-B0DCD8393F25",
+ "8368": "D4A236E7-E873-4C07-BF1D-BF6CF7F1C3C6",
+ "8369": "F5E2C20C-45B2-4FFA-BCE9-2A60737E1AAF",
+ "836A": "1B31B5AA-ADD9-463A-B2ED-BD467FC857E7",
+ "836B": "3A112A75-8729-4380-B4CF-764D79934448",
+ "836C": "EFE0F087-EA8D-4469-821A-4C2A96A8386A",
+ "836D": "3482388E-4254-435A-A241-766A065F9960",
+ "836E": "C80187A5-73A3-491A-901A-017C3FA953E9",
+ "836F": "B3671439-97B0-4A53-90F7-2D5A8F3AD47B",
+ "8370": "41092B05-9FC8-4523-994F-2DEF0408B176",
+ "8371": "5996FC05-109C-48DE-808B-23FA0830B676",
+ "8372": "5C6E1C76-076A-457A-A0FE-F3B4CD21CE6E",
+ "8373": "94F9A9A1-9971-427A-A400-50CB297F0F35",
+ "8374": "D7FF812F-37D1-4902-A810-D76BA57B975A",
+ "8375": "C23CE4FF-44BD-4B00-B2D4-B41B3419E02A",
+ "8376": "8DE58BC2-2A43-460D-B14E-A76E4A17B47F",
+ "8377": "B024F315-D330-444C-8461-44BBDE524E99",
+ "8378": "97AE158D-F216-497B-8057-F7F905770F54",
+ "8379": "05816CE2-DD40-4AC6-A61D-37D32DC1BA7D",
+ "837A": "3E23CA0B-A4BC-4B4E-8087-5AB6A26AA8A9",
+ "837B": "F2C2C7EE-ADCC-4351-B5C6-EE9816B66E16",
+ "837C": "450DD7D1-3224-45EC-9CF2-A43A346D71EE",
+ "837D": "C8BFBD1E-268E-4521-8BBA-BF314C399557",
+ "837E": "0B888863-D7F8-4D9E-9766-239FCE4D58AF",
+ "837F": "7007891D-D371-4A80-86A4-5CB875B9302E",
+ "8380": "C3836A13-3137-45BA-B583-B16C50FE5EB4",
+ "8381": "D2F9000A-7A18-453F-B5CD-4D32F77A7B32",
+ "8382": "17440E4F-A8D0-467F-A46E-3912AE6EF2C5",
+ "8383": "3F324816-667B-46AE-86EE-9B0C0C6C11B4",
+ "8384": "4EDE75E2-6CCC-4CC8-B9C7-70334B087510",
+ "8385": "E7BB33FB-06CF-4E81-8273-E543B413E2E2",
+ "8386": "974A71C0-DE41-43C3-BE5D-5C5CCD1AD2C0",
+ "8400": "D3BFE2DE-3DAF-11DF-BA40-E3A556D89593",
+ "8401": "7C5222BD-8F5D-4087-9C00-BF9843C7B58C",
+ "8500": "5DFBF5F4-2848-4BAC-AA5E-0D9A20B745A6",
+ "8501": "3884DD41-8582-4404-B9A8-E9B84F2DF50E",
+ "8502": "C95DC21A-DF0E-4340-8D7B-26CBFA9A03E0",
+ "8503": "BE9067B9-EA49-4F15-B4F6-F36F8C9E1818",
+ "8E00": "E6D6D379-F507-44C2-A23C-238F2A3DF928",
+ "A000": "2568845D-2332-4675-BC39-8FA5A4748D15",
+ "A001": "114EAFFE-1552-4022-B26E-9B053604CF84",
+ "A002": "49A4D17F-93A3-45C1-A0DE-F50B2EBE2599",
+ "A003": "4177C722-9E92-4AAB-8644-43502BFD5506",
+ "A004": "EF32A33B-A409-486C-9141-9FFB711F6266",
+ "A005": "20AC26BE-20B7-11E3-84C5-6CFDB94711E9",
+ "A006": "38F428E6-D326-425D-9140-6E0EA133647C",
+ "A007": "A893EF21-E428-470A-9E55-0668FD91A2D9",
+ "A008": "DC76DDA9-5AC1-491C-AF42-A82591580C0D",
+ "A009": "EBC597D0-2053-4B15-8B64-E0AAC75F4DB1",
+ "A00A": "8F68CC74-C5E5-48DA-BE91-A0C8C15E9C80",
+ "A00B": "767941D0-2085-11E3-AD3B-6CFDB94711E9",
+ "A00C": "AC6D7924-EB71-4DF8-B48D-E267B27148FF",
+ "A00D": "C5A0AEEC-13EA-11E5-A1B1-001E67CA0C3C",
+ "A00E": "BD59408B-4514-490D-BF12-9878D963F378",
+ "A00F": "9FDAA6EF-4B3F-40D2-BA8D-BFF16BFB887B",
+ "A010": "19A710A2-B3CA-11E4-B026-10604B889DCF",
+ "A011": "193D1EA4-B3CA-11E4-B075-10604B889DCF",
+ "A012": "DEA0BA2C-CBDD-4805-B4F9-F428251C3E98",
+ "A013": "8C6B52AD-8A9E-4398-AD09-AE916E53AE2D",
+ "A014": "05E044DF-92F1-4325-B69E-374A82E97D6E",
+ "A015": "400FFDCD-22E0-47E7-9A23-F16ED9382388",
+ "A016": "A053AA7F-40B8-4B1C-BA08-2F68AC71A4F4",
+ "A017": "E1A6A689-0C8D-4CC6-B4E8-55A4320FBD8A",
+ "A018": "098DF793-D712-413D-9D4E-89D711772228",
+ "A019": "D4E0D938-B7FA-48C1-9D21-BC5ED5C4B203",
+ "A01A": "20A0C19C-286A-42FA-9CE7-F64C3226A794",
+ "A01B": "A19F205F-CCD8-4B6D-8F1E-2D9BC24CFFB1",
+ "A01C": "66C9B323-F7FC-48B6-BF96-6F32E335A428",
+ "A01D": "303E6AC3-AF15-4C54-9E9B-D9A8FBECF401",
+ "A01E": "C00EEF24-7709-43D6-9799-DD2B411E7A3C",
+ "A01F": "82ACC91F-357C-4A68-9C8F-689E1B1A23A1",
+ "A020": "E2802D54-0545-E8A1-A1E8-C7A3E245ACD4",
+ "A021": "65ADDCF4-0C5C-4D9A-AC2D-D90B5CBFCD03",
+ "A022": "E6E98DA2-E22A-4D12-AB33-169E7DEAA507",
+ "A023": "ED9E8101-05FA-46B7-82AA-8D58770D200B",
+ "A024": "11406F35-1173-4869-807B-27DF71802812",
+ "A025": "9D72D4E4-9958-42DA-AC26-BEA7A90B0434",
+ "A026": "6C95E238-E343-4BA8-B489-8681ED22AD0B",
+ "A027": "EBBEADAF-22C9-E33B-8F5D-0E81686A68CB",
+ "A028": "0A288B1F-22C9-E33B-8F5D-0E81686A68CB",
+ "A029": "57B90A16-22C9-E33B-8F5D-0E81686A68CB",
+ "A02A": "638FF8E2-22C9-E33B-8F5D-0E81686A68CB",
+ "A02B": "2013373E-1AC4-4131-BFD8-B6A7AC638772",
+ "A02C": "2C86E742-745E-4FDD-BFD8-B6A7AC638772",
+ "A02D": "DE7D4029-0F5B-41C8-AE7E-F6C023A02B33",
+ "A02E": "323EF595-AF7A-4AFA-8060-97BE72841BB9",
+ "A02F": "45864011-CF89-46E6-A445-85262E065604",
+ "A030": "8ED8AE95-597F-4C8A-A5BD-A7FF8E4DFAA9",
+ "A031": "DF24E5ED-8C96-4B86-B00B-79667DC6DE11",
+ "A032": "7C29D3AD-78B9-452E-9DEB-D098D542F092",
+ "A033": "379D107E-229E-499D-AD4F-61F5BCF87BD4",
+ "A034": "0DEA65E5-A676-4CDF-823C-77568B577ED5",
+ "A035": "4627AE27-CFEF-48A1-88FE-99C3509ADE26",
+ "A036": "20117F86-E985-4357-B9EE-374BC1D8487D",
+ "A037": "86A7CB80-84E1-408C-99AB-694F1A410FC7",
+ "A038": "97D7B011-54DA-4835-B3C4-917AD6E73D74",
+ "A039": "5594C694-C871-4B5F-90B1-690A6F68E0F7",
+ "A03A": "1B81E7E6-F50D-419B-A739-2AEEF8DA3335",
+ "A03B": "98523EC6-90FE-4C67-B50A-0FC59ED6F56D",
+ "A03C": "2644BCC0-F36A-4792-9533-1738BED53EE3",
+ "A03D": "DD7C91E9-38C9-45C5-8A12-4A80F7E14057",
+ "A03E": "7696D5B6-43FD-4664-A228-C563C4A1E8CC",
+ "A03F": "0D802D54-058D-4A20-AD2D-C7A362CEACD4",
+ "A040": "10A0C19C-516A-5444-5CE3-664C3226A794",
+ "A200": "734E5AFE-F61A-11E6-BC64-92361F002671",
+ "A500": "516E7CB4-6ECF-11D6-8FF8-00022D09712B",
+ "A501": "83BD6B9D-7F41-11DC-BE0B-001560B84F0F",
+ "A502": "516E7CB5-6ECF-11D6-8FF8-00022D09712B",
+ "A503": "516E7CB6-6ECF-11D6-8FF8-00022D09712B",
+ "A504": "516E7CBA-6ECF-11D6-8FF8-00022D09712B",
+ "A505": "516E7CB8-6ECF-11D6-8FF8-00022D09712B",
+ "A506": "74BA7DD9-A689-11E1-BD04-00E081286ACF",
+ "A580": "85D5E45A-237C-11E1-B4B3-E89A8F7FC3A7",
+ "A581": "85D5E45E-237C-11E1-B4B3-E89A8F7FC3A7",
+ "A582": "85D5E45B-237C-11E1-B4B3-E89A8F7FC3A7",
+ "A583": "0394EF8B-237E-11E1-B4B3-E89A8F7FC3A7",
+ "A584": "85D5E45D-237C-11E1-B4B3-E89A8F7FC3A7",
+ "A585": "85D5E45C-237C-11E1-B4B3-E89A8F7FC3A7",
+ "A600": "824CC7A0-36A8-11E3-890A-952519AD3F61",
+ "A800": "55465300-0000-11AA-AA11-00306543ECAC",
+ "A900": "516E7CB4-6ECF-11D6-8FF8-00022D09712B",
+ "A901": "49F48D32-B10E-11DC-B99B-0019D1879648",
+ "A902": "49F48D5A-B10E-11DC-B99B-0019D1879648",
+ "A903": "49F48D82-B10E-11DC-B99B-0019D1879648",
+ "A904": "2DB519C4-B10F-11DC-B99B-0019D1879648",
+ "A905": "2DB519EC-B10F-11DC-B99B-0019D1879648",
+ "A906": "49F48DAA-B10E-11DC-B99B-0019D1879648",
+ "AB00": "426F6F74-0000-11AA-AA11-00306543ECAC",
+ "AF00": "48465300-0000-11AA-AA11-00306543ECAC",
+ "AF01": "52414944-0000-11AA-AA11-00306543ECAC",
+ "AF02": "52414944-5F4F-11AA-AA11-00306543ECAC",
+ "AF03": "4C616265-6C00-11AA-AA11-00306543ECAC",
+ "AF04": "5265636F-7665-11AA-AA11-00306543ECAC",
+ "AF05": "53746F72-6167-11AA-AA11-00306543ECAC",
+ "AF06": "B6FA30DA-92D2-4A9A-96F1-871EC6486200",
+ "AF07": "2E313465-19B9-463F-8126-8A7993773801",
+ "AF08": "FA709C7E-65B1-4593-BFD5-E71D61DE9B02",
+ "AF09": "BBBA6DF5-F46F-4A89-8F59-8765B2727503",
+ "AF0A": "7C3457EF-0000-11AA-AA11-00306543ECAC",
+ "AF0B": "69646961-6700-11AA-AA11-00306543ECAC",
+ "AF0C": "52637672-7900-11AA-AA11-00306543ECAC",
+ "B000": "3DE21764-95BD-54BD-A5C3-4ABE786F38A8",
+ "B300": "CEF5A9AD-73BC-4601-89F3-CDEEEEE321A1",
+ "BB00": "4778ED65-BF42-45FA-9C5B-287A1DC4AAB1",
+ "BC00": "0311FC50-01CA-4725-AD77-9ADBB20ACE98",
+ "BE00": "6A82CB45-1DD2-11B2-99A6-080020736631",
+ "BF00": "6A85CF4D-1DD2-11B2-99A6-080020736631",
+ "BF01": "6A898CC3-1DD2-11B2-99A6-080020736631",
+ "BF02": "6A87C46F-1DD2-11B2-99A6-080020736631",
+ "BF03": "6A8B642B-1DD2-11B2-99A6-080020736631",
+ "BF04": "6A8EF2E9-1DD2-11B2-99A6-080020736631",
+ "BF05": "6A90BA39-1DD2-11B2-99A6-080020736631",
+ "BF06": "6A9283A5-1DD2-11B2-99A6-080020736631",
+ "BF07": "6A945A3B-1DD2-11B2-99A6-080020736631",
+ "BF08": "6A9630D1-1DD2-11B2-99A6-080020736631",
+ "BF09": "6A980767-1DD2-11B2-99A6-080020736631",
+ "BF0A": "6A96237F-1DD2-11B2-99A6-080020736631",
+ "BF0B": "6A8D2AC7-1DD2-11B2-99A6-080020736631",
+ "C001": "75894C1E-3AEB-11D3-B7C1-7B03A0000000",
+ "C002": "E2A1E728-32E3-11D6-A682-7B03A0000000",
+ "E100": "7412F7D5-A156-4B13-81DC-867174929325",
+ "E101": "D4E6E2CD-4469-46F3-B5CB-1BFF57AFC149",
+ "E900": "8C8F8EFF-AC95-4770-814A-21994F2DBC8F",
+ "EA00": "BC13C2FF-59E6-4262-A352-B275FD6F7172",
+ "EB00": "42465331-3BA3-10F1-802A-4861696B7521",
+ "ED00": "F4019732-066E-4E12-8273-346C5641494F",
+ "ED01": "BFBFAFE7-A34F-448A-9A5B-6213EB736C22",
+ "EF00": "C12A7328-F81F-11D2-BA4B-00A0C93EC93B",
+ "EF01": "024DEE41-33E7-11D3-9D69-0008C781F39F",
+ "EF02": "21686148-6449-6E6F-744E-656564454649",
+ "F100": "FE8A2634-5E2E-46BA-99E3-3A192091A350",
+ "F101": "D9FD4535-106C-4CEC-8D37-DFC020CA87CB",
+ "F102": "A409E16B-78AA-4ACC-995C-302352621A41",
+ "F103": "F95D940E-CABA-4578-9B93-BB6C90F29D3E",
+ "F104": "10B8DBAA-D2BF-42A9-98C6-A7C5DB3701E7",
+ "F105": "49FD7CB8-DF15-4E73-B9D9-992070127F0F",
+ "F106": "421A8BFC-85D9-4D85-ACDA-B64EEC0133E9",
+ "F107": "9B37FFF6-2E58-466A-983A-F7926D0B04E0",
+ "F108": "C12A7328-F81F-11D2-BA4B-00A0C93EC93B",
+ "F109": "606B000B-B7C7-4653-A7D5-B737332C899D",
+ "F10A": "08185F0C-892D-428A-A789-DBEEC8F55E6A",
+ "F10B": "48435546-4953-2041-494E-5354414C4C52",
+ "F10C": "2967380E-134C-4CBB-B6DA-17E7CE1CA45D",
+ "F10D": "41D0E340-57E3-954E-8C1E-17ECAC44CFF5",
+ "F10E": "DE30CC86-1F4A-4A31-93C4-66F147D33E05",
+ "F10F": "23CC04DF-C278-4CE7-8471-897D1A4BCDF7",
+ "F110": "A0E5CF57-2DEF-46BE-A80C-A2067C37CD49",
+ "F111": "4E5E989E-4C86-11E8-A15B-480FCF35F8E6",
+ "F112": "5A3A90BE-4C86-11E8-A15B-480FCF35F8E6",
+ "F113": "5ECE94FE-4C86-11E8-A15B-480FCF35F8E6",
+ "F114": "8B94D043-30BE-4871-9DFA-D69556E8C1F3",
+ "F115": "A13B4D9A-EC5F-11E8-97D8-6C3BE52705BF",
+ "F116": "A288ABF2-EC5F-11E8-97D8-6C3BE52705BF",
+ "F117": "6A2460C3-CD11-4E8B-80A8-12CCE268ED0A",
+ "F118": "1D75395D-F2C6-476B-A8B7-45CC1C97B476",
+ "F119": "900B0FC5-90CD-4D4F-84F9-9F8ED579DB88",
+ "F11A": "B2B2E8D1-7C10-4EBC-A2D0-4614568260AD",
+ "F800": "4FBD7E29-9D25-41B8-AFD0-062C0CEFF05D",
+ "F801": "4FBD7E29-9D25-41B8-AFD0-5EC00CEFF05D",
+ "F802": "45B0969E-9B03-4F30-B4C6-B4B80CEFF106",
+ "F803": "45B0969E-9B03-4F30-B4C6-5EC00CEFF106",
+ "F804": "89C57F98-2FE5-4DC0-89C1-F3AD0CEFF2BE",
+ "F805": "89C57F98-2FE5-4DC0-89C1-5EC00CEFF2BE",
+ "F806": "CAFECAFE-9B03-4F30-B4C6-B4B80CEFF106",
+ "F807": "30CD0809-C2B2-499C-8879-2D6B78529876",
+ "F808": "5CE17FCE-4087-4169-B7FF-056CC58473F9",
+ "F809": "FB3AABF9-D25F-47CC-BF5E-721D1816496B",
+ "F80A": "4FBD7E29-8AE0-4982-BF9D-5A8D867AF560",
+ "F80B": "45B0969E-8AE0-4982-BF9D-5A8D867AF560",
+ "F80C": "CAFECAFE-8AE0-4982-BF9D-5A8D867AF560",
+ "F80D": "7F4A666A-16F3-47A2-8445-152EF4D03F6C",
+ "F80E": "EC6D6385-E346-45DC-BE91-DA2A7C8B3261",
+ "F80F": "01B41E1B-002A-453C-9F17-88793989FF8F",
+ "F810": "CAFECAFE-9B03-4F30-B4C6-5EC00CEFF106",
+ "F811": "93B0052D-02D9-4D8A-A43B-33A3EE4DFBC3",
+ "F812": "306E8683-4FE2-4330-B7C0-00A917C16966",
+ "F813": "45B0969E-9B03-4F30-B4C6-35865CEFF106",
+ "F814": "CAFECAFE-9B03-4F30-B4C6-35865CEFF106",
+ "F815": "166418DA-C469-4022-ADF4-B30AFD37F176",
+ "F816": "86A32090-3647-40B9-BBBD-38D8C573AA86",
+ "F817": "4FBD7E29-9D25-41B8-AFD0-35865CEFF05D",
+ "FB00": "AA31E02A-400F-11DB-9590-000C2911D1B8",
+ "FB01": "9198EFFC-31C0-11DB-8F78-000C2911D1B8",
+ "FC00": "9D275380-40AD-11DB-BF97-000C2911D1B8",
+ "FD00": "A19D880F-05FC-4D3B-A006-743F0F84911E",
+}
+
+gpt_id_to_sgdisk = {v: k for k, v in reversed(sgdisk_to_gpt_id.items())}
def check_partition_gpt_layout(device, layout):
prt_cmd = [SGDISK_CMD, "-p", device]
--
2.39.3

@ -1,15 +1,15 @@
From 52c04e1a523a450dfce70bc441963eb6a026eb59 Mon Sep 17 00:00:00 2001
From fba185085b53f7813b433166c00c0249ea4f2ac3 Mon Sep 17 00:00:00 2001
From: Ani Sinha <anisinha@redhat.com>
Date: Thu, 20 Jun 2024 11:18:40 +0530
Subject: [PATCH 3/6] doc: update examples to reflect alternative ways to
Subject: [PATCH 3/4] doc: update examples to reflect alternative ways to
provide `sudo` option (#5418)
RH-Author: Ani Sinha <anisinha@redhat.com>
RH-MergeRequest: 90: fix(jsonschema): Add missing sudo definition (#5418)
RH-Jira: RHEL-44337
RH-MergeRequest: 91: fix(jsonschema): Add missing sudo definition (#5418)
RH-Jira: RHEL-44338
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [2/2] 62eac6d731cb725c32cd0beac0219ecc2b407198 (anisinha/cloud-init)
RH-Commit: [2/2] fdaf2d29b4e90882435bfcdcb57a3b8a1d574082 (anisinha/cloud-init)
For creating users and groups, it is possible to pass a `sudo` option to the
config file that accepts a sudo rule. The option can be a sudo rule string,

@ -1,14 +1,14 @@
From c933187af44a5de1d6eafde5dcd48e8ac369cf34 Mon Sep 17 00:00:00 2001
From d64a8c310bd73c00ad88898be507d48ef653bfe4 Mon Sep 17 00:00:00 2001
From: James Falcon <james.falcon@canonical.com>
Date: Thu, 18 Apr 2024 20:21:14 -0500
Subject: [PATCH 2/3] docs: Add deprecated system_info to schema (#5168)
RH-Author: Ani Sinha <anisinha@redhat.com>
RH-MergeRequest: 95: Deprecate the users ssh-authorized-keys property (#5162)
RH-Jira: RHEL-45262
RH-MergeRequest: 94: Deprecate the users ssh-authorized-keys property (#5162)
RH-Jira: RHEL-45263
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [2/3] c4ea6f45ee0997e2f749c290fb8f2ceb8c05c691 (anisinha/cloud-init)
RH-Commit: [2/3] c3454815e569896df0368ddbda0c648216363ed0 (anisinha/cloud-init)
In some cases, `system_info` can be passed via user data or vendor data
to override the system_info in /etc/cloud/cloud.cfg . While this
@ -18,33 +18,23 @@ indicate that it is deprecated.
Also remove/update examples.
(cherry picked from commit 7c67f7732f04b41600934818f7d5bcb4d085ed7c)
Conflicts:
cloudinit/config/schemas/schema-cloud-config-v1.json
- due to change fdefe08ad19cea5eb ("fix: Fix typos (#4850)") not
present in downstream.
doc/examples/cloud-config-user-groups.txt
- due to change 0aa17cd10bdd6 ("docs: set the home directory using homedir, not home (#5101)")
not present downstream.
tests/unittests/sources/test_vultr.py
- due to change 144782a838 ("test: Remove side effects from tests (#5074)") not present
downstream.
---
.../schemas/schema-cloud-config-v1.json | 7 ++++++
doc/examples/cloud-config-apt.txt | 23 -------------------
doc/examples/cloud-config-user-groups.txt | 12 ++--------
tests/data/user_data.1.txt | 10 --------
tests/unittests/runs/test_merge_run.py | 16 ++++++++++++-
5 files changed, 24 insertions(+), 44 deletions(-)
tests/unittests/sources/test_vultr.py | 3 ---
6 files changed, 24 insertions(+), 47 deletions(-)
diff --git a/cloudinit/config/schemas/schema-cloud-config-v1.json b/cloudinit/config/schemas/schema-cloud-config-v1.json
index 670ef4c2..97cf2b74 100644
index 24b6c4bd..23573583 100644
--- a/cloudinit/config/schemas/schema-cloud-config-v1.json
+++ b/cloudinit/config/schemas/schema-cloud-config-v1.json
@@ -513,6 +513,12 @@
@@ -602,6 +602,12 @@
},
"merge_type": {
"$ref": "#/$defs/merge_defintion"
"$ref": "#/$defs/merge_definition"
+ },
+ "system_info": {
+ "type": "object",
@ -54,14 +44,14 @@ index 670ef4c2..97cf2b74 100644
}
}
},
@@ -3905,6 +3911,7 @@
@@ -3894,6 +3900,7 @@
"ssh_pwauth": {},
"ssh_quiet_keygen": {},
"swap": {},
+ "system_info": {},
"timezone": {},
"ubuntu_advantage": {},
"updates": {},
"ubuntu_pro": {},
diff --git a/doc/examples/cloud-config-apt.txt b/doc/examples/cloud-config-apt.txt
index dd6a0f6a..04968035 100644
--- a/doc/examples/cloud-config-apt.txt
@ -135,7 +125,7 @@ index 4c4543de..a1b5aa60 100644
- primary: []
- security: []
diff --git a/tests/unittests/runs/test_merge_run.py b/tests/unittests/runs/test_merge_run.py
index afc256ec..251c5ae5 100644
index 7b1559b9..e7f32d03 100644
--- a/tests/unittests/runs/test_merge_run.py
+++ b/tests/unittests/runs/test_merge_run.py
@@ -22,7 +22,21 @@ class TestMergeRun(helpers.FilesystemMockingTestCase):
@ -161,6 +151,20 @@ index afc256ec..251c5ae5 100644
}
ud = helpers.readResource("user_data.1.txt")
cloud_cfg = safeyaml.dumps(cfg)
diff --git a/tests/unittests/sources/test_vultr.py b/tests/unittests/sources/test_vultr.py
index 117fdab0..e5f1c39e 100644
--- a/tests/unittests/sources/test_vultr.py
+++ b/tests/unittests/sources/test_vultr.py
@@ -22,9 +22,6 @@ chpasswd:
expire: false
list:
- root:$6$SxXx...k2mJNIzZB5vMCDBlYT1
-system_info:
- default_user:
- name: root
"""
# Vultr metadata test data
--
2.39.3

@ -0,0 +1,147 @@
From 1a2f6a3e17aff53bcc239d66b7095ea0441b5d7b Mon Sep 17 00:00:00 2001
From: Ani Sinha <anisinha@redhat.com>
Date: Tue, 21 May 2024 03:04:06 +0530
Subject: [PATCH] feat: Set RH ssh key permissions when no 'ssh_keys' group
(#5296)
RH-Author: Ani Sinha <anisinha@redhat.com>
RH-MergeRequest: 83: feat: Set RH ssh key permissions when no 'ssh_keys' group (#5296)
RH-Jira: RHEL-36456
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
RH-Acked-by: Cathy Avery <cavery@redhat.com>
RH-Commit: [1/1] d32c2c56227903cc00d3f807500e8cbda478b5c8 (anisinha/cloud-init)
Fedora core 38 and above, centos 10 stream and all distributions derived from
them do not have the group 'ssh_keys'. Please see the fedora rawhide change
https://src.fedoraproject.org/rpms/openssh/c/7a21555354a2c5e724aa4c287b640c24bf108780?branch=rawhide
In those distributions, openssh versions are 9 and above. The private
key permissions are set as 0o600 and the public key permissions are set as
0o644 from sshd-keygen utility. The 'root' group owns the keys.
Please see
https://src.fedoraproject.org/rpms/openssh/c/b615362fd0b4da657d624571441cb74983de6e3f?branch=rawhide
In older releases where 'ssh_keys' group is present, the private key
permissions are set as 0o640. Public key permissions are 0o644. These
releases have openssh version less than 9.
Since cloud-init generates the keys and not the sshd-genkey utility,
permissions must be set accordingly for cloud-init generated public and
private keys for all cases. This includes cases where 'ssh_keys' group is
absent. This change fixes this. The code has been reworked a little
bit so as to simplify things. Unit tests have been adjusted accordingly.
Signed-off-by: Ani Sinha <anisinha@redhat.com>
(cherry picked from commit 23136e6a94821320a85117a2e4c4bb9b0926541f)
---
cloudinit/config/cc_ssh.py | 48 +++++++++++++++++++++------
tests/unittests/config/test_cc_ssh.py | 15 ++++-----
2 files changed, 45 insertions(+), 18 deletions(-)
diff --git a/cloudinit/config/cc_ssh.py b/cloudinit/config/cc_ssh.py
index f69e49c1..d44e1302 100644
--- a/cloudinit/config/cc_ssh.py
+++ b/cloudinit/config/cc_ssh.py
@@ -184,6 +184,42 @@ for k in GENERATE_KEY_NAMES:
KEY_GEN_TPL = 'o=$(ssh-keygen -yf "%s") && echo "$o" root@localhost > "%s"'
+def set_redhat_keyfile_perms(keyfile: str) -> None:
+ """
+ For fedora 37, centos 9 stream and below:
+ - sshd version is earlier than version 9.
+ - 'ssh_keys' group is present and owns the private keys.
+ - private keys have permission 0o640.
+ For fedora 38, centos 10 stream and above:
+ - ssh version is atleast version 9.
+ - 'ssh_keys' group is absent. 'root' group owns the keys.
+ - private keys have permission 0o600, same as upstream.
+ Public keys in all cases have permission 0o644.
+ """
+ permissions_public = 0o644
+ ssh_version = ssh_util.get_opensshd_upstream_version()
+ if ssh_version and ssh_version < util.Version(9, 0):
+ # fedora 37, centos 9 stream and below has sshd
+ # versions less than 9 and private key permissions are
+ # set to 0o640 from sshd-keygen.
+ # See sanitize permissions" section in sshd-keygen.
+ permissions_private = 0o640
+ else:
+ # fedora 38, centos 10 stream and above. sshd-keygen sets
+ # private key persmissions to 0o600.
+ permissions_private = 0o600
+
+ gid = util.get_group_id("ssh_keys")
+ if gid != -1:
+ # 'ssh_keys' group exists for fedora 37, centos 9 stream
+ # and below. On these distros, 'ssh_keys' group own the private
+ # keys. When 'ssh_keys' group is absent for newer distros,
+ # 'root' group owns the private keys which is the default.
+ os.chown(keyfile, -1, gid)
+ os.chmod(keyfile, permissions_private)
+ os.chmod(f"{keyfile}.pub", permissions_public)
+
+
def handle(name: str, cfg: Config, cloud: Cloud, args: list) -> None:
# remove the static keys from the pristine image
@@ -280,16 +316,8 @@ def handle(name: str, cfg: Config, cloud: Cloud, args: list) -> None:
):
sys.stdout.write(util.decode_binary(out))
- gid = util.get_group_id("ssh_keys")
- if gid != -1:
- # perform same "sanitize permissions" as sshd-keygen
- permissions_private = 0o600
- ssh_version = ssh_util.get_opensshd_upstream_version()
- if ssh_version and ssh_version < util.Version(9, 0):
- permissions_private = 0o640
- os.chown(keyfile, -1, gid)
- os.chmod(keyfile, permissions_private)
- os.chmod(f"{keyfile}.pub", 0o644)
+ if cloud.distro.osfamily == "redhat":
+ set_redhat_keyfile_perms(keyfile)
except subp.ProcessExecutionError as e:
err = util.decode_binary(e.stderr).lower()
if e.exit_code == 1 and err.lower().startswith(
diff --git a/tests/unittests/config/test_cc_ssh.py b/tests/unittests/config/test_cc_ssh.py
index 102519eb..49327bb6 100644
--- a/tests/unittests/config/test_cc_ssh.py
+++ b/tests/unittests/config/test_cc_ssh.py
@@ -307,7 +307,7 @@ class TestHandleSsh:
@pytest.mark.parametrize(
"ssh_keys_group_exists,sshd_version,expected_private_permissions",
- [(False, 0, 0), (True, 8, 0o640), (True, 10, 0o600)],
+ [(False, 9, 0o600), (True, 8, 0o640), (True, 10, 0o600)],
)
@mock.patch(MODPATH + "subp.subp", return_value=("", ""))
@mock.patch(MODPATH + "util.get_group_id", return_value=10)
@@ -336,18 +336,17 @@ class TestHandleSsh:
m_gid.return_value = 10 if ssh_keys_group_exists else -1
m_sshd_version.return_value = util.Version(sshd_version, 0)
key_path = cc_ssh.KEY_FILE_TPL % "rsa"
- cloud = get_cloud(distro="ubuntu")
+ cloud = get_cloud(distro="centos")
cc_ssh.handle("name", {"ssh_genkeytypes": ["rsa"]}, cloud, [])
if ssh_keys_group_exists:
m_chown.assert_called_once_with(key_path, -1, 10)
- assert m_chmod.call_args_list == [
- mock.call(key_path, expected_private_permissions),
- mock.call(f"{key_path}.pub", 0o644),
- ]
else:
- m_sshd_version.assert_not_called()
m_chown.assert_not_called()
- m_chmod.assert_not_called()
+
+ assert m_chmod.call_args_list == [
+ mock.call(key_path, expected_private_permissions),
+ mock.call(f"{key_path}.pub", 0o644),
+ ]
@pytest.mark.parametrize("with_sshd_dconf", [False, True])
@mock.patch(MODPATH + "util.ensure_dir")
--
2.39.3

@ -1,207 +0,0 @@
From c21351ad9da5aebcb252aa36cbfa92ac16fa9746 Mon Sep 17 00:00:00 2001
From: Florian Apolloner <florian@apolloner.eu>
Date: Fri, 5 Jan 2024 19:07:12 +0100
Subject: [PATCH 2/3] feat: apply global DNS to interfaces in network-manager
(#4723)
RH-Author: Cathy Avery <cavery@redhat.com>
RH-MergeRequest: 72: Fixes for cloud-init fails to configure DNS/search domains for network-config v1
RH-Jira: RHEL-20964
RH-Acked-by: Ani Sinha <anisinha@redhat.com>
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
RH-Commit: [2/2] 1d2b10133ec2558e9665f21f53e4b1a898e283a8 (cavery/cloud-init-c-9-s)
Sometimes DNS settings in cloud configs are specified globally and
not per interface / subnet. This results in a configuration without
proper nameservers. This was fixed for netplan in d29eeccd and is
now also applied to the network-manager renderer.
Co-authored-by: James Falcon <james.falcon@canonical.com>
(cherry picked from commit 0d787d0a262f70ff848b315633742aa8fc45a1de)
Signed-off-by: Cathy Avery <cavery@redhat.com>
---
cloudinit/net/network_manager.py | 52 ++++++++++++++---------
tests/unittests/net/test_net_rendering.py | 3 ++
tests/unittests/test_net.py | 11 +++++
tools/.github-cla-signers | 1 +
4 files changed, 47 insertions(+), 20 deletions(-)
diff --git a/cloudinit/net/network_manager.py b/cloudinit/net/network_manager.py
index bd6e6d75..0ba210b7 100644
--- a/cloudinit/net/network_manager.py
+++ b/cloudinit/net/network_manager.py
@@ -246,7 +246,7 @@ class NMConnection:
"""
return addr.replace("-", ":").upper()
- def render_interface(self, iface, renderer):
+ def render_interface(self, iface, network_state, renderer):
"""
Integrate information from network state interface information
into the connection. Most of the work is done here.
@@ -311,7 +311,6 @@ class NMConnection:
found_dns_search = []
# Deal with Layer 3 configuration
- use_top_level_dns = "dns" in iface
for subnet in iface["subnets"]:
family = "ipv6" if subnet_is_ipv6(subnet) else "ipv4"
@@ -322,26 +321,39 @@ class NMConnection:
self.config[family]["gateway"] = subnet["gateway"]
for route in subnet["routes"]:
self._add_route(route)
- if not use_top_level_dns and "dns_nameservers" in subnet:
- for nameserver in subnet["dns_nameservers"]:
- found_nameservers.append(nameserver)
- if not use_top_level_dns and "dns_search" in subnet:
- found_dns_search.append(subnet["dns_search"])
+ # Add subnet-level DNS
+ if "dns_nameservers" in subnet:
+ found_nameservers.extend(subnet["dns_nameservers"])
+ if "dns_search" in subnet:
+ found_dns_search.extend(subnet["dns_search"])
if family == "ipv4" and "mtu" in subnet:
ipv4_mtu = subnet["mtu"]
- # Now add our DNS search domains. We add them later because we
- # only want them if an IP family has already been defined
- if use_top_level_dns:
- for nameserver in iface["dns"]["nameservers"]:
- self._add_nameserver(nameserver)
- if iface["dns"]["search"]:
- self._add_dns_search(iface["dns"]["search"])
- else:
- for nameserver in found_nameservers:
- self._add_nameserver(nameserver)
- for dns_search in found_dns_search:
- self._add_dns_search(dns_search)
+ # Add interface-level DNS
+ if "dns" in iface:
+ found_nameservers += [
+ dns
+ for dns in iface["dns"]["nameservers"]
+ if dns not in found_nameservers
+ ]
+ found_dns_search += [
+ search
+ for search in iface["dns"]["search"]
+ if search not in found_dns_search
+ ]
+
+ # We prefer any interface-specific DNS entries, but if we do not
+ # have any, add the global DNS to the connection
+ if not found_nameservers and network_state.dns_nameservers:
+ found_nameservers = network_state.dns_nameservers
+ if not found_dns_search and network_state.dns_searchdomains:
+ found_dns_search = network_state.dns_searchdomains
+
+ # Write out all DNS entries to the connection
+ for nameserver in found_nameservers:
+ self._add_nameserver(nameserver)
+ if found_dns_search:
+ self._add_dns_search(found_dns_search)
# we do not want to set may-fail to false for both ipv4 and ipv6 dhcp
# at the at the same time. This will make the network configuration
@@ -457,7 +469,7 @@ class Renderer(renderer.Renderer):
# Now render the actual interface configuration
for iface in network_state.iter_interfaces():
conn = self.connections[iface["name"]]
- conn.render_interface(iface, self)
+ conn.render_interface(iface, network_state, self)
# And finally write the files
for con_id, conn in self.connections.items():
diff --git a/tests/unittests/net/test_net_rendering.py b/tests/unittests/net/test_net_rendering.py
index 06feab89..f340ffc1 100644
--- a/tests/unittests/net/test_net_rendering.py
+++ b/tests/unittests/net/test_net_rendering.py
@@ -88,6 +88,9 @@ def _check_network_manager(network_state: NetworkState, tmp_path: Path):
"test_name, renderers",
[("no_matching_mac_v2", Renderer.Netplan | Renderer.NetworkManager)],
)
+@pytest.mark.xfail(
+ reason="v2 interface-specific DNS errantly gets applied globally"
+)
def test_convert(test_name, renderers, tmp_path):
network_config = safeyaml.load(
Path(ARTIFACT_DIR, f"{test_name}.yaml").read_text()
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
index 2a99f150..d7c9a414 100644
--- a/tests/unittests/test_net.py
+++ b/tests/unittests/test_net.py
@@ -646,6 +646,7 @@ method=manual
may-fail=false
address1=172.19.1.34/22
route1=0.0.0.0/0,172.19.3.254
+dns=172.19.0.12;
""".lstrip(),
),
@@ -2797,6 +2798,8 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
[ipv4]
method=auto
may-fail=false
+ dns=8.8.8.8;4.4.4.4;8.8.4.4;
+ dns-search=barley.maas;wark.maas;foobar.maas;
"""
),
@@ -2822,6 +2825,8 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
method=manual
may-fail=false
address1=192.168.200.7/24
+ dns=8.8.8.8;4.4.4.4;8.8.4.4;
+ dns-search=barley.maas;wark.maas;foobar.maas;
"""
),
@@ -2846,6 +2851,8 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
[ipv4]
method=auto
may-fail=false
+ dns=8.8.8.8;4.4.4.4;8.8.4.4;
+ dns-search=barley.maas;wark.maas;foobar.maas;
"""
),
@@ -2930,12 +2937,15 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
method=manual
may-fail=false
address1=192.168.14.2/24
+ dns=8.8.8.8;4.4.4.4;8.8.4.4;
+ dns-search=barley.maas;wark.maas;foobar.maas;
[ipv6]
method=manual
may-fail=false
address1=2001:1::1/64
route1=::/0,2001:4800:78ff:1b::1
+ dns-search=barley.maas;wark.maas;foobar.maas;
"""
),
@@ -2990,6 +3000,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
[ipv6]
method=auto
may-fail=false
+ dns-search=barley.maas;wark.maas;foobar.maas;
"""
),
diff --git a/tools/.github-cla-signers b/tools/.github-cla-signers
index dbdb9cfa..f4da0989 100644
--- a/tools/.github-cla-signers
+++ b/tools/.github-cla-signers
@@ -13,6 +13,7 @@ andrewbogott
andrewlukoshko
ani-sinha
antonyc
+apollo13
aswinrajamannar
bdrung
beantaxi
--
2.39.3

@ -1,15 +1,15 @@
From 6b32b371bfd37759ddce3d7f29d15546500698e6 Mon Sep 17 00:00:00 2001
From 6090957ba065b799f03eb1f767653d7ce65c59e7 Mon Sep 17 00:00:00 2001
From: Ani Sinha <anisinha@redhat.com>
Date: Thu, 20 Jun 2024 22:27:03 +0530
Subject: [PATCH 1/6] feat(sysconfig): Add DNS from interface config to
Subject: [PATCH 1/4] feat(sysconfig): Add DNS from interface config to
resolv.conf (#5401)
RH-Author: Ani Sinha <anisinha@redhat.com>
RH-MergeRequest: 88: feat(sysconfig): Add DNS from interface config to resolv.conf (#5401)
RH-Jira: RHEL-17961
RH-MergeRequest: 89: feat(sysconfig): Add DNS from interface config to resolv.conf (#5401)
RH-Jira: RHEL-44334
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [1/1] f353b73cc0f4bb9e1aee037708a1d3cb23b83cc3 (anisinha/cloud-init)
RH-Commit: [1/1] 71e88f087df08ddf6247faea2a5239ae02090bc9 (anisinha/cloud-init)
sysconfig renderer currently only uses global dns and search domain
configuration in order to populate /etc/resolv.conf. This means it ignores
@ -29,10 +29,10 @@ Signed-off-by: Ani Sinha <anisinha@redhat.com>
2 files changed, 230 insertions(+), 6 deletions(-)
diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
index d39f4fe3..7eb430ed 100644
index 1678fcde..32ee7901 100644
--- a/cloudinit/net/sysconfig.py
+++ b/cloudinit/net/sysconfig.py
@@ -825,20 +825,62 @@ class Renderer(renderer.Renderer):
@@ -825,11 +825,53 @@ class Renderer(renderer.Renderer):
@staticmethod
def _render_dns(network_state, existing_dns_path=None):
@ -89,9 +89,10 @@ index d39f4fe3..7eb430ed 100644
]
):
return None
content = resolv_conf.ResolvConf("")
if existing_dns_path and os.path.isfile(existing_dns_path):
content = resolv_conf.ResolvConf(util.load_file(existing_dns_path))
@@ -838,9 +880,9 @@ class Renderer(renderer.Renderer):
content = resolv_conf.ResolvConf(
util.load_text_file(existing_dns_path)
)
- for nameserver in network_state.dns_nameservers:
+ for nameserver in found_nameservers:
content.add_nameserver(nameserver)
@ -101,7 +102,7 @@ index d39f4fe3..7eb430ed 100644
header = _make_header(";")
content_str = str(content)
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
index d7c9a414..2d716f4b 100644
index fee8e035..de149f5e 100644
--- a/tests/unittests/test_net.py
+++ b/tests/unittests/test_net.py
@@ -516,6 +516,8 @@ OS_SAMPLES = [

@ -1,14 +1,14 @@
From 6a61ce0f0cde11551bfe92835d0b33c7b1022b68 Mon Sep 17 00:00:00 2001
From a6d02d8c4b4744e94638262ca28f998085f2558c Mon Sep 17 00:00:00 2001
From: James Falcon <james.falcon@canonical.com>
Date: Thu, 18 Apr 2024 20:27:27 -0500
Subject: [PATCH] fix: Add subnet ipv4/ipv6 to network schema (#5191)
RH-Author: Ani Sinha <anisinha@redhat.com>
RH-MergeRequest: 109: fix: Add subnet ipv4/ipv6 to network schema (#5191)
RH-Jira: RHEL-54686
RH-MergeRequest: 110: fix: Add subnet ipv4/ipv6 to network schema (#5191)
RH-Jira: RHEL-54688
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
RH-Acked-by: Cathy Avery <cavery@redhat.com>
RH-Commit: [1/1] 83692fac8f9af1831970091bdf7c43d0e59f314c (anisinha/cloud-init)
RH-Commit: [1/1] a63b3c5f534155aaff36cec137fe1ad7d2f9ed6b (anisinha/cloud-init)
These are used by our openstack network_data.json parsing code and
get used by the sysconfig renderer.
@ -22,10 +22,10 @@ Signed-off-by: Ani Sinha <anisinha@redhat.com>
1 file changed, 8 insertions(+)
diff --git a/cloudinit/config/schemas/schema-network-config-v1.json b/cloudinit/config/schemas/schema-network-config-v1.json
index 64c492a4..f485c784 100644
index 78628178..6f97f571 100644
--- a/cloudinit/config/schemas/schema-network-config-v1.json
+++ b/cloudinit/config/schemas/schema-network-config-v1.json
@@ -523,6 +523,14 @@
@@ -532,6 +532,14 @@
"items": {
"$ref": "#/$defs/anyOf_type_route"
}

@ -1,110 +0,0 @@
From 2f7f3dc6237ea70825dcb70f71d9718f631a9d95 Mon Sep 17 00:00:00 2001
From: James Falcon <james.falcon@canonical.com>
Date: Tue, 6 Feb 2024 09:24:37 -0600
Subject: [PATCH] fix: Add types to network v1 schema (#4841)
RH-Author: Cathy Avery <cavery@redhat.com>
RH-MergeRequest: 69: fix: Add types to network v1 schema (#4841)
RH-Jira: RHEL-21324
RH-Acked-by: Ani Sinha <None>
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
RH-Commit: [1/1] 59b2b4b07dd9eed956943a22b90af487f18b4cbd (cavery/cloud-init-c-9-s)
Conflicts:
No log argument as we are not including commit e168b4a1383b6eae9c1dc81411d7684fcbbf7df9
Even though it has conflicted with our documentation, we have allowed
nameserver address to a be a string, mtu to be empty, and nameserver
search to be missing. Since we have allowed these, expand our schema
and documentation accordingly.
Fixes GH-4710
(cherry picked from commit b08193b376552ede5d162d8283310adc783d81bf)
Signed-off-by: Cathy Avery <cavery@redhat.com>
---
.../config/schemas/schema-network-config-v1.json | 13 +++++++++----
doc/rtd/reference/network-config-format-v1.rst | 4 ++--
tests/unittests/config/test_schema.py | 13 +++++++++++++
3 files changed, 24 insertions(+), 6 deletions(-)
diff --git a/cloudinit/config/schemas/schema-network-config-v1.json b/cloudinit/config/schemas/schema-network-config-v1.json
index c77885ec..56dc27c9 100644
--- a/cloudinit/config/schemas/schema-network-config-v1.json
+++ b/cloudinit/config/schemas/schema-network-config-v1.json
@@ -24,7 +24,10 @@
"description": "The lowercase MAC address of the physical device."
},
"mtu": {
- "type": "integer",
+ "type": [
+ "integer",
+ "null"
+ ],
"description": "The MTU size in bytes. The ``mtu`` key represents a device's Maximum Transmission Unit, which is the largest size packet or frame, specified in octets (eight-bit bytes), that can be sent in a packet- or frame-based network. Specifying ``mtu`` is optional. Values too small or too large for a device may be ignored by that device."
},
"subnets": {
@@ -384,8 +387,7 @@
"additionalProperties": false,
"required": [
"type",
- "address",
- "search"
+ "address"
],
"properties": {
"type": {
@@ -396,7 +398,10 @@
},
"address": {
"description": "List of IPv4 or IPv6 address of nameservers.",
- "type": "array",
+ "type": [
+ "array",
+ "string"
+ ],
"items": {
"type": "string"
}
diff --git a/doc/rtd/reference/network-config-format-v1.rst b/doc/rtd/reference/network-config-format-v1.rst
index d267eb94..42f2dc22 100644
--- a/doc/rtd/reference/network-config-format-v1.rst
+++ b/doc/rtd/reference/network-config-format-v1.rst
@@ -252,8 +252,8 @@ Users can specify a ``nameserver`` type. Nameserver dictionaries include
the following keys:
- ``address``: List of IPv4 or IPv6 address of nameservers.
-- ``search``: List of hostnames to include in the :file:`resolv.conf` search
- path.
+- ``search``: Optional. List of hostnames to include in the :file:`resolv.conf`
+ search path.
- ``interface``: Optional. Ties the nameserver definition to the specified
interface. The value specified here must match the ``name`` of an interface
defined in this config. If unspecified, this nameserver will be considered
diff --git a/tests/unittests/config/test_schema.py b/tests/unittests/config/test_schema.py
index 28f0b39d..52667332 100644
--- a/tests/unittests/config/test_schema.py
+++ b/tests/unittests/config/test_schema.py
@@ -2048,6 +2048,19 @@ class TestNetworkSchema:
does_not_raise(),
id="bond_with_all_known_properties",
),
+ pytest.param(
+ {
+ "network": {
+ "version": 1,
+ "config": [
+ {"type": "physical", "name": "eth0", "mtu": None},
+ {"type": "nameserver", "address": "8.8.8.8"},
+ ],
+ }
+ },
+ does_not_raise(),
+ id="GH-4710_mtu_none_and_str_address",
+ ),
),
)
def test_network_schema(self, src_config, expectation):
--
2.39.3

@ -1,73 +0,0 @@
From 8ead44cb39f7726a695aa21a34820f6d40270829 Mon Sep 17 00:00:00 2001
From: James Falcon <james.falcon@canonical.com>
Date: Mon, 12 Feb 2024 14:48:01 -0600
Subject: [PATCH 5/6] fix: Address TIOBE abstract interpretation issues (#4866)
RH-Author: Ani Sinha <anisinha@redhat.com>
RH-MergeRequest: 92: Update pylint version to support python 3.12
RH-Jira: RHEL-44598
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [2/3] 3ca11206fa159ab45b2db21e78c4cfaf358b1e01 (anisinha/cloud-init)
These involve operations on possibly null variables or impossible logic.
(cherry picked from commit 5e7ef1032a12267a9a518358fbf89da0a88ddb99)
---
cloudinit/config/cc_lxd.py | 2 +-
cloudinit/distros/parsers/ifconfig.py | 6 ++++++
cloudinit/util.py | 1 +
3 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/cloudinit/config/cc_lxd.py b/cloudinit/config/cc_lxd.py
index cb9fc4f3..9f267b4c 100644
--- a/cloudinit/config/cc_lxd.py
+++ b/cloudinit/config/cc_lxd.py
@@ -432,7 +432,7 @@ def bridge_to_cmd(bridge_cfg):
% (bridge_cfg.get("ipv6_address"), bridge_cfg.get("ipv6_netmask"))
)
- if bridge_cfg.get("ipv6_nat", "false") == "true":
+ if bridge_cfg.get("ipv6_nat") == "true":
cmd_create.append("ipv6.nat=true")
else:
diff --git a/cloudinit/distros/parsers/ifconfig.py b/cloudinit/distros/parsers/ifconfig.py
index 516b5eb5..d671df1f 100644
--- a/cloudinit/distros/parsers/ifconfig.py
+++ b/cloudinit/distros/parsers/ifconfig.py
@@ -102,6 +102,7 @@ class Ifconfig:
"""
ifindex = 0
ifs_by_mac = defaultdict(list)
+ dev = None
for line in text.splitlines():
if len(line) == 0:
continue
@@ -119,6 +120,11 @@ class Ifconfig:
dev.index = ifindex
self._ifs_by_name[curif] = dev
+ if not dev:
+ # This shouldn't happen with normal ifconfig output, but
+ # if it does, ensure we don't Traceback
+ continue
+
toks = line.lower().strip().split()
if len(toks) > 1 and toks[1].startswith("flags="):
diff --git a/cloudinit/util.py b/cloudinit/util.py
index 3295735c..5f787c5c 100644
--- a/cloudinit/util.py
+++ b/cloudinit/util.py
@@ -1417,6 +1417,7 @@ def find_devs_with_netbsd(
devlist = []
label = None
_type = None
+ mscdlabel_out = ""
if criteria:
if criteria.startswith("LABEL="):
label = criteria.lstrip("LABEL=")
--
2.39.3

@ -1,66 +0,0 @@
From 62cec1e38e117fe6b24888862576ac57be14bbda Mon Sep 17 00:00:00 2001
From: James Falcon <james.falcon@canonical.com>
Date: Tue, 26 Mar 2024 15:55:50 -0500
Subject: [PATCH] fix: Always use single datasource if specified (#5098)
RH-Author: Ani Sinha <anisinha@redhat.com>
RH-MergeRequest: 82: fix: Always use single datasource if specified (#5098)
RH-Jira: RHEL-36255
RH-Acked-by: Cathy Avery <cavery@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [1/1] 068e97fcc18dd99f1112a9109acdb30fe2880f6e (anisinha/cloud-init)
This change may require a user to add `None` to the `datasource_list`
defined in `/etc/cloud/cloud.cfg[.d]` if they have a customized
datasource_list and want the DataSourceNone fallback behavior.
ds-identify would automatically append "None" to the datasource_list
if a single entry was provided in /etc/cloud/cloud.cfg[.d].
This wasn't a problem in the past as the python code would detect
a single datasource along with None as an indication to automatically
use that datasource. Since the python code no longer does that,
we should ensure that one specified datasource results in one specified
datasource after ds-identify has run.
Fixes GH-5091
(cherry picked from commit cdbbd17ae400e432d13f674c18a6f5c873fa328b)
Signed-off-by: Ani Sinha <anisinha@redhat.com>
---
tests/unittests/test_ds_identify.py | 2 +-
tools/ds-identify | 6 +++++-
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/tests/unittests/test_ds_identify.py b/tests/unittests/test_ds_identify.py
index ba0bf779..acbf3f03 100644
--- a/tests/unittests/test_ds_identify.py
+++ b/tests/unittests/test_ds_identify.py
@@ -522,7 +522,7 @@ class TestDsIdentify(DsIdentifyBase):
mydata = copy.deepcopy(VALID_CFG["Ec2-hvm"])
cfgpath = "etc/cloud/cloud.cfg.d/myds.cfg"
mydata["files"][cfgpath] = 'datasource_list: ["NoCloud"]\n'
- self._check_via_dict(mydata, rc=RC_FOUND, dslist=["NoCloud", DS_NONE])
+ self._check_via_dict(mydata, rc=RC_FOUND, dslist=["NoCloud"])
def test_configured_list_with_none(self):
"""When datasource_list already contains None, None is not added.
diff --git a/tools/ds-identify b/tools/ds-identify
index ec2cc18a..6e49ded3 100755
--- a/tools/ds-identify
+++ b/tools/ds-identify
@@ -1865,7 +1865,11 @@ _main() {
# if there is only a single entry in $DI_DSLIST
if [ $# -eq 1 ] || [ $# -eq 2 -a "$2" = "None" ] ; then
debug 1 "single entry in datasource_list ($DI_DSLIST) use that."
- found "$@"
+ if [ $# -eq 1 ]; then
+ write_result "datasource_list: [ $1 ]"
+ else
+ found "$@"
+ fi
return
fi
--
2.39.3

@ -1,13 +1,14 @@
From 914ac26ebd889b1f5cbb13d55fc011e92fc213c6 Mon Sep 17 00:00:00 2001
From 6906bf34c34c9b8814823d8b0106ff2291050b64 Mon Sep 17 00:00:00 2001
From: James Falcon <james.falcon@canonical.com>
Date: Thu, 18 Jul 2024 09:04:54 -0400
Subject: [PATCH 1/2] fix: Clean cache if no datasource fallback (#5499)
RH-Author: Ani Sinha <anisinha@redhat.com>
RH-MergeRequest: 103: fix: Clean cache if no datasource fallback (#5499)
RH-Jira: RHEL-49736
RH-MergeRequest: 102: fix: Clean cache if no datasource fallback (#5499)
RH-Jira: RHEL-49740
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
RH-Commit: [1/1] 37eacd97f5e60fae2f71d401c528d508d3db517e (anisinha/cloud-init)
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [1/1] c29d87704b653401b90213ec88f5611493c35027 (anisinha/cloud-init)
9929a00 added the ability to used a cached datasource when none is
found. This was supposed to be per-datasource, but the lack of cache
@ -30,10 +31,10 @@ Signed-off-by: Ani Sinha <anisinha@redhat.com>
create mode 100644 tests/integration_tests/datasources/test_caching.py
diff --git a/cloudinit/stages.py b/cloudinit/stages.py
index 0b795624..ace94c9a 100644
index 894eeac5..feda6753 100644
--- a/cloudinit/stages.py
+++ b/cloudinit/stages.py
@@ -378,6 +378,7 @@ class Init:
@@ -405,6 +405,7 @@ class Init:
ds,
)
else:
@ -227,10 +228,10 @@ index 00000000..33e4b671
+ )
+ util.verify_clean_boot(client)
diff --git a/tests/integration_tests/instances.py b/tests/integration_tests/instances.py
index 3fc6558a..23c0dc98 100644
index 1b09cba1..3e360464 100644
--- a/tests/integration_tests/instances.py
+++ b/tests/integration_tests/instances.py
@@ -88,7 +88,9 @@ class IntegrationInstance:
@@ -100,7 +100,9 @@ class IntegrationInstance:
# First push to a temporary directory because of permissions issues
tmp_path = _get_tmp_path()
self.instance.push_file(str(local_path), tmp_path)

@ -1,391 +0,0 @@
From aaf1d063f198ce09f0d539a85e1a1a2bb834520b Mon Sep 17 00:00:00 2001
From: James Falcon <james.falcon@canonical.com>
Date: Tue, 2 Jan 2024 11:29:17 -0600
Subject: [PATCH 1/3] fix: Correct v2 NetworkManager route rendering (#4637)
RH-Author: Cathy Avery <cavery@redhat.com>
RH-MergeRequest: 72: Fixes for cloud-init fails to configure DNS/search domains for network-config v1
RH-Jira: RHEL-20964
RH-Acked-by: Ani Sinha <anisinha@redhat.com>
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
RH-Commit: [1/2] fb865987dbcf506a674eb9798f9c06859539a696 (cavery/cloud-init-c-9-s)
fix: Correct v2 NetworkManager route rendering
Because network v2 route defintions can have mixed v4 and v6 routes, we
need to determine the IP family per route rather than per subnet.
Similar, ensure dns-search is rendered correctly.
Fixes GH-4518
(cherry picked from commit c2c100e8c9fd8709539b3ab2b0ee34c66ba3f2f7)
Signed-off-by: Cathy Avery <cavery@redhat.com>
---
cloudinit/net/__init__.py | 2 +
cloudinit/net/network_manager.py | 87 +++++++++-------
tests/unittests/test_net.py | 165 ++++++++++++++++++++++++++++++-
3 files changed, 219 insertions(+), 35 deletions(-)
diff --git a/cloudinit/net/__init__.py b/cloudinit/net/__init__.py
index c0888f52..65e7ff33 100644
--- a/cloudinit/net/__init__.py
+++ b/cloudinit/net/__init__.py
@@ -1287,6 +1287,8 @@ def subnet_is_ipv6(subnet) -> bool:
"""Common helper for checking network_state subnets for ipv6."""
# 'static6', 'dhcp6', 'ipv6_dhcpv6-stateful', 'ipv6_dhcpv6-stateless' or
# 'ipv6_slaac'
+ # This function is inappropriate for v2-based routes as routes defined
+ # under v2 subnets can contain ipv4 and ipv6 simultaneously
if subnet["type"].endswith("6") or subnet["type"] in IPV6_DYNAMIC_TYPES:
# This is a request either static6 type or DHCPv6.
return True
diff --git a/cloudinit/net/network_manager.py b/cloudinit/net/network_manager.py
index 76a0ac15..bd6e6d75 100644
--- a/cloudinit/net/network_manager.py
+++ b/cloudinit/net/network_manager.py
@@ -12,10 +12,15 @@ import itertools
import logging
import os
import uuid
-from typing import Optional
+from typing import List, Optional
from cloudinit import subp, util
-from cloudinit.net import is_ipv6_address, renderer, subnet_is_ipv6
+from cloudinit.net import (
+ is_ipv6_address,
+ is_ipv6_network,
+ renderer,
+ subnet_is_ipv6,
+)
from cloudinit.net.network_state import NetworkState
from cloudinit.net.sysconfig import available_nm_ifcfg_rh
@@ -158,11 +163,11 @@ class NMConnection:
if self.config[family]["method"] == "auto" and method == "manual":
return
- if (
- subnet_type == "ipv6_dhcpv6-stateful"
- or subnet_type == "ipv6_dhcpv6-stateless"
- or subnet_type == "ipv6_slaac"
- ):
+ if subnet_type in [
+ "ipv6_dhcpv6-stateful",
+ "ipv6_dhcpv6-stateless",
+ "ipv6_slaac",
+ ]:
# set ipv4 method to 'disabled' to align with sysconfig renderer.
self._set_default("ipv4", "method", "disabled")
@@ -174,7 +179,8 @@ class NMConnection:
Adds a numbered property, such as address<n> or route<n>, ensuring
the appropriate value gets used for <n>.
"""
-
+ if not self.config.has_section(section):
+ self.config[section] = {}
for index in itertools.count(1):
key = f"{key_prefix}{index}"
if not self.config.has_option(section, key):
@@ -189,40 +195,37 @@ class NMConnection:
value = subnet["address"] + "/" + str(subnet["prefix"])
self._add_numbered(family, "address", value)
- def _add_route(self, family, route):
- """
- Adds a ipv[46].route<n> property.
- """
-
+ def _add_route(self, route):
+ """Adds a ipv[46].route<n> property."""
+ # Because network v2 route definitions can have mixed v4 and v6
+ # routes, determine the family per route based on the gateway
+ family = "ipv6" if is_ipv6_network(route["gateway"]) else "ipv4"
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):
+ def _add_nameserver(self, dns: str) -> None:
"""
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_address(dns) else "ipv4"
- self._set_default(family, "method", "disabled")
-
- self._set_default(family, "dns", "")
- self.config[family]["dns"] = self.config[family]["dns"] + dns + ";"
+ if self.config.has_section(family):
+ self._set_default(family, "dns", "")
+ self.config[family]["dns"] = self.config[family]["dns"] + dns + ";"
- def _add_dns_search(self, family, dns_search):
+ def _add_dns_search(self, dns_search: List[str]) -> None:
"""
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) + ";"
- )
+ for family in ["ipv4", "ipv6"]:
+ if self.config.has_section(family):
+ self._set_default(family, "dns-search", "")
+ self.config[family]["dns-search"] = (
+ self.config[family]["dns-search"]
+ + ";".join(dns_search)
+ + ";"
+ )
def con_uuid(self):
"""
@@ -304,8 +307,11 @@ class NMConnection:
device_mtu = iface["mtu"]
ipv4_mtu = None
+ found_nameservers = []
+ found_dns_search = []
# Deal with Layer 3 configuration
+ use_top_level_dns = "dns" in iface
for subnet in iface["subnets"]:
family = "ipv6" if subnet_is_ipv6(subnet) else "ipv4"
@@ -315,15 +321,28 @@ class NMConnection:
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:
+ self._add_route(route)
+ if not use_top_level_dns and "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"])
+ found_nameservers.append(nameserver)
+ if not use_top_level_dns and "dns_search" in subnet:
+ found_dns_search.append(subnet["dns_search"])
if family == "ipv4" and "mtu" in subnet:
ipv4_mtu = subnet["mtu"]
+ # Now add our DNS search domains. We add them later because we
+ # only want them if an IP family has already been defined
+ if use_top_level_dns:
+ for nameserver in iface["dns"]["nameservers"]:
+ self._add_nameserver(nameserver)
+ if iface["dns"]["search"]:
+ self._add_dns_search(iface["dns"]["search"])
+ else:
+ for nameserver in found_nameservers:
+ self._add_nameserver(nameserver)
+ for dns_search in found_dns_search:
+ self._add_dns_search(dns_search)
+
# we do not want to set may-fail to false for both ipv4 and ipv6 dhcp
# at the at the same time. This will make the network configuration
# work only when both ipv4 and ipv6 dhcp succeeds. This may not be
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
index d9ef493b..2a99f150 100644
--- a/tests/unittests/test_net.py
+++ b/tests/unittests/test_net.py
@@ -2962,9 +2962,9 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
may-fail=false
address1=192.168.0.2/24
gateway=192.168.0.1
+ address2=192.168.2.10/24
dns=192.168.0.10;10.23.23.134;
dns-search=barley.maas;sacchromyces.maas;brettanomyces.maas;
- address2=192.168.2.10/24
"""
),
@@ -4154,6 +4154,148 @@ iface bond0 inet6 static
"""
),
},
+ "v2-mixed-routes": {
+ "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
+ autoconnect-priority=120
+ type=ethernet
+ interface-name=eth0
+
+ [user]
+ org.freedesktop.NetworkManager.origin=cloud-init
+
+ [ethernet]
+
+ [ipv4]
+ method=auto
+ may-fail=true
+ route1=169.254.42.42/32,62.210.0.1
+ route2=169.254.42.43/32,62.210.0.2
+ address1=192.168.1.20/16
+ dns=8.8.8.8;
+ dns-search=lab;home;
+
+ [ipv6]
+ route1=::/0,fe80::dc00:ff:fe20:186
+ route2=fe80::dc00:ff:fe20:188/64,fe80::dc00:ff:fe20:187
+ method=auto
+ may-fail=true
+ address1=2001:bc8:1210:232:dc00:ff:fe20:185/64
+ dns=FEDC::1;
+ dns-search=lab;home;
+
+ """
+ )
+ },
+ "yaml": textwrap.dedent(
+ """\
+ version: 2
+ ethernets:
+ eth0:
+ dhcp4: true
+ dhcp6: true
+ nameservers:
+ search: [lab, home]
+ addresses: [8.8.8.8, "FEDC::1"]
+ routes:
+ - to: 169.254.42.42/32
+ via: 62.210.0.1
+ - via: fe80::dc00:ff:fe20:186
+ to: ::/0
+ - to: 169.254.42.43/32
+ via: 62.210.0.2
+ - via: fe80::dc00:ff:fe20:187
+ to: fe80::dc00:ff:fe20:188
+ addresses:
+ - 192.168.1.20/16
+ - 2001:bc8:1210:232:dc00:ff:fe20:185/64
+ """
+ ),
+ },
+ "v2-dns-no-if-ips": {
+ "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
+ autoconnect-priority=120
+ type=ethernet
+ interface-name=eth0
+
+ [user]
+ org.freedesktop.NetworkManager.origin=cloud-init
+
+ [ethernet]
+
+ [ipv4]
+ method=auto
+ may-fail=true
+ dns=8.8.8.8;
+ dns-search=lab;home;
+
+ [ipv6]
+ method=auto
+ may-fail=true
+ dns=FEDC::1;
+ dns-search=lab;home;
+
+ """
+ )
+ },
+ "yaml": textwrap.dedent(
+ """\
+ version: 2
+ ethernets:
+ eth0:
+ dhcp4: true
+ dhcp6: true
+ nameservers:
+ search: [lab, home]
+ addresses: [8.8.8.8, "FEDC::1"]
+ """
+ ),
+ },
+ "v2-dns-no-dhcp": {
+ "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
+ autoconnect-priority=120
+ type=ethernet
+ interface-name=eth0
+
+ [user]
+ org.freedesktop.NetworkManager.origin=cloud-init
+
+ [ethernet]
+
+ """
+ )
+ },
+ "yaml": textwrap.dedent(
+ """\
+ version: 2
+ ethernets:
+ eth0:
+ nameservers:
+ search: [lab, home]
+ addresses: [8.8.8.8, "FEDC::1"]
+ """
+ ),
+ },
}
@@ -6267,6 +6409,27 @@ class TestNetworkManagerRendering(CiTestCase):
entry[self.expected_name], self.expected_conf_d, found
)
+ def test_v2_mixed_routes(self):
+ entry = NETWORK_CONFIGS["v2-mixed-routes"]
+ found = self._render_and_read(network_config=yaml.load(entry["yaml"]))
+ self._compare_files_to_expected(
+ entry[self.expected_name], self.expected_conf_d, found
+ )
+
+ def test_v2_dns_no_ips(self):
+ entry = NETWORK_CONFIGS["v2-dns-no-if-ips"]
+ found = self._render_and_read(network_config=yaml.load(entry["yaml"]))
+ self._compare_files_to_expected(
+ entry[self.expected_name], self.expected_conf_d, found
+ )
+
+ def test_v2_dns_no_dhcp(self):
+ entry = NETWORK_CONFIGS["v2-dns-no-dhcp"]
+ found = self._render_and_read(network_config=yaml.load(entry["yaml"]))
+ self._compare_files_to_expected(
+ entry[self.expected_name], self.expected_conf_d, found
+ )
+
@mock.patch(
"cloudinit.net.is_openvswitch_internal_interface",
--
2.39.3

@ -1,16 +1,9 @@
From cf35040b46abb66c7239d156bd92c7267d7c40f7 Mon Sep 17 00:00:00 2001
From 79668d45288e7a17bc627fdc05a609423161a44c Mon Sep 17 00:00:00 2001
From: PengpengSun <40026211+PengpengSun@users.noreply.github.com>
Date: Fri, 29 Mar 2024 22:39:13 +0800
Subject: [PATCH] fix: Fall back to cached local ds if no valid ds found
Subject: [PATCH 2/2] fix: Fall back to cached local ds if no valid ds found
(#4997)
RH-Author: Ani Sinha <anisinha@redhat.com>
RH-MergeRequest: 75: fix: Fall back to cached local ds if no valid ds found (#4997)
RH-Jira: RHEL-32846
RH-Acked-by: Cathy Avery <cavery@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [1/1] 408c41fd8009255d98c31210ef936f2e68dfde75 (anisinha/cloud-init)
Rebooting an instance which has finished VMware guest
customization with DataSourceVMware will load
DataSourceNone due to metadata is NOT available.
@ -37,10 +30,10 @@ Conflicts:
3 files changed, 53 insertions(+), 15 deletions(-)
diff --git a/cloudinit/sources/DataSourceVMware.py b/cloudinit/sources/DataSourceVMware.py
index 1591121d..2d5d42eb 100644
index 77a2de6c..2a91a307 100644
--- a/cloudinit/sources/DataSourceVMware.py
+++ b/cloudinit/sources/DataSourceVMware.py
@@ -197,7 +197,7 @@ class DataSourceVMware(sources.DataSource):
@@ -223,7 +223,7 @@ class DataSourceVMware(sources.DataSource):
break
if not self.data_access_method:
@ -49,7 +42,7 @@ index 1591121d..2d5d42eb 100644
return False
LOG.info("using data access method %s", self._get_subplatform())
@@ -291,6 +291,18 @@ class DataSourceVMware(sources.DataSource):
@@ -317,6 +317,18 @@ class DataSourceVMware(sources.DataSource):
self.metadata["instance-id"] = str(id_file.read()).rstrip().lower()
return self.metadata["instance-id"]
@ -69,10 +62,10 @@ index 1591121d..2d5d42eb 100644
for key_name in (
"public-keys-data",
diff --git a/cloudinit/sources/__init__.py b/cloudinit/sources/__init__.py
index c207b5ed..453801be 100644
index 4ea1fc56..e2b3029e 100644
--- a/cloudinit/sources/__init__.py
+++ b/cloudinit/sources/__init__.py
@@ -312,6 +312,10 @@ class DataSource(CloudInitPickleMixin, metaclass=abc.ABCMeta):
@@ -332,6 +332,10 @@ class DataSource(CloudInitPickleMixin, metaclass=abc.ABCMeta):
self.vendordata2_raw = None
if not hasattr(self, "skip_hotplug_detect"):
self.skip_hotplug_detect = False
@ -83,7 +76,7 @@ index c207b5ed..453801be 100644
if hasattr(self, "userdata") and self.userdata is not None:
# If userdata stores MIME data, on < python3.6 it will be
# missing the 'policy' attribute that exists on >=python3.6.
@@ -914,6 +918,16 @@ class DataSource(CloudInitPickleMixin, metaclass=abc.ABCMeta):
@@ -925,6 +929,16 @@ class DataSource(CloudInitPickleMixin, metaclass=abc.ABCMeta):
# quickly (local check only) if self.instance_id is still
return False
@ -101,10 +94,10 @@ index c207b5ed..453801be 100644
def _determine_dsmode(candidates, default=None, valid=None):
# return the first candidate that is non None, warn if not valid
diff --git a/cloudinit/stages.py b/cloudinit/stages.py
index 3b6405f5..0b795624 100644
index e95bb76f..894eeac5 100644
--- a/cloudinit/stages.py
+++ b/cloudinit/stages.py
@@ -353,20 +353,32 @@ class Init:
@@ -380,20 +380,32 @@ class Init:
LOG.debug(myrep.description)
if not ds:

@ -1,15 +1,15 @@
From 1df31428c87f08c790c300ba402318378cea8d65 Mon Sep 17 00:00:00 2001
From 60eca5a45a35982f42db58dd0d6d53bd2587e477 Mon Sep 17 00:00:00 2001
From: James Falcon <james.falcon@canonical.com>
Date: Thu, 10 Oct 2024 23:19:28 -0500
Subject: [PATCH 1/2] fix: Render bridges correctly for v2 on sysconfig with
Subject: [PATCH 2/3] fix: Render bridges correctly for v2 on sysconfig with
set-name (#5674)
RH-Author: xiachen <xiachen@redhat.com>
RH-MergeRequest: 147: fix: Render bridges correctly for v2 on sysconfig with set-name (#5674)
RH-Jira: RHEL-65021
RH-MergeRequest: 114: fix: Render bridges correctly for v2 on sysconfig with set-name (#5674)
RH-Jira: RHEL-65019
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
RH-Acked-by: Ani Sinha <anisinha@redhat.com>
RH-Commit: [1/2] 7f7fce173ee9a3ba719fc36580fbce813c5bfbd0 (xiachen/cloud-init)
RH-Commit: [1/2] 4171be9d48c4c4f7b8aa8d231cea8591daec9c93 (xiachen/cloud-init-centos)
When listing interfaces in v2 format, we should expect to be able to
reference other interfaces using the name in the configuration, not
@ -25,13 +25,13 @@ Fixes GH-5574
Signed-off-by: Amy Chen <xiachen@redhat.com>
---
cloudinit/net/eni.py | 6 +++
cloudinit/net/network_state.py | 30 ++++-------
cloudinit/net/network_state.py | 29 ++++------
cloudinit/net/sysconfig.py | 24 ++++++---
tests/unittests/test_net.py | 96 ++++++++++++++++++++++++++++++++++
4 files changed, 128 insertions(+), 28 deletions(-)
4 files changed, 128 insertions(+), 27 deletions(-)
diff --git a/cloudinit/net/eni.py b/cloudinit/net/eni.py
index 486fa22dc..ac0306d6a 100644
index 59dc395f..fa0b47af 100644
--- a/cloudinit/net/eni.py
+++ b/cloudinit/net/eni.py
@@ -5,6 +5,7 @@ import glob
@ -55,7 +55,7 @@ index 486fa22dc..ac0306d6a 100644
subnets = iface.get("subnets", {})
accept_ra = iface.pop("accept-ra", None)
diff --git a/cloudinit/net/network_state.py b/cloudinit/net/network_state.py
index 14c57cdcc..226421bd0 100644
index 9f34467b..fb08491f 100644
--- a/cloudinit/net/network_state.py
+++ b/cloudinit/net/network_state.py
@@ -411,6 +411,7 @@ class NetworkStateInterpreter:
@ -84,7 +84,7 @@ index 14c57cdcc..226421bd0 100644
"type": "physical",
}
match = cfg.get("match", {})
@@ -800,28 +803,15 @@ class NetworkStateInterpreter:
@@ -800,26 +803,14 @@ class NetworkStateInterpreter:
def _v2_common(self, cfg) -> None:
LOG.debug("v2_common: handling config:\n%s", cfg)
for iface, dev_cfg in cfg.items():
@ -102,11 +102,6 @@ index 14c57cdcc..226421bd0 100644
- name_cmd.update({"search": search})
- if len(dns) > 0:
- name_cmd.update({"address": dns})
+ if search:
+ name_cmd["search"] = search
+ if dns:
+ name_cmd["address"] = dns
self.handle_nameserver(name_cmd)
-
- mac_address: Optional[str] = dev_cfg.get("match", {}).get(
- "macaddress"
@ -115,12 +110,15 @@ index 14c57cdcc..226421bd0 100644
- real_if_name = find_interface_name_from_mac(mac_address)
- if real_if_name:
- iface = real_if_name
-
+ if search:
+ name_cmd["search"] = search
+ if dns:
+ name_cmd["address"] = dns
self._handle_individual_nameserver(name_cmd, iface)
def _handle_bond_bridge(self, command, cmd_type=None):
diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
index b50a6a8a0..e4a65187f 100644
index 503b6993..96652e15 100644
--- a/cloudinit/net/sysconfig.py
+++ b/cloudinit/net/sysconfig.py
@@ -6,7 +6,7 @@ import io
@ -141,7 +139,7 @@ index b50a6a8a0..e4a65187f 100644
iface_subnets = iface.get("subnets", [])
iface_cfg = iface_contents[iface_name]
route_cfg = iface_cfg.routes
@@ -924,7 +924,9 @@ class Renderer(renderer.Renderer):
@@ -926,7 +926,9 @@ class Renderer(renderer.Renderer):
return out
@classmethod
@ -152,7 +150,7 @@ index b50a6a8a0..e4a65187f 100644
bridge_key_map = {
old_k: new_k
for old_k, new_k in cls.cfg_key_maps[flavor].items()
@@ -1005,23 +1007,29 @@ class Renderer(renderer.Renderer):
@@ -1007,23 +1009,29 @@ class Renderer(renderer.Renderer):
@classmethod
def _render_sysconfig(
@ -188,10 +186,10 @@ index b50a6a8a0..e4a65187f 100644
cls._render_bond_interfaces(network_state, iface_contents, flavor)
cls._render_vlan_interfaces(network_state, iface_contents, flavor)
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
index 4673e4eaf..004da81ab 100644
index 00198232..41e6fa56 100644
--- a/tests/unittests/test_net.py
+++ b/tests/unittests/test_net.py
@@ -4489,6 +4489,95 @@ iface bond0 inet6 static
@@ -4822,6 +4822,95 @@ iface bond0 inet6 static
"""
),
},
@ -287,7 +285,7 @@ index 4673e4eaf..004da81ab 100644
}
@@ -5558,6 +5647,13 @@ USERCTL=no
@@ -5891,6 +5980,13 @@ USERCTL=no
self._compare_files_to_expected(entry[self.expected_name], found)
self._assert_headers(found)

@ -1,15 +1,15 @@
From 58904df7d689df6e3d1d4ddf47b5cb5a267006da Mon Sep 17 00:00:00 2001
From 59079c817ead856135ce40698f4d350a425cd65e Mon Sep 17 00:00:00 2001
From: James Falcon <james.falcon@canonical.com>
Date: Fri, 11 Oct 2024 13:58:19 -0500
Subject: [PATCH 2/2] fix: Render v2 bridges correctly on network-manager with
Subject: [PATCH 3/3] fix: Render v2 bridges correctly on network-manager with
set-name (#5740)
RH-Author: xiachen <xiachen@redhat.com>
RH-MergeRequest: 147: fix: Render bridges correctly for v2 on sysconfig with set-name (#5674)
RH-Jira: RHEL-65021
RH-MergeRequest: 114: fix: Render bridges correctly for v2 on sysconfig with set-name (#5674)
RH-Jira: RHEL-65019
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
RH-Acked-by: Ani Sinha <anisinha@redhat.com>
RH-Commit: [2/2] e101d8ff06a379752958a3eb19d209bcb7d1e0ed (xiachen/cloud-init)
RH-Commit: [2/2] a33642f97a8e5cb3816f17ce726187aa33825362 (xiachen/cloud-init-centos)
Similar to the recent sysconfig fix, ensure bridges render correctly
for configs that contain `set-name`.
@ -24,10 +24,10 @@ Signed-off-by: Amy Chen <xiachen@redhat.com>
2 files changed, 98 insertions(+), 2 deletions(-)
diff --git a/cloudinit/net/network_manager.py b/cloudinit/net/network_manager.py
index 0ba210b74..f50fafa39 100644
index a13d4c14..67614399 100644
--- a/cloudinit/net/network_manager.py
+++ b/cloudinit/net/network_manager.py
@@ -464,11 +464,13 @@ class Renderer(renderer.Renderer):
@@ -496,11 +496,13 @@ class Renderer(renderer.Renderer):
# interfaces that have UUIDs that can be linked to from related
# interfaces
for iface in network_state.iter_interfaces():
@ -44,10 +44,10 @@ index 0ba210b74..f50fafa39 100644
# And finally write the files
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
index 004da81ab..ddb45dc69 100644
index 41e6fa56..8a75c42b 100644
--- a/tests/unittests/test_net.py
+++ b/tests/unittests/test_net.py
@@ -4577,6 +4577,94 @@ iface bond0 inet6 static
@@ -4910,6 +4910,94 @@ iface bond0 inet6 static
"""
),
},
@ -142,7 +142,7 @@ index 004da81ab..ddb45dc69 100644
},
}
@@ -6722,6 +6810,12 @@ class TestNetworkManagerRendering(CiTestCase):
@@ -7102,6 +7190,12 @@ class TestNetworkManagerRendering(CiTestCase):
entry[self.expected_name], self.expected_conf_d, found
)

@ -1,42 +0,0 @@
From 332bb23bcfde801edf792e6c629ec350be07b952 Mon Sep 17 00:00:00 2001
From: James Falcon <james.falcon@canonical.com>
Date: Tue, 19 Mar 2024 14:24:11 -0500
Subject: [PATCH 3/3] fix: Undeprecate 'network' in schema route definition
(#5072)
RH-Author: Ani Sinha <anisinha@redhat.com>
RH-MergeRequest: 73: fix: Undeprecate 'network' in schema route definition (#5072)
RH-Jira: RHEL-29709
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
RH-Acked-by: Cathy Avery <cavery@redhat.com>
RH-Commit: [1/1] 61c660be43fd25999bca0cfd66d7b2150fee5a14 (anisinha/cloud-init)
It is passed through to our v1 schema from OpenStack network_data.json
Fixes GH-5051
(cherry picked from commit ff40d1af8a6de3ee27937382ec4ceea931d80a88)
Signed-off-by: Ani Sinha <anisinha@redhat.com>
---
cloudinit/config/schemas/schema-network-config-v1.json | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/cloudinit/config/schemas/schema-network-config-v1.json b/cloudinit/config/schemas/schema-network-config-v1.json
index 56dc27c9..64c492a4 100644
--- a/cloudinit/config/schemas/schema-network-config-v1.json
+++ b/cloudinit/config/schemas/schema-network-config-v1.json
@@ -445,10 +445,7 @@
},
"network": {
"type": "string",
- "description": "IPv4 network address with CIDR netmask notation or IPv6 with prefix length. Alias for ``destination`` and only read when ``destination`` key is absent.",
- "deprecated": true,
- "deprecated_version": "23.3",
- "deprecated_description": "Use ``destination`` instead."
+ "description": "IPv4 network address with CIDR netmask notation or IPv6 with prefix length. Alias for ``destination`` and only read when ``destination`` key is absent. This exists for OpenStack support. OpenStack route definitions are passed through to v1 config and OpenStack's ``network_data.json`` uses ``network`` instead of ``destination``."
},
"destination": {
"type": "string",
--
2.39.3

@ -1,15 +1,15 @@
From ed3c05af60c0d50a4576a63c8638e148e58ebf06 Mon Sep 17 00:00:00 2001
From ea306d2848490f3c962a2d80b88fc8dbe7c0ef84 Mon Sep 17 00:00:00 2001
From: Ani Sinha <anisinha@redhat.com>
Date: Thu, 11 Jul 2024 00:49:58 +0530
Subject: [PATCH] fix: add schema rules for 'baseurl' and 'metalink' in yum
repo config (#5501)
RH-Author: Ani Sinha <anisinha@redhat.com>
RH-MergeRequest: 101: fix: add schema rules for 'baseurl' and 'metalink' in yum repo config (#5501)
RH-Jira: RHEL-46873
RH-Author: xiachen <xiachen@redhat.com>
RH-MergeRequest: 100: fix: add schema rules for 'baseurl' and 'metalink' in yum repo config (#5501)
RH-Jira: RHEL-46874
RH-Acked-by: Ani Sinha <anisinha@redhat.com>
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
RH-Acked-by: xiachen <xiachen@redhat.com>
RH-Commit: [1/1] df01c93fde517e66ce71a66f80ee54d3ed504906 (anisinha/cloud-init)
RH-Commit: [1/1] 81ae8cf649785c5fb6296ca9d552248e6afb2960 (xiachen/cloud-init-centos)
At least one of (or both) 'baseurl' or 'metalink' should be provided for yum
repository specification. Add schema changes to enforce it. Without this,
@ -21,15 +21,16 @@ Error: Cloud config schema errors: yum_repos.epel-release: 'baseurl' is a requir
Signed-off-by: Ani Sinha <anisinha@redhat.com>
(cherry picked from commit 7d35664ef8b85840f92f18cc48187f7284d227bc)
Signed-off-by: Amy Chen <xiachen@redhat.com>
---
.../config/schemas/schema-cloud-config-v1.json | 18 ++++++++++++++++--
1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/cloudinit/config/schemas/schema-cloud-config-v1.json b/cloudinit/config/schemas/schema-cloud-config-v1.json
index 03e723e2..4fb7fd93 100644
index 3cf7aaf8..5758777a 100644
--- a/cloudinit/config/schemas/schema-cloud-config-v1.json
+++ b/cloudinit/config/schemas/schema-cloud-config-v1.json
@@ -3442,6 +3442,11 @@
@@ -3434,6 +3434,11 @@
"format": "uri",
"description": "URL to the directory where the yum repository's 'repodata' directory lives"
},
@ -41,7 +42,7 @@ index 03e723e2..4fb7fd93 100644
"name": {
"type": "string",
"description": "Optional human-readable name of the yum repo."
@@ -3469,8 +3474,17 @@
@@ -3461,8 +3466,17 @@
"description": "Any supported yum repository configuration options will be written to the yum repo config file. See: man yum.conf"
}
},

@ -1,58 +0,0 @@
From fcaff2e02a07af587d8366f61df1685435e32288 Mon Sep 17 00:00:00 2001
From: Brett Holman <brett.holman@canonical.com>
Date: Wed, 3 Jan 2024 09:11:40 -0700
Subject: [PATCH] fix(cloudstack): Use parsed lease file for virtual router in
cloudstack
RH-Author: Ani Sinha <anisinha@redhat.com>
RH-MergeRequest: 85: fix(cloudstack): Use parsed lease file for virtual router in cloudstack
RH-Jira: RHEL-40217
RH-Acked-by: Cathy Avery <cavery@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [1/1] 9d1353620ee2c773170e424479bb2664116554f4 (anisinha/cloud-init)
Fixes 5942f4023e2581a
(cherry picked from commit cb36bf38b823f811a3e938ccffc03d7d13190095)
Signed-off-by: Ani Sinha <anisinha@redhat.com>
---
cloudinit/sources/DataSourceCloudStack.py | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/cloudinit/sources/DataSourceCloudStack.py b/cloudinit/sources/DataSourceCloudStack.py
index fd2482a3..f752765d 100644
--- a/cloudinit/sources/DataSourceCloudStack.py
+++ b/cloudinit/sources/DataSourceCloudStack.py
@@ -229,18 +229,18 @@ def get_vr_address():
)
return latest_address
- # Try dhcp lease files next...
+ # Try dhcp lease files next
lease_file = dhcp.IscDhclient.get_latest_lease()
- if not lease_file:
- LOG.debug("No lease file found, using default gateway")
- return get_default_gateway()
-
- lease_file = dhcp.IscDhclient.parse_dhcp_server_from_lease_file(lease_file)
- if not latest_address:
- # No virtual router found, fallback on default gateway
- LOG.debug("No DHCP found, using default gateway")
- return get_default_gateway()
- return latest_address
+ if lease_file:
+ latest_address = dhcp.IscDhclient.parse_dhcp_server_from_lease_file(
+ lease_file
+ )
+ if latest_address:
+ return latest_address
+
+ # No virtual router found, fallback to default gateway
+ LOG.debug("No DHCP found, using default gateway")
+ return get_default_gateway()
# Used to match classes to dependencies
--
2.39.3

@ -1,132 +0,0 @@
From 2b74b0eb94edfd7caa42bc0d8affc37311ba041b Mon Sep 17 00:00:00 2001
From: Brett Holman <brett.holman@canonical.com>
Date: Wed, 3 Jan 2024 09:11:21 -0700
Subject: [PATCH 4/6] fix(dhcp): Guard against FileNotFoundError and NameError
exceptions
RH-Author: Ani Sinha <anisinha@redhat.com>
RH-MergeRequest: 92: Update pylint version to support python 3.12
RH-Jira: RHEL-44598
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [1/3] 730b8de9ceb2c380d3b15573d83691ab95a1487e (anisinha/cloud-init)
(cherry picked from commit 53eb8555e091474803b724700815adc09aa84f05)
---
cloudinit/net/dhcp.py | 20 ++++++++++------
tests/unittests/net/test_dhcp.py | 40 ++++++++++++++++++++++++++++++++
2 files changed, 53 insertions(+), 7 deletions(-)
diff --git a/cloudinit/net/dhcp.py b/cloudinit/net/dhcp.py
index 07c13390..a0aee98c 100644
--- a/cloudinit/net/dhcp.py
+++ b/cloudinit/net/dhcp.py
@@ -5,15 +5,15 @@
# This file is part of cloud-init. See LICENSE file for license information.
import abc
-import contextlib
import glob
import logging
import os
import re
import signal
import time
+from contextlib import suppress
from io import StringIO
-from typing import Any, Dict, List
+from typing import Any, Dict, List, Optional
import configobj
@@ -268,7 +268,7 @@ class IscDhclient(DhcpClient):
# this function waits for these files to exist, clean previous runs
# to avoid false positive in wait_for_files
- with contextlib.suppress(FileNotFoundError):
+ with suppress(FileNotFoundError):
os.remove(pid_file)
os.remove(lease_file)
@@ -514,9 +514,15 @@ class IscDhclient(DhcpClient):
return latest_file
@staticmethod
- def parse_dhcp_server_from_lease_file(lease_file):
- with open(lease_file, "r") as fd:
- for line in fd:
+ def parse_dhcp_server_from_lease_file(lease_file) -> Optional[str]:
+ """Parse a lease file for the dhcp server address
+
+ @param lease_file: Name of a file to be parsed
+ @return: An address if found, or None
+ """
+ latest_address = None
+ with suppress(FileNotFoundError), open(lease_file, "r") as file:
+ for line in file:
if "dhcp-server-identifier" in line:
words = line.strip(" ;\r\n").split(" ")
if len(words) > 2:
@@ -561,7 +567,7 @@ class Udhcpc(DhcpClient):
tmp_dir = temp_utils.get_tmp_ancestor(needs_exe=True)
lease_file = os.path.join(tmp_dir, interface + ".lease.json")
- with contextlib.suppress(FileNotFoundError):
+ with suppress(FileNotFoundError):
os.remove(lease_file)
# udhcpc needs the interface up to send initial discovery packets
diff --git a/tests/unittests/net/test_dhcp.py b/tests/unittests/net/test_dhcp.py
index a7b62312..8ec96eef 100644
--- a/tests/unittests/net/test_dhcp.py
+++ b/tests/unittests/net/test_dhcp.py
@@ -32,6 +32,46 @@ LEASE_F = "/run/dhclient.lease"
DHCLIENT = "/sbin/dhclient"
+@pytest.mark.parametrize(
+ "server_address,lease_file_content",
+ (
+ pytest.param(None, None, id="no_server_addr_on_absent_lease_file"),
+ pytest.param(None, "", id="no_server_addr_on_empty_lease_file"),
+ pytest.param(
+ None,
+ "lease {\n fixed-address: 10.1.2.3;\n}\n",
+ id="no_server_addr_when_no_server_ident",
+ ),
+ pytest.param(
+ "10.4.5.6",
+ "lease {\n fixed-address: 10.1.2.3;\n"
+ " option dhcp-server-identifier 10.4.5.6;\n"
+ " option dhcp-renewal-time 1800;\n}\n",
+ id="server_addr_found_when_server_ident_present",
+ ),
+ ),
+)
+class TestParseDHCPServerFromLeaseFile:
+ def test_find_server_address_when_present(
+ self, server_address, lease_file_content, tmp_path
+ ):
+ """Test that we return None in the case of no file or file contains no
+ server address, otherwise return the address.
+ """
+ lease_file = tmp_path / "dhcp.leases"
+ if server_address:
+ if lease_file_content:
+ lease_file.write_text(lease_file_content)
+ assert (
+ server_address
+ == IscDhclient.parse_dhcp_server_from_lease_file(lease_file)
+ )
+ else:
+ assert not IscDhclient.parse_dhcp_server_from_lease_file(
+ lease_file
+ )
+
+
class TestParseDHCPLeasesFile(CiTestCase):
def test_parse_empty_lease_file_errors(self):
"""parse_dhcp_lease_file errors when file content is empty."""
--
2.39.3

@ -1,14 +1,14 @@
From b7fddab36d805099639358736dab474d2924906b Mon Sep 17 00:00:00 2001
From 77fdb71d8947b4bc3b0fb19c2a0dbf0423c51163 Mon Sep 17 00:00:00 2001
From: Brett Holman <brett.holman@canonical.com>
Date: Wed, 19 Jun 2024 17:07:56 -0600
Subject: [PATCH 2/6] fix(jsonschema): Add missing sudo definition (#5418)
Subject: [PATCH 2/4] fix(jsonschema): Add missing sudo definition (#5418)
RH-Author: Ani Sinha <anisinha@redhat.com>
RH-MergeRequest: 90: fix(jsonschema): Add missing sudo definition (#5418)
RH-Jira: RHEL-44337
RH-MergeRequest: 91: fix(jsonschema): Add missing sudo definition (#5418)
RH-Jira: RHEL-44338
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [1/2] 9e56c7ab35744c6530c8cef2f122ffdcc0480d29 (anisinha/cloud-init)
RH-Commit: [1/2] c94e7e63470d04c23ebb45fe654c7bdd5a30c162 (anisinha/cloud-init)
This configuration:
@ -29,10 +29,10 @@ Fixes GH-5399
1 file changed, 9 insertions(+)
diff --git a/cloudinit/config/schemas/schema-cloud-config-v1.json b/cloudinit/config/schemas/schema-cloud-config-v1.json
index a553c52c..8b10fe70 100644
index ff61dcaa..c47e7c4f 100644
--- a/cloudinit/config/schemas/schema-cloud-config-v1.json
+++ b/cloudinit/config/schemas/schema-cloud-config-v1.json
@@ -299,6 +299,15 @@
@@ -388,6 +388,15 @@
],
"description": "Sudo rule to use or false. Absence of a sudo value or ``null`` will result in no sudo rules added for this user."
},

@ -1,34 +0,0 @@
From e6e7c274235d924fde752b228f68ec5773e39029 Mon Sep 17 00:00:00 2001
From: Brett Holman <brett.holman@canonical.com>
Date: Tue, 5 Dec 2023 16:40:03 -0700
Subject: [PATCH 2/2] fix(python3.13): Fix import error for passlib on Python
3.13 (#4669)
RH-Author: xiachen <xiachen@redhat.com>
RH-MergeRequest: 145: Fix metric setting for ifcfg network connections for rhel (#5777)
RH-Jira: RHEL-65018
RH-Acked-by: Ani Sinha <anisinha@redhat.com>
RH-Commit: [2/2] 226ae26a9f903774cb36f8f72b89071ba4545a66 (xiachen/cloud-init)
(cherry picked from commit 09b70436b3a0aae1fe24fdde6e8cdd7ee98d9c15)
Signed-off-by: Amy Chen <xiachen@redhat.com>
---
cloudinit/sources/DataSourceAzure.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/cloudinit/sources/DataSourceAzure.py b/cloudinit/sources/DataSourceAzure.py
index eb0304c3d..939210100 100644
--- a/cloudinit/sources/DataSourceAzure.py
+++ b/cloudinit/sources/DataSourceAzure.py
@@ -58,7 +58,7 @@ try:
)
except (ImportError, AttributeError):
try:
- import passlib
+ import passlib.hash
blowfish_hash = passlib.hash.sha512_crypt.hash
except ImportError:
--
2.39.3

@ -1,15 +1,15 @@
From ce69cd178d9c05827db1ca1654de82dc3f9f521e Mon Sep 17 00:00:00 2001
From 2b7a984fc57443c7ea1f5cab0e9a85878ef1a847 Mon Sep 17 00:00:00 2001
From: Chad Smith <chad.smith@canonical.com>
Date: Thu, 27 Jun 2024 18:12:31 -0600
Subject: [PATCH 3/3] fix(schema): permit deprecated hyphenated keys under
users key (#5456)
RH-Author: Ani Sinha <anisinha@redhat.com>
RH-MergeRequest: 95: Deprecate the users ssh-authorized-keys property (#5162)
RH-Jira: RHEL-45262
RH-MergeRequest: 94: Deprecate the users ssh-authorized-keys property (#5162)
RH-Jira: RHEL-45263
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [3/3] 76804599a9166796dc52bab2031a706993ad2e3c (anisinha/cloud-init)
RH-Commit: [3/3] 88c8502922e2f85f5ce04d170fdd6b7596117a1f (anisinha/cloud-init)
Both hyphenated and underscore delimited key names are permitted
by cloudinit/distros/ug_util.py#L114 due to magic replacement
@ -29,6 +29,11 @@ will provided the necessary context.
Fixes GH-5454
Conflicts:
tests/unittests/config/test_schema.py
- due to absence of change 7f98af900f ("test: Add unit tests for features.DEPRECATION_INFO_BOUNDARY")
which in turn depends on change e80514b56139 ("feat: Add deprecation boundary to logger (#5411)")
(cherry picked from commit b3618d44a37ae6345f0c3d935b77ae0ae9dd1c92)
---
.../schemas/schema-cloud-config-v1.json | 103 +++++++++++++-----
@ -39,10 +44,10 @@ Fixes GH-5454
5 files changed, 108 insertions(+), 58 deletions(-)
diff --git a/cloudinit/config/schemas/schema-cloud-config-v1.json b/cloudinit/config/schemas/schema-cloud-config-v1.json
index 97cf2b74..03e723e2 100644
index 23573583..3cf7aaf8 100644
--- a/cloudinit/config/schemas/schema-cloud-config-v1.json
+++ b/cloudinit/config/schemas/schema-cloud-config-v1.json
@@ -178,9 +178,9 @@
@@ -267,9 +267,9 @@
"patternProperties": {
"^.+$": {
"label": "<group_name>",
@ -53,7 +58,7 @@ index 97cf2b74..03e723e2 100644
"type": [
"null"
],
@@ -203,9 +203,7 @@
@@ -292,9 +292,7 @@
"type": "string"
},
"lock-passwd": {
@ -63,7 +68,7 @@ index 97cf2b74..03e723e2 100644
"deprecated": true,
"deprecated_version": "22.3",
"deprecated_description": "Use ``lock_passwd`` instead."
@@ -215,16 +213,34 @@
@@ -304,16 +302,34 @@
"description": "Disable password login. Default: ``true``",
"type": "boolean"
},
@ -98,8 +103,8 @@ index 97cf2b74..03e723e2 100644
"no_user_group": {
"default": false,
"description": "Do not create group named after user. Default: ``false``",
@@ -234,24 +250,54 @@
"description": "Hash of user password applied when user does not exist. This will NOT be applied if the user already exists. To generate this hash, run: mkpasswd --method=SHA-512 --rounds=4096. **Note:** While hashed password is better than plain text, using ``passwd`` in user-data represents a security risk as user-data could be accessible by third-parties depending on your cloud platform.",
@@ -323,24 +339,54 @@
"description": "Hash of user password applied when user does not exist. This will NOT be applied if the user already exists. To generate this hash, run: ``mkpasswd --method=SHA-512 --rounds=500000`` **Note:** Your password might possibly be visible to unprivileged users on your system, depending on your cloud's security model. Check if your cloud's IMDS server is visible from an unprivileged user to evaluate risk.",
"type": "string"
},
+ "hashed-passwd": {
@ -109,7 +114,7 @@ index 97cf2b74..03e723e2 100644
+ "deprecated_description": "Use ``hashed_passwd`` instead."
+ },
"hashed_passwd": {
"description": "Hash of user password to be applied. This will be applied even if the user is pre-existing. To generate this hash, run: mkpasswd --method=SHA-512 --rounds=4096. **Note:** While ``hashed_password`` is better than ``plain_text_passwd``, using ``passwd`` in user-data represents a security risk as user-data could be accessible by third-parties depending on your cloud platform.",
"description": "Hash of user password to be applied. This will be applied even if the user is preexisting. To generate this hash, run: ``mkpasswd --method=SHA-512 --rounds=500000``. **Note:** Your password might possibly be visible to unprivileged users on your system, depending on your cloud's security model. Check if your cloud's IMDS server is visible from an unprivileged user to evaluate risk.",
"type": "string"
},
+ "plain-text-passwd": {
@ -119,7 +124,7 @@ index 97cf2b74..03e723e2 100644
+ "deprecated_description": "Use ``plain_text_passwd`` instead."
+ },
"plain_text_passwd": {
"description": "Clear text of user password to be applied. This will be applied even if the user is pre-existing. There are many more secure options than using plain text passwords, such as ``ssh_import_id`` or ``hashed_passwd``. Do not use this in production as user-data and your password can be exposed.",
"description": "Clear text of user password to be applied. This will be applied even if the user is preexisting. **Note:** SSH keys or certificates are a safer choice for logging in to your system. For local escalation, supplying a hashed password is a safer choice than plain text. Your password might possibly be visible to unprivileged users on your system, depending on your cloud's security model. An exposed plain text password is an immediate security concern. Check if your cloud's IMDS server is visible from an unprivileged user to evaluate risk.",
"type": "string"
},
+ "create-groups": {
@ -151,9 +156,9 @@ index 97cf2b74..03e723e2 100644
+ "deprecated_description": "Use ``selinux_user`` instead."
+ },
"selinux_user": {
"description": "SELinux user for user's login. Default to default SELinux user.",
"description": "SELinux user for user's login. Default: the default SELinux user.",
"type": "string"
@@ -273,20 +319,24 @@
@@ -362,20 +408,24 @@
"minItems": 1
},
"ssh-authorized-keys": {
@ -191,8 +196,8 @@ index 97cf2b74..03e723e2 100644
+ "deprecated_description": "Use ``ssh_import_id`` instead."
},
"ssh_import_id": {
"description": "List of SSH IDs to import for user. Can not be combined with ``ssh_redirect_user``.",
@@ -296,6 +346,12 @@
"description": "List of ssh ids to import for user. Can not be combined with ``ssh_redirect_user``. See the man page[1] for more details. [1] https://manpages.ubuntu.com/manpages/noble/en/man1/ssh-import-id.1.html",
@@ -385,6 +435,12 @@
},
"minItems": 1
},
@ -205,7 +210,7 @@ index 97cf2b74..03e723e2 100644
"ssh_redirect_user": {
"type": "boolean",
"default": false,
@@ -398,7 +454,6 @@
@@ -487,7 +543,6 @@
"properties": {
"remove-defaults": {
"type": "boolean",
@ -213,7 +218,7 @@ index 97cf2b74..03e723e2 100644
"deprecated": true,
"deprecated_version": "22.3",
"deprecated_description": "Use ``remove_defaults`` instead."
@@ -516,9 +571,9 @@
@@ -605,9 +660,9 @@
},
"system_info": {
"type": "object",
@ -225,7 +230,7 @@ index 97cf2b74..03e723e2 100644
}
}
},
@@ -1483,7 +1538,6 @@
@@ -1572,7 +1627,6 @@
},
"grub-dpkg": {
"type": "object",
@ -233,7 +238,7 @@ index 97cf2b74..03e723e2 100644
"deprecated": true,
"deprecated_version": "22.2",
"deprecated_description": "Use ``grub_dpkg`` instead."
@@ -2082,24 +2136,18 @@
@@ -2159,24 +2213,18 @@
},
"apt_update": {
"type": "boolean",
@ -258,7 +263,7 @@ index 97cf2b74..03e723e2 100644
"deprecated": true,
"deprecated_version": "22.2",
"deprecated_description": "Use ``package_reboot_if_required`` instead."
@@ -2798,7 +2846,6 @@
@@ -2874,7 +2922,6 @@
}
],
"minItems": 1,
@ -282,10 +287,10 @@ index b4bd48df..36ef7fd9 100644
),
),
diff --git a/tests/unittests/config/test_cc_package_update_upgrade_install.py b/tests/unittests/config/test_cc_package_update_upgrade_install.py
index 9ba7f178..734dbc53 100644
index 08db05a0..ad3651ad 100644
--- a/tests/unittests/config/test_cc_package_update_upgrade_install.py
+++ b/tests/unittests/config/test_cc_package_update_upgrade_install.py
@@ -192,16 +192,16 @@ class TestPackageUpdateUpgradeSchema:
@@ -300,16 +300,16 @@ class TestPackageUpdateUpgradeSchema:
(
{"apt_update": False},
(
@ -306,7 +311,7 @@ index 9ba7f178..734dbc53 100644
"Use ``package_upgrade`` instead."
),
),
@@ -209,8 +209,7 @@ class TestPackageUpdateUpgradeSchema:
@@ -317,8 +317,7 @@ class TestPackageUpdateUpgradeSchema:
{"apt_reboot_if_required": False},
(
"Cloud config schema deprecations: "
@ -375,10 +380,10 @@ index 53e231e1..4ca67f77 100644
),
False,
diff --git a/tests/unittests/config/test_schema.py b/tests/unittests/config/test_schema.py
index 52667332..8208affc 100644
index ce55534b..d175083b 100644
--- a/tests/unittests/config/test_schema.py
+++ b/tests/unittests/config/test_schema.py
@@ -2251,9 +2251,9 @@ class TestHandleSchemaArgs:
@@ -2542,9 +2542,9 @@ class TestHandleSchemaArgs:
apt_reboot_if_required: true # D3
# Deprecations: -------------
@ -391,7 +396,7 @@ index 52667332..8208affc 100644
Valid schema {cfg_file}
""" # noqa: E501
@@ -2264,11 +2264,10 @@ class TestHandleSchemaArgs:
@@ -2555,11 +2555,10 @@ class TestHandleSchemaArgs:
dedent(
"""\
Cloud config schema deprecations: \

@ -1,15 +1,15 @@
From 9ee9fe608b906fe4e523cbf7fbe4539f0322ba2f Mon Sep 17 00:00:00 2001
From e1f1152cd883988f3b5cb7552b11c883e8e423f1 Mon Sep 17 00:00:00 2001
From: PengpengSun <40026211+PengpengSun@users.noreply.github.com>
Date: Thu, 4 Jul 2024 04:06:39 +0800
Subject: [PATCH 2/2] fix(vmware): Set IPv6 to dhcp when there is no IPv6 addr
(#5471)
RH-Author: xiachen <xiachen@redhat.com>
RH-MergeRequest: 99: fix(vmware): Set IPv6 to dhcp when there is no IPv6 addr (#5471)
RH-Jira: RHEL-46194
RH-MergeRequest: 98: fix(vmware): Set IPv6 to dhcp when there is no IPv6 addr (#5471)
RH-Jira: RHEL-35562
RH-Acked-by: Ani Sinha <anisinha@redhat.com>
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
RH-Commit: [1/1] fbae24c7e7f48239200eaf457d260203fb550845 (xiachen/cloud-init-centos)
RH-Commit: [1/1] 5b64e6ce3df0aebbadfcbc00cf7d768408aac6cf (xiachen/cloud-init-centos)
When there is no IPv6 addr given in the customization configuration,
we shall set IPv6 type to dhcp6, then customized Linux network will be
@ -35,10 +35,10 @@ index b07214a2..254518af 100644
subnet_list = []
# Static Ipv6
diff --git a/tests/unittests/sources/vmware/test_vmware_config_file.py b/tests/unittests/sources/vmware/test_vmware_config_file.py
index b53ea96c..25d3b093 100644
index fd4bb481..c1415934 100644
--- a/tests/unittests/sources/vmware/test_vmware_config_file.py
+++ b/tests/unittests/sources/vmware/test_vmware_config_file.py
@@ -240,27 +240,45 @@ class TestVmwareConfigFile(CiTestCase):
@@ -241,27 +241,45 @@ class TestVmwareConfigFile(CiTestCase):
elif cfg.get("name") == nic2.get("name"):
nic2.update(cfg)
@ -92,7 +92,7 @@ index b53ea96c..25d3b093 100644
def test_get_nics_list_static(self):
"""Tests if NicConfigurator properly calculates network subnets
@@ -285,6 +303,7 @@ class TestVmwareConfigFile(CiTestCase):
@@ -286,6 +304,7 @@ class TestVmwareConfigFile(CiTestCase):
elif cfg.get("name") == nic2.get("name"):
nic2.update(cfg)
@ -100,7 +100,7 @@ index b53ea96c..25d3b093 100644
self.assertEqual("physical", nic1.get("type"), "type of NIC1")
self.assertEqual("NIC1", nic1.get("name"), "name of NIC1")
self.assertEqual(
@@ -344,6 +363,7 @@ class TestVmwareConfigFile(CiTestCase):
@@ -345,6 +364,7 @@ class TestVmwareConfigFile(CiTestCase):
else:
self.assertEqual(True, False, "invalid gateway %s" % (gateway))
@ -108,7 +108,7 @@ index b53ea96c..25d3b093 100644
self.assertEqual("physical", nic2.get("type"), "type of NIC2")
self.assertEqual("NIC2", nic2.get("name"), "name of NIC2")
self.assertEqual(
@@ -351,16 +371,18 @@ class TestVmwareConfigFile(CiTestCase):
@@ -352,16 +372,18 @@ class TestVmwareConfigFile(CiTestCase):
)
subnets = nic2.get("subnets")
@ -132,7 +132,7 @@ index b53ea96c..25d3b093 100644
def test_custom_script(self):
cf = ConfigFile("tests/data/vmware/cust-dhcp-2nic.cfg")
@@ -447,7 +469,10 @@ class TestVmwareNetConfig(CiTestCase):
@@ -448,7 +470,10 @@ class TestVmwareNetConfig(CiTestCase):
"type": "static",
"address": "10.20.87.154",
"netmask": "255.255.252.0",
@ -144,7 +144,7 @@ index b53ea96c..25d3b093 100644
],
}
],
@@ -498,7 +523,10 @@ class TestVmwareNetConfig(CiTestCase):
@@ -499,7 +524,10 @@ class TestVmwareNetConfig(CiTestCase):
"metric": 10000,
}
],
@ -156,7 +156,7 @@ index b53ea96c..25d3b093 100644
],
}
],
@@ -558,7 +586,10 @@ class TestVmwareNetConfig(CiTestCase):
@@ -559,7 +587,10 @@ class TestVmwareNetConfig(CiTestCase):
"metric": 10000,
}
],
@ -168,7 +168,7 @@ index b53ea96c..25d3b093 100644
],
}
],
@@ -603,7 +634,10 @@ class TestVmwareNetConfig(CiTestCase):
@@ -604,7 +635,10 @@ class TestVmwareNetConfig(CiTestCase):
"address": "10.20.87.154",
"netmask": "255.255.252.0",
"gateway": "10.20.87.253",

@ -1,91 +0,0 @@
From 9a3c16dc89d2813c90df2e57e71ae5df704083be Mon Sep 17 00:00:00 2001
From: James Falcon <james.falcon@canonical.com>
Date: Tue, 9 Jan 2024 10:32:12 -0600
Subject: [PATCH] refactor: Ensure internal DNS state same for v1 and v2
(#4756)
RH-Author: Ani Sinha <anisinha@redhat.com>
RH-MergeRequest: 152: refactor: Ensure internal DNS state same for v1 and v2 (#4756)
RH-Jira: RHEL-68409
RH-Acked-by: xiachen <xiachen@redhat.com>
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
RH-Commit: [1/1] f006996f7b418103ffaf73ff9ded5b5d149bedf6
When defining interface-level DNS on the network state, v1 uses the
"nameservers" key whereas v2 was using an "addresses" key.
This commit updates the v2 parsing to set the key as "nameservers".
Also update networkd renderer as this was only renderer using the v2
"addresses" key.
(cherry picked from commit 436e6f5ce3fbb8b391a2158538873644058904e6)
Signed-off-by: Ani Sinha <anisinha@redhat.com>
---
cloudinit/net/network_state.py | 2 +-
cloudinit/net/networkd.py | 13 ++++---------
tests/unittests/net/test_network_state.py | 5 ++++-
3 files changed, 9 insertions(+), 11 deletions(-)
diff --git a/cloudinit/net/network_state.py b/cloudinit/net/network_state.py
index 226421bd0..82c3bf894 100644
--- a/cloudinit/net/network_state.py
+++ b/cloudinit/net/network_state.py
@@ -336,7 +336,7 @@ class NetworkStateInterpreter:
if iface:
nameservers, search = dns
iface["dns"] = {
- "addresses": nameservers,
+ "nameservers": nameservers,
"search": search,
}
diff --git a/cloudinit/net/networkd.py b/cloudinit/net/networkd.py
index 0978849c8..29f466eda 100644
--- a/cloudinit/net/networkd.py
+++ b/cloudinit/net/networkd.py
@@ -221,12 +221,6 @@ class Renderer(renderer.Renderer):
def parse_dns(self, iface, cfg: CfgParser, ns: NetworkState):
sec = "Network"
- dns_cfg_map = {
- "search": "Domains",
- "nameservers": "DNS",
- "addresses": "DNS",
- }
-
dns = iface.get("dns")
if not dns and ns.version == 1:
dns = {
@@ -236,9 +230,10 @@ class Renderer(renderer.Renderer):
elif not dns and ns.version == 2:
return
- for k, v in dns_cfg_map.items():
- if k in dns and dns[k]:
- cfg.update_section(sec, v, " ".join(dns[k]))
+ if dns.get("search"):
+ cfg.update_section(sec, "Domains", " ".join(dns["search"]))
+ if dns.get("nameservers"):
+ cfg.update_section(sec, "DNS", " ".join(dns["nameservers"]))
def parse_dhcp_overrides(self, cfg: CfgParser, device, dhcp, version):
dhcp_config_maps = {
diff --git a/tests/unittests/net/test_network_state.py b/tests/unittests/net/test_network_state.py
index 7d304ca3a..74a6bb34c 100644
--- a/tests/unittests/net/test_network_state.py
+++ b/tests/unittests/net/test_network_state.py
@@ -258,7 +258,10 @@ class TestNetworkStateParseNameservers:
# If an interface was specified, DNS should be part of the interface
for iface in config.iter_interfaces():
if iface["name"] == "eth1":
- assert iface["dns"]["addresses"] == ["192.168.1.1", "8.8.8.8"]
+ assert iface["dns"]["nameservers"] == [
+ "192.168.1.1",
+ "8.8.8.8",
+ ]
assert iface["dns"]["search"] == ["spam.local"]
else:
assert "dns" not in iface
--
2.39.3

@ -0,0 +1,544 @@
From d5c2095abb4d22fc976ed3011679134c75bead99 Mon Sep 17 00:00:00 2001
From: Cat Red <catmsred@users.noreply.github.com>
Date: Mon, 4 Mar 2024 21:38:14 -0500
Subject: [PATCH 2/3] refactor: remove dependency on netifaces (#4634)
RH-Author: Ani Sinha <anisinha@redhat.com>
RH-MergeRequest: 80: refactor: remove dependency on netifaces (#4634)
RH-Jira: RHEL-34518
RH-Acked-by: xiachen <xiachen@redhat.com>
RH-Acked-by: Cathy Avery <cavery@redhat.com>
RH-Commit: [1/2] e55e7a588301234f62dfaf36080fb5f95aa52b2f (anisinha/cloud-init)
Upstream netifaces is no longer being maintained and is only
used by the VMWare data source. As such this commit
replaces the calls to netifaces with cloudinit's native netinfo.
(cherry picked from commit 2ba7fdf0e1eb0bc597ceac8903695f67571fd873)
Signed-off-by: Ani Sinha <anisinha@redhat.com>
---
cloudinit/sources/DataSourceVMware.py | 207 ++++++++++---------------
pyproject.toml | 1 -
requirements.txt | 9 --
tests/unittests/sources/test_vmware.py | 161 ++++++++++++++++++-
tools/build-on-netbsd | 1 -
tools/build-on-openbsd | 1 -
tox.ini | 1 -
7 files changed, 239 insertions(+), 142 deletions(-)
diff --git a/cloudinit/sources/DataSourceVMware.py b/cloudinit/sources/DataSourceVMware.py
index 2a91a307..6ed6a6a5 100644
--- a/cloudinit/sources/DataSourceVMware.py
+++ b/cloudinit/sources/DataSourceVMware.py
@@ -16,51 +16,6 @@ multiple transports types, including:
* EnvVars
* GuestInfo
* IMC (Guest Customization)
-
-Netifaces (https://github.com/al45tair/netifaces)
-
- Please note this module relies on the netifaces project to introspect the
- runtime, network configuration of the host on which this datasource is
- running. This is in contrast to the rest of cloud-init which uses the
- cloudinit/netinfo module.
-
- The reasons for using netifaces include:
-
- * Netifaces is built in C and is more portable across multiple systems
- and more deterministic than shell exec'ing local network commands and
- parsing their output.
-
- * Netifaces provides a stable way to determine the view of the host's
- network after DHCP has brought the network online. Unlike most other
- datasources, this datasource still provides support for JINJA queries
- based on networking information even when the network is based on a
- DHCP lease. While this does not tie this datasource directly to
- netifaces, it does mean the ability to consistently obtain the
- correct information is paramount.
-
- * It is currently possible to execute this datasource on macOS
- (which many developers use today) to print the output of the
- get_host_info function. This function calls netifaces to obtain
- the same runtime network configuration that the datasource would
- persist to the local system's instance data.
-
- However, the netinfo module fails on macOS. The result is either a
- hung operation that requires a SIGINT to return control to the user,
- or, if brew is used to install iproute2mac, the ip commands are used
- but produce output the netinfo module is unable to parse.
-
- While macOS is not a target of cloud-init, this feature is quite
- useful when working on this datasource.
-
- For more information about this behavior, please see the following
- PR comment, https://bit.ly/3fG7OVh.
-
- The authors of this datasource are not opposed to moving away from
- netifaces. The goal may be to eventually do just that. This proviso was
- added to the top of this module as a way to remind future-us and others
- why netifaces was used in the first place in order to either smooth the
- transition away from netifaces or embrace it further up the cloud-init
- stack.
"""
import collections
@@ -72,9 +27,7 @@ import os
import socket
import time
-import netifaces
-
-from cloudinit import atomic_helper, dmi, log, net, sources, util
+from cloudinit import atomic_helper, dmi, log, net, netinfo, sources, util
from cloudinit.sources.helpers.vmware.imc import guestcust_util
from cloudinit.subp import ProcessExecutionError, subp, which
@@ -814,91 +767,64 @@ def get_default_ip_addrs():
addresses associated with the device used by the default route for a given
address.
"""
- # TODO(promote and use netifaces in cloudinit.net* modules)
- gateways = netifaces.gateways()
- if "default" not in gateways:
- return None, None
-
- default_gw = gateways["default"]
- if (
- netifaces.AF_INET not in default_gw
- and netifaces.AF_INET6 not in default_gw
- ):
- return None, None
+ # Get ipv4 and ipv6 interfaces associated with default routes
+ ipv4_if = None
+ ipv6_if = None
+ routes = netinfo.route_info()
+ for route in routes["ipv4"]:
+ if route["destination"] == "0.0.0.0":
+ ipv4_if = route["iface"]
+ break
+ for route in routes["ipv6"]:
+ if route["destination"] == "::/0":
+ ipv6_if = route["iface"]
+ break
+
+ # Get ip address associated with default interface
ipv4 = None
ipv6 = None
-
- gw4 = default_gw.get(netifaces.AF_INET)
- if gw4:
- _, dev4 = gw4
- addr4_fams = netifaces.ifaddresses(dev4)
- if addr4_fams:
- af_inet4 = addr4_fams.get(netifaces.AF_INET)
- if af_inet4:
- if len(af_inet4) > 1:
- LOG.debug(
- "device %s has more than one ipv4 address: %s",
- dev4,
- af_inet4,
- )
- elif "addr" in af_inet4[0]:
- ipv4 = af_inet4[0]["addr"]
-
- # Try to get the default IPv6 address by first seeing if there is a default
- # IPv6 route.
- gw6 = default_gw.get(netifaces.AF_INET6)
- if gw6:
- _, dev6 = gw6
- addr6_fams = netifaces.ifaddresses(dev6)
- if addr6_fams:
- af_inet6 = addr6_fams.get(netifaces.AF_INET6)
- if af_inet6:
- if len(af_inet6) > 1:
- LOG.debug(
- "device %s has more than one ipv6 address: %s",
- dev6,
- af_inet6,
- )
- elif "addr" in af_inet6[0]:
- ipv6 = af_inet6[0]["addr"]
+ netdev = netinfo.netdev_info()
+ if ipv4_if in netdev:
+ addrs = netdev[ipv4_if]["ipv4"]
+ if len(addrs) > 1:
+ LOG.debug(
+ "device %s has more than one ipv4 address: %s", ipv4_if, addrs
+ )
+ elif len(addrs) == 1 and "ip" in addrs[0]:
+ ipv4 = addrs[0]["ip"]
+ if ipv6_if in netdev:
+ addrs = netdev[ipv6_if]["ipv6"]
+ if len(addrs) > 1:
+ LOG.debug(
+ "device %s has more than one ipv6 address: %s", ipv6_if, addrs
+ )
+ elif len(addrs) == 1 and "ip" in addrs[0]:
+ ipv6 = addrs[0]["ip"]
# If there is a default IPv4 address but not IPv6, then see if there is a
# single IPv6 address associated with the same device associated with the
# default IPv4 address.
- if ipv4 and not ipv6:
- af_inet6 = addr4_fams.get(netifaces.AF_INET6)
- if af_inet6:
- if len(af_inet6) > 1:
- LOG.debug(
- "device %s has more than one ipv6 address: %s",
- dev4,
- af_inet6,
- )
- elif "addr" in af_inet6[0]:
- ipv6 = af_inet6[0]["addr"]
+ if ipv4 is not None and ipv6 is None:
+ for dev_name in netdev:
+ for addr in netdev[dev_name]["ipv4"]:
+ if addr["ip"] == ipv4 and len(netdev[dev_name]["ipv6"]) == 1:
+ ipv6 = netdev[dev_name]["ipv6"][0]["ip"]
+ break
# If there is a default IPv6 address but not IPv4, then see if there is a
# single IPv4 address associated with the same device associated with the
# default IPv6 address.
- if not ipv4 and ipv6:
- af_inet4 = addr6_fams.get(netifaces.AF_INET)
- if af_inet4:
- if len(af_inet4) > 1:
- LOG.debug(
- "device %s has more than one ipv4 address: %s",
- dev6,
- af_inet4,
- )
- elif "addr" in af_inet4[0]:
- ipv4 = af_inet4[0]["addr"]
+ if ipv4 is None and ipv6 is not None:
+ for dev_name in netdev:
+ for addr in netdev[dev_name]["ipv6"]:
+ if addr["ip"] == ipv6 and len(netdev[dev_name]["ipv4"]) == 1:
+ ipv4 = netdev[dev_name]["ipv4"][0]["ip"]
+ break
return ipv4, ipv6
-# patched socket.getfqdn() - see https://bugs.python.org/issue5004
-
-
def getfqdn(name=""):
"""Get fully qualified domain name from name.
An empty argument is interpreted as meaning the local host.
@@ -933,6 +859,33 @@ def is_valid_ip_addr(val):
)
+def convert_to_netifaces_format(addr):
+ """
+ Takes a cloudinit.netinfo formatted address and converts to netifaces
+ format, since this module was originally written with netifaces as the
+ network introspection module.
+ netifaces format:
+ {
+ "broadcast": "10.15.255.255",
+ "netmask": "255.240.0.0",
+ "addr": "10.0.1.4"
+ }
+
+ cloudinit.netinfo format:
+ {
+ "ip": "10.0.1.4",
+ "mask": "255.240.0.0",
+ "bcast": "10.15.255.255",
+ "scope": "global",
+ }
+ """
+ return {
+ "broadcast": addr["bcast"],
+ "netmask": addr["mask"],
+ "addr": addr["ip"],
+ }
+
+
def get_host_info():
"""
Returns host information such as the host name and network interfaces.
@@ -963,16 +916,16 @@ def get_host_info():
by_ipv4 = host_info["network"]["interfaces"]["by-ipv4"]
by_ipv6 = host_info["network"]["interfaces"]["by-ipv6"]
- ifaces = netifaces.interfaces()
+ ifaces = netinfo.netdev_info()
for dev_name in ifaces:
- addr_fams = netifaces.ifaddresses(dev_name)
- af_link = addr_fams.get(netifaces.AF_LINK)
- af_inet4 = addr_fams.get(netifaces.AF_INET)
- af_inet6 = addr_fams.get(netifaces.AF_INET6)
-
- mac = None
- if af_link and "addr" in af_link[0]:
- mac = af_link[0]["addr"]
+ af_inet4 = []
+ af_inet6 = []
+ for addr in ifaces[dev_name]["ipv4"]:
+ af_inet4.append(convert_to_netifaces_format(addr))
+ for addr in ifaces[dev_name]["ipv6"]:
+ af_inet6.append(convert_to_netifaces_format(addr))
+
+ mac = ifaces[dev_name].get("hwaddr")
# Do not bother recording localhost
if mac == "00:00:00:00:00:00":
diff --git a/pyproject.toml b/pyproject.toml
index 99854f39..6f8ccdd1 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -28,7 +28,6 @@ module = [
"debconf",
"httplib",
"jsonpatch",
- "netifaces",
"paramiko.*",
"pip.*",
"pycloudlib.*",
diff --git a/requirements.txt b/requirements.txt
index edec46a7..eabd7a22 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -29,12 +29,3 @@ jsonpatch
# For validating cloud-config sections per schema definitions
jsonschema
-
-# Used by DataSourceVMware to inspect the host's network configuration during
-# the "setup()" function.
-#
-# This allows a host that uses DHCP to bring up the network during BootLocal
-# and still participate in instance-data by gathering the network in detail at
-# runtime and merge that information into the metadata and repersist that to
-# disk.
-netifaces>=0.10.4
diff --git a/tests/unittests/sources/test_vmware.py b/tests/unittests/sources/test_vmware.py
index 585f4fbd..33193f89 100644
--- a/tests/unittests/sources/test_vmware.py
+++ b/tests/unittests/sources/test_vmware.py
@@ -63,6 +63,45 @@ runcmd:
- echo "Hello, world."
"""
+VMW_IPV4_ROUTEINFO = {
+ "destination": "0.0.0.0",
+ "flags": "G",
+ "gateway": "10.85.130.1",
+ "genmask": "0.0.0.0",
+ "iface": "eth0",
+ "metric": "50",
+}
+VMW_IPV4_NETDEV_ADDR = {
+ "bcast": "10.85.130.255",
+ "ip": "10.85.130.116",
+ "mask": "255.255.255.0",
+ "scope": "global",
+}
+VMW_IPV6_ROUTEINFO = {
+ "destination": "::/0",
+ "flags": "UG",
+ "gateway": "2001:67c:1562:8007::1",
+ "iface": "eth0",
+ "metric": "50",
+}
+VMW_IPV6_NETDEV_ADDR = {
+ "ip": "fd42:baa2:3dd:17a:216:3eff:fe16:db54/64",
+ "scope6": "global",
+}
+
+
+def generate_test_netdev_data(ipv4=None, ipv6=None):
+ ipv4 = ipv4 or []
+ ipv6 = ipv6 or []
+ return {
+ "eth0": {
+ "hwaddr": "00:16:3e:16:db:54",
+ "ipv4": ipv4,
+ "ipv6": ipv6,
+ "up": True,
+ },
+ }
+
@pytest.fixture(autouse=True)
def common_patches():
@@ -74,8 +113,8 @@ def common_patches():
is_FreeBSD=mock.Mock(return_value=False),
),
mock.patch(
- "cloudinit.sources.DataSourceVMware.netifaces.interfaces",
- return_value=[],
+ "cloudinit.netinfo.netdev_info",
+ return_value={},
),
mock.patch(
"cloudinit.sources.DataSourceVMware.getfqdn",
@@ -152,6 +191,124 @@ class TestDataSourceVMware(CiTestCase):
host_info[DataSourceVMware.LOCAL_IPV6] == "2001:db8::::::8888"
)
+ # TODO migrate this entire test suite to pytest then parameterize
+ @mock.patch("cloudinit.netinfo.route_info")
+ @mock.patch("cloudinit.netinfo.netdev_info")
+ def test_get_default_ip_addrs_ipv4only(
+ self,
+ m_netdev_info,
+ m_route_info,
+ ):
+ """Test get_default_ip_addrs use cases"""
+ m_route_info.return_value = {
+ "ipv4": [VMW_IPV4_ROUTEINFO],
+ "ipv6": [],
+ }
+ m_netdev_info.return_value = generate_test_netdev_data(
+ ipv4=[VMW_IPV4_NETDEV_ADDR]
+ )
+ ipv4, ipv6 = DataSourceVMware.get_default_ip_addrs()
+ self.assertEqual(ipv4, "10.85.130.116")
+ self.assertEqual(ipv6, None)
+
+ @mock.patch("cloudinit.netinfo.route_info")
+ @mock.patch("cloudinit.netinfo.netdev_info")
+ def test_get_default_ip_addrs_ipv6only(
+ self,
+ m_netdev_info,
+ m_route_info,
+ ):
+ m_route_info.return_value = {
+ "ipv4": [],
+ "ipv6": [VMW_IPV6_ROUTEINFO],
+ }
+ m_netdev_info.return_value = generate_test_netdev_data(
+ ipv6=[VMW_IPV6_NETDEV_ADDR]
+ )
+ ipv4, ipv6 = DataSourceVMware.get_default_ip_addrs()
+ self.assertEqual(ipv4, None)
+ self.assertEqual(ipv6, "fd42:baa2:3dd:17a:216:3eff:fe16:db54/64")
+
+ @mock.patch("cloudinit.netinfo.route_info")
+ @mock.patch("cloudinit.netinfo.netdev_info")
+ def test_get_default_ip_addrs_dualstack(
+ self,
+ m_netdev_info,
+ m_route_info,
+ ):
+ m_route_info.return_value = {
+ "ipv4": [VMW_IPV4_ROUTEINFO],
+ "ipv6": [VMW_IPV6_ROUTEINFO],
+ }
+ m_netdev_info.return_value = generate_test_netdev_data(
+ ipv4=[VMW_IPV4_NETDEV_ADDR],
+ ipv6=[VMW_IPV6_NETDEV_ADDR],
+ )
+ ipv4, ipv6 = DataSourceVMware.get_default_ip_addrs()
+ self.assertEqual(ipv4, "10.85.130.116")
+ self.assertEqual(ipv6, "fd42:baa2:3dd:17a:216:3eff:fe16:db54/64")
+
+ @mock.patch("cloudinit.netinfo.route_info")
+ @mock.patch("cloudinit.netinfo.netdev_info")
+ def test_get_default_ip_addrs_multiaddr(
+ self,
+ m_netdev_info,
+ m_route_info,
+ ):
+ m_route_info.return_value = {
+ "ipv4": [VMW_IPV4_ROUTEINFO],
+ "ipv6": [],
+ }
+ m_netdev_info.return_value = generate_test_netdev_data(
+ ipv4=[
+ VMW_IPV4_NETDEV_ADDR,
+ {
+ "bcast": "10.85.131.255",
+ "ip": "10.85.131.117",
+ "mask": "255.255.255.0",
+ "scope": "global",
+ },
+ ],
+ ipv6=[
+ VMW_IPV6_NETDEV_ADDR,
+ {
+ "ip": "fe80::216:3eff:fe16:db54/64",
+ "scope6": "link",
+ },
+ ],
+ )
+ ipv4, ipv6 = DataSourceVMware.get_default_ip_addrs()
+ self.assertEqual(ipv4, None)
+ self.assertEqual(ipv6, None)
+
+ @mock.patch("cloudinit.netinfo.route_info")
+ @mock.patch("cloudinit.netinfo.netdev_info")
+ def test_get_default_ip_addrs_nodefault(
+ self,
+ m_netdev_info,
+ m_route_info,
+ ):
+ m_route_info.return_value = {
+ "ipv4": [
+ {
+ "destination": "185.125.188.0",
+ "flags": "G",
+ "gateway": "10.85.130.1",
+ "genmask": "0.0.0.255",
+ "iface": "eth0",
+ "metric": "50",
+ },
+ ],
+ "ipv6": [],
+ }
+ m_netdev_info.return_value = generate_test_netdev_data(
+ ipv4=[VMW_IPV4_NETDEV_ADDR],
+ ipv6=[VMW_IPV6_NETDEV_ADDR],
+ )
+ ipv4, ipv6 = DataSourceVMware.get_default_ip_addrs()
+ self.assertEqual(ipv4, None)
+ self.assertEqual(ipv6, None)
+
@mock.patch("cloudinit.sources.DataSourceVMware.get_host_info")
def test_wait_on_network(self, m_fn):
metadata = {
diff --git a/tools/build-on-netbsd b/tools/build-on-netbsd
index 0d4eb58b..b743d591 100755
--- a/tools/build-on-netbsd
+++ b/tools/build-on-netbsd
@@ -19,7 +19,6 @@ pkgs="
${py_prefix}-oauthlib
${py_prefix}-requests
${py_prefix}-setuptools
- ${py_prefix}-netifaces
${py_prefix}-yaml
${py_prefix}-jsonschema
sudo
diff --git a/tools/build-on-openbsd b/tools/build-on-openbsd
index 948ebeb8..09262aff 100755
--- a/tools/build-on-openbsd
+++ b/tools/build-on-openbsd
@@ -16,7 +16,6 @@ pkgs="
py3-configobj
py3-jinja2
py3-jsonschema
- py3-netifaces
py3-oauthlib
py3-requests
py3-setuptools
diff --git a/tox.ini b/tox.ini
index 34b87d01..473e937c 100644
--- a/tox.ini
+++ b/tox.ini
@@ -194,7 +194,6 @@ deps =
requests==2.18.4
jsonpatch==1.16
jsonschema==2.6.0
- netifaces==0.10.4
# test-requirements
pytest==3.3.2
pytest-cov==2.5.1
--
2.39.3

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save