Merge branch 'c10s' into a10s

This commit is contained in:
eabdullin 2025-01-16 12:19:53 +03:00
commit 7089f8f86d
36 changed files with 1182 additions and 5712 deletions

View File

@ -1,110 +0,0 @@
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 10 Stream koji.
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.
Changes from 23.1.1 rebase follows:
Merged patches (23.1.1):
724a80ac Add TargetRelease
967a4405b rhel/cloud.cfg: remove ssh_genkeytypes in settings.py and set in cloud.cfg
^ Merged since it removes hunks added in this commit itself
Discarded because not needed anymore (packit):
e3fd7ce12 Configure Packit to ignore the .gitignore file
e18654e9 Fixes for packit support
Discarded because file does not exist anymore and templates are aligned with upstream:
3576b12460bf18557857ee25df6bf530dab66612 Adding _netdev to the default mount configuration
8092b57ab245856ff1fdde1469960608a489c95e Remove rhel specific files
Added the following entry to %files to keep track of the new README file in config/clean.d/README
%doc %{_sysconfdir}/cloud/clean.d/README
ignored
c75e509b0 Revert "Revert "Setting highest autoconnect priority for network-scripts""
0eba5c619 Revert "Setting highest autoconnect priority for network-scripts"
ignored
ba19343c0d9807d0c68a2d8e4ab274f3ca884247 Add Gitlab CI
fe09305a5479a4814d6c46df07a906bafa29d637 Delete .gitlab-ci.yml
Conflicts:
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 b075682f..f749c509 100644
--- a/cloudinit/settings.py
+++ b/cloudinit/settings.py
@@ -55,13 +55,14 @@ CFG_BUILTIN = {
],
"def_log_file": "/var/log/cloud-init.log",
"log_cfgs": [],
- "syslog_fix_perms": ["syslog:adm", "root:adm", "root:wheel", "root:root"],
+ "mount_default_fields": [None, None, "auto", "defaults,nofail", "0", "2"],
+ "syslog_fix_perms": [],
"system_info": {
"paths": {
"cloud_dir": "/var/lib/cloud",
"templates_dir": "/etc/cloud/templates/",
},
- "distro": "ubuntu",
+ "distro": "rhel",
"network": {"renderers": None},
},
"vendor_data": {"enabled": True, "prefix": []},
diff --git a/tests/unittests/cmd/test_main.py b/tests/unittests/cmd/test_main.py
index 7f580203..19316be3 100644
--- a/tests/unittests/cmd/test_main.py
+++ b/tests/unittests/cmd/test_main.py
@@ -131,14 +131,17 @@ class TestMain(FilesystemMockingTestCase):
{
"def_log_file": "/var/log/cloud-init.log",
"log_cfgs": [],
- "syslog_fix_perms": [
- "syslog:adm",
- "root:adm",
- "root:wheel",
- "root:root",
- ],
"vendor_data": {"enabled": True, "prefix": []},
"vendor_data2": {"enabled": True, "prefix": []},
+ "syslog_fix_perms": [],
+ "mount_default_fields": [
+ None,
+ None,
+ "auto",
+ "defaults,nofail",
+ "0",
+ "2",
+ ],
}
)
updated_cfg.pop("system_info")

View File

@ -1,7 +1,8 @@
From 4e24e6f9e786437d94ba5e2d3e084ef2a2fc534f Mon Sep 17 00:00:00 2001
From aa64b67f0d62c78f7a879df4a09124fd82fc60ac 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
Subject: [PATCH] downstream: Setting autoconnect priority setting for
network-scripts
Changes for 24.1.2 (c10s):
- Fixed additional unit tests.
@ -59,15 +60,18 @@ fixes: c589da20eb92 ("Setting highest autoconnect priority for network-scripts")
Signed-off-by: Ani Sinha <anisinha@redhat.com>
(cherry picked from commit 8a2fcbbcfdfc1df6f6c18f96588154f40083a239)
(cherry picked from commit 67e8d963161e5487b1bfcd775fde9f957d6488ea)
Signed-off-by: Cathy Avery <cavery@redhat.com>
---
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 | 54 +++++++++++++++++++
4 files changed, 64 insertions(+)
tests/unittests/net/network_configs.py | 57 +++++++++++++++++++
tests/unittests/test_net.py | 18 ++++++
5 files changed, 85 insertions(+)
diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
index b9e9593b..1678fcde 100644
index d75012d26..2151db3ab 100644
--- a/cloudinit/net/sysconfig.py
+++ b/cloudinit/net/sysconfig.py
@@ -318,6 +318,7 @@ class Renderer(renderer.Renderer):
@ -79,7 +83,7 @@ index b9e9593b..1678fcde 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 3e9a4f90..b6da87ca 100644
index 39e049227..ed970e413 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
@ -91,10 +95,10 @@ index 3e9a4f90..b6da87ca 100644
DEVICE=eth0
ONBOOT=yes
diff --git a/tests/unittests/distros/test_netconfig.py b/tests/unittests/distros/test_netconfig.py
index f35e5b0a..6b4fc666 100644
index b447757be..3768623f2 100644
--- a/tests/unittests/distros/test_netconfig.py
+++ b/tests/unittests/distros/test_netconfig.py
@@ -717,6 +717,7 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
@@ -711,6 +711,7 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
expected_cfgs = {
self.ifcfg_path("eth0"): dedent(
"""\
@ -102,7 +106,7 @@ index f35e5b0a..6b4fc666 100644
BOOTPROTO=none
DEFROUTE=yes
DEVICE=eth0
@@ -730,6 +731,7 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
@@ -724,6 +725,7 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
),
self.ifcfg_path("eth1"): dedent(
"""\
@ -110,7 +114,7 @@ index f35e5b0a..6b4fc666 100644
BOOTPROTO=dhcp
DEVICE=eth1
ONBOOT=yes
@@ -754,6 +756,7 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
@@ -748,6 +750,7 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
expected_cfgs = {
self.ifcfg_path("eth0"): dedent(
"""\
@ -118,7 +122,7 @@ index f35e5b0a..6b4fc666 100644
BOOTPROTO=none
DEFROUTE=yes
DEVICE=eth0
@@ -769,6 +772,7 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
@@ -763,6 +766,7 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
),
self.ifcfg_path("eth1"): dedent(
"""\
@ -126,7 +130,7 @@ index f35e5b0a..6b4fc666 100644
BOOTPROTO=dhcp
DEVICE=eth1
ONBOOT=yes
@@ -812,6 +816,7 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
@@ -806,6 +810,7 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
expected_cfgs = {
self.ifcfg_path("eth0"): dedent(
"""\
@ -134,7 +138,7 @@ index f35e5b0a..6b4fc666 100644
BOOTPROTO=none
DEVICE=eth0
HWADDR=00:16:3e:60:7c:df
@@ -824,6 +829,7 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
@@ -818,6 +823,7 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
),
self.ifcfg_path("infra0"): dedent(
"""\
@ -142,7 +146,7 @@ index f35e5b0a..6b4fc666 100644
BOOTPROTO=none
DEVICE=infra0
IPADDR=10.0.1.2
@@ -859,6 +865,7 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
@@ -853,6 +859,7 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
expected_cfgs = {
self.ifcfg_path("eth0"): dedent(
"""\
@ -150,7 +154,7 @@ index f35e5b0a..6b4fc666 100644
BOOTPROTO=none
DEVICE=eth0
IPADDR=192.10.1.2
@@ -870,6 +877,7 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
@@ -864,6 +871,7 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
),
self.ifcfg_path("eth0.1001"): dedent(
"""\
@ -158,35 +162,11 @@ index f35e5b0a..6b4fc666 100644
BOOTPROTO=none
DEVICE=eth0.1001
IPADDR=10.0.1.2
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
index d83c52f0..fee8e035 100644
--- a/tests/unittests/test_net.py
+++ b/tests/unittests/test_net.py
@@ -578,6 +578,7 @@ dns = none
"""
# Created by cloud-init automatically, do not edit.
#
+AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEFROUTE=yes
DEVICE=eth0
@@ -741,6 +742,7 @@ dns = none
"""
# Created by cloud-init automatically, do not edit.
#
+AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEFROUTE=yes
DEVICE=eth0
@@ -898,6 +900,7 @@ dns = none
"""
# Created by cloud-init automatically, do not edit.
#
+AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEFROUTE=yes
DEVICE=eth0
@@ -1138,6 +1141,7 @@ NETWORK_CONFIGS = {
diff --git a/tests/unittests/net/network_configs.py b/tests/unittests/net/network_configs.py
index 6e870f6ed..dd0bf73d2 100644
--- a/tests/unittests/net/network_configs.py
+++ b/tests/unittests/net/network_configs.py
@@ -184,6 +184,7 @@ NETWORK_CONFIGS = {
"expected_sysconfig_rhel": {
"ifcfg-eth1": textwrap.dedent(
"""\
@ -194,7 +174,7 @@ index d83c52f0..fee8e035 100644
BOOTPROTO=none
DEVICE=eth1
HWADDR=cf:d6:af:48:e8:80
@@ -1147,6 +1151,7 @@ NETWORK_CONFIGS = {
@@ -193,6 +194,7 @@ NETWORK_CONFIGS = {
),
"ifcfg-eth99": textwrap.dedent(
"""\
@ -202,7 +182,7 @@ index d83c52f0..fee8e035 100644
BOOTPROTO=dhcp
DEFROUTE=yes
DEVICE=eth99
@@ -1310,6 +1315,7 @@ NETWORK_CONFIGS = {
@@ -357,6 +359,7 @@ NETWORK_CONFIGS = {
"expected_sysconfig_rhel": {
"ifcfg-eth1": textwrap.dedent(
"""\
@ -210,7 +190,7 @@ index d83c52f0..fee8e035 100644
BOOTPROTO=none
DEVICE=eth1
HWADDR=cf:d6:af:48:e8:80
@@ -1319,6 +1325,7 @@ NETWORK_CONFIGS = {
@@ -366,6 +369,7 @@ NETWORK_CONFIGS = {
),
"ifcfg-eth99": textwrap.dedent(
"""\
@ -218,7 +198,7 @@ index d83c52f0..fee8e035 100644
BOOTPROTO=dhcp
DEFROUTE=yes
DEVICE=eth99
@@ -1565,6 +1572,7 @@ NETWORK_CONFIGS = {
@@ -622,6 +626,7 @@ NETWORK_CONFIGS = {
"expected_sysconfig_rhel": {
"ifcfg-iface0": textwrap.dedent(
"""\
@ -226,7 +206,15 @@ index d83c52f0..fee8e035 100644
BOOTPROTO=none
DEVICE=iface0
IPADDR=192.168.14.2
@@ -1711,6 +1719,7 @@ NETWORK_CONFIGS = {
@@ -738,6 +743,7 @@ NETWORK_CONFIGS = {
"expected_sysconfig_rhel": {
"ifcfg-iface0": textwrap.dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEVICE=iface0
IPADDR=192.168.14.2
@@ -893,6 +899,7 @@ NETWORK_CONFIGS = {
"expected_sysconfig_rhel": {
"ifcfg-iface0": textwrap.dedent(
"""\
@ -234,7 +222,7 @@ index d83c52f0..fee8e035 100644
BOOTPROTO=none
DEVICE=iface0
DHCPV6C=yes
@@ -1800,6 +1809,7 @@ NETWORK_CONFIGS = {
@@ -982,6 +989,7 @@ NETWORK_CONFIGS = {
"expected_sysconfig_rhel": {
"ifcfg-iface0": textwrap.dedent(
"""\
@ -242,7 +230,7 @@ index d83c52f0..fee8e035 100644
BOOTPROTO=none
DEVICE=iface0
DHCPV6C=yes
@@ -1875,6 +1885,7 @@ NETWORK_CONFIGS = {
@@ -1057,6 +1065,7 @@ NETWORK_CONFIGS = {
"expected_sysconfig_rhel": {
"ifcfg-iface0": textwrap.dedent(
"""\
@ -250,7 +238,7 @@ index d83c52f0..fee8e035 100644
BOOTPROTO=none
DEVICE=iface0
DHCPV6C=yes
@@ -1939,6 +1950,7 @@ NETWORK_CONFIGS = {
@@ -1123,6 +1132,7 @@ NETWORK_CONFIGS = {
"expected_sysconfig_rhel": {
"ifcfg-iface0": textwrap.dedent(
"""\
@ -258,7 +246,7 @@ index d83c52f0..fee8e035 100644
BOOTPROTO=none
DEVICE=iface0
IPV6_AUTOCONF=yes
@@ -1994,6 +2006,7 @@ NETWORK_CONFIGS = {
@@ -1188,6 +1198,7 @@ NETWORK_CONFIGS = {
"expected_sysconfig_rhel": {
"ifcfg-iface0": textwrap.dedent(
"""\
@ -266,7 +254,7 @@ index d83c52f0..fee8e035 100644
BOOTPROTO=none
DEVICE=iface0
IPV6ADDR=2001:1::1/64
@@ -2050,6 +2063,7 @@ NETWORK_CONFIGS = {
@@ -1246,6 +1257,7 @@ NETWORK_CONFIGS = {
"expected_sysconfig_rhel": {
"ifcfg-iface0": textwrap.dedent(
"""\
@ -274,7 +262,7 @@ index d83c52f0..fee8e035 100644
BOOTPROTO=none
DEVICE=iface0
DHCPV6C=yes
@@ -2134,6 +2148,7 @@ NETWORK_CONFIGS = {
@@ -1332,6 +1344,7 @@ NETWORK_CONFIGS = {
"expected_sysconfig_rhel": {
"ifcfg-iface0": textwrap.dedent(
"""\
@ -282,7 +270,7 @@ index d83c52f0..fee8e035 100644
BOOTPROTO=none
DEVICE=iface0
DHCPV6C=yes
@@ -2180,6 +2195,7 @@ NETWORK_CONFIGS = {
@@ -1378,6 +1391,7 @@ NETWORK_CONFIGS = {
"expected_sysconfig_rhel": {
"ifcfg-iface0": textwrap.dedent(
"""\
@ -290,7 +278,7 @@ index d83c52f0..fee8e035 100644
BOOTPROTO=dhcp
DEVICE=iface0
ONBOOT=yes
@@ -2255,6 +2271,7 @@ NETWORK_CONFIGS = {
@@ -1453,6 +1467,7 @@ NETWORK_CONFIGS = {
"expected_sysconfig_rhel": {
"ifcfg-iface0": textwrap.dedent(
"""\
@ -298,7 +286,7 @@ index d83c52f0..fee8e035 100644
BOOTPROTO=dhcp
DEVICE=iface0
ETHTOOL_OPTS="wol g"
@@ -2590,6 +2607,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
@@ -1788,6 +1803,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(
"""\
@ -306,7 +294,7 @@ index d83c52f0..fee8e035 100644
BONDING_MASTER=yes
BONDING_OPTS="mode=active-backup """
"""xmit_hash_policy=layer3+4 """
@@ -2607,6 +2625,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
@@ -1805,6 +1821,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
),
"ifcfg-bond0.200": textwrap.dedent(
"""\
@ -314,7 +302,7 @@ index d83c52f0..fee8e035 100644
BOOTPROTO=dhcp
DEVICE=bond0.200
DHCLIENT_SET_DEFAULT_ROUTE=no
@@ -2618,6 +2637,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
@@ -1816,6 +1833,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
@ -322,7 +310,7 @@ index d83c52f0..fee8e035 100644
BOOTPROTO=none
DEFROUTE=yes
DEVICE=br0
@@ -2637,6 +2657,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
@@ -1835,6 +1853,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
),
"ifcfg-eth0": textwrap.dedent(
"""\
@ -330,7 +318,7 @@ index d83c52f0..fee8e035 100644
BOOTPROTO=none
DEVICE=eth0
HWADDR=c0:d6:9f:2c:e8:80
@@ -2646,6 +2667,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
@@ -1844,6 +1863,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
),
"ifcfg-eth0.101": textwrap.dedent(
"""\
@ -338,7 +326,7 @@ index d83c52f0..fee8e035 100644
BOOTPROTO=none
DEFROUTE=yes
DEVICE=eth0.101
@@ -2665,6 +2687,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
@@ -1863,6 +1883,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
),
"ifcfg-eth1": textwrap.dedent(
"""\
@ -346,7 +334,7 @@ index d83c52f0..fee8e035 100644
BOOTPROTO=none
DEVICE=eth1
HWADDR=aa:d6:9f:2c:e8:80
@@ -2676,6 +2699,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
@@ -1874,6 +1895,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
),
"ifcfg-eth2": textwrap.dedent(
"""\
@ -354,7 +342,7 @@ index d83c52f0..fee8e035 100644
BOOTPROTO=none
DEVICE=eth2
HWADDR=c0:bb:9f:2c:e8:80
@@ -2687,6 +2711,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
@@ -1885,6 +1907,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
),
"ifcfg-eth3": textwrap.dedent(
"""\
@ -362,7 +350,7 @@ index d83c52f0..fee8e035 100644
BOOTPROTO=none
BRIDGE=br0
DEVICE=eth3
@@ -2697,6 +2722,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
@@ -1895,6 +1918,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
),
"ifcfg-eth4": textwrap.dedent(
"""\
@ -370,7 +358,7 @@ index d83c52f0..fee8e035 100644
BOOTPROTO=none
BRIDGE=br0
DEVICE=eth4
@@ -2707,6 +2733,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
@@ -1905,6 +1929,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
),
"ifcfg-eth5": textwrap.dedent(
"""\
@ -378,7 +366,7 @@ index d83c52f0..fee8e035 100644
BOOTPROTO=dhcp
DEVICE=eth5
DHCLIENT_SET_DEFAULT_ROUTE=no
@@ -2717,6 +2744,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
@@ -1915,6 +1940,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
),
"ifcfg-ib0": textwrap.dedent(
"""\
@ -386,15 +374,79 @@ index d83c52f0..fee8e035 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
@@ -3431,6 +3459,7 @@ iface bond0 inet6 static
@@ -2575,6 +2601,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
),
"ifcfg-eth0": textwrap.dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEVICE=eth0
HWADDR=c0:d6:9f:2c:e8:80
@@ -2584,6 +2611,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
),
"ifcfg-eth0.101": textwrap.dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEFROUTE=yes
DEVICE=eth0.101
@@ -2603,6 +2631,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
),
"ifcfg-eth1": textwrap.dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEVICE=eth1
HWADDR=aa:d6:9f:2c:e8:80
@@ -2614,6 +2643,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
),
"ifcfg-eth2": textwrap.dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEVICE=eth2
HWADDR=c0:bb:9f:2c:e8:80
@@ -2625,6 +2655,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
),
"ifcfg-eth3": textwrap.dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
BRIDGE=br0
DEVICE=eth3
@@ -2635,6 +2666,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
),
"ifcfg-eth4": textwrap.dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
BRIDGE=br0
DEVICE=eth4
@@ -2645,6 +2677,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
),
"ifcfg-eth5": textwrap.dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=dhcp
DEVICE=eth5
DHCLIENT_SET_DEFAULT_ROUTE=no
@@ -2655,6 +2688,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
),
"ifcfg-ib0": textwrap.dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
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
@@ -3232,6 +3266,7 @@ iface bond0 inet6 static
"expected_sysconfig_rhel": {
"ifcfg-bond0": textwrap.dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BONDING_MASTER=yes
BONDING_OPTS="mode=active-backup xmit_hash_policy=layer3+4 """
"""miimon=100 num_grat_arp=5 """
@@ -3461,6 +3490,7 @@ iface bond0 inet6 static
BONDING_OPTS="mode=active-backup miimon=100 """
"""downdelay=10 updelay=20 primary=bond0s0"
@@ -3258,6 +3293,7 @@ iface bond0 inet6 static
),
"ifcfg-bond0s0": textwrap.dedent(
"""\
@ -402,7 +454,7 @@ index d83c52f0..fee8e035 100644
BOOTPROTO=none
DEVICE=bond0s0
HWADDR=aa:bb:cc:dd:e8:00
@@ -3488,6 +3518,7 @@ iface bond0 inet6 static
@@ -3285,6 +3321,7 @@ iface bond0 inet6 static
),
"ifcfg-bond0s1": textwrap.dedent(
"""\
@ -410,7 +462,31 @@ index d83c52f0..fee8e035 100644
BOOTPROTO=none
DEVICE=bond0s1
HWADDR=aa:bb:cc:dd:e8:01
@@ -3637,6 +3668,7 @@ iface bond0 inet6 static
@@ -3585,6 +3622,7 @@ iface bond0 inet6 static
"expected_sysconfig_rhel": {
"ifcfg-bond0": textwrap.dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BONDING_MASTER=yes
BONDING_OPTS="mode=active-backup xmit_hash_policy=layer3+4 """
"""miimon=100 num_grat_arp=5 """
@@ -3615,6 +3653,7 @@ iface bond0 inet6 static
),
"ifcfg-bond0s0": textwrap.dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEVICE=bond0s0
HWADDR=aa:bb:cc:dd:e8:00
@@ -3642,6 +3681,7 @@ iface bond0 inet6 static
),
"ifcfg-bond0s1": textwrap.dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEVICE=bond0s1
HWADDR=aa:bb:cc:dd:e8:01
@@ -3789,6 +3829,7 @@ iface bond0 inet6 static
"expected_sysconfig_rhel": {
"ifcfg-en0": textwrap.dedent(
"""\
@ -418,7 +494,7 @@ index d83c52f0..fee8e035 100644
BOOTPROTO=none
DEVICE=en0
HWADDR=aa:bb:cc:dd:e8:00
@@ -3646,6 +3678,7 @@ iface bond0 inet6 static
@@ -3798,6 +3839,7 @@ iface bond0 inet6 static
),
"ifcfg-en0.99": textwrap.dedent(
"""\
@ -426,7 +502,23 @@ index d83c52f0..fee8e035 100644
BOOTPROTO=none
DEFROUTE=yes
DEVICE=en0.99
@@ -3783,6 +3816,7 @@ iface bond0 inet6 static
@@ -3924,6 +3966,7 @@ iface bond0 inet6 static
"expected_sysconfig_rhel": {
"ifcfg-en0": textwrap.dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEVICE=en0
HWADDR=aa:bb:cc:dd:e8:00
@@ -3933,6 +3976,7 @@ iface bond0 inet6 static
),
"ifcfg-en0.99": textwrap.dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEFROUTE=yes
DEVICE=en0.99
@@ -4098,6 +4142,7 @@ iface bond0 inet6 static
"expected_sysconfig_rhel": {
"ifcfg-br0": textwrap.dedent(
"""\
@ -434,7 +526,7 @@ index d83c52f0..fee8e035 100644
BOOTPROTO=none
DEVICE=br0
IPADDR=192.168.2.2
@@ -3796,6 +3830,7 @@ iface bond0 inet6 static
@@ -4111,6 +4156,7 @@ iface bond0 inet6 static
),
"ifcfg-eth0": textwrap.dedent(
"""\
@ -442,7 +534,7 @@ index d83c52f0..fee8e035 100644
BOOTPROTO=none
BRIDGE=br0
DEVICE=eth0
@@ -3811,6 +3846,7 @@ iface bond0 inet6 static
@@ -4126,6 +4172,7 @@ iface bond0 inet6 static
),
"ifcfg-eth1": textwrap.dedent(
"""\
@ -450,7 +542,7 @@ index d83c52f0..fee8e035 100644
BOOTPROTO=none
BRIDGE=br0
DEVICE=eth1
@@ -3998,6 +4034,7 @@ iface bond0 inet6 static
@@ -4313,6 +4360,7 @@ iface bond0 inet6 static
"expected_sysconfig_rhel": {
"ifcfg-eth0": textwrap.dedent(
"""\
@ -458,7 +550,7 @@ index d83c52f0..fee8e035 100644
BOOTPROTO=none
DEVICE=eth0
HWADDR=52:54:00:12:34:00
@@ -4010,6 +4047,7 @@ iface bond0 inet6 static
@@ -4325,6 +4373,7 @@ iface bond0 inet6 static
),
"ifcfg-eth1": textwrap.dedent(
"""\
@ -466,7 +558,7 @@ index d83c52f0..fee8e035 100644
BOOTPROTO=none
DEVICE=eth1
HWADDR=52:54:00:12:34:aa
@@ -4021,6 +4059,7 @@ iface bond0 inet6 static
@@ -4336,6 +4385,7 @@ iface bond0 inet6 static
),
"ifcfg-eth2": textwrap.dedent(
"""\
@ -474,7 +566,15 @@ index d83c52f0..fee8e035 100644
BOOTPROTO=none
DEVICE=eth2
HWADDR=52:54:00:12:34:ff
@@ -4268,6 +4307,7 @@ iface bond0 inet6 static
@@ -4505,6 +4555,7 @@ iface bond0 inet6 static
"""\
# Created by cloud-init automatically, do not edit.
#
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEFROUTE=yes
DEVICE=interface0
@@ -4583,6 +4634,7 @@ iface bond0 inet6 static
"expected_sysconfig_rhel": {
"ifcfg-eth0": textwrap.dedent(
"""\
@ -482,7 +582,7 @@ index d83c52f0..fee8e035 100644
BOOTPROTO=none
DEVICE=eth0
HWADDR=cf:d6:af:48:e8:80
@@ -4419,6 +4459,7 @@ iface bond0 inet6 static
@@ -4734,6 +4786,7 @@ iface bond0 inet6 static
"""\
# Created by cloud-init automatically, do not edit.
#
@ -490,7 +590,83 @@ index d83c52f0..fee8e035 100644
BOOTPROTO=none
DEVICE=eth0
DNS1=8.8.8.8
@@ -5185,6 +5226,7 @@ class TestRhelSysConfigRendering(CiTestCase):
@@ -4945,6 +4998,7 @@ iface bond0 inet6 static
"""\
# Created by cloud-init automatically, do not edit.
#
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEVICE=baremetal
IPV6ADDR=fc00:1:1::2/64
@@ -4960,6 +5014,7 @@ iface bond0 inet6 static
"""\
# Created by cloud-init automatically, do not edit.
#
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
BRIDGE=baremetal
DEVICE=baremetal0
@@ -4973,6 +5028,7 @@ iface bond0 inet6 static
"""\
# Created by cloud-init automatically, do not edit.
#
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEVICE=provisioning
IPV6ADDR=fc00:1:2::2/64
@@ -4988,6 +5044,7 @@ iface bond0 inet6 static
"""\
# Created by cloud-init automatically, do not edit.
#
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
BRIDGE=provisioning
DEVICE=provisioning0
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
index 531302f70..d95ee2979 100644
--- a/tests/unittests/test_net.py
+++ b/tests/unittests/test_net.py
@@ -612,6 +612,7 @@ dns = none
"""
# Created by cloud-init automatically, do not edit.
#
+AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEFROUTE=yes
DEVICE=eth0
@@ -777,6 +778,7 @@ dns = none
"""
# Created by cloud-init automatically, do not edit.
#
+AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEFROUTE=yes
DEVICE=eth0
@@ -951,6 +953,7 @@ dns = none
"""
# Created by cloud-init automatically, do not edit.
#
+AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEFROUTE=yes
DEVICE=eth0
@@ -1074,6 +1077,7 @@ dns = none
"""
# Created by cloud-init automatically, do not edit.
#
+AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEFROUTE=yes
DEVICE=eth0
@@ -1266,6 +1270,7 @@ dns = none
"""
# Created by cloud-init automatically, do not edit.
#
+AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEFROUTE=yes
DEVICE=eth0
@@ -1934,6 +1939,7 @@ class TestRhelSysConfigRendering:
expected_content = """
# Created by cloud-init automatically, do not edit.
#
@ -498,7 +674,7 @@ index d83c52f0..fee8e035 100644
BOOTPROTO=dhcp
DEVICE=eth1000
DHCPV6C=yes
@@ -5394,6 +5436,7 @@ USERCTL=no
@@ -2143,6 +2149,7 @@ USERCTL=no
expected = """\
# Created by cloud-init automatically, do not edit.
#
@ -506,7 +682,7 @@ index d83c52f0..fee8e035 100644
BOOTPROTO=none
DEFROUTE=yes
DEVICE=interface0
@@ -5423,6 +5466,7 @@ USERCTL=no
@@ -2172,6 +2179,7 @@ USERCTL=no
expected_i1 = """\
# Created by cloud-init automatically, do not edit.
#
@ -514,7 +690,7 @@ index d83c52f0..fee8e035 100644
BOOTPROTO=none
DEFROUTE=yes
DEVICE=eth0
@@ -5439,6 +5483,7 @@ USERCTL=no
@@ -2188,6 +2196,7 @@ USERCTL=no
expected_i2 = """\
# Created by cloud-init automatically, do not edit.
#
@ -522,7 +698,7 @@ index d83c52f0..fee8e035 100644
BOOTPROTO=dhcp
DEVICE=eth1
DHCLIENT_SET_DEFAULT_ROUTE=no
@@ -5466,6 +5511,7 @@ USERCTL=no
@@ -2215,6 +2224,7 @@ USERCTL=no
expected = """\
# Created by cloud-init automatically, do not edit.
#
@ -530,7 +706,7 @@ index d83c52f0..fee8e035 100644
BOOTPROTO=dhcp
DEVICE=eth0
ONBOOT=yes
@@ -5699,6 +5745,7 @@ USERCTL=no
@@ -2396,6 +2406,7 @@ USERCTL=no
"expected_sysconfig": {
"ifcfg-ens3": textwrap.dedent(
"""\
@ -538,7 +714,7 @@ index d83c52f0..fee8e035 100644
BOOTPROTO=none
DEFROUTE=yes
DEVICE=ens3
@@ -5743,6 +5790,7 @@ USERCTL=no
@@ -2442,6 +2453,7 @@ USERCTL=no
expected = {
"ifcfg-eno1": textwrap.dedent(
"""\
@ -546,7 +722,7 @@ index d83c52f0..fee8e035 100644
BOOTPROTO=none
DEVICE=eno1
ONBOOT=yes
@@ -5752,6 +5800,7 @@ USERCTL=no
@@ -2451,6 +2463,7 @@ USERCTL=no
),
"ifcfg-eno1.1000": textwrap.dedent(
"""\
@ -554,7 +730,7 @@ index d83c52f0..fee8e035 100644
BOOTPROTO=none
DEVICE=eno1.1000
IPADDR=192.6.1.9
@@ -5784,6 +5833,7 @@ USERCTL=no
@@ -2483,6 +2496,7 @@ USERCTL=no
expected = {
"ifcfg-bond0": textwrap.dedent(
"""\
@ -562,7 +738,7 @@ index d83c52f0..fee8e035 100644
BONDING_MASTER=yes
BONDING_SLAVE0=enp0s0
BONDING_SLAVE1=enp0s1
@@ -5799,6 +5849,7 @@ USERCTL=no
@@ -2498,6 +2512,7 @@ USERCTL=no
),
"ifcfg-enp0s0": textwrap.dedent(
"""\
@ -570,7 +746,7 @@ index d83c52f0..fee8e035 100644
BONDING_MASTER=yes
BOOTPROTO=none
DEVICE=enp0s0
@@ -5811,6 +5862,7 @@ USERCTL=no
@@ -2510,6 +2525,7 @@ USERCTL=no
),
"ifcfg-enp0s1": textwrap.dedent(
"""\
@ -578,15 +754,15 @@ index d83c52f0..fee8e035 100644
BONDING_MASTER=yes
BOOTPROTO=none
DEVICE=enp0s1
@@ -5841,6 +5893,7 @@ USERCTL=no
expected = {
"ifcfg-eno1": textwrap.dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=dhcp
DEVICE=eno1
HWADDR=07-1c-c6-75-a4-be
@@ -5919,6 +5972,7 @@ USERCTL=no
@@ -2541,6 +2557,7 @@ USERCTL=no
expected = {
"ifcfg-eno1": textwrap.dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=dhcp
DEVICE=eno1
HWADDR=07-1c-c6-75-a4-be
@@ -2621,6 +2638,7 @@ USERCTL=no
"""\
# Created by cloud-init automatically, do not edit.
#

View File

@ -1,268 +0,0 @@
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

View File

@ -1,372 +0,0 @@
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
correct settings for NM_CONTROLLED.
Merged patches (21.1):
- ecbace48 sysconfig: Don't write BOOTPROTO=dhcp for ipv6 dhcp
- a1a00383 include 'NOZEROCONF=yes' in /etc/sysconfig/network
X-downstream-only: true
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 | 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 3be35126..b9e9593b 100644
--- a/cloudinit/net/sysconfig.py
+++ b/cloudinit/net/sysconfig.py
@@ -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_text_file(sysconfig_path, quiet=True).split(
+ "\n"
+ ):
+ if "cloud-init" in line:
+ break
+ if not line.startswith(
+ ("NETWORKING=", "IPV6_AUTOCONF=", "NETWORKING_IPV6=")
+ ):
+ netcfg.append(line)
+ # Now generate the cloud-init portion of sysconfig/network
+ netcfg.extend([_make_header(), "NETWORKING=yes"])
if network_state.use_ipv6:
netcfg.append("NETWORKING_IPV6=yes")
netcfg.append("IPV6_AUTOCONF=no")
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
index f898543c..d83c52f0 100644
--- a/tests/unittests/test_net.py
+++ b/tests/unittests/test_net.py
@@ -1141,7 +1141,6 @@ NETWORK_CONFIGS = {
BOOTPROTO=none
DEVICE=eth1
HWADDR=cf:d6:af:48:e8:80
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no"""
@@ -1160,7 +1159,6 @@ NETWORK_CONFIGS = {
IPADDR=192.168.21.3
NETMASK=255.255.255.0
METRIC=10000
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no"""
@@ -1315,7 +1313,6 @@ NETWORK_CONFIGS = {
BOOTPROTO=none
DEVICE=eth1
HWADDR=cf:d6:af:48:e8:80
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no"""
@@ -1334,7 +1331,6 @@ NETWORK_CONFIGS = {
IPADDR=192.168.21.3
NETMASK=255.255.255.0
METRIC=10000
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no"""
@@ -1577,7 +1573,6 @@ NETWORK_CONFIGS = {
IPV6_AUTOCONF=no
IPV6_FORCE_ACCEPT_RA=no
NETMASK=255.255.255.0
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -1721,7 +1716,6 @@ NETWORK_CONFIGS = {
DHCPV6C=yes
IPV6INIT=yes
DEVICE=iface0
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -1812,7 +1806,6 @@ NETWORK_CONFIGS = {
IPV6INIT=yes
IPV6_FORCE_ACCEPT_RA=yes
DEVICE=iface0
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -1888,7 +1881,6 @@ NETWORK_CONFIGS = {
IPV6INIT=yes
IPV6_FORCE_ACCEPT_RA=no
DEVICE=iface0
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -1952,7 +1944,6 @@ NETWORK_CONFIGS = {
IPV6_AUTOCONF=yes
IPV6INIT=yes
DEVICE=iface0
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -2010,7 +2001,6 @@ NETWORK_CONFIGS = {
IPV6_AUTOCONF=no
IPV6_FORCE_ACCEPT_RA=no
DEVICE=iface0
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -2067,7 +2057,6 @@ NETWORK_CONFIGS = {
IPV6_AUTOCONF=yes
IPV6INIT=yes
DEVICE=iface0
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -2153,7 +2142,6 @@ NETWORK_CONFIGS = {
IPV6_FAILURE_FATAL=yes
IPV6_FORCE_ACCEPT_RA=yes
DEVICE=iface0
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -2194,7 +2182,6 @@ NETWORK_CONFIGS = {
"""\
BOOTPROTO=dhcp
DEVICE=iface0
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -2271,7 +2258,6 @@ NETWORK_CONFIGS = {
BOOTPROTO=dhcp
DEVICE=iface0
ETHTOOL_OPTS="wol g"
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -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
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Bond
USERCTL=no"""
@@ -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
- NM_CONTROLLED=no
ONBOOT=yes
PHYSDEV=bond0
USERCTL=no
@@ -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
- NM_CONTROLLED=no
ONBOOT=yes
PRIO=22
STP=no
@@ -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
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no"""
@@ -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
- NM_CONTROLLED=no
ONBOOT=yes
PHYSDEV=eth0
USERCTL=no
@@ -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
- NM_CONTROLLED=no
ONBOOT=yes
SLAVE=yes
TYPE=Ethernet
@@ -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
- NM_CONTROLLED=no
ONBOOT=yes
SLAVE=yes
TYPE=Ethernet
@@ -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
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no"""
@@ -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
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no"""
@@ -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
- NM_CONTROLLED=no
ONBOOT=no
TYPE=Ethernet
USERCTL=no"""
@@ -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
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=InfiniBand
USERCTL=no"""
@@ -3479,7 +3454,6 @@ iface bond0 inet6 static
MTU=9000
NETMASK=255.255.255.0
NETMASK1=255.255.255.0
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Bond
USERCTL=no
@@ -3491,7 +3465,6 @@ iface bond0 inet6 static
DEVICE=bond0s0
HWADDR=aa:bb:cc:dd:e8:00
MASTER=bond0
- NM_CONTROLLED=no
ONBOOT=yes
SLAVE=yes
TYPE=Ethernet
@@ -3519,7 +3492,6 @@ iface bond0 inet6 static
DEVICE=bond0s1
HWADDR=aa:bb:cc:dd:e8:01
MASTER=bond0
- NM_CONTROLLED=no
ONBOOT=yes
SLAVE=yes
TYPE=Ethernet
@@ -3668,7 +3640,6 @@ iface bond0 inet6 static
BOOTPROTO=none
DEVICE=en0
HWADDR=aa:bb:cc:dd:e8:00
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no"""
@@ -3689,7 +3660,6 @@ iface bond0 inet6 static
MTU=2222
NETMASK=255.255.255.0
NETMASK1=255.255.255.0
- NM_CONTROLLED=no
ONBOOT=yes
PHYSDEV=en0
USERCTL=no
@@ -3817,7 +3787,6 @@ iface bond0 inet6 static
DEVICE=br0
IPADDR=192.168.2.2
NETMASK=255.255.255.0
- NM_CONTROLLED=no
ONBOOT=yes
PRIO=22
STP=no
@@ -3835,7 +3804,6 @@ iface bond0 inet6 static
IPV6INIT=yes
IPV6_AUTOCONF=no
IPV6_FORCE_ACCEPT_RA=no
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -3851,7 +3819,6 @@ iface bond0 inet6 static
IPV6INIT=yes
IPV6_AUTOCONF=no
IPV6_FORCE_ACCEPT_RA=no
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -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
- NM_CONTROLLED=no
ONBOOT=no
TYPE=Ethernet
USERCTL=no
@@ -4048,7 +4014,6 @@ iface bond0 inet6 static
DEVICE=eth1
HWADDR=52:54:00:12:34:aa
MTU=1480
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -4059,7 +4024,6 @@ iface bond0 inet6 static
BOOTPROTO=none
DEVICE=eth2
HWADDR=52:54:00:12:34:ff
- NM_CONTROLLED=no
ONBOOT=no
TYPE=Ethernet
USERCTL=no
@@ -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
@@ -4308,7 +4271,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"""
@@ -4468,7 +4430,6 @@ iface bond0 inet6 static
IPV6_AUTOCONF=no
IPV6_FORCE_ACCEPT_RA=no
NETMASK=255.255.0.0
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no

View File

@ -0,0 +1,417 @@
From d4f05a45664111bfb2b83b68acd855278cd025f5 Mon Sep 17 00:00:00 2001
From: Vitaly Kuznetsov <vkuznets@redhat.com>
Date: Wed, 7 Aug 2024 16:43:55 +0200
Subject: [PATCH] downstream: 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>
Patch-name: ci-cc_disk_setup-add-sgdisk-to-sfdisk-convertion-dictio.patch
Patch-id: 22
Patch-present-in-specfile: True
(cherry picked from commit 756170f8bd98f3769640553a70e590343f49cb4b)
Signed-off-by: Cathy Avery <cavery@redhat.com>
---
cloudinit/config/cc_disk_setup.py | 375 ++++++++++++++++++++++++++++++
1 file changed, 375 insertions(+)
diff --git a/cloudinit/config/cc_disk_setup.py b/cloudinit/config/cc_disk_setup.py
index 0864140c5..f297d068e 100644
--- a/cloudinit/config/cc_disk_setup.py
+++ b/cloudinit/config/cc_disk_setup.py
@@ -396,6 +396,381 @@ def check_partition_mbr_layout(device, layout):
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", "-p", device]
try:

View File

@ -1,7 +1,7 @@
From f1fdff22c356fcfb6ef546633e7872313dca36d1 Mon Sep 17 00:00:00 2001
From ede946b4a212f6228dddce93ad9e5cc033cfb136 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
Subject: [PATCH] downstream: Get rid of gdisk dependency
RH-Author: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-MergeRequest: 106: Get rid of gdisk dependency
@ -18,38 +18,35 @@ for now.
X-downstream-only: true
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
Patch-name: ci-Get-rid-of-gdisk-dependency.patch
Patch-id: 23
Patch-present-in-specfile: True
(cherry picked from commit 2f9c7afa82de12cbe1e7b0c65ef379015260826d)
Signed-off-by: Cathy Avery <cavery@redhat.com>
---
.distro/cloud-init.spec | 1 -
cloudinit/config/cc_disk_setup.py | 98 +++++++++++++------------------
2 files changed, 42 insertions(+), 57 deletions(-)
cloudinit/config/cc_disk_setup.py | 97 +++++++++++++------------------
1 file changed, 42 insertions(+), 55 deletions(-)
diff --git a/cloudinit/config/cc_disk_setup.py b/cloudinit/config/cc_disk_setup.py
index fa6a52d3..7638b425 100644
index f297d068e..d9855f8e9 100644
--- a/cloudinit/config/cc_disk_setup.py
+++ b/cloudinit/config/cc_disk_setup.py
@@ -10,6 +10,7 @@
@@ -7,6 +7,7 @@
"""Disk Setup: Configure partitions and filesystems."""
+import json
import logging
import os
import shlex
+import json
from textwrap import dedent
@@ -772,44 +773,32 @@ gpt_id_to_sgdisk = {v: k for k, v in reversed(sgdisk_to_gpt_id.items())}
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]
- prt_cmd = ["sgdisk", "-p", device]
+ # Use sfdisk's JSON output for reliability
+ prt_cmd = [SFDISK_CMD, "-l", "-J", device]
+ prt_cmd = ["sfdisk", "-l", "-J", device]
try:
out, _err = subp.subp(prt_cmd, update_env=LANG_C_ENV)
+ ptable = json.loads(out)["partitiontable"]
@ -107,7 +104,7 @@ index fa6a52d3..7638b425 100644
def check_partition_layout(table_type, device, layout):
@@ -1066,11 +1054,11 @@ def get_partition_layout(table_type, size, layout):
@@ -982,11 +971,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.
@ -122,18 +119,18 @@ index fa6a52d3..7638b425 100644
raise RuntimeError("Unable to determine table type")
@@ -1110,28 +1098,26 @@ def exec_mkpart_mbr(device, layout):
@@ -1027,28 +1016,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])
- subp.subp(["sgdisk", "-Z", device])
- for index, (partition_type, (start, end)) in enumerate(layout):
- index += 1
- subp.subp(
- [
- SGDISK_CMD,
- "sgdisk",
- "-n",
- "{}:{}:{}".format(index, start, end),
- device,
@ -144,15 +141,15 @@ index fa6a52d3..7638b425 100644
- # 82 -> 8200. 'Linux' -> 'Linux'
- pinput = str(partition_type).ljust(4, "0")
- subp.subp(
- [SGDISK_CMD, "-t", "{}:{}".format(index, pinput), device]
- ["sgdisk", "-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(',')
+ 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:
@ -160,8 +157,8 @@ index fa6a52d3..7638b425 100644
+ 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)
+ 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(
@ -170,6 +167,3 @@ index fa6a52d3..7638b425 100644
read_parttbl(device)
--
2.39.3

View File

@ -0,0 +1,86 @@
From 829fedbff92a9d4385264b974e5dba4bded79bc3 Mon Sep 17 00:00:00 2001
From: Ani Sinha <anisinha@redhat.com>
Date: Fri, 6 Dec 2024 16:53:25 +0530
Subject: [PATCH] downstream: Revert "chore: eliminate redundant ordering
dependencies (#5819)"
This reverts commit 0680d03304c34fc4c3081f29d99f140d507dd923.
The reversal is necessary because the original change was meant to work with
the 'single process optimization' patch. Since we are reverting the
'single process optimization' (see next patch), we should revert this as well.
Moreover, without the reversal, we get the following error from
cloud-init-local:
Traceback (most recent call last):
File "/usr/lib/python3.9/site-packages/cloudinit/config/cc_set_hostname.py", line 86, in handle
cloud.distro.set_hostname(hostname, fqdn)
File "/usr/lib/python3.9/site-packages/cloudinit/distros/__init__.py", line 395, in set_hostname
self._write_hostname(writeable_hostname, self.hostname_conf_fn)
File "/usr/lib/python3.9/site-packages/cloudinit/distros/rhel.py", line 119, in _write_hostname
subp.subp(["hostnamectl", "set-hostname", str(hostname)])
File "/usr/lib/python3.9/site-packages/cloudinit/subp.py", line 291, in subp
raise ProcessExecutionError(
cloudinit.subp.ProcessExecutionError: Unexpected error while running command.
Command: ['hostnamectl', 'set-hostname', 'kvm-cloudinit-test']
Exit code: 1
Reason: -
Stdout:
Stderr: Failed to connect to bus: No such file or directory
Jira: https://issues.redhat.com/browse/RHEL-70365
X-downstream-only: true
Signed-off-by: Ani Sinha <anisinha@redhat.com>
Signed-off-by: Cathy Avery <cavery@redhat.com>
---
systemd/cloud-init-local.service.tmpl | 5 +++++
systemd/cloud-init-main.service.tmpl | 6 ++++++
2 files changed, 11 insertions(+)
diff --git a/systemd/cloud-init-local.service.tmpl b/systemd/cloud-init-local.service.tmpl
index e6a300fd4..f6a6cce41 100644
--- a/systemd/cloud-init-local.service.tmpl
+++ b/systemd/cloud-init-local.service.tmpl
@@ -7,6 +7,10 @@ DefaultDependencies=no
{% endif %}
Wants=network-pre.target
After=hv_kvp_daemon.service
+{% if variant in ["almalinux", "cloudlinux", "rhel"] %}
+Requires=dbus.socket
+After=dbus.socket
+{% endif %}
Before=network-pre.target
Before=shutdown.target
{% if variant in ["almalinux", "cloudlinux", "rhel"] %}
@@ -16,6 +20,7 @@ Before=firewalld.target
Before=sysinit.target
{% endif %}
Conflicts=shutdown.target
+RequiresMountsFor=/var/lib/cloud
ConditionPathExists=!/etc/cloud/cloud-init.disabled
ConditionKernelCommandLine=!cloud-init=disabled
ConditionEnvironment=!KERNEL_CMDLINE=cloud-init=disabled
diff --git a/systemd/cloud-init-main.service.tmpl b/systemd/cloud-init-main.service.tmpl
index b80f324fe..7a42a5746 100644
--- a/systemd/cloud-init-main.service.tmpl
+++ b/systemd/cloud-init-main.service.tmpl
@@ -8,12 +8,18 @@
# https://www.freedesktop.org/software/systemd/man/latest/systemd-remount-fs.service.html
[Unit]
Description=Cloud-init: Single Process
+Wants=network-pre.target
{% if variant in ["almalinux", "cloudlinux", "ubuntu", "unknown", "debian", "rhel"] %}
DefaultDependencies=no
{% endif %}
{% if variant in ["almalinux", "cloudlinux", "rhel"] %}
Requires=dbus.socket
After=dbus.socket
+Before=network.service
+Before=firewalld.target
+{% endif %}
+{% if variant in ["ubuntu", "unknown", "debian"] %}
+Before=sysinit.target
{% endif %}
After=systemd-remount-fs.service

View File

@ -1,26 +0,0 @@
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.

View File

@ -0,0 +1,267 @@
From a4f4d6b0bedbd8eb7287e799607b49a4e78932a4 Mon Sep 17 00:00:00 2001
From: Ani Sinha <anisinha@redhat.com>
Date: Tue, 3 Dec 2024 09:29:15 +0530
Subject: [PATCH] downstream: remove single process optimization
This optimization is a big change in behavior, patch it out.
Patch is taken from
https://github.com/canonical/cloud-init/blob/ubuntu/noble/debian/patches/no-single-process.patch
X-downstream-only: true
Signed-off-by: Ani Sinha <anisinha@redhat.com>
Signed-off-by: Cathy Avery <cavery@redhat.com>
---
cloudinit/cmd/status.py | 3 +-
cloudinit/config/cc_mounts.py | 2 +-
.../schemas/schema-cloud-config-v1.json | 4 +-
systemd/cloud-config.service | 9 +---
systemd/cloud-config.target | 4 +-
systemd/cloud-final.service | 10 +---
systemd/cloud-init-local.service.tmpl | 10 +---
systemd/cloud-init-main.service.tmpl | 48 -------------------
...k.service.tmpl => cloud-init.service.tmpl} | 12 +----
tests/unittests/config/test_cc_mounts.py | 4 +-
10 files changed, 15 insertions(+), 91 deletions(-)
delete mode 100644 systemd/cloud-init-main.service.tmpl
rename systemd/{cloud-init-network.service.tmpl => cloud-init.service.tmpl} (69%)
diff --git a/cloudinit/cmd/status.py b/cloudinit/cmd/status.py
index 98084a492..882492d96 100644
--- a/cloudinit/cmd/status.py
+++ b/cloudinit/cmd/status.py
@@ -318,9 +318,8 @@ def systemd_failed(wait: bool) -> bool:
for service in [
"cloud-final.service",
"cloud-config.service",
- "cloud-init-network.service",
+ "cloud-init.service",
"cloud-init-local.service",
- "cloud-init-main.service",
]:
try:
stdout = query_systemctl(
diff --git a/cloudinit/config/cc_mounts.py b/cloudinit/config/cc_mounts.py
index cec092902..cb36bdb87 100644
--- a/cloudinit/config/cc_mounts.py
+++ b/cloudinit/config/cc_mounts.py
@@ -521,7 +521,7 @@ def handle(name: str, cfg: Config, cloud: Cloud, args: list) -> None:
# fs_spec, fs_file, fs_vfstype, fs_mntops, fs-freq, fs_passno
uses_systemd = cloud.distro.uses_systemd()
default_mount_options = (
- "defaults,nofail,x-systemd.after=cloud-init-network.service,_netdev"
+ "defaults,nofail,x-systemd.after=cloud-init.service,_netdev"
if uses_systemd
else "defaults,nobootwait"
)
diff --git a/cloudinit/config/schemas/schema-cloud-config-v1.json b/cloudinit/config/schemas/schema-cloud-config-v1.json
index fffa04b52..7d5c87c60 100644
--- a/cloudinit/config/schemas/schema-cloud-config-v1.json
+++ b/cloudinit/config/schemas/schema-cloud-config-v1.json
@@ -2029,12 +2029,12 @@
},
"mount_default_fields": {
"type": "array",
- "description": "Default mount configuration for any mount entry with less than 6 options provided. When specified, 6 items are required and represent ``/etc/fstab`` entries. Default: ``defaults,nofail,x-systemd.after=cloud-init-network.service,_netdev``.",
+ "description": "Default mount configuration for any mount entry with less than 6 options provided. When specified, 6 items are required and represent ``/etc/fstab`` entries. Default: ``defaults,nofail,x-systemd.after=cloud-init.service,_netdev``.",
"default": [
null,
null,
"auto",
- "defaults,nofail,x-systemd.after=cloud-init-network.service",
+ "defaults,nofail,x-systemd.after=cloud-init.service",
"0",
"2"
],
diff --git a/systemd/cloud-config.service b/systemd/cloud-config.service
index 54599b346..79ff733a4 100644
--- a/systemd/cloud-config.service
+++ b/systemd/cloud-config.service
@@ -9,14 +9,7 @@ ConditionEnvironment=!KERNEL_CMDLINE=cloud-init=disabled
[Service]
Type=oneshot
-# This service is a shim which preserves systemd ordering while allowing a
-# single Python process to run cloud-init's logic. This works by communicating
-# with the cloud-init process over a unix socket to tell the process that this
-# stage can start, and then wait on a return socket until the cloud-init
-# process has completed this stage. The output from the return socket is piped
-# into a shell so that the process can send a completion message (defaults to
-# "done", otherwise includes an error message) and an exit code to systemd.
-ExecStart=sh -c 'echo "start" | netcat -Uu -W1 /run/cloud-init/share/config.sock -s /run/cloud-init/share/config-return.sock | sh'
+ExecStart=/usr/bin/cloud-init modules --mode=config
RemainAfterExit=yes
TimeoutSec=0
diff --git a/systemd/cloud-config.target b/systemd/cloud-config.target
index be754bbd1..2d65e3433 100644
--- a/systemd/cloud-config.target
+++ b/systemd/cloud-config.target
@@ -14,5 +14,5 @@
[Unit]
Description=Cloud-config availability
-Wants=cloud-init-local.service cloud-init-network.service
-After=cloud-init-local.service cloud-init-network.service
+Wants=cloud-init-local.service cloud-init.service
+After=cloud-init-local.service cloud-init.service
diff --git a/systemd/cloud-final.service b/systemd/cloud-final.service
index c48f95c4f..1489eb356 100644
--- a/systemd/cloud-final.service
+++ b/systemd/cloud-final.service
@@ -12,16 +12,10 @@ ConditionEnvironment=!KERNEL_CMDLINE=cloud-init=disabled
[Service]
Type=oneshot
-# This service is a shim which preserves systemd ordering while allowing a
-# single Python process to run cloud-init's logic. This works by communicating
-# with the cloud-init process over a unix socket to tell the process that this
-# stage can start, and then wait on a return socket until the cloud-init
-# process has completed this stage. The output from the return socket is piped
-# into a shell so that the process can send a completion message (defaults to
-# "done", otherwise includes an error message) and an exit code to systemd.
-ExecStart=sh -c 'echo "start" | netcat -Uu -W1 /run/cloud-init/share/final.sock -s /run/cloud-init/share/final-return.sock | sh'
+ExecStart=/usr/bin/cloud-init modules --mode=final
RemainAfterExit=yes
TimeoutSec=0
+KillMode=process
TasksMax=infinity
# Output needs to appear in instance console output
diff --git a/systemd/cloud-init-local.service.tmpl b/systemd/cloud-init-local.service.tmpl
index f6a6cce41..a3859dfeb 100644
--- a/systemd/cloud-init-local.service.tmpl
+++ b/systemd/cloud-init-local.service.tmpl
@@ -11,6 +11,7 @@ After=hv_kvp_daemon.service
Requires=dbus.socket
After=dbus.socket
{% endif %}
+After=systemd-remount-fs.service
Before=network-pre.target
Before=shutdown.target
{% if variant in ["almalinux", "cloudlinux", "rhel"] %}
@@ -30,14 +31,7 @@ Type=oneshot
{% if variant in ["almalinux", "cloudlinux", "rhel"] %}
ExecStartPre=/sbin/restorecon /run/cloud-init
{% endif %}
-# This service is a shim which preserves systemd ordering while allowing a
-# single Python process to run cloud-init's logic. This works by communicating
-# with the cloud-init process over a unix socket to tell the process that this
-# stage can start, and then wait on a return socket until the cloud-init
-# process has completed this stage. The output from the return socket is piped
-# into a shell so that the process can send a completion message (defaults to
-# "done", otherwise includes an error message) and an exit code to systemd.
-ExecStart=sh -c 'echo "start" | netcat -Uu -W1 /run/cloud-init/share/local.sock -s /run/cloud-init/share/local-return.sock | sh'
+ExecStart=/usr/bin/cloud-init init --local
RemainAfterExit=yes
TimeoutSec=0
diff --git a/systemd/cloud-init-main.service.tmpl b/systemd/cloud-init-main.service.tmpl
deleted file mode 100644
index 7a42a5746..000000000
--- a/systemd/cloud-init-main.service.tmpl
+++ /dev/null
@@ -1,48 +0,0 @@
-## template:jinja
-# systemd ordering resources
-# ==========================
-# https://systemd.io/NETWORK_ONLINE/
-# https://docs.cloud-init.io/en/latest/explanation/boot.html
-# https://www.freedesktop.org/wiki/Software/systemd/NetworkTarget/
-# https://www.freedesktop.org/software/systemd/man/latest/systemd.special.html
-# https://www.freedesktop.org/software/systemd/man/latest/systemd-remount-fs.service.html
-[Unit]
-Description=Cloud-init: Single Process
-Wants=network-pre.target
-{% if variant in ["almalinux", "cloudlinux", "ubuntu", "unknown", "debian", "rhel"] %}
-DefaultDependencies=no
-{% endif %}
-{% if variant in ["almalinux", "cloudlinux", "rhel"] %}
-Requires=dbus.socket
-After=dbus.socket
-Before=network.service
-Before=firewalld.target
-{% endif %}
-{% if variant in ["ubuntu", "unknown", "debian"] %}
-Before=sysinit.target
-{% endif %}
-
-After=systemd-remount-fs.service
-Before=cloud-init-local.service
-Before=shutdown.target
-Conflicts=shutdown.target
-RequiresMountsFor=/var/lib/cloud
-ConditionPathExists=!/etc/cloud/cloud-init.disabled
-ConditionKernelCommandLine=!cloud-init=disabled
-ConditionEnvironment=!KERNEL_CMDLINE=cloud-init=disabled
-
-[Service]
-Type=notify
-ExecStart=/usr/bin/cloud-init --all-stages
-KillMode=process
-TasksMax=infinity
-TimeoutStartSec=infinity
-{% if variant in ["almalinux", "cloudlinux", "rhel"] %}
-ExecStartPre=/sbin/restorecon /run/cloud-init
-{% endif %}
-
-# Output needs to appear in instance console output
-StandardOutput=journal+console
-
-[Install]
-WantedBy=cloud-init.target
diff --git a/systemd/cloud-init-network.service.tmpl b/systemd/cloud-init.service.tmpl
similarity index 69%
rename from systemd/cloud-init-network.service.tmpl
rename to systemd/cloud-init.service.tmpl
index af09fff35..939544313 100644
--- a/systemd/cloud-init-network.service.tmpl
+++ b/systemd/cloud-init.service.tmpl
@@ -9,15 +9,14 @@ Wants=cloud-init-local.service
Wants=sshd-keygen.service
Wants=sshd.service
After=cloud-init-local.service
-{% if variant not in ["ubuntu"] %}
After=systemd-networkd-wait-online.service
-{% endif %}
{% if variant in ["ubuntu", "unknown", "debian"] %}
After=networking.service
{% endif %}
{% if variant in ["almalinux", "centos", "cloudlinux", "eurolinux", "fedora",
"miraclelinux", "openeuler", "OpenCloudOS", "openmandriva", "rhel", "rocky",
"suse", "TencentOS", "virtuozzo"] %}
+
After=NetworkManager.service
After=NetworkManager-wait-online.service
{% endif %}
@@ -46,14 +45,7 @@ ConditionEnvironment=!KERNEL_CMDLINE=cloud-init=disabled
[Service]
Type=oneshot
-# This service is a shim which preserves systemd ordering while allowing a
-# single Python process to run cloud-init's logic. This works by communicating
-# with the cloud-init process over a unix socket to tell the process that this
-# stage can start, and then wait on a return socket until the cloud-init
-# process has completed this stage. The output from the return socket is piped
-# into a shell so that the process can send a completion message (defaults to
-# "done", otherwise includes an error message) and an exit code to systemd.
-ExecStart=sh -c 'echo "start" | netcat -Uu -W1 /run/cloud-init/share/network.sock -s /run/cloud-init/share/network-return.sock | sh'
+ExecStart=/usr/bin/cloud-init init
RemainAfterExit=yes
TimeoutSec=0
diff --git a/tests/unittests/config/test_cc_mounts.py b/tests/unittests/config/test_cc_mounts.py
index 0e6d83793..f710d8a4f 100644
--- a/tests/unittests/config/test_cc_mounts.py
+++ b/tests/unittests/config/test_cc_mounts.py
@@ -566,9 +566,9 @@ class TestFstabHandling:
LABEL=keepme none ext4 defaults 0 0
LABEL=UEFI
/dev/sda4 /mnt2 auto nofail,comment=cloudconfig 1 2
- /dev/sda5 /mnt3 auto defaults,nofail,x-systemd.after=cloud-init-network.service,_netdev,comment=cloudconfig 0 2
+ /dev/sda5 /mnt3 auto defaults,nofail,x-systemd.after=cloud-init.service,_netdev,comment=cloudconfig 0 2
/dev/sda1 /mnt xfs auto,comment=cloudconfig 0 2
- /dev/sda3 /mnt4 btrfs defaults,nofail,x-systemd.after=cloud-init-network.service,_netdev,comment=cloudconfig 0 2
+ /dev/sda3 /mnt4 btrfs defaults,nofail,x-systemd.after=cloud-init.service,_netdev,comment=cloudconfig 0 2
/dev/sdb1 none swap sw,comment=cloudconfig 0 0
""" # noqa: E501
).strip()

View File

@ -0,0 +1,90 @@
From 5f3213d8af6f1130d7fffb02ba420af802f916c2 Mon Sep 17 00:00:00 2001
From: Brett Holman <brett.holman@canonical.com>
Date: Tue, 17 Dec 2024 19:28:56 -0700
Subject: [PATCH] fix: don't deadlock when starting network service with
systemctl (#5935)
(cherry picked from commit bc26e15fd09b65a38ddd8cbafc5379cb19960d2b)
Signed-off-by: Ani Sinha <anisinha@redhat.com>
---
cloudinit/config/cc_set_passwords.py | 20 ++++++++++++++++---
cloudinit/distros/__init__.py | 4 ++--
.../unittests/config/test_cc_set_passwords.py | 4 +++-
3 files changed, 22 insertions(+), 6 deletions(-)
diff --git a/cloudinit/config/cc_set_passwords.py b/cloudinit/config/cc_set_passwords.py
index 8cb6a1ec5..22547d0fd 100644
--- a/cloudinit/config/cc_set_passwords.py
+++ b/cloudinit/config/cc_set_passwords.py
@@ -45,9 +45,9 @@ def get_users_by_type(users_list: list, pw_type: str) -> list:
)
-def _restart_ssh_daemon(distro, service):
+def _restart_ssh_daemon(distro: Distro, service: str, *extra_args: str):
try:
- distro.manage_service("restart", service)
+ distro.manage_service("restart", service, *extra_args)
LOG.debug("Restarted the SSH daemon.")
except subp.ProcessExecutionError as e:
LOG.warning(
@@ -104,7 +104,21 @@ def handle_ssh_pwauth(pw_auth, distro: Distro):
]
).stdout.strip()
if state.lower() in ["active", "activating", "reloading"]:
- _restart_ssh_daemon(distro, service)
+ # This module runs Before=sshd.service. What that means is that
+ # the code can only get to this point if a user manually starts the
+ # network stage. While this isn't a well-supported use-case, this
+ # does cause a deadlock if started via systemd directly:
+ # "systemctl start cloud-init.service". Prevent users from causing
+ # this deadlock by forcing systemd to ignore dependencies when
+ # restarting. Note that this deadlock is not possible in newer
+ # versions of cloud-init, since starting the second service doesn't
+ # run the second stage in 24.3+. This code therefore exists solely
+ # for backwards compatibility so that users who think that they
+ # need to manually start cloud-init (why?) with systemd (again,
+ # why?) can do so.
+ _restart_ssh_daemon(
+ distro, service, "--job-mode=ignore-dependencies"
+ )
else:
_restart_ssh_daemon(distro, service)
diff --git a/cloudinit/distros/__init__.py b/cloudinit/distros/__init__.py
index 183df368a..34c0836e8 100644
--- a/cloudinit/distros/__init__.py
+++ b/cloudinit/distros/__init__.py
@@ -142,7 +142,7 @@ class Distro(persistence.CloudInitPickleMixin, metaclass=abc.ABCMeta):
shadow_empty_locked_passwd_patterns = ["^{username}::", "^{username}:!:"]
tz_zone_dir = "/usr/share/zoneinfo"
default_owner = "root:root"
- init_cmd = ["service"] # systemctl, service etc
+ init_cmd: List[str] = ["service"] # systemctl, service etc
renderer_configs: Mapping[str, MutableMapping[str, Any]] = {}
_preferred_ntp_clients = None
networking_cls: Type[Networking] = LinuxNetworking
@@ -1373,7 +1373,7 @@ class Distro(persistence.CloudInitPickleMixin, metaclass=abc.ABCMeta):
"try-reload": [service, "restart"],
"status": [service, "status"],
}
- cmd = list(init_cmd) + list(cmds[action])
+ cmd = init_cmd + cmds[action] + list(extra_args)
return subp.subp(cmd, capture=True, rcs=rcs)
def set_keymap(self, layout: str, model: str, variant: str, options: str):
diff --git a/tests/unittests/config/test_cc_set_passwords.py b/tests/unittests/config/test_cc_set_passwords.py
index c068f62d8..a706917d7 100644
--- a/tests/unittests/config/test_cc_set_passwords.py
+++ b/tests/unittests/config/test_cc_set_passwords.py
@@ -27,7 +27,9 @@ SYSTEMD_CHECK_CALL = mock.call(
["systemctl", "show", "--property", "ActiveState", "--value", "ssh"]
)
SYSTEMD_RESTART_CALL = mock.call(
- ["systemctl", "restart", "ssh"], capture=True, rcs=None
+ ["systemctl", "restart", "ssh", "--job-mode=ignore-dependencies"],
+ capture=True,
+ rcs=None,
)
SERVICE_RESTART_CALL = mock.call(
["service", "ssh", "restart"], capture=True, rcs=None

View File

@ -1,176 +0,0 @@
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

View File

@ -1,108 +0,0 @@
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)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Ani Sinha <anisinha@redhat.com>
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] 79e1b116a8c60ebe7e70a9670ff7626fb204d6a1 (anisinha/cloud-init)
Deprecate the users ssh-authorized-keys property
Signed-off-by: Anders F Björklund <anders.f.bjorklund@gmail.com>
(cherry picked from commit 5205b4dd74eb2168ebbeba56579b6f116a272937)
---
.../schemas/schema-cloud-config-v1.json | 16 ++++++++++
.../unittests/config/test_cc_users_groups.py | 30 +++++++++++++++++++
tools/.github-cla-signers | 1 +
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 c47e7c4f..24b6c4bd 100644
--- a/cloudinit/config/schemas/schema-cloud-config-v1.json
+++ b/cloudinit/config/schemas/schema-cloud-config-v1.json
@@ -361,6 +361,22 @@
},
"minItems": 1
},
+ "ssh-authorized-keys": {
+ "allOf": [
+ {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "minItems": 1
+ },
+ {
+ "deprecated": true,
+ "deprecated_version": "18.3",
+ "deprecated_description": "Use ``ssh_authorized_keys`` instead."
+ }
+ ]
+ },
"ssh_import_id": {
"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
--- a/tests/unittests/config/test_cc_users_groups.py
+++ b/tests/unittests/config/test_cc_users_groups.py
@@ -503,6 +503,36 @@ class TestUsersGroupsSchema:
),
True,
),
+ (
+ {
+ "users": [
+ {
+ "name": "lima",
+ "uid": "1000",
+ "homedir": "/home/lima.linux",
+ "shell": "/bin/bash",
+ "sudo": "ALL=(ALL) NOPASSWD:ALL",
+ "lock_passwd": True,
+ "ssh-authorized-keys": ["ssh-ed25519 ..."],
+ }
+ ]
+ },
+ pytest.raises(
+ SchemaValidationError,
+ match=(
+ "Cloud config schema deprecations: "
+ "users.0.ssh-authorized-keys: "
+ " Deprecated in version 18.3."
+ " Use ``ssh_authorized_keys`` instead."
+ ", "
+ "users.0.uid: "
+ " Changed in version 22.3."
+ " The use of ``string`` type is deprecated."
+ " Use an ``integer`` instead."
+ ),
+ ),
+ False,
+ ),
],
)
@skipUnlessJsonSchema()
diff --git a/tools/.github-cla-signers b/tools/.github-cla-signers
index bd50dc84..8da1e3a3 100644
--- a/tools/.github-cla-signers
+++ b/tools/.github-cla-signers
@@ -3,6 +3,7 @@ aciba90
acourdavAkamai
ader1990
adobley
+afbjorklund
ajmyyra
akutz
AlexBaranowski
--
2.39.3

View File

@ -1,146 +0,0 @@
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/3] Fix metric setting for ifcfg network connections for rhel
(#5777)
RH-Author: xiachen <xiachen@redhat.com>
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/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.
It uses IPV4_ROUTE_METRIC and IPV6_ROUTE_METRIC options. Please see
https://people.freedesktop.org/~lkundrak/nm-docs/nm-settings-ifcfg-rh.html
This change ensures that cloud-init generates ifcfg network connection files
with IPV{4/6}_ROUTE_METRIC options that are compatible with RHEL and
network manager.
Fixes GH-5776
(cherry picked from commit a399f4b0815234e3fe11255178c737902b2d243d)
Signed-off-by: Amy Chen <xiachen@redhat.com>
---
cloudinit/net/sysconfig.py | 21 ++++++++++++++++++---
tests/unittests/test_net.py | 37 ++++++++++++++++++++-----------------
2 files changed, 38 insertions(+), 20 deletions(-)
diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
index 32ee7901..503b6993 100644
--- a/cloudinit/net/sysconfig.py
+++ b/cloudinit/net/sysconfig.py
@@ -205,7 +205,7 @@ class Route(ConfigMap):
)
metric_key = "METRIC" + index
if metric_key in self._conf:
- metric_value = str(self._conf["METRIC" + index])
+ metric_value = str(self._conf[metric_key])
buf.write(
"%s=%s\n"
% ("METRIC" + str(reindex), _quote_value(metric_value))
@@ -549,7 +549,12 @@ class Renderer(renderer.Renderer):
subnet_type = subnet.get("type")
# metric may apply to both dhcp and static config
if "metric" in subnet:
- if flavor != "suse":
+ if flavor == "rhel":
+ if subnet_is_ipv6(subnet):
+ iface_cfg["IPV6_ROUTE_METRIC"] = subnet["metric"]
+ else:
+ iface_cfg["IPV4_ROUTE_METRIC"] = subnet["metric"]
+ elif flavor != "suse":
iface_cfg["METRIC"] = subnet["metric"]
if subnet_type in ["dhcp", "dhcp4"]:
# On SUSE distros 'DHCLIENT_SET_DEFAULT_ROUTE' is a global
@@ -656,7 +661,17 @@ class Renderer(renderer.Renderer):
iface_cfg["GATEWAY"] = route["gateway"]
route_cfg.has_set_default_ipv4 = True
if "metric" in route:
- iface_cfg["METRIC"] = route["metric"]
+ if flavor == "rhel":
+ if subnet_is_ipv6(subnet):
+ iface_cfg["IPV6_ROUTE_METRIC"] = route[
+ "metric"
+ ]
+ else:
+ iface_cfg["IPV4_ROUTE_METRIC"] = route[
+ "metric"
+ ]
+ else:
+ iface_cfg["METRIC"] = route["metric"]
else:
# add default routes only to ifcfg files, not
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
index de149f5e..00198232 100644
--- a/tests/unittests/test_net.py
+++ b/tests/unittests/test_net.py
@@ -1345,7 +1345,7 @@ NETWORK_CONFIGS = {
HWADDR=c0:d6:9f:2c:e8:80
IPADDR=192.168.21.3
NETMASK=255.255.255.0
- METRIC=10000
+ IPV4_ROUTE_METRIC=10000
ONBOOT=yes
TYPE=Ethernet
USERCTL=no"""
@@ -1519,7 +1519,7 @@ NETWORK_CONFIGS = {
HWADDR=c0:d6:9f:2c:e8:80
IPADDR=192.168.21.3
NETMASK=255.255.255.0
- METRIC=10000
+ IPV4_ROUTE_METRIC=10000
ONBOOT=yes
TYPE=Ethernet
USERCTL=no"""
@@ -6072,24 +6072,27 @@ USERCTL=no
}
},
}
- expected = {
- "ifcfg-eno1": textwrap.dedent(
- """\
- AUTOCONNECT_PRIORITY=120
- BOOTPROTO=dhcp
- DEVICE=eno1
- HWADDR=07-1c-c6-75-a4-be
- METRIC=100
- ONBOOT=yes
- TYPE=Ethernet
- USERCTL=no
- """
- ),
- }
for dhcp_ver in ("dhcp4", "dhcp6"):
+ expected = {
+ "ifcfg-eno1": textwrap.dedent(
+ """\
+ AUTOCONNECT_PRIORITY=120
+ BOOTPROTO=dhcp
+ DEVICE=eno1
+ HWADDR=07-1c-c6-75-a4-be
+ ONBOOT=yes
+ TYPE=Ethernet
+ USERCTL=no
+ """
+ ),
+ }
v2data = copy.deepcopy(v2base)
if dhcp_ver == "dhcp6":
- expected["ifcfg-eno1"] += "IPV6INIT=yes\nDHCPV6C=yes\n"
+ expected[
+ "ifcfg-eno1"
+ ] += "IPV6INIT=yes\nDHCPV6C=yes\nIPV6_ROUTE_METRIC=100\n"
+ else:
+ expected["ifcfg-eno1"] += "IPV4_ROUTE_METRIC=100\n"
v2data["ethernets"]["eno1"].update(
{dhcp_ver: True, "{0}-overrides".format(dhcp_ver): overrides}
)
--
2.39.3

View File

@ -1,247 +0,0 @@
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: 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] 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
/etc/resolv.conf. Therefore, if either or both global DNS/search domain config
is present along with per-interface DNS/search domain information, we should add
a network manager configuration to prevent network manager from manipulating
/etc/resolv.conf.
This is in addition to what we already do when only global DNS data is
configured.
Fixes bug added in 1b8030e0 .
Signed-off-by: Ani Sinha <anisinha@redhat.com>
(cherry picked from commit 2df49b652471999434f06d9d83ed9db8b4055895)
---
cloudinit/net/sysconfig.py | 26 +++++-
tests/unittests/test_net.py | 158 ++++++++++++++++++++++++++++++++++++
2 files changed, 180 insertions(+), 4 deletions(-)
diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
index 96652e15..363d052a 100644
--- a/cloudinit/net/sysconfig.py
+++ b/cloudinit/net/sysconfig.py
@@ -907,17 +907,35 @@ class Renderer(renderer.Renderer):
@staticmethod
def _render_networkmanager_conf(network_state, templates=None):
+ iface_dns = False
content = networkmanager_conf.NetworkManagerConf("")
+ # check if there is interface specific DNS information configured
+ for iface in network_state.iter_interfaces():
+ for subnet in iface["subnets"]:
+ if "dns_nameservers" in subnet or "dns_search" in subnet:
+ iface_dns = True
+ break
+ if (
+ not iface_dns
+ and "dns" in iface
+ and (iface["dns"]["nameservers"] or iface["dns"]["search"])
+ ):
+ 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.
# This is not required for NetworkManager renderer as it
# does not write /etc/resolv.conf directly. DNS information is
# written to the interface keyfile and NetworkManager is then
# responsible for using the DNS information from the keyfile,
# including managing /etc/resolv.conf.
- if network_state.dns_nameservers:
+ if (
+ network_state.dns_nameservers
+ or network_state.dns_searchdomains
+ or iface_dns
+ ):
content.set_section_keypair("main", "dns", "none")
if len(content) == 0:
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
index 8a75c42b..215807ba 100644
--- a/tests/unittests/test_net.py
+++ b/tests/unittests/test_net.py
@@ -967,6 +967,164 @@ dns = none
),
],
},
+ {
+ "in_data": {
+ "networks": [
+ {
+ "network_id": "dacd568d-5be6-4786-91fe-750c374b78b4",
+ "type": "ipv4",
+ "netmask": "255.255.252.0",
+ "link": "eth0",
+ "routes": [
+ {
+ "netmask": "0.0.0.0",
+ "network": "0.0.0.0",
+ "gateway": "172.19.3.254",
+ }
+ ],
+ "ip_address": "172.19.1.34",
+ "dns_search": ["example3.com"],
+ "dns_nameservers": ["172.19.0.12"],
+ "id": "network0",
+ }
+ ],
+ "links": [
+ {
+ "ethernet_mac_address": "fa:16:3e:ed:9a:59",
+ "mtu": None,
+ "type": "physical",
+ "id": "eth0",
+ },
+ ],
+ },
+ "in_macs": {
+ "fa:16:3e:ed:9a:59": "eth0",
+ },
+ "out_sysconfig_opensuse": [
+ (
+ "etc/sysconfig/network/ifcfg-eth0",
+ """
+# Created by cloud-init automatically, do not edit.
+#
+BOOTPROTO=static
+IPADDR=172.19.1.34
+LLADDR=fa:16:3e:ed:9a:59
+NETMASK=255.255.252.0
+STARTMODE=auto
+""".lstrip(),
+ ),
+ (
+ "etc/resolv.conf",
+ """
+; Created by cloud-init automatically, do not edit.
+;
+nameserver 172.19.0.12
+search example3.com
+""".lstrip(),
+ ),
+ (
+ "etc/NetworkManager/conf.d/99-cloud-init.conf",
+ """
+# Created by cloud-init automatically, do not edit.
+#
+[main]
+dns = none
+""".lstrip(),
+ ),
+ (
+ "etc/udev/rules.d/85-persistent-net-cloud-init.rules",
+ "".join(
+ [
+ 'SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ',
+ 'ATTR{address}=="fa:16:3e:ed:9a:59", NAME="eth0"\n',
+ ]
+ ),
+ ),
+ ],
+ "out_sysconfig_rhel": [
+ (
+ "etc/sysconfig/network-scripts/ifcfg-eth0",
+ """
+# Created by cloud-init automatically, do not edit.
+#
+AUTOCONNECT_PRIORITY=120
+BOOTPROTO=none
+DEFROUTE=yes
+DEVICE=eth0
+DNS1=172.19.0.12
+DOMAIN=example3.com
+GATEWAY=172.19.3.254
+HWADDR=fa:16:3e:ed:9a:59
+IPADDR=172.19.1.34
+NETMASK=255.255.252.0
+ONBOOT=yes
+TYPE=Ethernet
+USERCTL=no
+""".lstrip(),
+ ),
+ (
+ "etc/resolv.conf",
+ """
+; Created by cloud-init automatically, do not edit.
+;
+nameserver 172.19.0.12
+search example3.com
+""".lstrip(),
+ ),
+ (
+ "etc/NetworkManager/conf.d/99-cloud-init.conf",
+ """
+# Created by cloud-init automatically, do not edit.
+#
+[main]
+dns = none
+""".lstrip(),
+ ),
+ (
+ "etc/udev/rules.d/70-persistent-net.rules",
+ "".join(
+ [
+ 'SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ',
+ 'ATTR{address}=="fa:16:3e:ed:9a:59", NAME="eth0"\n',
+ ]
+ ),
+ ),
+ ],
+ "expected_network_manager": [
+ (
+ "".join(
+ [
+ "etc/NetworkManager/system-connections",
+ "/cloud-init-eth0.nmconnection",
+ ]
+ ),
+ """
+# Generated by cloud-init. Changes will be lost.
+
+[connection]
+id=cloud-init eth0
+uuid=1dd9a779-d327-56e1-8454-c65e2556c12c
+autoconnect-priority=120
+type=ethernet
+
+[user]
+org.freedesktop.NetworkManager.origin=cloud-init
+
+[ethernet]
+mac-address=FA:16:3E:ED:9A:59
+
+[ipv4]
+method=manual
+may-fail=false
+address1=172.19.1.34/22
+route1=0.0.0.0/0,172.19.3.254
+dns=172.19.0.12;
+dns-search=example3.com;
+
+""".lstrip(),
+ ),
+ ],
+ },
{
"in_data": {
"services": [{"type": "dns", "address": "172.19.0.12"}],
--
2.39.3

View File

@ -1,54 +0,0 @@
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

View File

@ -1,190 +0,0 @@
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: 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] ac9414d2f1ee605d70bb94277d48ce97c21ea4b8 (xiachen/cloud-init-centos)
This reverts commit 2b6fe6403db769de14f7c7b7e4aa65f5bea8f3e0.
When there is no IPv6 set to dhcp explicitly, NetworkManager keyfile
defaults to method=auto, may-fail=true. When there is Ipv6 set to dhcp
explictily, NetworkManager keyfile will be set to
method=auto, may-fail=false. The default settings are what we want, so
revert the previous change to keep IPv6 not set explicitly.
(cherry picked from commit 65014b97420b41dcb6e7ea17c66bb2539f9b09fc)
Signed-off-by: Amy Chen <xiachen@redhat.com>
---
.../sources/helpers/vmware/imc/config_nic.py | 2 +-
.../sources/vmware/test_vmware_config_file.py | 68 +++++--------------
2 files changed, 18 insertions(+), 52 deletions(-)
diff --git a/cloudinit/sources/helpers/vmware/imc/config_nic.py b/cloudinit/sources/helpers/vmware/imc/config_nic.py
index 254518af..b07214a2 100644
--- a/cloudinit/sources/helpers/vmware/imc/config_nic.py
+++ b/cloudinit/sources/helpers/vmware/imc/config_nic.py
@@ -207,7 +207,7 @@ class NicConfigurator:
"""
if not nic.staticIpv6:
- return ([{"type": "dhcp6"}], [])
+ return ([], [])
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 c1415934..fd4bb481 100644
--- a/tests/unittests/sources/vmware/test_vmware_config_file.py
+++ b/tests/unittests/sources/vmware/test_vmware_config_file.py
@@ -241,45 +241,27 @@ class TestVmwareConfigFile(CiTestCase):
elif cfg.get("name") == nic2.get("name"):
nic2.update(cfg)
- # Test NIC1
self.assertEqual("physical", nic1.get("type"), "type of NIC1")
self.assertEqual("NIC1", nic1.get("name"), "name of NIC1")
self.assertEqual(
"00:50:56:a6:8c:08", nic1.get("mac_address"), "mac address of NIC1"
)
subnets = nic1.get("subnets")
- self.assertEqual(2, len(subnets), "number of subnets for NIC1")
- subnet_ipv4 = subnets[0]
- self.assertEqual(
- "dhcp", subnet_ipv4.get("type"), "Ipv4 DHCP type for NIC1"
- )
- self.assertEqual(
- "auto", subnet_ipv4.get("control"), "NIC1 Control type"
- )
- subnet_ipv6 = subnets[1]
- self.assertEqual(
- "dhcp6", subnet_ipv6.get("type"), "Ipv6 DHCP type for NIC1"
- )
+ self.assertEqual(1, len(subnets), "number of subnets for NIC1")
+ subnet = subnets[0]
+ self.assertEqual("dhcp", subnet.get("type"), "DHCP type for NIC1")
+ self.assertEqual("auto", subnet.get("control"), "NIC1 Control type")
- # Test NIC2
self.assertEqual("physical", nic2.get("type"), "type of NIC2")
self.assertEqual("NIC2", nic2.get("name"), "name of NIC2")
self.assertEqual(
"00:50:56:a6:5a:de", nic2.get("mac_address"), "mac address of NIC2"
)
subnets = nic2.get("subnets")
- self.assertEqual(2, len(subnets), "number of subnets for NIC2")
- subnet_ipv4 = subnets[0]
- self.assertEqual(
- "dhcp", subnet_ipv4.get("type"), "Ipv4 DHCP type for NIC2"
- )
- self.assertEqual(
- "auto", subnet_ipv4.get("control"), "NIC2 Control type"
- )
- subnet_ipv6 = subnets[1]
- self.assertEqual(
- "dhcp6", subnet_ipv6.get("type"), "Ipv6 DHCP type for NIC2"
- )
+ self.assertEqual(1, len(subnets), "number of subnets for NIC2")
+ subnet = subnets[0]
+ self.assertEqual("dhcp", subnet.get("type"), "DHCP type for NIC2")
+ self.assertEqual("auto", subnet.get("control"), "NIC2 Control type")
def test_get_nics_list_static(self):
"""Tests if NicConfigurator properly calculates network subnets
@@ -304,7 +286,6 @@ class TestVmwareConfigFile(CiTestCase):
elif cfg.get("name") == nic2.get("name"):
nic2.update(cfg)
- # Test NIC1
self.assertEqual("physical", nic1.get("type"), "type of NIC1")
self.assertEqual("NIC1", nic1.get("name"), "name of NIC1")
self.assertEqual(
@@ -364,7 +345,6 @@ class TestVmwareConfigFile(CiTestCase):
else:
self.assertEqual(True, False, "invalid gateway %s" % (gateway))
- # Test NIC2
self.assertEqual("physical", nic2.get("type"), "type of NIC2")
self.assertEqual("NIC2", nic2.get("name"), "name of NIC2")
self.assertEqual(
@@ -372,18 +352,16 @@ class TestVmwareConfigFile(CiTestCase):
)
subnets = nic2.get("subnets")
- self.assertEqual(2, len(subnets), "Number of subnets for NIC2")
+ self.assertEqual(1, len(subnets), "Number of subnets for NIC2")
- subnet_ipv4 = subnets[0]
- self.assertEqual("static", subnet_ipv4.get("type"), "Subnet type")
+ subnet = subnets[0]
+ self.assertEqual("static", subnet.get("type"), "Subnet type")
self.assertEqual(
- "192.168.6.102", subnet_ipv4.get("address"), "Subnet address"
+ "192.168.6.102", subnet.get("address"), "Subnet address"
)
self.assertEqual(
- "255.255.0.0", subnet_ipv4.get("netmask"), "Subnet netmask"
+ "255.255.0.0", subnet.get("netmask"), "Subnet netmask"
)
- subnet_ipv6 = subnets[1]
- self.assertEqual("dhcp6", subnet_ipv6.get("type"), "Subnet type")
def test_custom_script(self):
cf = ConfigFile("tests/data/vmware/cust-dhcp-2nic.cfg")
@@ -470,10 +448,7 @@ class TestVmwareNetConfig(CiTestCase):
"type": "static",
"address": "10.20.87.154",
"netmask": "255.255.252.0",
- },
- {
- "type": "dhcp6",
- },
+ }
],
}
],
@@ -524,10 +499,7 @@ class TestVmwareNetConfig(CiTestCase):
"metric": 10000,
}
],
- },
- {
- "type": "dhcp6",
- },
+ }
],
}
],
@@ -587,10 +559,7 @@ class TestVmwareNetConfig(CiTestCase):
"metric": 10000,
}
],
- },
- {
- "type": "dhcp6",
- },
+ }
],
}
],
@@ -635,10 +604,7 @@ class TestVmwareNetConfig(CiTestCase):
"address": "10.20.87.154",
"netmask": "255.255.252.0",
"gateway": "10.20.87.253",
- },
- {
- "type": "dhcp6",
- },
+ }
],
}
],
--
2.39.3

View File

@ -1,140 +0,0 @@
From fc7ef10d5ca56af69eeef6d5d66a757dc01352ee Mon Sep 17 00:00:00 2001
From: Ani Sinha <anisinha@redhat.com>
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: 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] 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'.
Fixes GH-5359
Signed-off-by: Ani Sinha <anisinha@redhat.com>
Co-authored-by: Ben Gray <ben.gray@clearcapital.com>
(cherry picked from commit 525026061404ef09baebb85631d9af3b0a4d8930)
---
cloudinit/config/cc_yum_add_repo.py | 24 ++++++------
doc/examples/cloud-config-yum-repo.txt | 3 +-
.../unittests/config/test_cc_yum_add_repo.py | 38 +++++++++++++++++++
3 files changed, 51 insertions(+), 14 deletions(-)
diff --git a/cloudinit/config/cc_yum_add_repo.py b/cloudinit/config/cc_yum_add_repo.py
index 1ab5008f..4fd66250 100644
--- a/cloudinit/config/cc_yum_add_repo.py
+++ b/cloudinit/config/cc_yum_add_repo.py
@@ -210,24 +210,22 @@ def handle(name: str, cfg: Config, cloud: Cloud, args: list) -> None:
n_repo_config[k] = v
repo_config = n_repo_config
missing_required = 0
- for req_field in ["baseurl"]:
+ req_fields = ["baseurl", "metalink"]
+ for req_field in req_fields:
if req_field not in repo_config:
- LOG.warning(
- "Repository %s does not contain a %s"
- " configuration 'required' entry",
- repo_id,
- req_field,
- )
missing_required += 1
- if not missing_required:
- repo_configs[canon_repo_id] = repo_config
- repo_locations[canon_repo_id] = repo_fn_pth
- else:
+
+ if missing_required == len(req_fields):
LOG.warning(
- "Repository %s is missing %s required fields, skipping!",
+ "Repository %s should contain atleast one of the"
+ " following configuration entries: %s, skipping!",
repo_id,
- missing_required,
+ ", ".join(req_fields),
)
+ else:
+ repo_configs[canon_repo_id] = repo_config
+ repo_locations[canon_repo_id] = repo_fn_pth
+
for (c_repo_id, path) in repo_locations.items():
repo_blob = _format_repository_config(
c_repo_id, repo_configs.get(c_repo_id)
diff --git a/doc/examples/cloud-config-yum-repo.txt b/doc/examples/cloud-config-yum-repo.txt
index e8f2bbb4..6a4037e2 100644
--- a/doc/examples/cloud-config-yum-repo.txt
+++ b/doc/examples/cloud-config-yum-repo.txt
@@ -11,8 +11,9 @@ yum_repos:
# Any repository configuration options
# See: man yum.conf
#
- # This one is required!
+ # At least one of 'baseurl' or 'metalink' is required!
baseurl: http://download.fedoraproject.org/pub/epel/testing/5/$basearch
+ metalink: https://mirrors.fedoraproject.org/metalink?repo=epel-$releasever&arch=$basearch&infra=$infra&content=$contentdir
enabled: false
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 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):
"yum_repos": {
"epel-testing": {
"name": "Extra Packages for Enterprise Linux 5 - Testing",
+ # At least one of baseurl or metalink must be present.
# Missing this should cause the repo not to be written
# 'baseurl': 'http://blah.org/pub/epel/testing/5/$barch',
"enabled": False,
@@ -46,6 +47,43 @@ class TestConfig(helpers.FilesystemMockingTestCase):
IOError, util.load_text_file, "/etc/yum.repos.d/epel_testing.repo"
)
+ def test_metalink_config(self):
+ cfg = {
+ "yum_repos": {
+ "epel-testing": {
+ "name": "Extra Packages for Enterprise Linux 5 - Testing",
+ "metalink": "http://blah.org/pub/epel/testing/5/$basearch",
+ "enabled": False,
+ "gpgcheck": True,
+ "gpgkey": "file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL",
+ "failovermethod": "priority",
+ },
+ },
+ }
+ self.patchUtils(self.tmp)
+ self.patchOS(self.tmp)
+ cc_yum_add_repo.handle("yum_add_repo", cfg, None, [])
+ contents = util.load_text_file("/etc/yum.repos.d/epel-testing.repo")
+ parser = configparser.ConfigParser()
+ parser.read_string(contents)
+ expected = {
+ "epel-testing": {
+ "name": "Extra Packages for Enterprise Linux 5 - Testing",
+ "failovermethod": "priority",
+ "gpgkey": "file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL",
+ "enabled": "0",
+ "metalink": "http://blah.org/pub/epel/testing/5/$basearch",
+ "gpgcheck": "1",
+ }
+ }
+ for section in expected:
+ self.assertTrue(
+ parser.has_section(section),
+ "Contains section {0}".format(section),
+ )
+ for k, v in expected[section].items():
+ self.assertEqual(parser.get(section, k), v)
+
def test_write_config(self):
cfg = {
"yum_repos": {
--
2.39.3

View File

@ -1,145 +0,0 @@
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: 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] 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'.
Fixes GH-5520
Signed-off-by: Ani Sinha <anisinha@redhat.com>
(cherry picked from commit 0b4084374440d2a5a9968129e0460a1a009d9830)
Signed-off-by: Amy Chen <xiachen@redhat.com>
---
cloudinit/config/cc_yum_add_repo.py | 2 +-
.../schemas/schema-cloud-config-v1.json | 10 +++++
doc/examples/cloud-config-yum-repo.txt | 3 +-
.../unittests/config/test_cc_yum_add_repo.py | 40 ++++++++++++++++++-
4 files changed, 52 insertions(+), 3 deletions(-)
diff --git a/cloudinit/config/cc_yum_add_repo.py b/cloudinit/config/cc_yum_add_repo.py
index 4fd66250..3870d24e 100644
--- a/cloudinit/config/cc_yum_add_repo.py
+++ b/cloudinit/config/cc_yum_add_repo.py
@@ -210,7 +210,7 @@ def handle(name: str, cfg: Config, cloud: Cloud, args: list) -> None:
n_repo_config[k] = v
repo_config = n_repo_config
missing_required = 0
- req_fields = ["baseurl", "metalink"]
+ req_fields = ["baseurl", "metalink", "mirrorlist"]
for req_field in req_fields:
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 5758777a..6e0e7db9 100644
--- a/cloudinit/config/schemas/schema-cloud-config-v1.json
+++ b/cloudinit/config/schemas/schema-cloud-config-v1.json
@@ -3439,6 +3439,11 @@
"format": "uri",
"description": "Specifies a URL to a metalink file for the repomd.xml"
},
+ "mirrorlist": {
+ "type": "string",
+ "format": "uri",
+ "description": "Specifies a URL to a file containing a baseurls list"
+ },
"name": {
"type": "string",
"description": "Optional human-readable name of the yum repo."
@@ -3476,6 +3481,11 @@
"required": [
"metalink"
]
+ },
+ {
+ "required": [
+ "mirrorlist"
+ ]
}
]
}
diff --git a/doc/examples/cloud-config-yum-repo.txt b/doc/examples/cloud-config-yum-repo.txt
index 6a4037e2..cee26677 100644
--- a/doc/examples/cloud-config-yum-repo.txt
+++ b/doc/examples/cloud-config-yum-repo.txt
@@ -11,9 +11,10 @@ yum_repos:
# Any repository configuration options
# See: man yum.conf
#
- # At least one of 'baseurl' or 'metalink' is required!
+ # At least one of 'baseurl' or 'metalink' or 'mirrorlist' is required!
baseurl: http://download.fedoraproject.org/pub/epel/testing/5/$basearch
metalink: https://mirrors.fedoraproject.org/metalink?repo=epel-$releasever&arch=$basearch&infra=$infra&content=$contentdir
+ mirrorlist: https://mirrors.fedoraproject.org/metalink?repo=fedora-$releasever&
enabled: false
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 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):
"yum_repos": {
"epel-testing": {
"name": "Extra Packages for Enterprise Linux 5 - Testing",
- # At least one of baseurl or metalink must be present.
+ # At least one of baseurl or metalink or mirrorlist
+ # must be present.
# Missing this should cause the repo not to be written
# 'baseurl': 'http://blah.org/pub/epel/testing/5/$barch',
"enabled": False,
@@ -84,6 +85,43 @@ class TestConfig(helpers.FilesystemMockingTestCase):
for k, v in expected[section].items():
self.assertEqual(parser.get(section, k), v)
+ def test_mirrorlist_config(self):
+ cfg = {
+ "yum_repos": {
+ "epel-testing": {
+ "name": "Extra Packages for Enterprise Linux 5 - Testing",
+ "mirrorlist": "http://mirrors.blah.org/metalink?repo=rhel-$releasever",
+ "enabled": False,
+ "gpgcheck": True,
+ "gpgkey": "file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL",
+ "failovermethod": "priority",
+ },
+ },
+ }
+ self.patchUtils(self.tmp)
+ self.patchOS(self.tmp)
+ cc_yum_add_repo.handle("yum_add_repo", cfg, None, [])
+ contents = util.load_text_file("/etc/yum.repos.d/epel-testing.repo")
+ parser = configparser.ConfigParser()
+ parser.read_string(contents)
+ expected = {
+ "epel-testing": {
+ "name": "Extra Packages for Enterprise Linux 5 - Testing",
+ "failovermethod": "priority",
+ "gpgkey": "file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL",
+ "enabled": "0",
+ "mirrorlist": "http://mirrors.blah.org/metalink?repo=rhel-$releasever",
+ "gpgcheck": "1",
+ }
+ }
+ for section in expected:
+ self.assertTrue(
+ parser.has_section(section),
+ "Contains section {0}".format(section),
+ )
+ for k, v in expected[section].items():
+ self.assertEqual(parser.get(section, k), v)
+
def test_write_config(self):
cfg = {
"yum_repos": {
--
2.39.3

View File

@ -1,231 +0,0 @@
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 4/4] Update pylint version to support python 3.12 (#5338)
RH-Author: Ani Sinha <anisinha@redhat.com>
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: [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:
https://github.com/pylint-dev/pylint/issues/8782
Minimum version of pylint required in order to support python 3.12 is 3.0.2.
Please see https://github.com/pylint-dev/astroid/issues/2201 . Upon further
experimentation, it is seen that we need minimum pylint version 3.2.0 for
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)
---
cloudinit/config/cc_mounts.py | 4 ++++
cloudinit/distros/bsd.py | 2 ++
cloudinit/distros/netbsd.py | 2 +-
cloudinit/sources/DataSourceAzure.py | 2 +-
cloudinit/sources/DataSourceEc2.py | 3 ++-
cloudinit/sources/DataSourceLXD.py | 2 +-
tests/integration_tests/conftest.py | 6 +++---
tests/integration_tests/util.py | 2 +-
tests/unittests/config/test_cc_ntp.py | 2 ++
tests/unittests/sources/test_gce.py | 1 +
tests/unittests/test_util.py | 2 ++
tox.ini | 2 +-
12 files changed, 21 insertions(+), 9 deletions(-)
diff --git a/cloudinit/config/cc_mounts.py b/cloudinit/config/cc_mounts.py
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:
"bs=1M",
"count=%s" % size,
]
+ else:
+ raise subp.ProcessExecutionError(
+ "Missing dependency: 'dd' and 'fallocate' are not available"
+ )
try:
subp.subp(cmd, capture=True)
diff --git a/cloudinit/distros/bsd.py b/cloudinit/distros/bsd.py
index 995a1ba2..b0e63964 100644
--- a/cloudinit/distros/bsd.py
+++ b/cloudinit/distros/bsd.py
@@ -120,6 +120,8 @@ class BSD(distros.Distro):
if not self.pkg_cmd_upgrade_prefix:
return
cmd = self.pkg_cmd_upgrade_prefix
+ else:
+ cmd = []
if args and isinstance(args, str):
cmd.append(args)
diff --git a/cloudinit/distros/netbsd.py b/cloudinit/distros/netbsd.py
index e8b9bcd5..972528c6 100644
--- a/cloudinit/distros/netbsd.py
+++ b/cloudinit/distros/netbsd.py
@@ -12,7 +12,7 @@ import cloudinit.distros.bsd
from cloudinit import subp, util
try:
- import crypt
+ import crypt # pylint: disable=W4901
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 bd654cc0..11dc6686 100644
--- a/cloudinit/sources/DataSourceAzure.py
+++ b/cloudinit/sources/DataSourceAzure.py
@@ -49,7 +49,7 @@ from cloudinit.sources.helpers.azure import (
from cloudinit.url_helper import UrlError
try:
- import crypt
+ import crypt # pylint: disable=W4901
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 1b81b21f..28822e37 100644
--- a/cloudinit/sources/DataSourceEc2.py
+++ b/cloudinit/sources/DataSourceEc2.py
@@ -333,6 +333,8 @@ class DataSourceEc2(sources.DataSource):
return None
def wait_for_metadata_service(self):
+ urls = []
+ start_time = 0
mcfg = self.ds_cfg
url_params = self.get_url_params()
@@ -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
- urls = []
url2base = {}
url_path = "{ver}/meta-data/instance-id".format(
ver=self.min_metadata_version
diff --git a/cloudinit/sources/DataSourceLXD.py b/cloudinit/sources/DataSourceLXD.py
index cd316101..4c95b907 100644
--- a/cloudinit/sources/DataSourceLXD.py
+++ b/cloudinit/sources/DataSourceLXD.py
@@ -331,7 +331,7 @@ class MetaDataKeys(Flag):
CONFIG = auto()
DEVICES = auto()
META_DATA = auto()
- ALL = CONFIG | DEVICES | META_DATA
+ ALL = CONFIG | DEVICES | META_DATA # pylint: disable=E1131
class _MetaDataReader:
diff --git a/tests/integration_tests/conftest.py b/tests/integration_tests/conftest.py
index ccbf6a71..58133815 100644
--- a/tests/integration_tests/conftest.py
+++ b/tests/integration_tests/conftest.py
@@ -273,7 +273,7 @@ def _client(
@pytest.fixture
-def client(
+def client( # pylint: disable=W0135
request, fixture_utils, session_cloud, setup_image
) -> Iterator[IntegrationInstance]:
"""Provide a client that runs for every test."""
@@ -282,7 +282,7 @@ def client(
@pytest.fixture(scope="module")
-def module_client(
+def module_client( # pylint: disable=W0135
request, fixture_utils, session_cloud, setup_image
) -> Iterator[IntegrationInstance]:
"""Provide a client that runs once per module."""
@@ -291,7 +291,7 @@ def module_client(
@pytest.fixture(scope="class")
-def class_client(
+def class_client( # pylint: disable=W0135
request, fixture_utils, session_cloud, setup_image
) -> 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 8ee3631d..cbe00c83 100644
--- a/tests/integration_tests/util.py
+++ b/tests/integration_tests/util.py
@@ -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)
- raise Exception(
+ raise Exception( # pylint: disable=W0719
"cloud-init status did not return successfully."
) from last_exception
diff --git a/tests/unittests/config/test_cc_ntp.py b/tests/unittests/config/test_cc_ntp.py
index 74ccf2de..6f6c3360 100644
--- a/tests/unittests/config/test_cc_ntp.py
+++ b/tests/unittests/config/test_cc_ntp.py
@@ -249,6 +249,7 @@ class TestNtp(FilesystemMockingTestCase):
)
def _get_expected_pools(self, pools, distro, client):
+ expected_pools = None
if client in ["ntp", "chrony"]:
if client == "ntp" and distro == "alpine":
# NTP for Alpine Linux is Busybox's ntp which does not
@@ -264,6 +265,7 @@ class TestNtp(FilesystemMockingTestCase):
return expected_pools
def _get_expected_servers(self, servers, distro, client):
+ expected_servers = None
if client in ["ntp", "chrony"]:
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 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):
gce_meta = GCE_META
def _request_callback(request):
+ recursive = False
url_path = urlparse(request.url).path
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 70edb40b..b534a1a7 100644
--- a/tests/unittests/test_util.py
+++ b/tests/unittests/test_util.py
@@ -1700,6 +1700,8 @@ class TestRedirectOutputPreexecFn:
args = (test_string, None)
elif request.param == "errfmt":
args = (None, test_string)
+ else:
+ args = (None, None)
with mock.patch(M_PATH + "subprocess.Popen") as m_popen:
util.redirect_output(*args)
diff --git a/tox.ini b/tox.ini
index 473e937c..85af1a14 100644
--- a/tox.ini
+++ b/tox.ini
@@ -25,7 +25,7 @@ hypothesis==6.31.6
hypothesis_jsonschema==0.20.1
isort==5.10.1
mypy==0.950
-pylint==2.13.9
+pylint==3.2.0
pytest==7.0.1
ruff==0.0.285
types-jsonschema==4.4.2
--
2.39.3

View File

@ -1,409 +0,0 @@
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

View File

@ -1,51 +0,0 @@
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/4] doc: update examples to reflect alternative ways to
provide `sudo` option (#5418)
RH-Author: Ani Sinha <anisinha@redhat.com>
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] 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,
a list of sudo rule strings or `False` to explicitly deny sudo usage. Update
examples to show how a list of strings can be used with `sudo` option.
Signed-off-by: Ani Sinha <anisinha@redhat.com>
(cherry picked from commit cbcb05349e35023ee6e81ccaf13e79adb8f65f63)
---
doc/examples/cloud-config-user-groups.txt | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/doc/examples/cloud-config-user-groups.txt b/doc/examples/cloud-config-user-groups.txt
index 87fc52e8..56eb674f 100644
--- a/doc/examples/cloud-config-user-groups.txt
+++ b/doc/examples/cloud-config-user-groups.txt
@@ -35,6 +35,10 @@ users:
lock_passwd: true
ssh_authorized_keys:
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDSL7uWGj8cgWyIOaspgKdVy0cKJ+UTjfv7jBOjG2H/GN8bJVXy72XAvnhM0dUM+CCs8FOf0YlPX+Frvz2hKInrmRhZVwRSL129PasD12MlI3l44u6IwS1o/W86Q+tkQYEljtqDOo0a+cOsaZkvUNzUyEXUwz/lmYa6G4hMKZH4NBj7nbAAF96wsMCoyNwbWryBnDYUr6wMbjRR1J9Pw7Xh7WRC73wy4Va2YuOgbD3V/5ZrFPLbWZW/7TFXVrql04QVbyei4aiFR5n//GvoqwQDNe58LmbzX/xvxyKJYdny2zXmdAhMxbrpFQsfpkJ9E/H5w0yOdSvnWbUoG5xNGoOB csmith@fringe
+ - name: testuser
+ gecos: Mr. Test
+ homedir: /local/testdir
+ sudo: ["ALL=(ALL) NOPASSWD:ALL"]
- name: cloudy
gecos: Magic Cloud App Daemon User
inactive: '5'
@@ -100,6 +104,8 @@ users:
#
# Allow a user unrestricted sudo access.
# sudo: ALL=(ALL) NOPASSWD:ALL
+# or
+# sudo: ["ALL=(ALL) NOPASSWD:ALL"]
#
# Adding multiple sudo rule strings.
# sudo:
--
2.39.3

View File

@ -1,170 +0,0 @@
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: 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] 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
technically can work, this is a use case we no longer support and should
indicate that it is deprecated.
Also remove/update examples.
(cherry picked from commit 7c67f7732f04b41600934818f7d5bcb4d085ed7c)
---
.../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 ++++++++++++-
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 24b6c4bd..23573583 100644
--- a/cloudinit/config/schemas/schema-cloud-config-v1.json
+++ b/cloudinit/config/schemas/schema-cloud-config-v1.json
@@ -602,6 +602,12 @@
},
"merge_type": {
"$ref": "#/$defs/merge_definition"
+ },
+ "system_info": {
+ "type": "object",
+ "description": "System and/or distro specific settings. This is not intended to be overridden by user data or vendor data.",
+ "deprecated": true,
+ "deprecated_version": "24.2"
}
}
},
@@ -3894,6 +3900,7 @@
"ssh_pwauth": {},
"ssh_quiet_keygen": {},
"swap": {},
+ "system_info": {},
"timezone": {},
"ubuntu_advantage": {},
"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
+++ b/doc/examples/cloud-config-apt.txt
@@ -8,29 +8,6 @@
# Number: Set pipelining to some number (not recommended)
apt_pipelining: False
-## apt config via system_info:
-# under the 'system_info', you can customize cloud-init's interaction
-# with apt.
-# system_info:
-# apt_get_command: [command, argument, argument]
-# apt_get_upgrade_subcommand: dist-upgrade
-#
-# apt_get_command:
-# To specify a different 'apt-get' command, set 'apt_get_command'.
-# This must be a list, and the subcommand (update, upgrade) is appended to it.
-# default is:
-# ['apt-get', '--option=Dpkg::Options::=--force-confold',
-# '--option=Dpkg::options::=--force-unsafe-io', '--assume-yes', '--quiet']
-#
-# apt_get_upgrade_subcommand: "dist-upgrade"
-# Specify a different subcommand for 'upgrade. The default is 'dist-upgrade'.
-# This is the subcommand that is invoked for package_upgrade.
-#
-# apt_get_wrapper:
-# command: eatmydata
-# enabled: [True, False, "auto"]
-#
-
# Install additional packages on first boot
#
# Default: none
diff --git a/doc/examples/cloud-config-user-groups.txt b/doc/examples/cloud-config-user-groups.txt
index 56eb674f..2cafef88 100644
--- a/doc/examples/cloud-config-user-groups.txt
+++ b/doc/examples/cloud-config-user-groups.txt
@@ -143,13 +143,5 @@ users:
#
# users[0] (the first user in users) overrides the user directive.
#
-# The 'default' user above references the distro's config:
-# system_info:
-# default_user:
-# name: Ubuntu
-# plain_text_passwd: 'ubuntu'
-# home: /home/ubuntu
-# shell: /bin/bash
-# lock_passwd: True
-# gecos: Ubuntu
-# groups: [adm, cdrom, dip, lxd, sudo]
+# The 'default' user above references the distro's config set in
+# /etc/cloud/cloud.cfg.
diff --git a/tests/data/user_data.1.txt b/tests/data/user_data.1.txt
index 4c4543de..a1b5aa60 100644
--- a/tests/data/user_data.1.txt
+++ b/tests/data/user_data.1.txt
@@ -3,13 +3,3 @@ write_files:
- content: blah
path: /etc/blah.ini
permissions: 493
-
-system_info:
- package_mirrors:
- - arches: [i386, amd64, blah]
- failsafe:
- primary: http://my.archive.mydomain.com/ubuntu
- security: http://my.security.mydomain.com/ubuntu
- search:
- primary: []
- security: []
diff --git a/tests/unittests/runs/test_merge_run.py b/tests/unittests/runs/test_merge_run.py
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):
cfg = {
"datasource_list": ["None"],
"cloud_init_modules": ["write_files"],
- "system_info": {"paths": {"run_dir": new_root}},
+ "system_info": {
+ "paths": {"run_dir": new_root},
+ "package_mirrors": [
+ {
+ "arches": ["i386", "amd64", "blah"],
+ "failsafe": {
+ "primary": "http://my.archive.mydomain.com/ubuntu",
+ "security": (
+ "http://my.security.mydomain.com/ubuntu"
+ ),
+ },
+ "search": {"primary": [], "security": []},
+ },
+ ],
+ },
}
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

View File

@ -1,147 +0,0 @@
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

View File

@ -1,352 +0,0 @@
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/4] feat(sysconfig): Add DNS from interface config to
resolv.conf (#5401)
RH-Author: Ani Sinha <anisinha@redhat.com>
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] 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
interface specific dns configuration completely. This means, when global dns
information is absent and only interface specific dns configuration is present,
/etc/resolv.conf will not have complete dns information. Fix this so that
per interface dns information is also taken into account along with global dns
configuration in order to populate /etc/resolv.conf.
Fixes: GH-5400
Signed-off-by: Ani Sinha <anisinha@redhat.com>
(cherry picked from commit 1b8030e0c7fd6fbff7e38ad1e3e6266ae50c83a5)
---
cloudinit/net/sysconfig.py | 52 +++++++++-
tests/unittests/test_net.py | 184 +++++++++++++++++++++++++++++++++++-
2 files changed, 230 insertions(+), 6 deletions(-)
diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
index 1678fcde..32ee7901 100644
--- a/cloudinit/net/sysconfig.py
+++ b/cloudinit/net/sysconfig.py
@@ -825,11 +825,53 @@ class Renderer(renderer.Renderer):
@staticmethod
def _render_dns(network_state, existing_dns_path=None):
- # skip writing resolv.conf if network_state doesn't include any input.
+
+ found_nameservers = []
+ found_dns_search = []
+
+ for iface in network_state.iter_interfaces():
+ for subnet in iface["subnets"]:
+ # 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"])
+
+ # 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
+ ]
+
+ # When both global and interface specific entries are present,
+ # use them both to generate /etc/resolv.conf eliminating duplicate
+ # entries. Otherwise use global or interface specific entries whichever
+ # is provided.
+ if network_state.dns_nameservers:
+ found_nameservers += [
+ nameserver
+ for nameserver in network_state.dns_nameservers
+ if nameserver not in found_nameservers
+ ]
+ if network_state.dns_searchdomains:
+ found_dns_search += [
+ search
+ for search in network_state.dns_searchdomains
+ if search not in found_dns_search
+ ]
+
+ # skip writing resolv.conf if no dns information is provided in conf.
if not any(
[
- len(network_state.dns_nameservers),
- len(network_state.dns_searchdomains),
+ len(found_nameservers),
+ len(found_dns_search),
]
):
return None
@@ -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)
- for searchdomain in network_state.dns_searchdomains:
+ for searchdomain in found_dns_search:
content.add_search_domain(searchdomain)
header = _make_header(";")
content_str = str(content)
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
index fee8e035..de149f5e 100644
--- a/tests/unittests/test_net.py
+++ b/tests/unittests/test_net.py
@@ -516,6 +516,8 @@ OS_SAMPLES = [
}
],
"ip_address": "172.19.1.34",
+ "dns_search": ["testweb.com"],
+ "dns_nameservers": ["172.19.0.13"],
"id": "network0",
}
],
@@ -550,7 +552,9 @@ STARTMODE=auto
"""
; Created by cloud-init automatically, do not edit.
;
+nameserver 172.19.0.13
nameserver 172.19.0.12
+search testweb.com
""".lstrip(),
),
(
@@ -582,6 +586,8 @@ AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEFROUTE=yes
DEVICE=eth0
+DNS1=172.19.0.13
+DOMAIN=testweb.com
GATEWAY=172.19.3.254
HWADDR=fa:16:3e:ed:9a:59
IPADDR=172.19.1.34
@@ -596,7 +602,174 @@ USERCTL=no
"""
; Created by cloud-init automatically, do not edit.
;
+nameserver 172.19.0.13
nameserver 172.19.0.12
+search testweb.com
+""".lstrip(),
+ ),
+ (
+ "etc/NetworkManager/conf.d/99-cloud-init.conf",
+ """
+# Created by cloud-init automatically, do not edit.
+#
+[main]
+dns = none
+""".lstrip(),
+ ),
+ (
+ "etc/udev/rules.d/70-persistent-net.rules",
+ "".join(
+ [
+ 'SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ',
+ 'ATTR{address}=="fa:16:3e:ed:9a:59", NAME="eth0"\n',
+ ]
+ ),
+ ),
+ ],
+ "expected_network_manager": [
+ (
+ "".join(
+ [
+ "etc/NetworkManager/system-connections",
+ "/cloud-init-eth0.nmconnection",
+ ]
+ ),
+ """
+# Generated by cloud-init. Changes will be lost.
+
+[connection]
+id=cloud-init eth0
+uuid=1dd9a779-d327-56e1-8454-c65e2556c12c
+autoconnect-priority=120
+type=ethernet
+
+[user]
+org.freedesktop.NetworkManager.origin=cloud-init
+
+[ethernet]
+mac-address=FA:16:3E:ED:9A:59
+
+[ipv4]
+method=manual
+may-fail=false
+address1=172.19.1.34/22
+route1=0.0.0.0/0,172.19.3.254
+dns=172.19.0.13;
+dns-search=testweb.com;
+
+""".lstrip(),
+ ),
+ ],
+ },
+ {
+ "in_data": {
+ "services": [
+ {
+ "type": "dns",
+ "address": "172.19.0.12",
+ "search": ["example1.com", "example2.com"],
+ }
+ ],
+ "networks": [
+ {
+ "network_id": "dacd568d-5be6-4786-91fe-750c374b78b4",
+ "type": "ipv4",
+ "netmask": "255.255.252.0",
+ "link": "eth0",
+ "routes": [
+ {
+ "netmask": "0.0.0.0",
+ "network": "0.0.0.0",
+ "gateway": "172.19.3.254",
+ }
+ ],
+ "ip_address": "172.19.1.34",
+ "dns_search": ["example3.com"],
+ "dns_nameservers": ["172.19.0.12"],
+ "id": "network0",
+ }
+ ],
+ "links": [
+ {
+ "ethernet_mac_address": "fa:16:3e:ed:9a:59",
+ "mtu": None,
+ "type": "physical",
+ "id": "eth0",
+ },
+ ],
+ },
+ "in_macs": {
+ "fa:16:3e:ed:9a:59": "eth0",
+ },
+ "out_sysconfig_opensuse": [
+ (
+ "etc/sysconfig/network/ifcfg-eth0",
+ """
+# Created by cloud-init automatically, do not edit.
+#
+BOOTPROTO=static
+IPADDR=172.19.1.34
+LLADDR=fa:16:3e:ed:9a:59
+NETMASK=255.255.252.0
+STARTMODE=auto
+""".lstrip(),
+ ),
+ (
+ "etc/resolv.conf",
+ """
+; Created by cloud-init automatically, do not edit.
+;
+nameserver 172.19.0.12
+search example3.com example1.com example2.com
+""".lstrip(),
+ ),
+ (
+ "etc/NetworkManager/conf.d/99-cloud-init.conf",
+ """
+# Created by cloud-init automatically, do not edit.
+#
+[main]
+dns = none
+""".lstrip(),
+ ),
+ (
+ "etc/udev/rules.d/85-persistent-net-cloud-init.rules",
+ "".join(
+ [
+ 'SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ',
+ 'ATTR{address}=="fa:16:3e:ed:9a:59", NAME="eth0"\n',
+ ]
+ ),
+ ),
+ ],
+ "out_sysconfig_rhel": [
+ (
+ "etc/sysconfig/network-scripts/ifcfg-eth0",
+ """
+# Created by cloud-init automatically, do not edit.
+#
+AUTOCONNECT_PRIORITY=120
+BOOTPROTO=none
+DEFROUTE=yes
+DEVICE=eth0
+DNS1=172.19.0.12
+DOMAIN=example3.com
+GATEWAY=172.19.3.254
+HWADDR=fa:16:3e:ed:9a:59
+IPADDR=172.19.1.34
+NETMASK=255.255.252.0
+ONBOOT=yes
+TYPE=Ethernet
+USERCTL=no
+""".lstrip(),
+ ),
+ (
+ "etc/resolv.conf",
+ """
+; Created by cloud-init automatically, do not edit.
+;
+nameserver 172.19.0.12
+search example3.com example1.com example2.com
""".lstrip(),
),
(
@@ -647,6 +820,7 @@ may-fail=false
address1=172.19.1.34/22
route1=0.0.0.0/0,172.19.3.254
dns=172.19.0.12;
+dns-search=example3.com;
""".lstrip(),
),
@@ -654,7 +828,13 @@ dns=172.19.0.12;
},
{
"in_data": {
- "services": [{"type": "dns", "address": "172.19.0.12"}],
+ "services": [
+ {
+ "type": "dns",
+ "address": "172.19.0.12",
+ "search": "example.com",
+ }
+ ],
"networks": [
{
"network_id": "public-ipv4",
@@ -715,6 +895,7 @@ STARTMODE=auto
; Created by cloud-init automatically, do not edit.
;
nameserver 172.19.0.12
+search example.com
""".lstrip(),
),
(
@@ -763,6 +944,7 @@ USERCTL=no
; Created by cloud-init automatically, do not edit.
;
nameserver 172.19.0.12
+search example.com
""".lstrip(),
),
(
--
2.39.3

View File

@ -1,45 +0,0 @@
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: 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] a63b3c5f534155aaff36cec137fe1ad7d2f9ed6b (anisinha/cloud-init)
These are used by our openstack network_data.json parsing code and
get used by the sysconfig renderer.
Fixes GH-4911
(cherry picked from commit 0b1ca174095e3ad685e6d6649bb08aafb19a95b9)
Signed-off-by: Ani Sinha <anisinha@redhat.com>
---
cloudinit/config/schemas/schema-network-config-v1.json | 8 ++++++++
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 78628178..6f97f571 100644
--- a/cloudinit/config/schemas/schema-network-config-v1.json
+++ b/cloudinit/config/schemas/schema-network-config-v1.json
@@ -532,6 +532,14 @@
"items": {
"$ref": "#/$defs/anyOf_type_route"
}
+ },
+ "ipv4": {
+ "type": "boolean",
+ "description": "Indicate if the subnet is IPv4. If not specified, it will be inferred from the subnet type or address. This exists for compatibility with OpenStack's ``network_data.json`` when rendered through sysconfig."
+ },
+ "ipv6": {
+ "type": "boolean",
+ "description": "Indicate if the subnet is IPv6. If not specified, it will be inferred from the subnet type or address. This is exists for compatibility with OpenStack's ``network_data.json`` when rendered through sysconfig."
}
}
},
--
2.39.3

View File

@ -1,247 +0,0 @@
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: 102: fix: Clean cache if no datasource fallback (#5499)
RH-Jira: RHEL-49740
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
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
cleaning got applied universally. This commit makes it so cache will be
cleaned as it was before if fallback isn't implemented in datasource.
Fixes GH-5486
(cherry picked from commit 550c685c98551f65c30832b186fe091721b48477)
Signed-off-by: Ani Sinha <anisinha@redhat.com>
---
cloudinit/stages.py | 1 +
.../assets/DataSourceNoCacheNetworkOnly.py | 23 ++++
.../assets/DataSourceNoCacheWithFallback.py | 29 +++++
.../datasources/test_caching.py | 115 ++++++++++++++++++
tests/integration_tests/instances.py | 4 +-
5 files changed, 171 insertions(+), 1 deletion(-)
create mode 100644 tests/integration_tests/assets/DataSourceNoCacheNetworkOnly.py
create mode 100644 tests/integration_tests/assets/DataSourceNoCacheWithFallback.py
create mode 100644 tests/integration_tests/datasources/test_caching.py
diff --git a/cloudinit/stages.py b/cloudinit/stages.py
index 894eeac5..feda6753 100644
--- a/cloudinit/stages.py
+++ b/cloudinit/stages.py
@@ -405,6 +405,7 @@ class Init:
ds,
)
else:
+ util.del_file(self.paths.instance_link)
raise e
self.datasource = ds
# Ensure we adjust our path members datasource
diff --git a/tests/integration_tests/assets/DataSourceNoCacheNetworkOnly.py b/tests/integration_tests/assets/DataSourceNoCacheNetworkOnly.py
new file mode 100644
index 00000000..54a7bab3
--- /dev/null
+++ b/tests/integration_tests/assets/DataSourceNoCacheNetworkOnly.py
@@ -0,0 +1,23 @@
+import logging
+
+from cloudinit import sources
+
+LOG = logging.getLogger(__name__)
+
+
+class DataSourceNoCacheNetworkOnly(sources.DataSource):
+ def _get_data(self):
+ LOG.debug("TEST _get_data called")
+ return True
+
+
+datasources = [
+ (
+ DataSourceNoCacheNetworkOnly,
+ (sources.DEP_FILESYSTEM, sources.DEP_NETWORK),
+ ),
+]
+
+
+def get_datasource_list(depends):
+ return sources.list_from_depends(depends, datasources)
diff --git a/tests/integration_tests/assets/DataSourceNoCacheWithFallback.py b/tests/integration_tests/assets/DataSourceNoCacheWithFallback.py
new file mode 100644
index 00000000..fdfc473f
--- /dev/null
+++ b/tests/integration_tests/assets/DataSourceNoCacheWithFallback.py
@@ -0,0 +1,29 @@
+import logging
+import os
+
+from cloudinit import sources
+
+LOG = logging.getLogger(__name__)
+
+
+class DataSourceNoCacheWithFallback(sources.DataSource):
+ def _get_data(self):
+ if os.path.exists("/ci-test-firstboot"):
+ LOG.debug("TEST _get_data called")
+ return True
+ return False
+
+ def check_if_fallback_is_allowed(self):
+ return True
+
+
+datasources = [
+ (
+ DataSourceNoCacheWithFallback,
+ (sources.DEP_FILESYSTEM,),
+ ),
+]
+
+
+def get_datasource_list(depends):
+ return sources.list_from_depends(depends, datasources)
diff --git a/tests/integration_tests/datasources/test_caching.py b/tests/integration_tests/datasources/test_caching.py
new file mode 100644
index 00000000..33e4b671
--- /dev/null
+++ b/tests/integration_tests/datasources/test_caching.py
@@ -0,0 +1,115 @@
+import pytest
+
+from tests.integration_tests import releases, util
+from tests.integration_tests.instances import IntegrationInstance
+
+
+def setup_custom_datasource(client: IntegrationInstance, datasource_name: str):
+ client.write_to_file(
+ "/etc/cloud/cloud.cfg.d/99-imds.cfg",
+ f"datasource_list: [ {datasource_name}, None ]\n"
+ "datasource_pkg_list: [ cisources ]",
+ )
+ assert client.execute(
+ "mkdir -p /usr/lib/python3/dist-packages/cisources"
+ )
+ client.push_file(
+ util.ASSETS_DIR / f"DataSource{datasource_name}.py",
+ "/usr/lib/python3/dist-packages/cisources/"
+ f"DataSource{datasource_name}.py",
+ )
+
+
+def verify_no_cache_boot(client: IntegrationInstance):
+ log = client.read_from_file("/var/log/cloud-init.log")
+ util.verify_ordered_items_in_text(
+ [
+ "No local datasource found",
+ "running 'init'",
+ "no cache found",
+ "Detected platform",
+ "TEST _get_data called",
+ ],
+ text=log,
+ )
+ util.verify_clean_boot(client)
+
+
+@pytest.mark.skipif(
+ not releases.IS_UBUNTU,
+ reason="hardcoded dist-packages directory",
+)
+def test_no_cache_network_only(client: IntegrationInstance):
+ """Test cache removal per boot. GH-5486
+
+ This tests the CloudStack password reset use case. The expectation is:
+ - Metadata is fetched in network timeframe only
+ - Because `check_instance_id` is not defined, no cached datasource
+ is found in the init-local phase, but the cache is used in the
+ remaining phases due to existance of /run/cloud-init/.instance-id
+ - Because `check_if_fallback_is_allowed` is not defined, cloud-init
+ does NOT fall back to the pickled datasource, and will
+ instead delete the cache during the init-local phase
+ - Metadata is therefore fetched every boot in the network phase
+ """
+ setup_custom_datasource(client, "NoCacheNetworkOnly")
+
+ # Run cloud-init as if first boot
+ assert client.execute("cloud-init clean --logs")
+ client.restart()
+
+ verify_no_cache_boot(client)
+
+ # Clear the log without clean and run cloud-init for subsequent boot
+ assert client.execute("echo '' > /var/log/cloud-init.log")
+ client.restart()
+
+ verify_no_cache_boot(client)
+
+
+@pytest.mark.skipif(
+ not releases.IS_UBUNTU,
+ reason="hardcoded dist-packages directory",
+)
+def test_no_cache_with_fallback(client: IntegrationInstance):
+ """Test we use fallback when defined and no cache available."""
+ setup_custom_datasource(client, "NoCacheWithFallback")
+
+ # Run cloud-init as if first boot
+ assert client.execute("cloud-init clean --logs")
+ # Used by custom datasource
+ client.execute("touch /ci-test-firstboot")
+ client.restart()
+
+ log = client.read_from_file("/var/log/cloud-init.log")
+ util.verify_ordered_items_in_text(
+ [
+ "no cache found",
+ "Detected platform",
+ "TEST _get_data called",
+ "running 'init'",
+ "restored from cache with run check",
+ "running 'modules:config'",
+ ],
+ text=log,
+ )
+ util.verify_clean_boot(client)
+
+ # Clear the log without clean and run cloud-init for subsequent boot
+ assert client.execute("echo '' > /var/log/cloud-init.log")
+ client.execute("rm /ci-test-firstboot")
+ client.restart()
+
+ log = client.read_from_file("/var/log/cloud-init.log")
+ util.verify_ordered_items_in_text(
+ [
+ "cache invalid in datasource",
+ "Detected platform",
+ "Restored fallback datasource from checked cache",
+ "running 'init'",
+ "restored from cache with run check",
+ "running 'modules:config'",
+ ],
+ text=log,
+ )
+ util.verify_clean_boot(client)
diff --git a/tests/integration_tests/instances.py b/tests/integration_tests/instances.py
index 1b09cba1..3e360464 100644
--- a/tests/integration_tests/instances.py
+++ b/tests/integration_tests/instances.py
@@ -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)
- assert self.execute("mv {} {}".format(tmp_path, str(remote_path))).ok
+ assert self.execute(
+ "mv {} {}".format(tmp_path, str(remote_path))
+ ), f"Failed to push {tmp_path} to {remote_path}"
def read_from_file(self, remote_path) -> str:
result = self.execute("cat {}".format(remote_path))
--
2.39.3

View File

@ -1,149 +0,0 @@
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 2/2] fix: Fall back to cached local ds if no valid ds found
(#4997)
Rebooting an instance which has finished VMware guest
customization with DataSourceVMware will load
DataSourceNone due to metadata is NOT available.
This is mostly a re-post of PR#229, few differences are:
1. Let ds decide if fallback is allowed, not always fall back
to previous cached LOCAL ds.
2. No comparing instance-id of cached ds with previous instance-id
due to I think they are always identical.
Fixes GH-3402
(cherry picked from commit 9929a00580d50afc60bf4e0fb9f2f39d4f797b4b)
Signed-off-by: Ani Sinha <anisinha@redhat.com>
Conflicts:
cloudinit/sources/__init__.py
Conflicts because of changes in upstream source coming from
30d5e9a3358f4cbaced ("refactor: Use _unpickle rather than hasattr() in sources")
---
cloudinit/sources/DataSourceVMware.py | 14 +++++++++-
cloudinit/sources/__init__.py | 14 ++++++++++
cloudinit/stages.py | 40 +++++++++++++++++----------
3 files changed, 53 insertions(+), 15 deletions(-)
diff --git a/cloudinit/sources/DataSourceVMware.py b/cloudinit/sources/DataSourceVMware.py
index 77a2de6c..2a91a307 100644
--- a/cloudinit/sources/DataSourceVMware.py
+++ b/cloudinit/sources/DataSourceVMware.py
@@ -223,7 +223,7 @@ class DataSourceVMware(sources.DataSource):
break
if not self.data_access_method:
- LOG.error("failed to find a valid data access method")
+ LOG.debug("failed to find a valid data access method")
return False
LOG.info("using data access method %s", self._get_subplatform())
@@ -317,6 +317,18 @@ class DataSourceVMware(sources.DataSource):
self.metadata["instance-id"] = str(id_file.read()).rstrip().lower()
return self.metadata["instance-id"]
+ def check_if_fallback_is_allowed(self):
+ if (
+ self.data_access_method
+ and self.data_access_method == DATA_ACCESS_METHOD_IMC
+ and is_vmware_platform()
+ ):
+ LOG.debug(
+ "Cache fallback is allowed for : %s", self._get_subplatform()
+ )
+ return True
+ return False
+
def get_public_ssh_keys(self):
for key_name in (
"public-keys-data",
diff --git a/cloudinit/sources/__init__.py b/cloudinit/sources/__init__.py
index 4ea1fc56..e2b3029e 100644
--- a/cloudinit/sources/__init__.py
+++ b/cloudinit/sources/__init__.py
@@ -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
+
+ if not hasattr(self, "check_if_fallback_is_allowed"):
+ setattr(self, "check_if_fallback_is_allowed", lambda: False)
+
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.
@@ -925,6 +929,16 @@ class DataSource(CloudInitPickleMixin, metaclass=abc.ABCMeta):
# quickly (local check only) if self.instance_id is still
return False
+ def check_if_fallback_is_allowed(self):
+ """check_if_fallback_is_allowed()
+ Checks if a cached ds is allowed to be restored when no valid ds is
+ found in local mode by checking instance-id and searching valid data
+ through ds list.
+
+ @return True if a ds allows fallback, False otherwise.
+ """
+ return False
+
@staticmethod
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 e95bb76f..894eeac5 100644
--- a/cloudinit/stages.py
+++ b/cloudinit/stages.py
@@ -380,20 +380,32 @@ class Init:
LOG.debug(myrep.description)
if not ds:
- util.del_file(self.paths.instance_link)
- (cfg_list, pkg_list) = self._get_datasources()
- # Deep copy so that user-data handlers can not modify
- # (which will affect user-data handlers down the line...)
- (ds, dsname) = sources.find_source(
- self.cfg,
- self.distro,
- self.paths,
- copy.deepcopy(self.ds_deps),
- cfg_list,
- pkg_list,
- self.reporter,
- )
- LOG.info("Loaded datasource %s - %s", dsname, ds)
+ try:
+ cfg_list, pkg_list = self._get_datasources()
+ # Deep copy so that user-data handlers can not modify
+ # (which will affect user-data handlers down the line...)
+ ds, dsname = sources.find_source(
+ self.cfg,
+ self.distro,
+ self.paths,
+ copy.deepcopy(self.ds_deps),
+ cfg_list,
+ pkg_list,
+ self.reporter,
+ )
+ util.del_file(self.paths.instance_link)
+ LOG.info("Loaded datasource %s - %s", dsname, ds)
+ except sources.DataSourceNotFoundException as e:
+ if existing != "check":
+ raise e
+ ds = self._restore_from_cache()
+ if ds and ds.check_if_fallback_is_allowed():
+ LOG.info(
+ "Restored fallback datasource from checked cache: %s",
+ ds,
+ )
+ else:
+ raise e
self.datasource = ds
# Ensure we adjust our path members datasource
# now that we have one (thus allowing ipath to be used)
--
2.39.3

View File

@ -1,304 +0,0 @@
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 2/3] fix: Render bridges correctly for v2 on sysconfig with
set-name (#5674)
RH-Author: xiachen <xiachen@redhat.com>
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] 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
the name the interface will eventually take. This was broken when
using `set-name`.
To fix this, we now store the configuration id alongside the eventual
name, and reference that instead of the name.
Fixes GH-5574
(cherry picked from commit a8f69409e5cebf43767d3bb54fbad7ced1e8fc7b)
Signed-off-by: Amy Chen <xiachen@redhat.com>
---
cloudinit/net/eni.py | 6 +++
cloudinit/net/network_state.py | 29 ++++------
cloudinit/net/sysconfig.py | 24 ++++++---
tests/unittests/test_net.py | 96 ++++++++++++++++++++++++++++++++++
4 files changed, 128 insertions(+), 27 deletions(-)
diff --git a/cloudinit/net/eni.py b/cloudinit/net/eni.py
index 59dc395f..fa0b47af 100644
--- a/cloudinit/net/eni.py
+++ b/cloudinit/net/eni.py
@@ -5,6 +5,7 @@ import glob
import logging
import os
import re
+from contextlib import suppress
from typing import Optional
from cloudinit import subp, util
@@ -421,6 +422,11 @@ class Renderer(renderer.Renderer):
return content
def _render_iface(self, iface, render_hwaddress=False):
+ iface = copy.deepcopy(iface)
+
+ # Remove irrelevant keys
+ with suppress(KeyError):
+ iface.pop("config_id")
sections = []
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 9f34467b..fb08491f 100644
--- a/cloudinit/net/network_state.py
+++ b/cloudinit/net/network_state.py
@@ -411,6 +411,7 @@ class NetworkStateInterpreter:
wakeonlan = util.is_true(wakeonlan)
iface.update(
{
+ "config_id": command.get("config_id"),
"name": command.get("name"),
"type": command.get("type"),
"mac_address": command.get("mac_address"),
@@ -424,7 +425,8 @@ class NetworkStateInterpreter:
"wakeonlan": wakeonlan,
}
)
- self._network_state["interfaces"].update({command.get("name"): iface})
+ iface_key = command.get("config_id", command.get("name"))
+ self._network_state["interfaces"].update({iface_key: iface})
self.dump_network_state()
@ensure_command_keys(["name", "vlan_id", "vlan_link"])
@@ -712,6 +714,7 @@ class NetworkStateInterpreter:
for eth, cfg in command.items():
phy_cmd = {
+ "config_id": eth,
"type": "physical",
}
match = cfg.get("match", {})
@@ -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():
- if "set-name" in dev_cfg:
- set_name_iface = dev_cfg.get("set-name")
- if set_name_iface:
- iface = set_name_iface
if "nameservers" in dev_cfg:
- search = dev_cfg.get("nameservers").get("search", [])
- dns = dev_cfg.get("nameservers").get("addresses", [])
+ search = dev_cfg.get("nameservers").get("search")
+ dns = dev_cfg.get("nameservers").get("addresses")
name_cmd = {"type": "nameserver"}
- if len(search) > 0:
- name_cmd.update({"search": search})
- if len(dns) > 0:
- name_cmd.update({"address": dns})
-
- mac_address: Optional[str] = dev_cfg.get("match", {}).get(
- "macaddress"
- )
- if mac_address:
- 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)
diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
index 503b6993..96652e15 100644
--- a/cloudinit/net/sysconfig.py
+++ b/cloudinit/net/sysconfig.py
@@ -6,7 +6,7 @@ import io
import logging
import os
import re
-from typing import Mapping, Optional
+from typing import Dict, Optional
from cloudinit import subp, util
from cloudinit.distros.parsers import networkmanager_conf, resolv_conf
@@ -721,7 +721,7 @@ class Renderer(renderer.Renderer):
):
physical_filter = renderer.filter_by_physical
for iface in network_state.iter_interfaces(physical_filter):
- iface_name = iface["name"]
+ iface_name = iface.get("config_id") or iface["name"]
iface_subnets = iface.get("subnets", [])
iface_cfg = iface_contents[iface_name]
route_cfg = iface_cfg.routes
@@ -926,7 +926,9 @@ class Renderer(renderer.Renderer):
return out
@classmethod
- def _render_bridge_interfaces(cls, network_state, iface_contents, flavor):
+ def _render_bridge_interfaces(
+ cls, network_state: NetworkState, iface_contents, flavor
+ ):
bridge_key_map = {
old_k: new_k
for old_k, new_k in cls.cfg_key_maps[flavor].items()
@@ -1007,23 +1009,29 @@ class Renderer(renderer.Renderer):
@classmethod
def _render_sysconfig(
- cls, base_sysconf_dir, network_state, flavor, templates=None
+ cls,
+ base_sysconf_dir,
+ network_state: NetworkState,
+ flavor,
+ templates=None,
):
"""Given state, return /etc/sysconfig files + contents"""
if not templates:
templates = cls.templates
- iface_contents: Mapping[str, NetInterface] = {}
+ iface_contents: Dict[str, NetInterface] = {}
for iface in network_state.iter_interfaces():
if iface["type"] == "loopback":
continue
- iface_name = iface["name"]
- iface_cfg = NetInterface(iface_name, base_sysconf_dir, templates)
+ config_id: str = iface.get("config_id") or iface["name"]
+ iface_cfg = NetInterface(
+ iface["name"], base_sysconf_dir, templates
+ )
if flavor == "suse":
iface_cfg.drop("DEVICE")
# If type detection fails it is considered a bug in SUSE
iface_cfg.drop("TYPE")
cls._render_iface_shared(iface, iface_cfg, flavor)
- iface_contents[iface_name] = iface_cfg
+ iface_contents[config_id] = iface_cfg
cls._render_physical_interfaces(network_state, iface_contents, flavor)
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 00198232..41e6fa56 100644
--- a/tests/unittests/test_net.py
+++ b/tests/unittests/test_net.py
@@ -4822,6 +4822,95 @@ iface bond0 inet6 static
"""
),
},
+ "v2-bridges-set-name": {
+ "yaml": textwrap.dedent(
+ """\
+ version: 2
+ ethernets:
+ baremetalport:
+ match:
+ macaddress: 52:54:00:bd:8f:cb
+ set-name: baremetal0
+ provisioningport:
+ match:
+ macaddress: 52:54:00:25:ae:12
+ set-name: provisioning0
+ bridges:
+ baremetal:
+ addresses:
+ - fc00:1:1::2/64
+ interfaces:
+ - baremetalport
+ provisioning:
+ addresses:
+ - fc00:1:2::2/64
+ interfaces:
+ - provisioningport
+ """
+ ),
+ "expected_sysconfig_rhel": {
+ "ifcfg-baremetal": textwrap.dedent(
+ """\
+ # Created by cloud-init automatically, do not edit.
+ #
+ AUTOCONNECT_PRIORITY=120
+ BOOTPROTO=none
+ DEVICE=baremetal
+ IPV6ADDR=fc00:1:1::2/64
+ IPV6INIT=yes
+ IPV6_AUTOCONF=no
+ IPV6_FORCE_ACCEPT_RA=no
+ ONBOOT=yes
+ TYPE=Bridge
+ USERCTL=no
+ """
+ ),
+ "ifcfg-baremetal0": textwrap.dedent(
+ """\
+ # Created by cloud-init automatically, do not edit.
+ #
+ AUTOCONNECT_PRIORITY=120
+ BOOTPROTO=none
+ BRIDGE=baremetal
+ DEVICE=baremetal0
+ HWADDR=52:54:00:bd:8f:cb
+ ONBOOT=yes
+ TYPE=Ethernet
+ USERCTL=no
+ """
+ ),
+ "ifcfg-provisioning": textwrap.dedent(
+ """\
+ # Created by cloud-init automatically, do not edit.
+ #
+ AUTOCONNECT_PRIORITY=120
+ BOOTPROTO=none
+ DEVICE=provisioning
+ IPV6ADDR=fc00:1:2::2/64
+ IPV6INIT=yes
+ IPV6_AUTOCONF=no
+ IPV6_FORCE_ACCEPT_RA=no
+ ONBOOT=yes
+ TYPE=Bridge
+ USERCTL=no
+ """
+ ),
+ "ifcfg-provisioning0": textwrap.dedent(
+ """\
+ # Created by cloud-init automatically, do not edit.
+ #
+ AUTOCONNECT_PRIORITY=120
+ BOOTPROTO=none
+ BRIDGE=provisioning
+ DEVICE=provisioning0
+ HWADDR=52:54:00:25:ae:12
+ ONBOOT=yes
+ TYPE=Ethernet
+ USERCTL=no
+ """
+ ),
+ },
+ },
}
@@ -5891,6 +5980,13 @@ USERCTL=no
self._compare_files_to_expected(entry[self.expected_name], found)
self._assert_headers(found)
+ def test_bridges_set_name_config(self):
+ entry = NETWORK_CONFIGS["v2-bridges-set-name"]
+ found = self._render_and_read(network_config=yaml.load(entry["yaml"]))
+ self._compare_files_to_expected(
+ entry[self.expected_name], found)
+ self._assert_headers(found)
+
def test_netplan_dhcp_false_disable_dhcp_in_state(self):
"""netplan config with dhcp[46]: False should not add dhcp in state"""
net_config = yaml.load(NETPLAN_DHCP_FALSE)
--
2.39.3

View File

@ -1,160 +0,0 @@
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 3/3] fix: Render v2 bridges correctly on network-manager with
set-name (#5740)
RH-Author: xiachen <xiachen@redhat.com>
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] a33642f97a8e5cb3816f17ce726187aa33825362 (xiachen/cloud-init-centos)
Similar to the recent sysconfig fix, ensure bridges render correctly
for configs that contain `set-name`.
Fixes GH-5717
(cherry picked from commit 9554338e6ecf49c66324cc637eaf0fa7bf10e407)
Signed-off-by: Amy Chen <xiachen@redhat.com>
---
cloudinit/net/network_manager.py | 6 +-
tests/unittests/test_net.py | 94 ++++++++++++++++++++++++++++++++
2 files changed, 98 insertions(+), 2 deletions(-)
diff --git a/cloudinit/net/network_manager.py b/cloudinit/net/network_manager.py
index a13d4c14..67614399 100644
--- a/cloudinit/net/network_manager.py
+++ b/cloudinit/net/network_manager.py
@@ -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():
- self.connections[iface["name"]] = NMConnection(iface["name"])
+ conn_key = iface.get("config_id") or iface["name"]
+ self.connections[conn_key] = NMConnection(iface["name"])
# Now render the actual interface configuration
for iface in network_state.iter_interfaces():
- conn = self.connections[iface["name"]]
+ conn_key = iface.get("config_id") or iface["name"]
+ conn = self.connections[conn_key]
conn.render_interface(iface, network_state, self)
# And finally write the files
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
index 41e6fa56..8a75c42b 100644
--- a/tests/unittests/test_net.py
+++ b/tests/unittests/test_net.py
@@ -4910,6 +4910,94 @@ iface bond0 inet6 static
"""
),
},
+ "expected_network_manager": {
+ "cloud-init-baremetal.nmconnection": textwrap.dedent(
+ """\
+ # Generated by cloud-init. Changes will be lost.
+
+ [connection]
+ id=cloud-init baremetal
+ uuid=e63eed9a-cd1c-55de-8d5e-1e80b756a482
+ autoconnect-priority=120
+ type=bridge
+ interface-name=baremetal
+
+ [user]
+ org.freedesktop.NetworkManager.origin=cloud-init
+
+ [bridge]
+
+ [ipv6]
+ method=manual
+ may-fail=false
+ address1=fc00:1:1::2/64
+
+ """
+ ),
+ "cloud-init-baremetalport.nmconnection": textwrap.dedent(
+ """\
+ # Generated by cloud-init. Changes will be lost.
+
+ [connection]
+ id=cloud-init baremetal0
+ uuid=8e326690-51d6-5157-ab84-e4e822b06503
+ autoconnect-priority=120
+ type=ethernet
+ slave-type=bridge
+ master=e63eed9a-cd1c-55de-8d5e-1e80b756a482
+
+ [user]
+ org.freedesktop.NetworkManager.origin=cloud-init
+
+ [ethernet]
+ mac-address=52:54:00:BD:8F:CB
+
+ """
+ ),
+ "cloud-init-provisioning.nmconnection": textwrap.dedent(
+ """\
+ # Generated by cloud-init. Changes will be lost.
+
+ [connection]
+ id=cloud-init provisioning
+ uuid=e5bd3f1a-cdcc-55d3-a6d8-88f1ba73bd0e
+ autoconnect-priority=120
+ type=bridge
+ interface-name=provisioning
+
+ [user]
+ org.freedesktop.NetworkManager.origin=cloud-init
+
+ [bridge]
+
+ [ipv6]
+ method=manual
+ may-fail=false
+ address1=fc00:1:2::2/64
+
+ """
+ ),
+ "cloud-init-provisioningport.nmconnection": textwrap.dedent(
+ """\
+ # Generated by cloud-init. Changes will be lost.
+
+ [connection]
+ id=cloud-init provisioning0
+ uuid=d79b7b70-e9df-596f-ace7-89537db45684
+ autoconnect-priority=120
+ type=ethernet
+ slave-type=bridge
+ master=e5bd3f1a-cdcc-55d3-a6d8-88f1ba73bd0e
+
+ [user]
+ org.freedesktop.NetworkManager.origin=cloud-init
+
+ [ethernet]
+ mac-address=52:54:00:25:AE:12
+
+ """
+ ),
+ },
},
}
@@ -7102,6 +7190,12 @@ class TestNetworkManagerRendering(CiTestCase):
entry[self.expected_name], self.expected_conf_d, found
)
+ def test_v2_bridges_set_name(self):
+ entry = NETWORK_CONFIGS["v2-bridges-set-name"]
+ 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

View File

@ -1,67 +0,0 @@
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: 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-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,
with just 'metalink' property set, one would get the schema validator error
\---
Error: Cloud config schema errors: yum_repos.epel-release: 'baseurl' is a required property
\---
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 3cf7aaf8..5758777a 100644
--- a/cloudinit/config/schemas/schema-cloud-config-v1.json
+++ b/cloudinit/config/schemas/schema-cloud-config-v1.json
@@ -3434,6 +3434,11 @@
"format": "uri",
"description": "URL to the directory where the yum repository's 'repodata' directory lives"
},
+ "metalink": {
+ "type": "string",
+ "format": "uri",
+ "description": "Specifies a URL to a metalink file for the repomd.xml"
+ },
"name": {
"type": "string",
"description": "Optional human-readable name of the yum repo."
@@ -3461,8 +3466,17 @@
"description": "Any supported yum repository configuration options will be written to the yum repo config file. See: man yum.conf"
}
},
- "required": [
- "baseurl"
+ "anyOf": [
+ {
+ "required": [
+ "baseurl"
+ ]
+ },
+ {
+ "required": [
+ "metalink"
+ ]
+ }
]
}
}
--
2.39.3

View File

@ -1,53 +0,0 @@
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/4] fix(jsonschema): Add missing sudo definition (#5418)
RH-Author: Ani Sinha <anisinha@redhat.com>
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] c94e7e63470d04c23ebb45fe654c7bdd5a30c162 (anisinha/cloud-init)
This configuration:
```
users:
- name: osadmin
lock_passwd: false
sudo: ["ALL=(ALL) NOPASSWD:ALL"]
```
Is valid syntax but is missing from the jsonschema definition.
Fixes GH-5399
(cherry picked from commit b533fa51acb850ed754e2b1925e276ff8e5f3507)
---
cloudinit/config/schemas/schema-cloud-config-v1.json | 9 +++++++++
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 ff61dcaa..c47e7c4f 100644
--- a/cloudinit/config/schemas/schema-cloud-config-v1.json
+++ b/cloudinit/config/schemas/schema-cloud-config-v1.json
@@ -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."
},
+ {
+ "type": "array",
+ "items": {
+ "type": [
+ "string",
+ "null"
+ ]
+ }
+ },
{
"type": "boolean",
"changed": true,
--
2.39.3

View File

@ -1,417 +0,0 @@
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: 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] 88c8502922e2f85f5ce04d170fdd6b7596117a1f (anisinha/cloud-init)
Both hyphenated and underscore delimited key names are permitted
by cloudinit/distros/ug_util.py#L114 due to magic replacement
of key names.
Since this is still valid json schema, add the necessary hyphenated
aliases for all users/groups keys. Because the goal in the future is
to only support one config key for a given configuraion option, add
deprecated keys to those schema definitions.
Also drop the description key from the deprecates lock-passwd schema
key.
Any deprecated schema key which provides a suggested replacement should
not provide duplicated key descriptions as the preferred replacement
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 +++++++++++++-----
tests/unittests/config/test_cc_grub_dpkg.py | 4 +-
.../test_cc_package_update_upgrade_install.py | 11 +-
.../unittests/config/test_cc_users_groups.py | 33 +++---
tests/unittests/config/test_schema.py | 15 ++-
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 23573583..3cf7aaf8 100644
--- a/cloudinit/config/schemas/schema-cloud-config-v1.json
+++ b/cloudinit/config/schemas/schema-cloud-config-v1.json
@@ -267,9 +267,9 @@
"patternProperties": {
"^.+$": {
"label": "<group_name>",
- "description": "When providing an object for users.groups the ``<group_name>`` keys are the groups to add this user to",
"deprecated": true,
"deprecated_version": "23.1",
+ "deprecated_description": "The use of ``object`` type is deprecated. Use ``string`` or ``array`` of ``string`` instead.",
"type": [
"null"
],
@@ -292,9 +292,7 @@
"type": "string"
},
"lock-passwd": {
- "default": true,
"type": "boolean",
- "description": "Default: ``true``",
"deprecated": true,
"deprecated_version": "22.3",
"deprecated_description": "Use ``lock_passwd`` instead."
@@ -304,16 +302,34 @@
"description": "Disable password login. Default: ``true``",
"type": "boolean"
},
+ "no-create-home": {
+ "type": "boolean",
+ "deprecated": true,
+ "deprecated_version": "24.2",
+ "deprecated_description": "Use ``no_create_home`` instead."
+ },
"no_create_home": {
"default": false,
"description": "Do not create home directory. Default: ``false``",
"type": "boolean"
},
+ "no-log-init": {
+ "type": "boolean",
+ "deprecated": true,
+ "deprecated_version": "24.2",
+ "deprecated_description": "Use ``no_log_init`` instead."
+ },
"no_log_init": {
"default": false,
"description": "Do not initialize lastlog and faillog for user. Default: ``false``",
"type": "boolean"
},
+ "no-user-group": {
+ "type": "boolean",
+ "deprecated": true,
+ "deprecated_version": "24.2",
+ "deprecated_description": "Use ``no_user_group`` instead."
+ },
"no_user_group": {
"default": false,
"description": "Do not create group named after user. Default: ``false``",
@@ -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": {
+ "type": "string",
+ "deprecated": true,
+ "deprecated_version": "24.2",
+ "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 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": {
+ "type": "string",
+ "deprecated": true,
+ "deprecated_version": "24.2",
+ "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 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": {
+ "type": "boolean",
+ "deprecated": true,
+ "deprecated_version": "24.2",
+ "deprecated_description": "Use ``create_groups`` instead."
+ },
"create_groups": {
"default": true,
"description": "Boolean set ``false`` to disable creation of specified user ``groups``. Default: ``true``.",
"type": "boolean"
},
+ "primary-group": {
+ "type": "string",
+ "deprecated": true,
+ "deprecated_version": "24.2",
+ "deprecated_description": "Use ``primary_group`` instead."
+ },
"primary_group": {
"default": "``<username>``",
"description": "Primary group for user. Default: ``<username>``",
"type": "string"
},
+ "selinux-user": {
+ "type": "string",
+ "deprecated": true,
+ "deprecated_version": "24.2",
+ "deprecated_description": "Use ``selinux_user`` instead."
+ },
"selinux_user": {
"description": "SELinux user for user's login. Default: the default SELinux user.",
"type": "string"
@@ -362,20 +408,24 @@
"minItems": 1
},
"ssh-authorized-keys": {
- "allOf": [
- {
- "type": "array",
- "items": {
- "type": "string"
- },
- "minItems": 1
- },
- {
- "deprecated": true,
- "deprecated_version": "18.3",
- "deprecated_description": "Use ``ssh_authorized_keys`` instead."
- }
- ]
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "minItems": 1,
+ "deprecated": true,
+ "deprecated_version": "18.3",
+ "deprecated_description": "Use ``ssh_authorized_keys`` instead."
+ },
+ "ssh-import-id": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "minItems": 1,
+ "deprecated": true,
+ "deprecated_version": "24.2",
+ "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``. 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
},
+ "ssh-redirect-user": {
+ "type": "boolean",
+ "deprecated": true,
+ "deprecated_version": "24.2",
+ "deprecated_description": "Use ``ssh_redirect_user`` instead."
+ },
"ssh_redirect_user": {
"type": "boolean",
"default": false,
@@ -487,7 +543,6 @@
"properties": {
"remove-defaults": {
"type": "boolean",
- "default": false,
"deprecated": true,
"deprecated_version": "22.3",
"deprecated_description": "Use ``remove_defaults`` instead."
@@ -605,9 +660,9 @@
},
"system_info": {
"type": "object",
- "description": "System and/or distro specific settings. This is not intended to be overridden by user data or vendor data.",
"deprecated": true,
- "deprecated_version": "24.2"
+ "deprecated_version": "24.2",
+ "deprecated_description": "System and/or distro specific settings. This is not intended to be overridden by user data or vendor data."
}
}
},
@@ -1572,7 +1627,6 @@
},
"grub-dpkg": {
"type": "object",
- "description": "An alias for ``grub_dpkg``",
"deprecated": true,
"deprecated_version": "22.2",
"deprecated_description": "Use ``grub_dpkg`` instead."
@@ -2159,24 +2213,18 @@
},
"apt_update": {
"type": "boolean",
- "default": false,
- "description": "Default: ``false``.",
"deprecated": true,
"deprecated_version": "22.2",
"deprecated_description": "Use ``package_update`` instead."
},
"apt_upgrade": {
"type": "boolean",
- "default": false,
- "description": "Default: ``false``.",
"deprecated": true,
"deprecated_version": "22.2",
"deprecated_description": "Use ``package_upgrade`` instead."
},
"apt_reboot_if_required": {
"type": "boolean",
- "default": false,
- "description": "Default: ``false``.",
"deprecated": true,
"deprecated_version": "22.2",
"deprecated_description": "Use ``package_reboot_if_required`` instead."
@@ -2874,7 +2922,6 @@
}
],
"minItems": 1,
- "description": "List of ``username:password`` pairs. Each user will have the corresponding password set. A password can be randomly generated by specifying ``RANDOM`` or ``R`` as a user's password. A hashed password, created by a tool like ``mkpasswd``, can be specified. A regex (``r'\\$(1|2a|2y|5|6)(\\$.+){2}'``) is used to determine if a password value should be treated as a hash.",
"deprecated": true,
"deprecated_version": "22.2",
"deprecated_description": "Use ``users`` instead."
diff --git a/tests/unittests/config/test_cc_grub_dpkg.py b/tests/unittests/config/test_cc_grub_dpkg.py
index b4bd48df..36ef7fd9 100644
--- a/tests/unittests/config/test_cc_grub_dpkg.py
+++ b/tests/unittests/config/test_cc_grub_dpkg.py
@@ -300,8 +300,8 @@ class TestGrubDpkgSchema:
pytest.raises(
SchemaValidationError,
match=(
- "Cloud config schema deprecations: grub-dpkg: An alias"
- " for ``grub_dpkg`` Deprecated in version 22.2. Use "
+ "Cloud config schema deprecations: grub-dpkg:"
+ " Deprecated in version 22.2. Use "
"``grub_dpkg`` instead."
),
),
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 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
@@ -300,16 +300,16 @@ class TestPackageUpdateUpgradeSchema:
(
{"apt_update": False},
(
- "Cloud config schema deprecations: apt_update: "
- "Default: ``false``. Deprecated in version 22.2. "
+ "Cloud config schema deprecations: apt_update: "
+ "Deprecated in version 22.2. "
"Use ``package_update`` instead."
),
),
(
{"apt_upgrade": False},
(
- "Cloud config schema deprecations: apt_upgrade: "
- "Default: ``false``. Deprecated in version 22.2. "
+ "Cloud config schema deprecations: apt_upgrade: "
+ "Deprecated in version 22.2. "
"Use ``package_upgrade`` instead."
),
),
@@ -317,8 +317,7 @@ class TestPackageUpdateUpgradeSchema:
{"apt_reboot_if_required": False},
(
"Cloud config schema deprecations: "
- "apt_reboot_if_required: Default: ``false``. "
- "Deprecated in version 22.2. Use "
+ "apt_reboot_if_required: Deprecated in version 22.2. Use "
"``package_reboot_if_required`` instead."
),
),
diff --git a/tests/unittests/config/test_cc_users_groups.py b/tests/unittests/config/test_cc_users_groups.py
index 53e231e1..4ca67f77 100644
--- a/tests/unittests/config/test_cc_users_groups.py
+++ b/tests/unittests/config/test_cc_users_groups.py
@@ -371,9 +371,20 @@ class TestUsersGroupsSchema:
SchemaValidationError,
match=(
"Cloud config schema deprecations: "
- "users.0.lock-passwd: Default: ``true`` "
- "Deprecated in version 22.3. Use "
- "``lock_passwd`` instead."
+ "users.0.lock-passwd: Deprecated in version 22.3."
+ " Use ``lock_passwd`` instead."
+ ),
+ ),
+ False,
+ ),
+ (
+ {"users": [{"name": "bbsw", "no-create-home": True}]},
+ pytest.raises(
+ SchemaValidationError,
+ match=(
+ "Cloud config schema deprecations: "
+ "users.0.no-create-home: Deprecated in version 24.2."
+ " Use ``no_create_home`` instead."
),
),
False,
@@ -394,13 +405,10 @@ class TestUsersGroupsSchema:
SchemaValidationError,
match=(
"Cloud config schema deprecations: "
- "users.0.groups.adm: When providing an object "
- "for users.groups the ``<group_name>`` keys "
- "are the groups to add this user to Deprecated"
- " in version 23.1., users.0.groups.sudo: When "
- "providing an object for users.groups the "
- "``<group_name>`` keys are the groups to add "
- "this user to Deprecated in version 23.1."
+ "users.0.groups.adm: Deprecated in version 23.1. "
+ "The use of ``object`` type is deprecated. Use "
+ "``string`` or ``array`` of ``string`` instead., "
+ "users.0.groups.sudo: Deprecated in version 23.1."
),
),
False,
@@ -456,10 +464,7 @@ class TestUsersGroupsSchema:
SchemaValidationError,
match=(
"Cloud config schema deprecations: "
- "user.groups.sbuild: When providing an object "
- "for users.groups the ``<group_name>`` keys "
- "are the groups to add this user to Deprecated"
- " in version 23.1."
+ "user.groups.sbuild: Deprecated in version 23.1."
),
),
False,
diff --git a/tests/unittests/config/test_schema.py b/tests/unittests/config/test_schema.py
index ce55534b..d175083b 100644
--- a/tests/unittests/config/test_schema.py
+++ b/tests/unittests/config/test_schema.py
@@ -2542,9 +2542,9 @@ class TestHandleSchemaArgs:
apt_reboot_if_required: true # D3
# Deprecations: -------------
- # D1: Default: ``false``. Deprecated in version 22.2. Use ``package_update`` instead.
- # D2: Default: ``false``. Deprecated in version 22.2. Use ``package_upgrade`` instead.
- # D3: Default: ``false``. Deprecated in version 22.2. Use ``package_reboot_if_required`` instead.
+ # D1: Deprecated in version 22.2. Use ``package_update`` instead.
+ # D2: Deprecated in version 22.2. Use ``package_upgrade`` instead.
+ # D3: Deprecated in version 22.2. Use ``package_reboot_if_required`` instead.
Valid schema {cfg_file}
""" # noqa: E501
@@ -2555,11 +2555,10 @@ class TestHandleSchemaArgs:
dedent(
"""\
Cloud config schema deprecations: \
-apt_reboot_if_required: Default: ``false``. Deprecated in version 22.2.\
- Use ``package_reboot_if_required`` instead., apt_update: Default: \
-``false``. Deprecated in version 22.2. Use ``package_update`` instead.,\
- apt_upgrade: Default: ``false``. Deprecated in version 22.2. Use \
-``package_upgrade`` instead.\
+apt_reboot_if_required: Deprecated in version 22.2. Use\
+ ``package_reboot_if_required`` instead., apt_update: Deprecated in version\
+ 22.2. Use ``package_update`` instead., apt_upgrade: Deprecated in version\
+ 22.2. Use ``package_upgrade`` instead.\
Valid schema {cfg_file}
""" # noqa: E501
),
--
2.39.3

View File

@ -1,185 +0,0 @@
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: 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] 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
set to dhcp IPv6 explicitly.
(cherry picked from commit 2b6fe6403db769de14f7c7b7e4aa65f5bea8f3e0)
---
.../sources/helpers/vmware/imc/config_nic.py | 2 +-
.../sources/vmware/test_vmware_config_file.py | 68 ++++++++++++++-----
2 files changed, 52 insertions(+), 18 deletions(-)
diff --git a/cloudinit/sources/helpers/vmware/imc/config_nic.py b/cloudinit/sources/helpers/vmware/imc/config_nic.py
index b07214a2..254518af 100644
--- a/cloudinit/sources/helpers/vmware/imc/config_nic.py
+++ b/cloudinit/sources/helpers/vmware/imc/config_nic.py
@@ -207,7 +207,7 @@ class NicConfigurator:
"""
if not nic.staticIpv6:
- return ([], [])
+ return ([{"type": "dhcp6"}], [])
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 fd4bb481..c1415934 100644
--- a/tests/unittests/sources/vmware/test_vmware_config_file.py
+++ b/tests/unittests/sources/vmware/test_vmware_config_file.py
@@ -241,27 +241,45 @@ class TestVmwareConfigFile(CiTestCase):
elif cfg.get("name") == nic2.get("name"):
nic2.update(cfg)
+ # Test NIC1
self.assertEqual("physical", nic1.get("type"), "type of NIC1")
self.assertEqual("NIC1", nic1.get("name"), "name of NIC1")
self.assertEqual(
"00:50:56:a6:8c:08", nic1.get("mac_address"), "mac address of NIC1"
)
subnets = nic1.get("subnets")
- self.assertEqual(1, len(subnets), "number of subnets for NIC1")
- subnet = subnets[0]
- self.assertEqual("dhcp", subnet.get("type"), "DHCP type for NIC1")
- self.assertEqual("auto", subnet.get("control"), "NIC1 Control type")
+ self.assertEqual(2, len(subnets), "number of subnets for NIC1")
+ subnet_ipv4 = subnets[0]
+ self.assertEqual(
+ "dhcp", subnet_ipv4.get("type"), "Ipv4 DHCP type for NIC1"
+ )
+ self.assertEqual(
+ "auto", subnet_ipv4.get("control"), "NIC1 Control type"
+ )
+ subnet_ipv6 = subnets[1]
+ self.assertEqual(
+ "dhcp6", subnet_ipv6.get("type"), "Ipv6 DHCP type for NIC1"
+ )
+ # Test NIC2
self.assertEqual("physical", nic2.get("type"), "type of NIC2")
self.assertEqual("NIC2", nic2.get("name"), "name of NIC2")
self.assertEqual(
"00:50:56:a6:5a:de", nic2.get("mac_address"), "mac address of NIC2"
)
subnets = nic2.get("subnets")
- self.assertEqual(1, len(subnets), "number of subnets for NIC2")
- subnet = subnets[0]
- self.assertEqual("dhcp", subnet.get("type"), "DHCP type for NIC2")
- self.assertEqual("auto", subnet.get("control"), "NIC2 Control type")
+ self.assertEqual(2, len(subnets), "number of subnets for NIC2")
+ subnet_ipv4 = subnets[0]
+ self.assertEqual(
+ "dhcp", subnet_ipv4.get("type"), "Ipv4 DHCP type for NIC2"
+ )
+ self.assertEqual(
+ "auto", subnet_ipv4.get("control"), "NIC2 Control type"
+ )
+ subnet_ipv6 = subnets[1]
+ self.assertEqual(
+ "dhcp6", subnet_ipv6.get("type"), "Ipv6 DHCP type for NIC2"
+ )
def test_get_nics_list_static(self):
"""Tests if NicConfigurator properly calculates network subnets
@@ -286,6 +304,7 @@ class TestVmwareConfigFile(CiTestCase):
elif cfg.get("name") == nic2.get("name"):
nic2.update(cfg)
+ # Test NIC1
self.assertEqual("physical", nic1.get("type"), "type of NIC1")
self.assertEqual("NIC1", nic1.get("name"), "name of NIC1")
self.assertEqual(
@@ -345,6 +364,7 @@ class TestVmwareConfigFile(CiTestCase):
else:
self.assertEqual(True, False, "invalid gateway %s" % (gateway))
+ # Test NIC2
self.assertEqual("physical", nic2.get("type"), "type of NIC2")
self.assertEqual("NIC2", nic2.get("name"), "name of NIC2")
self.assertEqual(
@@ -352,16 +372,18 @@ class TestVmwareConfigFile(CiTestCase):
)
subnets = nic2.get("subnets")
- self.assertEqual(1, len(subnets), "Number of subnets for NIC2")
+ self.assertEqual(2, len(subnets), "Number of subnets for NIC2")
- subnet = subnets[0]
- self.assertEqual("static", subnet.get("type"), "Subnet type")
+ subnet_ipv4 = subnets[0]
+ self.assertEqual("static", subnet_ipv4.get("type"), "Subnet type")
self.assertEqual(
- "192.168.6.102", subnet.get("address"), "Subnet address"
+ "192.168.6.102", subnet_ipv4.get("address"), "Subnet address"
)
self.assertEqual(
- "255.255.0.0", subnet.get("netmask"), "Subnet netmask"
+ "255.255.0.0", subnet_ipv4.get("netmask"), "Subnet netmask"
)
+ subnet_ipv6 = subnets[1]
+ self.assertEqual("dhcp6", subnet_ipv6.get("type"), "Subnet type")
def test_custom_script(self):
cf = ConfigFile("tests/data/vmware/cust-dhcp-2nic.cfg")
@@ -448,7 +470,10 @@ class TestVmwareNetConfig(CiTestCase):
"type": "static",
"address": "10.20.87.154",
"netmask": "255.255.252.0",
- }
+ },
+ {
+ "type": "dhcp6",
+ },
],
}
],
@@ -499,7 +524,10 @@ class TestVmwareNetConfig(CiTestCase):
"metric": 10000,
}
],
- }
+ },
+ {
+ "type": "dhcp6",
+ },
],
}
],
@@ -559,7 +587,10 @@ class TestVmwareNetConfig(CiTestCase):
"metric": 10000,
}
],
- }
+ },
+ {
+ "type": "dhcp6",
+ },
],
}
],
@@ -604,7 +635,10 @@ class TestVmwareNetConfig(CiTestCase):
"address": "10.20.87.154",
"netmask": "255.255.252.0",
"gateway": "10.20.87.253",
- }
+ },
+ {
+ "type": "dhcp6",
+ },
],
}
],
--
2.39.3

View File

@ -1,544 +0,0 @@
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

View File

@ -5,68 +5,20 @@
%endif
Name: cloud-init
Version: 24.1.4
Release: 21%{?dist}.alma.1
Version: 24.4
Release: 1%{?dist}.alma.1
Summary: Cloud instance init scripts
License: Apache-2.0 OR GPL-3.0-only
URL: https://github.com/canonical/cloud-init
Source0: %{url}/archive/%{version}/%{version}.tar.gz
Source1: cloud-init-tmpfiles.conf
Patch1: 0001-Add-initial-redhat-changes.patch
Patch2: 0002-fix-rhel-Fix-network-ordering-in-sysconfig.patch
Patch3: 0003-Do-not-write-NM_CONTROLLED-no-in-generated-interface.patch
Patch4: 0004-Setting-autoconnect-priority-setting-for-network-scr.patch
Patch5: 0005-feat-Use-NetworkManager-renderer-by-default-in-RHEL-.patch
Patch6: ci-fix-Fall-back-to-cached-local-ds-if-no-valid-ds-foun.patch
# For RHEL-34518 - Remove dependency to netifcaces
Patch7: ci-refactor-remove-dependency-on-netifaces-4634.patch
# For RHEL-34518 - Remove dependency to netifcaces
Patch8: ci-DS-VMware-Fix-ipv6-addr-converter-from-netinfo-to-ne.patch
# For RHEL-36456 - [RHEL-10] Group ssh_keys is missing and ssh host key permission is changed in rhel-10
Patch9: ci-feat-Set-RH-ssh-key-permissions-when-no-ssh_keys-gro.patch
# For RHEL-44334 - [RHEL-10] cloud-init fails to configure DNS search domains
Patch10: ci-feat-sysconfig-Add-DNS-from-interface-config-to-reso.patch
# For RHEL-44338 - [RHEL-10] fix `SUDO` configuration schema for users and groups
Patch11: ci-fix-jsonschema-Add-missing-sudo-definition-5418.patch
# For RHEL-44338 - [RHEL-10] fix `SUDO` configuration schema for users and groups
Patch12: ci-doc-update-examples-to-reflect-alternative-ways-to-p.patch
# For RHEL-44599 - [rhel-10] fix pylint error and support python 3.12
Patch13: ci-Update-pylint-version-to-support-python-3.12-5338.patch
# For RHEL-45263 - Deprecate the users ssh-authorized-keys property and permit deprecated hyphenated keys under users key [rhel-10]
Patch14: ci-Deprecate-the-users-ssh-authorized-keys-property-516.patch
# For RHEL-45263 - Deprecate the users ssh-authorized-keys property and permit deprecated hyphenated keys under users key [rhel-10]
Patch15: ci-docs-Add-deprecated-system_info-to-schema-5168.patch
# For RHEL-45263 - Deprecate the users ssh-authorized-keys property and permit deprecated hyphenated keys under users key [rhel-10]
Patch16: ci-fix-schema-permit-deprecated-hyphenated-keys-under-u.patch
# For RHEL-44918 - [RFE] Support metalink in yum repository config [rhel-10]
Patch17: ci-Support-metalink-in-yum-repository-config-5444.patch
# For RHEL-35562 - [RHEL-10] It leaves the ipv6 networking config as blank in NM keyfile when config dhcp ipv6 with customization spec
Patch18: ci-fix-vmware-Set-IPv6-to-dhcp-when-there-is-no-IPv6-ad.patch
# For RHEL-46874 - Suggest to update schema to support metalink [rhel-10]
Patch19: ci-fix-add-schema-rules-for-baseurl-and-metalink-in-yum.patch
# For RHEL-49740 - [Cloud-init] [RHEL-10] Password reset feature broken with CloudstackDataSource
Patch20: ci-fix-Clean-cache-if-no-datasource-fallback-5499.patch
# For RHEL-49739 - Support setting mirrorlist in yum repository config [rhel-10]
Patch21: ci-Support-setting-mirrorlist-in-yum-repository-config-.patch
# For RHEL-36093 - Remove cloud-init dependency on obsolete gdisk
Patch22: ci-cc_disk_setup-add-sgdisk-to-sfdisk-convertion-dictio.patch
# For RHEL-36093 - Remove cloud-init dependency on obsolete gdisk
Patch23: ci-Get-rid-of-gdisk-dependency.patch
# For RHEL-54372 - [RHEL10]Revert "fix(vmware): Set IPv6 to dhcp when there is no IPv6 addr (#5471)"
Patch24: ci-Revert-fix-vmware-Set-IPv6-to-dhcp-when-there-is-no-.patch
# For RHEL-54688 - [RHEL 10.0] cloud-init schema validation fails.
Patch25: ci-fix-Add-subnet-ipv4-ipv6-to-network-schema-5191.patch
# For RHEL-65016 - Configuring metric for default gateway is not working [rhel-10]
Patch26: ci-Fix-metric-setting-for-ifcfg-network-connections-for.patch
# For RHEL-65019 - NoCloud - network_config bridges incorrectly configured [rhel-10]
Patch27: ci-fix-Render-bridges-correctly-for-v2-on-sysconfig-wit.patch
# For RHEL-65019 - NoCloud - network_config bridges incorrectly configured [rhel-10]
Patch28: ci-fix-Render-v2-bridges-correctly-on-network-manager-w.patch
# For RHEL-65849 - [RHEL-10] Drop cloud-init dependency on python-jsonschema
Patch29: ci-Remove-python3-jsonschema-dependency.patch
# For RHEL-65769 - [RHEL-10] Prevent NM from handling DNS when network interfaces have DNS config
Patch30: ci-Prevent-NM-from-handling-DNS-when-network-interfaces.patch
Patch1: 0002-downstream-Setting-autoconnect-priority-setting-for-.patch
Patch2: 0003-downstream-cc_disk_setup-add-sgdisk-to-sfdisk-conver.patch
Patch3: 0004-downstream-Get-rid-of-gdisk-dependency.patch
Patch4: 0005-downstream-Revert-chore-eliminate-redundant-ordering.patch
Patch5: 0006-downstream-remove-single-process-optimization.patch
Patch6: 0007-fix-don-t-deadlock-when-starting-network-service-wit.patch
# AlmaLinux patches
Patch1000: 0031-Improvements-for-AlmaLinux-OS-and-CloudLinux-OS.patch
@ -173,10 +125,6 @@ for man in cloud-id.1 cloud-init.1 cloud-init-per.1; do
chmod -x ${RPM_BUILD_ROOT}%{_mandir}/man1/*
done
# Put files in /etc/systemd/system in the right place
cp -a %{buildroot}/etc/systemd %{buildroot}/usr/lib
rm -rf %{buildroot}/etc/systemd
%check
%if %{with tests}
@ -279,9 +227,14 @@ fi
%changelog
* Mon Dec 09 2024 Eduard Abdullin <eabdullin@almalinux.org> - 24.1.4-21.alma.1
* Thu Jan 16 2025 Eduard Abdullin <eabdullin@almalinux.org> - 24.4-1.alma.1
- 0031-Improvements-for-AlmaLinux-OS-and-CloudLinux-OS.patch
* Mon Jan 06 2025 Miroslav Rezanina <mrezanin@redhat.com> - 24.4-1
- Rebase to 24.4 [RHEL-66254]
- Resolves: RHEL-66254
([RHEL-10] Rebase cloud-init to 24.4 version)
* Mon Nov 18 2024 Miroslav Rezanina <mrezanin@redhat.com> - 24.1.4-21
- ci-Prevent-NM-from-handling-DNS-when-network-interfaces.patch [RHEL-65769]
- Resolves: RHEL-65769

View File

@ -1 +1 @@
SHA512 (24.1.4.tar.gz) = 374a5a10895f4f850457f3015687fb2c5b605841658b819244139fadf0075cd818cfdec5aeb8d0ca9ddbfa40de3b5070d2c4ffd0f6bcc306349b0db70edee2c7
SHA512 (24.4.tar.gz) = df42fb0c97aba37599e3c9431e1dfffc0a3c0ce6d639fd9a980fe0da190c998da3130ab65e3288eecd193967dbaad41aac3c0040244cf6036db9584a3c87538d