* Mon Jan 06 2025 Miroslav Rezanina <mrezanin@redhat.com> - 24.4-1
- Rebase to 24.4 [RHEL-66251] - Resolves: RHEL-66251 ([RHEL-9] Rebase cloud-init to 24.4 version)
This commit is contained in:
parent
5e03c28b99
commit
dc82d4f216
@ -1,11 +1,25 @@
|
|||||||
From 03345a88b8b0008a4a81e010d46290f5ba643ebc Mon Sep 17 00:00:00 2001
|
From d05f201a13e2fdbd86c89647884ca08ae7d98b3a Mon Sep 17 00:00:00 2001
|
||||||
From: Ani Sinha <anisinha@redhat.com>
|
From: Camilla Conte <cconte@redhat.com>
|
||||||
Date: Wed, 13 Dec 2023 11:54:55 +0530
|
Date: Fri, 3 Mar 2023 15:44:48 +0000
|
||||||
Subject: [PATCH] Add initial redhat changes
|
Subject: [PATCH] downstream: Add initial redhat changes
|
||||||
|
|
||||||
Adding minimal set of changes necessary for successful build of the package
|
Adding minimal set of changes necessary for successful build of the package
|
||||||
on RHEL/CentOS 9 Stream koji.
|
on RHEL/CentOS 9 Stream koji.
|
||||||
|
|
||||||
|
Additional Changes on top of changes in 24.4 rebase:
|
||||||
|
- Merged all trivial downstream configuration commits
|
||||||
|
- Merged downstream patches
|
||||||
|
- c1a69d5e5 Remove dependency on python3-httpretty
|
||||||
|
- 69688c9cc Add warning during upgrade from an old version with null ssh_genkeytypes config
|
||||||
|
- bce114c96 Inform user when cloud-init generated config files are left during uninstalling
|
||||||
|
- 76de87b4e Rename render-cloudcfg -> render-template in spec file
|
||||||
|
|
||||||
|
Additional changes on top of changes in 23.4 rebase:
|
||||||
|
- Updated VERSION, TARSHA512, MARKER and BUILD_TARGET_RHEL parameters in
|
||||||
|
Makefile.common in .dist/
|
||||||
|
- In spec file, change the location of "disable-sshd-keygen-if-cloud-init-active.conf"
|
||||||
|
from /etc/systemd/system to /usr/lib/systemd/system
|
||||||
|
|
||||||
Additional changes on top of the changes in 23.1.1 rebase:
|
Additional changes on top of the changes in 23.1.1 rebase:
|
||||||
- Updated VERSION, TARSHA512, MARKER and BUILD_TARGET_RHEL parameters in
|
- Updated VERSION, TARSHA512, MARKER and BUILD_TARGET_RHEL parameters in
|
||||||
Makefile.common in .dist/
|
Makefile.common in .dist/
|
||||||
@ -43,16 +57,16 @@ missing rhel/ static files and "" instead of '' in setup.py
|
|||||||
X-downstram-only: true
|
X-downstram-only: true
|
||||||
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
||||||
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
||||||
|
(cherry picked from commit 03345a88b8b0008a4a81e010d46290f5ba643ebc)
|
||||||
---
|
---
|
||||||
cloudinit/settings.py | 5 +++--
|
cloudinit/settings.py | 5 +++--
|
||||||
tests/unittests/cmd/test_main.py | 15 +++++++++------
|
1 file changed, 3 insertions(+), 2 deletions(-)
|
||||||
2 files changed, 12 insertions(+), 8 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/cloudinit/settings.py b/cloudinit/settings.py
|
diff --git a/cloudinit/settings.py b/cloudinit/settings.py
|
||||||
index 592e144d..5ced21bd 100644
|
index a73f25118..ea7ac283f 100644
|
||||||
--- a/cloudinit/settings.py
|
--- a/cloudinit/settings.py
|
||||||
+++ b/cloudinit/settings.py
|
+++ b/cloudinit/settings.py
|
||||||
@@ -54,13 +54,14 @@ CFG_BUILTIN = {
|
@@ -56,14 +56,15 @@ CFG_BUILTIN = {
|
||||||
],
|
],
|
||||||
"def_log_file": "/var/log/cloud-init.log",
|
"def_log_file": "/var/log/cloud-init.log",
|
||||||
"log_cfgs": [],
|
"log_cfgs": [],
|
||||||
@ -62,6 +76,7 @@ index 592e144d..5ced21bd 100644
|
|||||||
"system_info": {
|
"system_info": {
|
||||||
"paths": {
|
"paths": {
|
||||||
"cloud_dir": "/var/lib/cloud",
|
"cloud_dir": "/var/lib/cloud",
|
||||||
|
"docs_dir": "/usr/share/doc/cloud-init/",
|
||||||
"templates_dir": "/etc/cloud/templates/",
|
"templates_dir": "/etc/cloud/templates/",
|
||||||
},
|
},
|
||||||
- "distro": "ubuntu",
|
- "distro": "ubuntu",
|
||||||
@ -69,31 +84,3 @@ index 592e144d..5ced21bd 100644
|
|||||||
"network": {"renderers": None},
|
"network": {"renderers": None},
|
||||||
},
|
},
|
||||||
"vendor_data": {"enabled": True, "prefix": []},
|
"vendor_data": {"enabled": True, "prefix": []},
|
||||||
diff --git a/tests/unittests/cmd/test_main.py b/tests/unittests/cmd/test_main.py
|
|
||||||
index ab427115..19d26ebe 100644
|
|
||||||
--- a/tests/unittests/cmd/test_main.py
|
|
||||||
+++ b/tests/unittests/cmd/test_main.py
|
|
||||||
@@ -119,14 +119,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")
|
|
@ -1,564 +0,0 @@
|
|||||||
From 5129908caa1867c7f584ec8d38607cf56b20521a 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
|
|
||||||
|
|
||||||
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>
|
|
||||||
---
|
|
||||||
cloudinit/net/sysconfig.py | 12 ++++-
|
|
||||||
tests/unittests/cmd/devel/test_net_convert.py | 1 -
|
|
||||||
tests/unittests/distros/test_netconfig.py | 8 ---
|
|
||||||
tests/unittests/test_net.py | 53 -------------------
|
|
||||||
4 files changed, 10 insertions(+), 64 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
|
|
||||||
index 7570a5e3..f01c4236 100644
|
|
||||||
--- a/cloudinit/net/sysconfig.py
|
|
||||||
+++ b/cloudinit/net/sysconfig.py
|
|
||||||
@@ -317,7 +317,6 @@ class Renderer(renderer.Renderer):
|
|
||||||
"rhel": {
|
|
||||||
"ONBOOT": True,
|
|
||||||
"USERCTL": False,
|
|
||||||
- "NM_CONTROLLED": False,
|
|
||||||
"BOOTPROTO": "none",
|
|
||||||
},
|
|
||||||
"suse": {"BOOTPROTO": "static", "STARTMODE": "auto"},
|
|
||||||
@@ -1030,7 +1029,16 @@ class Renderer(renderer.Renderer):
|
|
||||||
# Distros configuring /etc/sysconfig/network as a file e.g. Centos
|
|
||||||
if sysconfig_path.endswith("network"):
|
|
||||||
util.ensure_dir(os.path.dirname(sysconfig_path))
|
|
||||||
- netcfg = [_make_header(), "NETWORKING=yes"]
|
|
||||||
+ netcfg = []
|
|
||||||
+ for line in util.load_file(sysconfig_path, quiet=True).split("\n"):
|
|
||||||
+ 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/cmd/devel/test_net_convert.py b/tests/unittests/cmd/devel/test_net_convert.py
|
|
||||||
index fb72963f..7b9121b2 100644
|
|
||||||
--- a/tests/unittests/cmd/devel/test_net_convert.py
|
|
||||||
+++ b/tests/unittests/cmd/devel/test_net_convert.py
|
|
||||||
@@ -62,7 +62,6 @@ SAMPLE_SYSCONFIG_CONTENT = """\
|
|
||||||
#
|
|
||||||
BOOTPROTO=dhcp
|
|
||||||
DEVICE=eth0
|
|
||||||
-NM_CONTROLLED=no
|
|
||||||
ONBOOT=yes
|
|
||||||
TYPE=Ethernet
|
|
||||||
USERCTL=no
|
|
||||||
diff --git a/tests/unittests/distros/test_netconfig.py b/tests/unittests/distros/test_netconfig.py
|
|
||||||
index 7ba430f2..962ff7fb 100644
|
|
||||||
--- a/tests/unittests/distros/test_netconfig.py
|
|
||||||
+++ b/tests/unittests/distros/test_netconfig.py
|
|
||||||
@@ -723,7 +723,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
|
|
||||||
GATEWAY=192.168.1.254
|
|
||||||
IPADDR=192.168.1.5
|
|
||||||
NETMASK=255.255.255.0
|
|
||||||
- NM_CONTROLLED=no
|
|
||||||
ONBOOT=yes
|
|
||||||
TYPE=Ethernet
|
|
||||||
USERCTL=no
|
|
||||||
@@ -733,7 +732,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
|
|
||||||
"""\
|
|
||||||
BOOTPROTO=dhcp
|
|
||||||
DEVICE=eth1
|
|
||||||
- NM_CONTROLLED=no
|
|
||||||
ONBOOT=yes
|
|
||||||
TYPE=Ethernet
|
|
||||||
USERCTL=no
|
|
||||||
@@ -764,7 +762,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
|
|
||||||
IPV6_AUTOCONF=no
|
|
||||||
IPV6_DEFAULTGW=2607:f0d0:1002:0011::1
|
|
||||||
IPV6_FORCE_ACCEPT_RA=no
|
|
||||||
- NM_CONTROLLED=no
|
|
||||||
ONBOOT=yes
|
|
||||||
TYPE=Ethernet
|
|
||||||
USERCTL=no
|
|
||||||
@@ -774,7 +771,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
|
|
||||||
"""\
|
|
||||||
BOOTPROTO=dhcp
|
|
||||||
DEVICE=eth1
|
|
||||||
- NM_CONTROLLED=no
|
|
||||||
ONBOOT=yes
|
|
||||||
TYPE=Ethernet
|
|
||||||
USERCTL=no
|
|
||||||
@@ -821,7 +817,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
|
|
||||||
HWADDR=00:16:3e:60:7c:df
|
|
||||||
IPADDR=192.10.1.2
|
|
||||||
NETMASK=255.255.255.0
|
|
||||||
- NM_CONTROLLED=no
|
|
||||||
ONBOOT=yes
|
|
||||||
TYPE=Ethernet
|
|
||||||
USERCTL=no
|
|
||||||
@@ -833,7 +828,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
|
|
||||||
DEVICE=infra0
|
|
||||||
IPADDR=10.0.1.2
|
|
||||||
NETMASK=255.255.0.0
|
|
||||||
- NM_CONTROLLED=no
|
|
||||||
ONBOOT=yes
|
|
||||||
PHYSDEV=eth0
|
|
||||||
USERCTL=no
|
|
||||||
@@ -869,7 +863,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
|
|
||||||
DEVICE=eth0
|
|
||||||
IPADDR=192.10.1.2
|
|
||||||
NETMASK=255.255.255.0
|
|
||||||
- NM_CONTROLLED=no
|
|
||||||
ONBOOT=yes
|
|
||||||
TYPE=Ethernet
|
|
||||||
USERCTL=no
|
|
||||||
@@ -881,7 +874,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
|
|
||||||
DEVICE=eth0.1001
|
|
||||||
IPADDR=10.0.1.2
|
|
||||||
NETMASK=255.255.0.0
|
|
||||||
- NM_CONTROLLED=no
|
|
||||||
ONBOOT=yes
|
|
||||||
PHYSDEV=eth0
|
|
||||||
USERCTL=no
|
|
||||||
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
|
|
||||||
index c5509536..052b0674 100644
|
|
||||||
--- a/tests/unittests/test_net.py
|
|
||||||
+++ b/tests/unittests/test_net.py
|
|
||||||
@@ -585,7 +585,6 @@ GATEWAY=172.19.3.254
|
|
||||||
HWADDR=fa:16:3e:ed:9a:59
|
|
||||||
IPADDR=172.19.1.34
|
|
||||||
NETMASK=255.255.252.0
|
|
||||||
-NM_CONTROLLED=no
|
|
||||||
ONBOOT=yes
|
|
||||||
TYPE=Ethernet
|
|
||||||
USERCTL=no
|
|
||||||
@@ -750,7 +749,6 @@ IPADDR=172.19.1.34
|
|
||||||
IPADDR1=10.0.0.10
|
|
||||||
NETMASK=255.255.252.0
|
|
||||||
NETMASK1=255.255.255.0
|
|
||||||
-NM_CONTROLLED=no
|
|
||||||
ONBOOT=yes
|
|
||||||
TYPE=Ethernet
|
|
||||||
USERCTL=no
|
|
||||||
@@ -912,7 +910,6 @@ IPV6_AUTOCONF=no
|
|
||||||
IPV6_DEFAULTGW=2001:DB8::1
|
|
||||||
IPV6_FORCE_ACCEPT_RA=no
|
|
||||||
NETMASK=255.255.252.0
|
|
||||||
-NM_CONTROLLED=no
|
|
||||||
ONBOOT=yes
|
|
||||||
TYPE=Ethernet
|
|
||||||
USERCTL=no
|
|
||||||
@@ -1143,7 +1140,6 @@ NETWORK_CONFIGS = {
|
|
||||||
BOOTPROTO=none
|
|
||||||
DEVICE=eth1
|
|
||||||
HWADDR=cf:d6:af:48:e8:80
|
|
||||||
- NM_CONTROLLED=no
|
|
||||||
ONBOOT=yes
|
|
||||||
TYPE=Ethernet
|
|
||||||
USERCTL=no"""
|
|
||||||
@@ -1162,7 +1158,6 @@ NETWORK_CONFIGS = {
|
|
||||||
IPADDR=192.168.21.3
|
|
||||||
NETMASK=255.255.255.0
|
|
||||||
METRIC=10000
|
|
||||||
- NM_CONTROLLED=no
|
|
||||||
ONBOOT=yes
|
|
||||||
TYPE=Ethernet
|
|
||||||
USERCTL=no"""
|
|
||||||
@@ -1319,7 +1314,6 @@ NETWORK_CONFIGS = {
|
|
||||||
BOOTPROTO=none
|
|
||||||
DEVICE=eth1
|
|
||||||
HWADDR=cf:d6:af:48:e8:80
|
|
||||||
- NM_CONTROLLED=no
|
|
||||||
ONBOOT=yes
|
|
||||||
TYPE=Ethernet
|
|
||||||
USERCTL=no"""
|
|
||||||
@@ -1338,7 +1332,6 @@ NETWORK_CONFIGS = {
|
|
||||||
IPADDR=192.168.21.3
|
|
||||||
NETMASK=255.255.255.0
|
|
||||||
METRIC=10000
|
|
||||||
- NM_CONTROLLED=no
|
|
||||||
ONBOOT=yes
|
|
||||||
TYPE=Ethernet
|
|
||||||
USERCTL=no"""
|
|
||||||
@@ -1581,7 +1574,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
|
|
||||||
@@ -1725,7 +1717,6 @@ NETWORK_CONFIGS = {
|
|
||||||
DHCPV6C=yes
|
|
||||||
IPV6INIT=yes
|
|
||||||
DEVICE=iface0
|
|
||||||
- NM_CONTROLLED=no
|
|
||||||
ONBOOT=yes
|
|
||||||
TYPE=Ethernet
|
|
||||||
USERCTL=no
|
|
||||||
@@ -1816,7 +1807,6 @@ NETWORK_CONFIGS = {
|
|
||||||
IPV6INIT=yes
|
|
||||||
IPV6_FORCE_ACCEPT_RA=yes
|
|
||||||
DEVICE=iface0
|
|
||||||
- NM_CONTROLLED=no
|
|
||||||
ONBOOT=yes
|
|
||||||
TYPE=Ethernet
|
|
||||||
USERCTL=no
|
|
||||||
@@ -1892,7 +1882,6 @@ NETWORK_CONFIGS = {
|
|
||||||
IPV6INIT=yes
|
|
||||||
IPV6_FORCE_ACCEPT_RA=no
|
|
||||||
DEVICE=iface0
|
|
||||||
- NM_CONTROLLED=no
|
|
||||||
ONBOOT=yes
|
|
||||||
TYPE=Ethernet
|
|
||||||
USERCTL=no
|
|
||||||
@@ -1956,7 +1945,6 @@ NETWORK_CONFIGS = {
|
|
||||||
IPV6_AUTOCONF=yes
|
|
||||||
IPV6INIT=yes
|
|
||||||
DEVICE=iface0
|
|
||||||
- NM_CONTROLLED=no
|
|
||||||
ONBOOT=yes
|
|
||||||
TYPE=Ethernet
|
|
||||||
USERCTL=no
|
|
||||||
@@ -2014,7 +2002,6 @@ NETWORK_CONFIGS = {
|
|
||||||
IPV6_AUTOCONF=no
|
|
||||||
IPV6_FORCE_ACCEPT_RA=no
|
|
||||||
DEVICE=iface0
|
|
||||||
- NM_CONTROLLED=no
|
|
||||||
ONBOOT=yes
|
|
||||||
TYPE=Ethernet
|
|
||||||
USERCTL=no
|
|
||||||
@@ -2071,7 +2058,6 @@ NETWORK_CONFIGS = {
|
|
||||||
IPV6_AUTOCONF=yes
|
|
||||||
IPV6INIT=yes
|
|
||||||
DEVICE=iface0
|
|
||||||
- NM_CONTROLLED=no
|
|
||||||
ONBOOT=yes
|
|
||||||
TYPE=Ethernet
|
|
||||||
USERCTL=no
|
|
||||||
@@ -2157,7 +2143,6 @@ NETWORK_CONFIGS = {
|
|
||||||
IPV6_FAILURE_FATAL=yes
|
|
||||||
IPV6_FORCE_ACCEPT_RA=yes
|
|
||||||
DEVICE=iface0
|
|
||||||
- NM_CONTROLLED=no
|
|
||||||
ONBOOT=yes
|
|
||||||
TYPE=Ethernet
|
|
||||||
USERCTL=no
|
|
||||||
@@ -2198,7 +2183,6 @@ NETWORK_CONFIGS = {
|
|
||||||
"""\
|
|
||||||
BOOTPROTO=dhcp
|
|
||||||
DEVICE=iface0
|
|
||||||
- NM_CONTROLLED=no
|
|
||||||
ONBOOT=yes
|
|
||||||
TYPE=Ethernet
|
|
||||||
USERCTL=no
|
|
||||||
@@ -2275,7 +2259,6 @@ NETWORK_CONFIGS = {
|
|
||||||
BOOTPROTO=dhcp
|
|
||||||
DEVICE=iface0
|
|
||||||
ETHTOOL_OPTS="wol g"
|
|
||||||
- NM_CONTROLLED=no
|
|
||||||
ONBOOT=yes
|
|
||||||
TYPE=Ethernet
|
|
||||||
USERCTL=no
|
|
||||||
@@ -2619,7 +2602,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
|
|
||||||
DHCPV6C=yes
|
|
||||||
IPV6INIT=yes
|
|
||||||
MACADDR=aa:bb:cc:dd:ee:ff
|
|
||||||
- NM_CONTROLLED=no
|
|
||||||
ONBOOT=yes
|
|
||||||
TYPE=Bond
|
|
||||||
USERCTL=no"""
|
|
||||||
@@ -2629,7 +2611,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
|
|
||||||
BOOTPROTO=dhcp
|
|
||||||
DEVICE=bond0.200
|
|
||||||
DHCLIENT_SET_DEFAULT_ROUTE=no
|
|
||||||
- NM_CONTROLLED=no
|
|
||||||
ONBOOT=yes
|
|
||||||
PHYSDEV=bond0
|
|
||||||
USERCTL=no
|
|
||||||
@@ -2649,7 +2630,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
|
|
||||||
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
|
|
||||||
@@ -2661,7 +2641,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"""
|
|
||||||
@@ -2680,7 +2659,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
|
|
||||||
@@ -2692,7 +2670,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
|
|
||||||
@@ -2704,7 +2681,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
|
|
||||||
@@ -2716,7 +2692,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"""
|
|
||||||
@@ -2727,7 +2702,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"""
|
|
||||||
@@ -2738,7 +2712,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"""
|
|
||||||
@@ -2751,7 +2724,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"""
|
|
||||||
@@ -3473,7 +3445,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
|
|
||||||
@@ -3485,7 +3456,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
|
|
||||||
@@ -3513,7 +3483,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
|
|
||||||
@@ -3662,7 +3631,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"""
|
|
||||||
@@ -3683,7 +3651,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
|
|
||||||
@@ -3811,7 +3778,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
|
|
||||||
@@ -3829,7 +3795,6 @@ iface bond0 inet6 static
|
|
||||||
IPV6INIT=yes
|
|
||||||
IPV6_AUTOCONF=no
|
|
||||||
IPV6_FORCE_ACCEPT_RA=no
|
|
||||||
- NM_CONTROLLED=no
|
|
||||||
ONBOOT=yes
|
|
||||||
TYPE=Ethernet
|
|
||||||
USERCTL=no
|
|
||||||
@@ -3845,7 +3810,6 @@ iface bond0 inet6 static
|
|
||||||
IPV6INIT=yes
|
|
||||||
IPV6_AUTOCONF=no
|
|
||||||
IPV6_FORCE_ACCEPT_RA=no
|
|
||||||
- NM_CONTROLLED=no
|
|
||||||
ONBOOT=yes
|
|
||||||
TYPE=Ethernet
|
|
||||||
USERCTL=no
|
|
||||||
@@ -4030,7 +3994,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
|
|
||||||
@@ -4042,7 +4005,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
|
|
||||||
@@ -4053,7 +4015,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
|
|
||||||
@@ -4138,7 +4099,6 @@ iface bond0 inet6 static
|
|
||||||
BOOTPROTO=none
|
|
||||||
DEVICE=eth0
|
|
||||||
HWADDR=cf:d6:af:48:e8:80
|
|
||||||
- NM_CONTROLLED=no
|
|
||||||
ONBOOT=yes
|
|
||||||
TYPE=Ethernet
|
|
||||||
USERCTL=no"""
|
|
||||||
@@ -4736,7 +4696,6 @@ class TestRhelSysConfigRendering(CiTestCase):
|
|
||||||
BOOTPROTO=dhcp
|
|
||||||
DEVICE=eth1000
|
|
||||||
HWADDR=07-1c-c6-75-a4-be
|
|
||||||
-NM_CONTROLLED=no
|
|
||||||
ONBOOT=yes
|
|
||||||
TYPE=Ethernet
|
|
||||||
USERCTL=no
|
|
||||||
@@ -4948,7 +4907,6 @@ GATEWAY=10.0.2.2
|
|
||||||
HWADDR=52:54:00:12:34:00
|
|
||||||
IPADDR=10.0.2.15
|
|
||||||
NETMASK=255.255.255.0
|
|
||||||
-NM_CONTROLLED=no
|
|
||||||
ONBOOT=yes
|
|
||||||
TYPE=Ethernet
|
|
||||||
USERCTL=no
|
|
||||||
@@ -4979,7 +4937,6 @@ HWADDR=fa:16:3e:25:b4:59
|
|
||||||
IPADDR=51.68.89.122
|
|
||||||
MTU=1500
|
|
||||||
NETMASK=255.255.240.0
|
|
||||||
-NM_CONTROLLED=no
|
|
||||||
ONBOOT=yes
|
|
||||||
TYPE=Ethernet
|
|
||||||
USERCTL=no
|
|
||||||
@@ -4993,7 +4950,6 @@ DEVICE=eth1
|
|
||||||
DHCLIENT_SET_DEFAULT_ROUTE=no
|
|
||||||
HWADDR=fa:16:3e:b1:ca:29
|
|
||||||
MTU=9000
|
|
||||||
-NM_CONTROLLED=no
|
|
||||||
ONBOOT=yes
|
|
||||||
TYPE=Ethernet
|
|
||||||
USERCTL=no
|
|
||||||
@@ -5018,7 +4974,6 @@ USERCTL=no
|
|
||||||
#
|
|
||||||
BOOTPROTO=dhcp
|
|
||||||
DEVICE=eth0
|
|
||||||
-NM_CONTROLLED=no
|
|
||||||
ONBOOT=yes
|
|
||||||
TYPE=Ethernet
|
|
||||||
USERCTL=no
|
|
||||||
@@ -5251,7 +5206,6 @@ USERCTL=no
|
|
||||||
IPV6_FORCE_ACCEPT_RA=no
|
|
||||||
IPV6_DEFAULTGW=2001:db8::1
|
|
||||||
NETMASK=255.255.255.0
|
|
||||||
- NM_CONTROLLED=no
|
|
||||||
ONBOOT=yes
|
|
||||||
TYPE=Ethernet
|
|
||||||
USERCTL=no
|
|
||||||
@@ -5283,7 +5237,6 @@ USERCTL=no
|
|
||||||
"""\
|
|
||||||
BOOTPROTO=none
|
|
||||||
DEVICE=eno1
|
|
||||||
- NM_CONTROLLED=no
|
|
||||||
ONBOOT=yes
|
|
||||||
TYPE=Ethernet
|
|
||||||
USERCTL=no
|
|
||||||
@@ -5296,7 +5249,6 @@ USERCTL=no
|
|
||||||
IPADDR=192.6.1.9
|
|
||||||
MTU=1495
|
|
||||||
NETMASK=255.255.255.0
|
|
||||||
- NM_CONTROLLED=no
|
|
||||||
ONBOOT=yes
|
|
||||||
PHYSDEV=eno1
|
|
||||||
USERCTL=no
|
|
||||||
@@ -5332,7 +5284,6 @@ USERCTL=no
|
|
||||||
IPADDR=10.101.8.65
|
|
||||||
MTU=1334
|
|
||||||
NETMASK=255.255.255.192
|
|
||||||
- NM_CONTROLLED=no
|
|
||||||
ONBOOT=yes
|
|
||||||
TYPE=Bond
|
|
||||||
USERCTL=no
|
|
||||||
@@ -5344,7 +5295,6 @@ USERCTL=no
|
|
||||||
BOOTPROTO=none
|
|
||||||
DEVICE=enp0s0
|
|
||||||
MASTER=bond0
|
|
||||||
- NM_CONTROLLED=no
|
|
||||||
ONBOOT=yes
|
|
||||||
SLAVE=yes
|
|
||||||
TYPE=Bond
|
|
||||||
@@ -5357,7 +5307,6 @@ USERCTL=no
|
|
||||||
BOOTPROTO=none
|
|
||||||
DEVICE=enp0s1
|
|
||||||
MASTER=bond0
|
|
||||||
- NM_CONTROLLED=no
|
|
||||||
ONBOOT=yes
|
|
||||||
SLAVE=yes
|
|
||||||
TYPE=Bond
|
|
||||||
@@ -5388,7 +5337,6 @@ USERCTL=no
|
|
||||||
DEVICE=eno1
|
|
||||||
HWADDR=07-1c-c6-75-a4-be
|
|
||||||
METRIC=100
|
|
||||||
- NM_CONTROLLED=no
|
|
||||||
ONBOOT=yes
|
|
||||||
TYPE=Ethernet
|
|
||||||
USERCTL=no
|
|
||||||
@@ -5479,7 +5427,6 @@ USERCTL=no
|
|
||||||
IPV6_FORCE_ACCEPT_RA=no
|
|
||||||
MTU=1400
|
|
||||||
NETMASK=255.255.248.0
|
|
||||||
- NM_CONTROLLED=no
|
|
||||||
ONBOOT=yes
|
|
||||||
TYPE=Ethernet
|
|
||||||
USERCTL=no
|
|
@ -1,7 +1,8 @@
|
|||||||
From 8a2fcbbcfdfc1df6f6c18f96588154f40083a239 Mon Sep 17 00:00:00 2001
|
From 991690944e86cfe4f9b11862455f5a451f7080d3 Mon Sep 17 00:00:00 2001
|
||||||
From: Ani Sinha <anisinha@redhat.com>
|
From: Ani Sinha <anisinha@redhat.com>
|
||||||
Date: Wed, 13 Dec 2023 11:55:16 +0530
|
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
|
||||||
|
|
||||||
Squashed the following three downstream only commits from RHEL 9.3:
|
Squashed the following three downstream only commits from RHEL 9.3:
|
||||||
|
|
||||||
@ -53,15 +54,17 @@ fixes: 0a2c6b6118ff ("net/sysconfig: do not use the highest autoconnect priority
|
|||||||
fixes: c589da20eb92 ("Setting highest autoconnect priority for network-scripts")
|
fixes: c589da20eb92 ("Setting highest autoconnect priority for network-scripts")
|
||||||
|
|
||||||
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
||||||
|
(cherry picked from commit 8a2fcbbcfdfc1df6f6c18f96588154f40083a239)
|
||||||
---
|
---
|
||||||
cloudinit/net/sysconfig.py | 1 +
|
cloudinit/net/sysconfig.py | 1 +
|
||||||
tests/unittests/cmd/devel/test_net_convert.py | 1 +
|
tests/unittests/cmd/devel/test_net_convert.py | 1 +
|
||||||
tests/unittests/distros/test_netconfig.py | 8 +++
|
tests/unittests/distros/test_netconfig.py | 8 +++
|
||||||
tests/unittests/test_net.py | 53 +++++++++++++++++++
|
tests/unittests/net/network_configs.py | 57 +++++++++++++++++++
|
||||||
4 files changed, 63 insertions(+)
|
tests/unittests/test_net.py | 18 ++++++
|
||||||
|
5 files changed, 85 insertions(+)
|
||||||
|
|
||||||
diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
|
diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
|
||||||
index f01c4236..d39f4fe3 100644
|
index d75012d26..2151db3ab 100644
|
||||||
--- a/cloudinit/net/sysconfig.py
|
--- a/cloudinit/net/sysconfig.py
|
||||||
+++ b/cloudinit/net/sysconfig.py
|
+++ b/cloudinit/net/sysconfig.py
|
||||||
@@ -318,6 +318,7 @@ class Renderer(renderer.Renderer):
|
@@ -318,6 +318,7 @@ class Renderer(renderer.Renderer):
|
||||||
@ -73,7 +76,7 @@ index f01c4236..d39f4fe3 100644
|
|||||||
"suse": {"BOOTPROTO": "static", "STARTMODE": "auto"},
|
"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
|
diff --git a/tests/unittests/cmd/devel/test_net_convert.py b/tests/unittests/cmd/devel/test_net_convert.py
|
||||||
index 7b9121b2..288e3e37 100644
|
index 39e049227..ed970e413 100644
|
||||||
--- a/tests/unittests/cmd/devel/test_net_convert.py
|
--- a/tests/unittests/cmd/devel/test_net_convert.py
|
||||||
+++ b/tests/unittests/cmd/devel/test_net_convert.py
|
+++ b/tests/unittests/cmd/devel/test_net_convert.py
|
||||||
@@ -60,6 +60,7 @@ DHCP=ipv4
|
@@ -60,6 +60,7 @@ DHCP=ipv4
|
||||||
@ -85,10 +88,10 @@ index 7b9121b2..288e3e37 100644
|
|||||||
DEVICE=eth0
|
DEVICE=eth0
|
||||||
ONBOOT=yes
|
ONBOOT=yes
|
||||||
diff --git a/tests/unittests/distros/test_netconfig.py b/tests/unittests/distros/test_netconfig.py
|
diff --git a/tests/unittests/distros/test_netconfig.py b/tests/unittests/distros/test_netconfig.py
|
||||||
index 962ff7fb..4c624079 100644
|
index b447757be..3768623f2 100644
|
||||||
--- a/tests/unittests/distros/test_netconfig.py
|
--- a/tests/unittests/distros/test_netconfig.py
|
||||||
+++ b/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 = {
|
expected_cfgs = {
|
||||||
self.ifcfg_path("eth0"): dedent(
|
self.ifcfg_path("eth0"): dedent(
|
||||||
"""\
|
"""\
|
||||||
@ -96,7 +99,7 @@ index 962ff7fb..4c624079 100644
|
|||||||
BOOTPROTO=none
|
BOOTPROTO=none
|
||||||
DEFROUTE=yes
|
DEFROUTE=yes
|
||||||
DEVICE=eth0
|
DEVICE=eth0
|
||||||
@@ -730,6 +731,7 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
|
@@ -724,6 +725,7 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
|
||||||
),
|
),
|
||||||
self.ifcfg_path("eth1"): dedent(
|
self.ifcfg_path("eth1"): dedent(
|
||||||
"""\
|
"""\
|
||||||
@ -104,7 +107,7 @@ index 962ff7fb..4c624079 100644
|
|||||||
BOOTPROTO=dhcp
|
BOOTPROTO=dhcp
|
||||||
DEVICE=eth1
|
DEVICE=eth1
|
||||||
ONBOOT=yes
|
ONBOOT=yes
|
||||||
@@ -754,6 +756,7 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
|
@@ -748,6 +750,7 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
|
||||||
expected_cfgs = {
|
expected_cfgs = {
|
||||||
self.ifcfg_path("eth0"): dedent(
|
self.ifcfg_path("eth0"): dedent(
|
||||||
"""\
|
"""\
|
||||||
@ -112,7 +115,7 @@ index 962ff7fb..4c624079 100644
|
|||||||
BOOTPROTO=none
|
BOOTPROTO=none
|
||||||
DEFROUTE=yes
|
DEFROUTE=yes
|
||||||
DEVICE=eth0
|
DEVICE=eth0
|
||||||
@@ -769,6 +772,7 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
|
@@ -763,6 +766,7 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
|
||||||
),
|
),
|
||||||
self.ifcfg_path("eth1"): dedent(
|
self.ifcfg_path("eth1"): dedent(
|
||||||
"""\
|
"""\
|
||||||
@ -120,7 +123,7 @@ index 962ff7fb..4c624079 100644
|
|||||||
BOOTPROTO=dhcp
|
BOOTPROTO=dhcp
|
||||||
DEVICE=eth1
|
DEVICE=eth1
|
||||||
ONBOOT=yes
|
ONBOOT=yes
|
||||||
@@ -812,6 +816,7 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
|
@@ -806,6 +810,7 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
|
||||||
expected_cfgs = {
|
expected_cfgs = {
|
||||||
self.ifcfg_path("eth0"): dedent(
|
self.ifcfg_path("eth0"): dedent(
|
||||||
"""\
|
"""\
|
||||||
@ -128,7 +131,7 @@ index 962ff7fb..4c624079 100644
|
|||||||
BOOTPROTO=none
|
BOOTPROTO=none
|
||||||
DEVICE=eth0
|
DEVICE=eth0
|
||||||
HWADDR=00:16:3e:60:7c:df
|
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(
|
self.ifcfg_path("infra0"): dedent(
|
||||||
"""\
|
"""\
|
||||||
@ -136,7 +139,7 @@ index 962ff7fb..4c624079 100644
|
|||||||
BOOTPROTO=none
|
BOOTPROTO=none
|
||||||
DEVICE=infra0
|
DEVICE=infra0
|
||||||
IPADDR=10.0.1.2
|
IPADDR=10.0.1.2
|
||||||
@@ -859,6 +865,7 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
|
@@ -853,6 +859,7 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
|
||||||
expected_cfgs = {
|
expected_cfgs = {
|
||||||
self.ifcfg_path("eth0"): dedent(
|
self.ifcfg_path("eth0"): dedent(
|
||||||
"""\
|
"""\
|
||||||
@ -144,7 +147,7 @@ index 962ff7fb..4c624079 100644
|
|||||||
BOOTPROTO=none
|
BOOTPROTO=none
|
||||||
DEVICE=eth0
|
DEVICE=eth0
|
||||||
IPADDR=192.10.1.2
|
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(
|
self.ifcfg_path("eth0.1001"): dedent(
|
||||||
"""\
|
"""\
|
||||||
@ -152,35 +155,11 @@ index 962ff7fb..4c624079 100644
|
|||||||
BOOTPROTO=none
|
BOOTPROTO=none
|
||||||
DEVICE=eth0.1001
|
DEVICE=eth0.1001
|
||||||
IPADDR=10.0.1.2
|
IPADDR=10.0.1.2
|
||||||
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
|
diff --git a/tests/unittests/net/network_configs.py b/tests/unittests/net/network_configs.py
|
||||||
index 052b0674..cef4fa2d 100644
|
index 6e870f6ed..dd0bf73d2 100644
|
||||||
--- a/tests/unittests/test_net.py
|
--- a/tests/unittests/net/network_configs.py
|
||||||
+++ b/tests/unittests/test_net.py
|
+++ b/tests/unittests/net/network_configs.py
|
||||||
@@ -578,6 +578,7 @@ dns = none
|
@@ -184,6 +184,7 @@ NETWORK_CONFIGS = {
|
||||||
"""
|
|
||||||
# Created by cloud-init automatically, do not edit.
|
|
||||||
#
|
|
||||||
+AUTOCONNECT_PRIORITY=120
|
|
||||||
BOOTPROTO=none
|
|
||||||
DEFROUTE=yes
|
|
||||||
DEVICE=eth0
|
|
||||||
@@ -740,6 +741,7 @@ dns = none
|
|
||||||
"""
|
|
||||||
# Created by cloud-init automatically, do not edit.
|
|
||||||
#
|
|
||||||
+AUTOCONNECT_PRIORITY=120
|
|
||||||
BOOTPROTO=none
|
|
||||||
DEFROUTE=yes
|
|
||||||
DEVICE=eth0
|
|
||||||
@@ -897,6 +899,7 @@ dns = none
|
|
||||||
"""
|
|
||||||
# Created by cloud-init automatically, do not edit.
|
|
||||||
#
|
|
||||||
+AUTOCONNECT_PRIORITY=120
|
|
||||||
BOOTPROTO=none
|
|
||||||
DEFROUTE=yes
|
|
||||||
DEVICE=eth0
|
|
||||||
@@ -1137,6 +1140,7 @@ NETWORK_CONFIGS = {
|
|
||||||
"expected_sysconfig_rhel": {
|
"expected_sysconfig_rhel": {
|
||||||
"ifcfg-eth1": textwrap.dedent(
|
"ifcfg-eth1": textwrap.dedent(
|
||||||
"""\
|
"""\
|
||||||
@ -188,7 +167,7 @@ index 052b0674..cef4fa2d 100644
|
|||||||
BOOTPROTO=none
|
BOOTPROTO=none
|
||||||
DEVICE=eth1
|
DEVICE=eth1
|
||||||
HWADDR=cf:d6:af:48:e8:80
|
HWADDR=cf:d6:af:48:e8:80
|
||||||
@@ -1146,6 +1150,7 @@ NETWORK_CONFIGS = {
|
@@ -193,6 +194,7 @@ NETWORK_CONFIGS = {
|
||||||
),
|
),
|
||||||
"ifcfg-eth99": textwrap.dedent(
|
"ifcfg-eth99": textwrap.dedent(
|
||||||
"""\
|
"""\
|
||||||
@ -196,7 +175,7 @@ index 052b0674..cef4fa2d 100644
|
|||||||
BOOTPROTO=dhcp
|
BOOTPROTO=dhcp
|
||||||
DEFROUTE=yes
|
DEFROUTE=yes
|
||||||
DEVICE=eth99
|
DEVICE=eth99
|
||||||
@@ -1311,6 +1316,7 @@ NETWORK_CONFIGS = {
|
@@ -357,6 +359,7 @@ NETWORK_CONFIGS = {
|
||||||
"expected_sysconfig_rhel": {
|
"expected_sysconfig_rhel": {
|
||||||
"ifcfg-eth1": textwrap.dedent(
|
"ifcfg-eth1": textwrap.dedent(
|
||||||
"""\
|
"""\
|
||||||
@ -204,7 +183,7 @@ index 052b0674..cef4fa2d 100644
|
|||||||
BOOTPROTO=none
|
BOOTPROTO=none
|
||||||
DEVICE=eth1
|
DEVICE=eth1
|
||||||
HWADDR=cf:d6:af:48:e8:80
|
HWADDR=cf:d6:af:48:e8:80
|
||||||
@@ -1320,6 +1326,7 @@ NETWORK_CONFIGS = {
|
@@ -366,6 +369,7 @@ NETWORK_CONFIGS = {
|
||||||
),
|
),
|
||||||
"ifcfg-eth99": textwrap.dedent(
|
"ifcfg-eth99": textwrap.dedent(
|
||||||
"""\
|
"""\
|
||||||
@ -212,7 +191,7 @@ index 052b0674..cef4fa2d 100644
|
|||||||
BOOTPROTO=dhcp
|
BOOTPROTO=dhcp
|
||||||
DEFROUTE=yes
|
DEFROUTE=yes
|
||||||
DEVICE=eth99
|
DEVICE=eth99
|
||||||
@@ -1566,6 +1573,7 @@ NETWORK_CONFIGS = {
|
@@ -622,6 +626,7 @@ NETWORK_CONFIGS = {
|
||||||
"expected_sysconfig_rhel": {
|
"expected_sysconfig_rhel": {
|
||||||
"ifcfg-iface0": textwrap.dedent(
|
"ifcfg-iface0": textwrap.dedent(
|
||||||
"""\
|
"""\
|
||||||
@ -220,7 +199,15 @@ index 052b0674..cef4fa2d 100644
|
|||||||
BOOTPROTO=none
|
BOOTPROTO=none
|
||||||
DEVICE=iface0
|
DEVICE=iface0
|
||||||
IPADDR=192.168.14.2
|
IPADDR=192.168.14.2
|
||||||
@@ -1712,6 +1720,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": {
|
"expected_sysconfig_rhel": {
|
||||||
"ifcfg-iface0": textwrap.dedent(
|
"ifcfg-iface0": textwrap.dedent(
|
||||||
"""\
|
"""\
|
||||||
@ -228,7 +215,7 @@ index 052b0674..cef4fa2d 100644
|
|||||||
BOOTPROTO=none
|
BOOTPROTO=none
|
||||||
DEVICE=iface0
|
DEVICE=iface0
|
||||||
DHCPV6C=yes
|
DHCPV6C=yes
|
||||||
@@ -1801,6 +1810,7 @@ NETWORK_CONFIGS = {
|
@@ -982,6 +989,7 @@ NETWORK_CONFIGS = {
|
||||||
"expected_sysconfig_rhel": {
|
"expected_sysconfig_rhel": {
|
||||||
"ifcfg-iface0": textwrap.dedent(
|
"ifcfg-iface0": textwrap.dedent(
|
||||||
"""\
|
"""\
|
||||||
@ -236,7 +223,7 @@ index 052b0674..cef4fa2d 100644
|
|||||||
BOOTPROTO=none
|
BOOTPROTO=none
|
||||||
DEVICE=iface0
|
DEVICE=iface0
|
||||||
DHCPV6C=yes
|
DHCPV6C=yes
|
||||||
@@ -1876,6 +1886,7 @@ NETWORK_CONFIGS = {
|
@@ -1057,6 +1065,7 @@ NETWORK_CONFIGS = {
|
||||||
"expected_sysconfig_rhel": {
|
"expected_sysconfig_rhel": {
|
||||||
"ifcfg-iface0": textwrap.dedent(
|
"ifcfg-iface0": textwrap.dedent(
|
||||||
"""\
|
"""\
|
||||||
@ -244,7 +231,7 @@ index 052b0674..cef4fa2d 100644
|
|||||||
BOOTPROTO=none
|
BOOTPROTO=none
|
||||||
DEVICE=iface0
|
DEVICE=iface0
|
||||||
DHCPV6C=yes
|
DHCPV6C=yes
|
||||||
@@ -1940,6 +1951,7 @@ NETWORK_CONFIGS = {
|
@@ -1123,6 +1132,7 @@ NETWORK_CONFIGS = {
|
||||||
"expected_sysconfig_rhel": {
|
"expected_sysconfig_rhel": {
|
||||||
"ifcfg-iface0": textwrap.dedent(
|
"ifcfg-iface0": textwrap.dedent(
|
||||||
"""\
|
"""\
|
||||||
@ -252,7 +239,7 @@ index 052b0674..cef4fa2d 100644
|
|||||||
BOOTPROTO=none
|
BOOTPROTO=none
|
||||||
DEVICE=iface0
|
DEVICE=iface0
|
||||||
IPV6_AUTOCONF=yes
|
IPV6_AUTOCONF=yes
|
||||||
@@ -1995,6 +2007,7 @@ NETWORK_CONFIGS = {
|
@@ -1188,6 +1198,7 @@ NETWORK_CONFIGS = {
|
||||||
"expected_sysconfig_rhel": {
|
"expected_sysconfig_rhel": {
|
||||||
"ifcfg-iface0": textwrap.dedent(
|
"ifcfg-iface0": textwrap.dedent(
|
||||||
"""\
|
"""\
|
||||||
@ -260,7 +247,7 @@ index 052b0674..cef4fa2d 100644
|
|||||||
BOOTPROTO=none
|
BOOTPROTO=none
|
||||||
DEVICE=iface0
|
DEVICE=iface0
|
||||||
IPV6ADDR=2001:1::1/64
|
IPV6ADDR=2001:1::1/64
|
||||||
@@ -2051,6 +2064,7 @@ NETWORK_CONFIGS = {
|
@@ -1246,6 +1257,7 @@ NETWORK_CONFIGS = {
|
||||||
"expected_sysconfig_rhel": {
|
"expected_sysconfig_rhel": {
|
||||||
"ifcfg-iface0": textwrap.dedent(
|
"ifcfg-iface0": textwrap.dedent(
|
||||||
"""\
|
"""\
|
||||||
@ -268,7 +255,7 @@ index 052b0674..cef4fa2d 100644
|
|||||||
BOOTPROTO=none
|
BOOTPROTO=none
|
||||||
DEVICE=iface0
|
DEVICE=iface0
|
||||||
DHCPV6C=yes
|
DHCPV6C=yes
|
||||||
@@ -2135,6 +2149,7 @@ NETWORK_CONFIGS = {
|
@@ -1332,6 +1344,7 @@ NETWORK_CONFIGS = {
|
||||||
"expected_sysconfig_rhel": {
|
"expected_sysconfig_rhel": {
|
||||||
"ifcfg-iface0": textwrap.dedent(
|
"ifcfg-iface0": textwrap.dedent(
|
||||||
"""\
|
"""\
|
||||||
@ -276,7 +263,7 @@ index 052b0674..cef4fa2d 100644
|
|||||||
BOOTPROTO=none
|
BOOTPROTO=none
|
||||||
DEVICE=iface0
|
DEVICE=iface0
|
||||||
DHCPV6C=yes
|
DHCPV6C=yes
|
||||||
@@ -2181,6 +2196,7 @@ NETWORK_CONFIGS = {
|
@@ -1378,6 +1391,7 @@ NETWORK_CONFIGS = {
|
||||||
"expected_sysconfig_rhel": {
|
"expected_sysconfig_rhel": {
|
||||||
"ifcfg-iface0": textwrap.dedent(
|
"ifcfg-iface0": textwrap.dedent(
|
||||||
"""\
|
"""\
|
||||||
@ -284,7 +271,7 @@ index 052b0674..cef4fa2d 100644
|
|||||||
BOOTPROTO=dhcp
|
BOOTPROTO=dhcp
|
||||||
DEVICE=iface0
|
DEVICE=iface0
|
||||||
ONBOOT=yes
|
ONBOOT=yes
|
||||||
@@ -2256,6 +2272,7 @@ NETWORK_CONFIGS = {
|
@@ -1453,6 +1467,7 @@ NETWORK_CONFIGS = {
|
||||||
"expected_sysconfig_rhel": {
|
"expected_sysconfig_rhel": {
|
||||||
"ifcfg-iface0": textwrap.dedent(
|
"ifcfg-iface0": textwrap.dedent(
|
||||||
"""\
|
"""\
|
||||||
@ -292,7 +279,7 @@ index 052b0674..cef4fa2d 100644
|
|||||||
BOOTPROTO=dhcp
|
BOOTPROTO=dhcp
|
||||||
DEVICE=iface0
|
DEVICE=iface0
|
||||||
ETHTOOL_OPTS="wol g"
|
ETHTOOL_OPTS="wol g"
|
||||||
@@ -2591,6 +2608,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
|
@@ -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": {
|
"expected_sysconfig_rhel": {
|
||||||
"ifcfg-bond0": textwrap.dedent(
|
"ifcfg-bond0": textwrap.dedent(
|
||||||
"""\
|
"""\
|
||||||
@ -300,7 +287,7 @@ index 052b0674..cef4fa2d 100644
|
|||||||
BONDING_MASTER=yes
|
BONDING_MASTER=yes
|
||||||
BONDING_OPTS="mode=active-backup """
|
BONDING_OPTS="mode=active-backup """
|
||||||
"""xmit_hash_policy=layer3+4 """
|
"""xmit_hash_policy=layer3+4 """
|
||||||
@@ -2608,6 +2626,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
|
@@ -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(
|
"ifcfg-bond0.200": textwrap.dedent(
|
||||||
"""\
|
"""\
|
||||||
@ -308,7 +295,7 @@ index 052b0674..cef4fa2d 100644
|
|||||||
BOOTPROTO=dhcp
|
BOOTPROTO=dhcp
|
||||||
DEVICE=bond0.200
|
DEVICE=bond0.200
|
||||||
DHCLIENT_SET_DEFAULT_ROUTE=no
|
DHCLIENT_SET_DEFAULT_ROUTE=no
|
||||||
@@ -2619,6 +2638,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
|
@@ -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(
|
"ifcfg-br0": textwrap.dedent(
|
||||||
"""\
|
"""\
|
||||||
AGEING=250
|
AGEING=250
|
||||||
@ -316,7 +303,7 @@ index 052b0674..cef4fa2d 100644
|
|||||||
BOOTPROTO=none
|
BOOTPROTO=none
|
||||||
DEFROUTE=yes
|
DEFROUTE=yes
|
||||||
DEVICE=br0
|
DEVICE=br0
|
||||||
@@ -2638,6 +2658,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(
|
"ifcfg-eth0": textwrap.dedent(
|
||||||
"""\
|
"""\
|
||||||
@ -324,7 +311,7 @@ index 052b0674..cef4fa2d 100644
|
|||||||
BOOTPROTO=none
|
BOOTPROTO=none
|
||||||
DEVICE=eth0
|
DEVICE=eth0
|
||||||
HWADDR=c0:d6:9f:2c:e8:80
|
HWADDR=c0:d6:9f:2c:e8:80
|
||||||
@@ -2647,6 +2668,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
|
@@ -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(
|
"ifcfg-eth0.101": textwrap.dedent(
|
||||||
"""\
|
"""\
|
||||||
@ -332,7 +319,7 @@ index 052b0674..cef4fa2d 100644
|
|||||||
BOOTPROTO=none
|
BOOTPROTO=none
|
||||||
DEFROUTE=yes
|
DEFROUTE=yes
|
||||||
DEVICE=eth0.101
|
DEVICE=eth0.101
|
||||||
@@ -2666,6 +2688,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
|
@@ -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(
|
"ifcfg-eth1": textwrap.dedent(
|
||||||
"""\
|
"""\
|
||||||
@ -340,7 +327,7 @@ index 052b0674..cef4fa2d 100644
|
|||||||
BOOTPROTO=none
|
BOOTPROTO=none
|
||||||
DEVICE=eth1
|
DEVICE=eth1
|
||||||
HWADDR=aa:d6:9f:2c:e8:80
|
HWADDR=aa:d6:9f:2c:e8:80
|
||||||
@@ -2677,6 +2700,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
|
@@ -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(
|
"ifcfg-eth2": textwrap.dedent(
|
||||||
"""\
|
"""\
|
||||||
@ -348,7 +335,7 @@ index 052b0674..cef4fa2d 100644
|
|||||||
BOOTPROTO=none
|
BOOTPROTO=none
|
||||||
DEVICE=eth2
|
DEVICE=eth2
|
||||||
HWADDR=c0:bb:9f:2c:e8:80
|
HWADDR=c0:bb:9f:2c:e8:80
|
||||||
@@ -2688,6 +2712,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
|
@@ -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(
|
"ifcfg-eth3": textwrap.dedent(
|
||||||
"""\
|
"""\
|
||||||
@ -356,7 +343,7 @@ index 052b0674..cef4fa2d 100644
|
|||||||
BOOTPROTO=none
|
BOOTPROTO=none
|
||||||
BRIDGE=br0
|
BRIDGE=br0
|
||||||
DEVICE=eth3
|
DEVICE=eth3
|
||||||
@@ -2698,6 +2723,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(
|
"ifcfg-eth4": textwrap.dedent(
|
||||||
"""\
|
"""\
|
||||||
@ -364,7 +351,7 @@ index 052b0674..cef4fa2d 100644
|
|||||||
BOOTPROTO=none
|
BOOTPROTO=none
|
||||||
BRIDGE=br0
|
BRIDGE=br0
|
||||||
DEVICE=eth4
|
DEVICE=eth4
|
||||||
@@ -2708,6 +2734,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(
|
"ifcfg-eth5": textwrap.dedent(
|
||||||
"""\
|
"""\
|
||||||
@ -372,7 +359,7 @@ index 052b0674..cef4fa2d 100644
|
|||||||
BOOTPROTO=dhcp
|
BOOTPROTO=dhcp
|
||||||
DEVICE=eth5
|
DEVICE=eth5
|
||||||
DHCLIENT_SET_DEFAULT_ROUTE=no
|
DHCLIENT_SET_DEFAULT_ROUTE=no
|
||||||
@@ -2718,6 +2745,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
|
@@ -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(
|
"ifcfg-ib0": textwrap.dedent(
|
||||||
"""\
|
"""\
|
||||||
@ -380,15 +367,79 @@ index 052b0674..cef4fa2d 100644
|
|||||||
BOOTPROTO=none
|
BOOTPROTO=none
|
||||||
DEVICE=ib0
|
DEVICE=ib0
|
||||||
HWADDR=a0:00:02:20:fe:80:00:00:00:00:00:00:ec:0d:9a:03:00:15:e2:c1
|
HWADDR=a0:00:02:20:fe:80:00:00:00:00:00:00:ec:0d:9a:03:00:15:e2:c1
|
||||||
@@ -3422,6 +3450,7 @@ iface bond0 inet6 static
|
@@ -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": {
|
"expected_sysconfig_rhel": {
|
||||||
"ifcfg-bond0": textwrap.dedent(
|
"ifcfg-bond0": textwrap.dedent(
|
||||||
"""\
|
"""\
|
||||||
+ AUTOCONNECT_PRIORITY=120
|
+ AUTOCONNECT_PRIORITY=120
|
||||||
BONDING_MASTER=yes
|
BONDING_MASTER=yes
|
||||||
BONDING_OPTS="mode=active-backup xmit_hash_policy=layer3+4 """
|
BONDING_OPTS="mode=active-backup miimon=100 """
|
||||||
"""miimon=100 num_grat_arp=5 """
|
"""downdelay=10 updelay=20 primary=bond0s0"
|
||||||
@@ -3452,6 +3481,7 @@ iface bond0 inet6 static
|
@@ -3258,6 +3293,7 @@ iface bond0 inet6 static
|
||||||
),
|
),
|
||||||
"ifcfg-bond0s0": textwrap.dedent(
|
"ifcfg-bond0s0": textwrap.dedent(
|
||||||
"""\
|
"""\
|
||||||
@ -396,7 +447,7 @@ index 052b0674..cef4fa2d 100644
|
|||||||
BOOTPROTO=none
|
BOOTPROTO=none
|
||||||
DEVICE=bond0s0
|
DEVICE=bond0s0
|
||||||
HWADDR=aa:bb:cc:dd:e8:00
|
HWADDR=aa:bb:cc:dd:e8:00
|
||||||
@@ -3479,6 +3509,7 @@ iface bond0 inet6 static
|
@@ -3285,6 +3321,7 @@ iface bond0 inet6 static
|
||||||
),
|
),
|
||||||
"ifcfg-bond0s1": textwrap.dedent(
|
"ifcfg-bond0s1": textwrap.dedent(
|
||||||
"""\
|
"""\
|
||||||
@ -404,7 +455,31 @@ index 052b0674..cef4fa2d 100644
|
|||||||
BOOTPROTO=none
|
BOOTPROTO=none
|
||||||
DEVICE=bond0s1
|
DEVICE=bond0s1
|
||||||
HWADDR=aa:bb:cc:dd:e8:01
|
HWADDR=aa:bb:cc:dd:e8:01
|
||||||
@@ -3628,6 +3659,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": {
|
"expected_sysconfig_rhel": {
|
||||||
"ifcfg-en0": textwrap.dedent(
|
"ifcfg-en0": textwrap.dedent(
|
||||||
"""\
|
"""\
|
||||||
@ -412,7 +487,7 @@ index 052b0674..cef4fa2d 100644
|
|||||||
BOOTPROTO=none
|
BOOTPROTO=none
|
||||||
DEVICE=en0
|
DEVICE=en0
|
||||||
HWADDR=aa:bb:cc:dd:e8:00
|
HWADDR=aa:bb:cc:dd:e8:00
|
||||||
@@ -3637,6 +3669,7 @@ iface bond0 inet6 static
|
@@ -3798,6 +3839,7 @@ iface bond0 inet6 static
|
||||||
),
|
),
|
||||||
"ifcfg-en0.99": textwrap.dedent(
|
"ifcfg-en0.99": textwrap.dedent(
|
||||||
"""\
|
"""\
|
||||||
@ -420,7 +495,23 @@ index 052b0674..cef4fa2d 100644
|
|||||||
BOOTPROTO=none
|
BOOTPROTO=none
|
||||||
DEFROUTE=yes
|
DEFROUTE=yes
|
||||||
DEVICE=en0.99
|
DEVICE=en0.99
|
||||||
@@ -3774,6 +3807,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": {
|
"expected_sysconfig_rhel": {
|
||||||
"ifcfg-br0": textwrap.dedent(
|
"ifcfg-br0": textwrap.dedent(
|
||||||
"""\
|
"""\
|
||||||
@ -428,7 +519,7 @@ index 052b0674..cef4fa2d 100644
|
|||||||
BOOTPROTO=none
|
BOOTPROTO=none
|
||||||
DEVICE=br0
|
DEVICE=br0
|
||||||
IPADDR=192.168.2.2
|
IPADDR=192.168.2.2
|
||||||
@@ -3787,6 +3821,7 @@ iface bond0 inet6 static
|
@@ -4111,6 +4156,7 @@ iface bond0 inet6 static
|
||||||
),
|
),
|
||||||
"ifcfg-eth0": textwrap.dedent(
|
"ifcfg-eth0": textwrap.dedent(
|
||||||
"""\
|
"""\
|
||||||
@ -436,7 +527,7 @@ index 052b0674..cef4fa2d 100644
|
|||||||
BOOTPROTO=none
|
BOOTPROTO=none
|
||||||
BRIDGE=br0
|
BRIDGE=br0
|
||||||
DEVICE=eth0
|
DEVICE=eth0
|
||||||
@@ -3802,6 +3837,7 @@ iface bond0 inet6 static
|
@@ -4126,6 +4172,7 @@ iface bond0 inet6 static
|
||||||
),
|
),
|
||||||
"ifcfg-eth1": textwrap.dedent(
|
"ifcfg-eth1": textwrap.dedent(
|
||||||
"""\
|
"""\
|
||||||
@ -444,7 +535,7 @@ index 052b0674..cef4fa2d 100644
|
|||||||
BOOTPROTO=none
|
BOOTPROTO=none
|
||||||
BRIDGE=br0
|
BRIDGE=br0
|
||||||
DEVICE=eth1
|
DEVICE=eth1
|
||||||
@@ -3989,6 +4025,7 @@ iface bond0 inet6 static
|
@@ -4313,6 +4360,7 @@ iface bond0 inet6 static
|
||||||
"expected_sysconfig_rhel": {
|
"expected_sysconfig_rhel": {
|
||||||
"ifcfg-eth0": textwrap.dedent(
|
"ifcfg-eth0": textwrap.dedent(
|
||||||
"""\
|
"""\
|
||||||
@ -452,7 +543,7 @@ index 052b0674..cef4fa2d 100644
|
|||||||
BOOTPROTO=none
|
BOOTPROTO=none
|
||||||
DEVICE=eth0
|
DEVICE=eth0
|
||||||
HWADDR=52:54:00:12:34:00
|
HWADDR=52:54:00:12:34:00
|
||||||
@@ -4001,6 +4038,7 @@ iface bond0 inet6 static
|
@@ -4325,6 +4373,7 @@ iface bond0 inet6 static
|
||||||
),
|
),
|
||||||
"ifcfg-eth1": textwrap.dedent(
|
"ifcfg-eth1": textwrap.dedent(
|
||||||
"""\
|
"""\
|
||||||
@ -460,7 +551,7 @@ index 052b0674..cef4fa2d 100644
|
|||||||
BOOTPROTO=none
|
BOOTPROTO=none
|
||||||
DEVICE=eth1
|
DEVICE=eth1
|
||||||
HWADDR=52:54:00:12:34:aa
|
HWADDR=52:54:00:12:34:aa
|
||||||
@@ -4012,6 +4050,7 @@ iface bond0 inet6 static
|
@@ -4336,6 +4385,7 @@ iface bond0 inet6 static
|
||||||
),
|
),
|
||||||
"ifcfg-eth2": textwrap.dedent(
|
"ifcfg-eth2": textwrap.dedent(
|
||||||
"""\
|
"""\
|
||||||
@ -468,7 +559,15 @@ index 052b0674..cef4fa2d 100644
|
|||||||
BOOTPROTO=none
|
BOOTPROTO=none
|
||||||
DEVICE=eth2
|
DEVICE=eth2
|
||||||
HWADDR=52:54:00:12:34:ff
|
HWADDR=52:54:00:12:34:ff
|
||||||
@@ -4096,6 +4135,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": {
|
"expected_sysconfig_rhel": {
|
||||||
"ifcfg-eth0": textwrap.dedent(
|
"ifcfg-eth0": textwrap.dedent(
|
||||||
"""\
|
"""\
|
||||||
@ -476,15 +575,99 @@ index 052b0674..cef4fa2d 100644
|
|||||||
BOOTPROTO=none
|
BOOTPROTO=none
|
||||||
DEVICE=eth0
|
DEVICE=eth0
|
||||||
HWADDR=cf:d6:af:48:e8:80
|
HWADDR=cf:d6:af:48:e8:80
|
||||||
@@ -4693,6 +4733,7 @@ class TestRhelSysConfigRendering(CiTestCase):
|
@@ -4734,6 +4786,7 @@ iface bond0 inet6 static
|
||||||
|
"""\
|
||||||
|
# Created by cloud-init automatically, do not edit.
|
||||||
|
#
|
||||||
|
+ AUTOCONNECT_PRIORITY=120
|
||||||
|
BOOTPROTO=none
|
||||||
|
DEVICE=eth0
|
||||||
|
DNS1=8.8.8.8
|
||||||
|
@@ -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 = """
|
expected_content = """
|
||||||
# Created by cloud-init automatically, do not edit.
|
# Created by cloud-init automatically, do not edit.
|
||||||
#
|
#
|
||||||
+AUTOCONNECT_PRIORITY=120
|
+AUTOCONNECT_PRIORITY=120
|
||||||
BOOTPROTO=dhcp
|
BOOTPROTO=dhcp
|
||||||
DEVICE=eth1000
|
DEVICE=eth1000
|
||||||
HWADDR=07-1c-c6-75-a4-be
|
DHCPV6C=yes
|
||||||
@@ -4900,6 +4941,7 @@ USERCTL=no
|
@@ -2143,6 +2149,7 @@ USERCTL=no
|
||||||
expected = """\
|
expected = """\
|
||||||
# Created by cloud-init automatically, do not edit.
|
# Created by cloud-init automatically, do not edit.
|
||||||
#
|
#
|
||||||
@ -492,7 +675,7 @@ index 052b0674..cef4fa2d 100644
|
|||||||
BOOTPROTO=none
|
BOOTPROTO=none
|
||||||
DEFROUTE=yes
|
DEFROUTE=yes
|
||||||
DEVICE=interface0
|
DEVICE=interface0
|
||||||
@@ -4929,6 +4971,7 @@ USERCTL=no
|
@@ -2172,6 +2179,7 @@ USERCTL=no
|
||||||
expected_i1 = """\
|
expected_i1 = """\
|
||||||
# Created by cloud-init automatically, do not edit.
|
# Created by cloud-init automatically, do not edit.
|
||||||
#
|
#
|
||||||
@ -500,7 +683,7 @@ index 052b0674..cef4fa2d 100644
|
|||||||
BOOTPROTO=none
|
BOOTPROTO=none
|
||||||
DEFROUTE=yes
|
DEFROUTE=yes
|
||||||
DEVICE=eth0
|
DEVICE=eth0
|
||||||
@@ -4945,6 +4988,7 @@ USERCTL=no
|
@@ -2188,6 +2196,7 @@ USERCTL=no
|
||||||
expected_i2 = """\
|
expected_i2 = """\
|
||||||
# Created by cloud-init automatically, do not edit.
|
# Created by cloud-init automatically, do not edit.
|
||||||
#
|
#
|
||||||
@ -508,7 +691,7 @@ index 052b0674..cef4fa2d 100644
|
|||||||
BOOTPROTO=dhcp
|
BOOTPROTO=dhcp
|
||||||
DEVICE=eth1
|
DEVICE=eth1
|
||||||
DHCLIENT_SET_DEFAULT_ROUTE=no
|
DHCLIENT_SET_DEFAULT_ROUTE=no
|
||||||
@@ -4972,6 +5016,7 @@ USERCTL=no
|
@@ -2215,6 +2224,7 @@ USERCTL=no
|
||||||
expected = """\
|
expected = """\
|
||||||
# Created by cloud-init automatically, do not edit.
|
# Created by cloud-init automatically, do not edit.
|
||||||
#
|
#
|
||||||
@ -516,7 +699,7 @@ index 052b0674..cef4fa2d 100644
|
|||||||
BOOTPROTO=dhcp
|
BOOTPROTO=dhcp
|
||||||
DEVICE=eth0
|
DEVICE=eth0
|
||||||
ONBOOT=yes
|
ONBOOT=yes
|
||||||
@@ -5191,6 +5236,7 @@ USERCTL=no
|
@@ -2396,6 +2406,7 @@ USERCTL=no
|
||||||
"expected_sysconfig": {
|
"expected_sysconfig": {
|
||||||
"ifcfg-ens3": textwrap.dedent(
|
"ifcfg-ens3": textwrap.dedent(
|
||||||
"""\
|
"""\
|
||||||
@ -524,7 +707,7 @@ index 052b0674..cef4fa2d 100644
|
|||||||
BOOTPROTO=none
|
BOOTPROTO=none
|
||||||
DEFROUTE=yes
|
DEFROUTE=yes
|
||||||
DEVICE=ens3
|
DEVICE=ens3
|
||||||
@@ -5235,6 +5281,7 @@ USERCTL=no
|
@@ -2442,6 +2453,7 @@ USERCTL=no
|
||||||
expected = {
|
expected = {
|
||||||
"ifcfg-eno1": textwrap.dedent(
|
"ifcfg-eno1": textwrap.dedent(
|
||||||
"""\
|
"""\
|
||||||
@ -532,7 +715,7 @@ index 052b0674..cef4fa2d 100644
|
|||||||
BOOTPROTO=none
|
BOOTPROTO=none
|
||||||
DEVICE=eno1
|
DEVICE=eno1
|
||||||
ONBOOT=yes
|
ONBOOT=yes
|
||||||
@@ -5244,6 +5291,7 @@ USERCTL=no
|
@@ -2451,6 +2463,7 @@ USERCTL=no
|
||||||
),
|
),
|
||||||
"ifcfg-eno1.1000": textwrap.dedent(
|
"ifcfg-eno1.1000": textwrap.dedent(
|
||||||
"""\
|
"""\
|
||||||
@ -540,7 +723,7 @@ index 052b0674..cef4fa2d 100644
|
|||||||
BOOTPROTO=none
|
BOOTPROTO=none
|
||||||
DEVICE=eno1.1000
|
DEVICE=eno1.1000
|
||||||
IPADDR=192.6.1.9
|
IPADDR=192.6.1.9
|
||||||
@@ -5276,6 +5324,7 @@ USERCTL=no
|
@@ -2483,6 +2496,7 @@ USERCTL=no
|
||||||
expected = {
|
expected = {
|
||||||
"ifcfg-bond0": textwrap.dedent(
|
"ifcfg-bond0": textwrap.dedent(
|
||||||
"""\
|
"""\
|
||||||
@ -548,7 +731,7 @@ index 052b0674..cef4fa2d 100644
|
|||||||
BONDING_MASTER=yes
|
BONDING_MASTER=yes
|
||||||
BONDING_SLAVE0=enp0s0
|
BONDING_SLAVE0=enp0s0
|
||||||
BONDING_SLAVE1=enp0s1
|
BONDING_SLAVE1=enp0s1
|
||||||
@@ -5291,6 +5340,7 @@ USERCTL=no
|
@@ -2498,6 +2512,7 @@ USERCTL=no
|
||||||
),
|
),
|
||||||
"ifcfg-enp0s0": textwrap.dedent(
|
"ifcfg-enp0s0": textwrap.dedent(
|
||||||
"""\
|
"""\
|
||||||
@ -556,7 +739,7 @@ index 052b0674..cef4fa2d 100644
|
|||||||
BONDING_MASTER=yes
|
BONDING_MASTER=yes
|
||||||
BOOTPROTO=none
|
BOOTPROTO=none
|
||||||
DEVICE=enp0s0
|
DEVICE=enp0s0
|
||||||
@@ -5303,6 +5353,7 @@ USERCTL=no
|
@@ -2510,6 +2525,7 @@ USERCTL=no
|
||||||
),
|
),
|
||||||
"ifcfg-enp0s1": textwrap.dedent(
|
"ifcfg-enp0s1": textwrap.dedent(
|
||||||
"""\
|
"""\
|
||||||
@ -564,15 +747,15 @@ index 052b0674..cef4fa2d 100644
|
|||||||
BONDING_MASTER=yes
|
BONDING_MASTER=yes
|
||||||
BOOTPROTO=none
|
BOOTPROTO=none
|
||||||
DEVICE=enp0s1
|
DEVICE=enp0s1
|
||||||
@@ -5333,6 +5384,7 @@ USERCTL=no
|
@@ -2541,6 +2557,7 @@ USERCTL=no
|
||||||
expected = {
|
expected = {
|
||||||
"ifcfg-eno1": textwrap.dedent(
|
"ifcfg-eno1": textwrap.dedent(
|
||||||
"""\
|
"""\
|
||||||
+ AUTOCONNECT_PRIORITY=120
|
+ AUTOCONNECT_PRIORITY=120
|
||||||
BOOTPROTO=dhcp
|
BOOTPROTO=dhcp
|
||||||
DEVICE=eno1
|
DEVICE=eno1
|
||||||
HWADDR=07-1c-c6-75-a4-be
|
HWADDR=07-1c-c6-75-a4-be
|
||||||
@@ -5411,6 +5463,7 @@ USERCTL=no
|
@@ -2621,6 +2638,7 @@ USERCTL=no
|
||||||
"""\
|
"""\
|
||||||
# Created by cloud-init automatically, do not edit.
|
# Created by cloud-init automatically, do not edit.
|
||||||
#
|
#
|
@ -0,0 +1,85 @@
|
|||||||
|
From 46e39514415041f51468b3e40059891dd42f028a 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>
|
||||||
|
---
|
||||||
|
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
|
@ -1,140 +0,0 @@
|
|||||||
From 5fa8113a9efaa90f293b95477c4fa44e3d4b6537 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Ani Sinha <anisinha@redhat.com>
|
|
||||||
Date: Thu, 23 Nov 2023 12:27:51 +0530
|
|
||||||
Subject: [PATCH] net/network_manager: do not set "may-fail" to False for both
|
|
||||||
ipv4 and ipv6 dhcp
|
|
||||||
|
|
||||||
If "may-fail" is set to False in the Network Manager keyfile for both ipv4
|
|
||||||
and ipv6 for dhcp configuration, it essentially means both ipv4 and ipv6 network
|
|
||||||
initialization using dhcp must succeed for the overall network configuration to
|
|
||||||
succeed. This means, for environments where only ipv4 or ipv6 is available but
|
|
||||||
not both and we need to configure both ipv4 and ipv6 dhcp, the overall
|
|
||||||
network configuration will fail. This is not what we want. When both ipv4
|
|
||||||
and ipv6 dhcp are configured, it is enough for the overall configuration to
|
|
||||||
succeed if any one succeeds.
|
|
||||||
Therefore, set "may-fail" to True for both ipv4 and ipv6 if and only if both
|
|
||||||
ipv4 and ipv6 are configured as dhcp in the Network Manager keyfile and
|
|
||||||
"may-fail" is set to False for both. If both ipv4 and ipv6 are configured
|
|
||||||
in the keyfile and if for any of them "may-fail" is already set to True,then
|
|
||||||
do nothing.
|
|
||||||
All other cases remain same as before.
|
|
||||||
|
|
||||||
Please see discussions in PR #4474.
|
|
||||||
|
|
||||||
Co-authored-by: James Falcon <james.falcon@canonical.com>
|
|
||||||
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
|
||||||
(cherry picked from commit 29dd5ace73ad60c7452c39b840045fb47fe0711f)
|
|
||||||
---
|
|
||||||
cloudinit/net/network_manager.py | 59 ++++++++++++++++++++++++++++++++
|
|
||||||
tests/unittests/test_net.py | 8 ++---
|
|
||||||
2 files changed, 63 insertions(+), 4 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/cloudinit/net/network_manager.py b/cloudinit/net/network_manager.py
|
|
||||||
index 8374cfcc..8a99eb3a 100644
|
|
||||||
--- a/cloudinit/net/network_manager.py
|
|
||||||
+++ b/cloudinit/net/network_manager.py
|
|
||||||
@@ -71,6 +71,57 @@ class NMConnection:
|
|
||||||
if not self.config.has_option(section, option):
|
|
||||||
self.config[section][option] = value
|
|
||||||
|
|
||||||
+ def _config_option_is_set(self, section, option):
|
|
||||||
+ """
|
|
||||||
+ Checks if a config option is set. Returns True if it is,
|
|
||||||
+ else returns False.
|
|
||||||
+ """
|
|
||||||
+ return self.config.has_section(section) and self.config.has_option(
|
|
||||||
+ section, option
|
|
||||||
+ )
|
|
||||||
+
|
|
||||||
+ def _get_config_option(self, section, option):
|
|
||||||
+ """
|
|
||||||
+ Returns the value of a config option if its set,
|
|
||||||
+ else returns None.
|
|
||||||
+ """
|
|
||||||
+ if self._config_option_is_set(section, option):
|
|
||||||
+ return self.config[section][option]
|
|
||||||
+ else:
|
|
||||||
+ return None
|
|
||||||
+
|
|
||||||
+ def _change_set_config_option(self, section, option, value):
|
|
||||||
+ """
|
|
||||||
+ Overrides the value of a config option if its already set.
|
|
||||||
+ Else, if the config option is not set, it does nothing.
|
|
||||||
+ """
|
|
||||||
+ if self._config_option_is_set(section, option):
|
|
||||||
+ self.config[section][option] = value
|
|
||||||
+
|
|
||||||
+ def _set_mayfail_true_if_both_false_dhcp(self):
|
|
||||||
+ """
|
|
||||||
+ If for both ipv4 and ipv6, 'may-fail' is set to be False,
|
|
||||||
+ set it to True for both of them.
|
|
||||||
+ """
|
|
||||||
+ for family in ["ipv4", "ipv6"]:
|
|
||||||
+ if self._get_config_option(family, "may-fail") != "false":
|
|
||||||
+ # if either ipv4 or ipv6 sections are not set/configured,
|
|
||||||
+ # or if both are configured but for either ipv4 or ipv6,
|
|
||||||
+ # 'may-fail' is not 'false', do not do anything.
|
|
||||||
+ return
|
|
||||||
+ if self._get_config_option(family, "method") not in [
|
|
||||||
+ "dhcp",
|
|
||||||
+ "auto",
|
|
||||||
+ ]:
|
|
||||||
+ # if both v4 and v6 are not dhcp, do not do anything.
|
|
||||||
+ return
|
|
||||||
+
|
|
||||||
+ # If we landed here, it means both ipv4 and ipv6 are configured
|
|
||||||
+ # with dhcp/auto and both have 'may-fail' set to 'false'. So set
|
|
||||||
+ # both to 'true'.
|
|
||||||
+ for family in ["ipv4", "ipv6"]:
|
|
||||||
+ self._change_set_config_option(family, "may-fail", "true")
|
|
||||||
+
|
|
||||||
def _set_ip_method(self, family, subnet_type):
|
|
||||||
"""
|
|
||||||
Ensures there's appropriate [ipv4]/[ipv6] for given family
|
|
||||||
@@ -271,6 +322,14 @@ class NMConnection:
|
|
||||||
if family == "ipv4" and "mtu" in subnet:
|
|
||||||
ipv4_mtu = subnet["mtu"]
|
|
||||||
|
|
||||||
+ # we do not want to set may-fail to false for both ipv4 and ipv6 dhcp
|
|
||||||
+ # at the at the same time. This will make the network configuration
|
|
||||||
+ # work only when both ipv4 and ipv6 dhcp succeeds. This may not be
|
|
||||||
+ # what we want. If we have configured both ipv4 and ipv6 dhcp, any one
|
|
||||||
+ # succeeding should be enough. Therefore, if "may-fail" is set to
|
|
||||||
+ # False for both ipv4 and ipv6 dhcp, set them both to True.
|
|
||||||
+ self._set_mayfail_true_if_both_false_dhcp()
|
|
||||||
+
|
|
||||||
if ipv4_mtu is None:
|
|
||||||
ipv4_mtu = device_mtu
|
|
||||||
if not ipv4_mtu == device_mtu:
|
|
||||||
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
|
|
||||||
index cef4fa2d..fb4c863c 100644
|
|
||||||
--- a/tests/unittests/test_net.py
|
|
||||||
+++ b/tests/unittests/test_net.py
|
|
||||||
@@ -1477,11 +1477,11 @@ NETWORK_CONFIGS = {
|
|
||||||
|
|
||||||
[ipv4]
|
|
||||||
method=auto
|
|
||||||
- may-fail=false
|
|
||||||
+ may-fail=true
|
|
||||||
|
|
||||||
[ipv6]
|
|
||||||
method=auto
|
|
||||||
- may-fail=false
|
|
||||||
+ may-fail=true
|
|
||||||
|
|
||||||
"""
|
|
||||||
),
|
|
||||||
@@ -1650,11 +1650,11 @@ NETWORK_CONFIGS = {
|
|
||||||
|
|
||||||
[ipv6]
|
|
||||||
method=auto
|
|
||||||
- may-fail=false
|
|
||||||
+ may-fail=true
|
|
||||||
|
|
||||||
[ipv4]
|
|
||||||
method=auto
|
|
||||||
- may-fail=false
|
|
||||||
+ may-fail=true
|
|
||||||
|
|
||||||
"""
|
|
||||||
),
|
|
266
0005-downstream-remove-single-process-optimization.patch
Normal file
266
0005-downstream-remove-single-process-optimization.patch
Normal file
@ -0,0 +1,266 @@
|
|||||||
|
From 84d1141690d4fe5d88878d2eb60e03d06ba3d422 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>
|
||||||
|
---
|
||||||
|
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 0dfb9b2f7..fbd772e52 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()
|
@ -1,172 +0,0 @@
|
|||||||
From 54e87eaad7841270e530beff2dcfe68292ae87ef Mon Sep 17 00:00:00 2001
|
|
||||||
From: Ani Sinha <anisinha@redhat.com>
|
|
||||||
Date: Tue, 21 Nov 2023 13:57:15 +0530
|
|
||||||
Subject: [PATCH] net: allow dhcp6 configuration from
|
|
||||||
generate_fallback_configuration()
|
|
||||||
|
|
||||||
This will make sure on Azure we can use both dhcp4 and dhcp6 when IMDS is not
|
|
||||||
used. This is useful in situations where only ipv6 network is available and
|
|
||||||
there is no dhcp4 running.
|
|
||||||
|
|
||||||
This change is mostly a reversal of commit 29ed5f5b646ee and therefore,
|
|
||||||
re-application of the commit 518047aea9 with some small changes.
|
|
||||||
|
|
||||||
The issue that caused the reversal of 518047aea9 is fixed by the earlier commit:
|
|
||||||
cab0eaf290af7 ("net/network_manager: do not set "may-fail" to False for both ipv4 and ipv6 dhcp")
|
|
||||||
|
|
||||||
Fixes GH-4439
|
|
||||||
|
|
||||||
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
|
||||||
(cherry picked from commit 0264e969166846b2f5cf87ccdb051a3a795eca15)
|
|
||||||
---
|
|
||||||
cloudinit/net/__init__.py | 7 ++++++-
|
|
||||||
tests/unittests/net/test_init.py | 4 ++++
|
|
||||||
tests/unittests/test_net.py | 24 +++++++++++++++++++++---
|
|
||||||
3 files changed, 31 insertions(+), 4 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/cloudinit/net/__init__.py b/cloudinit/net/__init__.py
|
|
||||||
index bf21633b..c0888f52 100644
|
|
||||||
--- a/cloudinit/net/__init__.py
|
|
||||||
+++ b/cloudinit/net/__init__.py
|
|
||||||
@@ -571,7 +571,12 @@ def generate_fallback_config(config_driver=None):
|
|
||||||
match = {
|
|
||||||
"macaddress": read_sys_net_safe(target_name, "address").lower()
|
|
||||||
}
|
|
||||||
- cfg = {"dhcp4": True, "set-name": target_name, "match": match}
|
|
||||||
+ cfg = {
|
|
||||||
+ "dhcp4": True,
|
|
||||||
+ "dhcp6": True,
|
|
||||||
+ "set-name": target_name,
|
|
||||||
+ "match": match,
|
|
||||||
+ }
|
|
||||||
if config_driver:
|
|
||||||
driver = device_driver(target_name)
|
|
||||||
if driver:
|
|
||||||
diff --git a/tests/unittests/net/test_init.py b/tests/unittests/net/test_init.py
|
|
||||||
index 561d5151..60a44186 100644
|
|
||||||
--- a/tests/unittests/net/test_init.py
|
|
||||||
+++ b/tests/unittests/net/test_init.py
|
|
||||||
@@ -261,6 +261,7 @@ class TestGenerateFallbackConfig(CiTestCase):
|
|
||||||
"eth1": {
|
|
||||||
"match": {"macaddress": mac},
|
|
||||||
"dhcp4": True,
|
|
||||||
+ "dhcp6": True,
|
|
||||||
"set-name": "eth1",
|
|
||||||
}
|
|
||||||
},
|
|
||||||
@@ -278,6 +279,7 @@ class TestGenerateFallbackConfig(CiTestCase):
|
|
||||||
"eth0": {
|
|
||||||
"match": {"macaddress": mac},
|
|
||||||
"dhcp4": True,
|
|
||||||
+ "dhcp6": True,
|
|
||||||
"set-name": "eth0",
|
|
||||||
}
|
|
||||||
},
|
|
||||||
@@ -293,6 +295,7 @@ class TestGenerateFallbackConfig(CiTestCase):
|
|
||||||
"ethernets": {
|
|
||||||
"eth0": {
|
|
||||||
"dhcp4": True,
|
|
||||||
+ "dhcp6": True,
|
|
||||||
"match": {"macaddress": mac},
|
|
||||||
"set-name": "eth0",
|
|
||||||
}
|
|
||||||
@@ -359,6 +362,7 @@ class TestGenerateFallbackConfig(CiTestCase):
|
|
||||||
"ethernets": {
|
|
||||||
"ens3": {
|
|
||||||
"dhcp4": True,
|
|
||||||
+ "dhcp6": True,
|
|
||||||
"match": {"name": "ens3"},
|
|
||||||
"set-name": "ens3",
|
|
||||||
}
|
|
||||||
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
|
|
||||||
index fb4c863c..d9ef493b 100644
|
|
||||||
--- a/tests/unittests/test_net.py
|
|
||||||
+++ b/tests/unittests/test_net.py
|
|
||||||
@@ -4339,6 +4339,7 @@ class TestGenerateFallbackConfig(CiTestCase):
|
|
||||||
"ethernets": {
|
|
||||||
"eth0": {
|
|
||||||
"dhcp4": True,
|
|
||||||
+ "dhcp6": True,
|
|
||||||
"set-name": "eth0",
|
|
||||||
"match": {
|
|
||||||
"macaddress": "00:11:22:33:44:55",
|
|
||||||
@@ -4423,6 +4424,9 @@ iface lo inet loopback
|
|
||||||
|
|
||||||
auto eth0
|
|
||||||
iface eth0 inet dhcp
|
|
||||||
+
|
|
||||||
+# control-alias eth0
|
|
||||||
+iface eth0 inet6 dhcp
|
|
||||||
"""
|
|
||||||
self.assertEqual(expected.lstrip(), contents.lstrip())
|
|
||||||
|
|
||||||
@@ -4512,6 +4516,9 @@ iface lo inet loopback
|
|
||||||
|
|
||||||
auto eth1
|
|
||||||
iface eth1 inet dhcp
|
|
||||||
+
|
|
||||||
+# control-alias eth1
|
|
||||||
+iface eth1 inet6 dhcp
|
|
||||||
"""
|
|
||||||
self.assertEqual(expected.lstrip(), contents.lstrip())
|
|
||||||
|
|
||||||
@@ -4736,7 +4743,9 @@ class TestRhelSysConfigRendering(CiTestCase):
|
|
||||||
AUTOCONNECT_PRIORITY=120
|
|
||||||
BOOTPROTO=dhcp
|
|
||||||
DEVICE=eth1000
|
|
||||||
+DHCPV6C=yes
|
|
||||||
HWADDR=07-1c-c6-75-a4-be
|
|
||||||
+IPV6INIT=yes
|
|
||||||
ONBOOT=yes
|
|
||||||
TYPE=Ethernet
|
|
||||||
USERCTL=no
|
|
||||||
@@ -5646,7 +5655,8 @@ class TestOpenSuseSysConfigRendering(CiTestCase):
|
|
||||||
expected_content = """
|
|
||||||
# Created by cloud-init automatically, do not edit.
|
|
||||||
#
|
|
||||||
-BOOTPROTO=dhcp4
|
|
||||||
+BOOTPROTO=dhcp
|
|
||||||
+DHCLIENT6_MODE=managed
|
|
||||||
LLADDR=07-1c-c6-75-a4-be
|
|
||||||
STARTMODE=auto
|
|
||||||
""".lstrip()
|
|
||||||
@@ -6032,7 +6042,11 @@ class TestNetworkManagerRendering(CiTestCase):
|
|
||||||
|
|
||||||
[ipv4]
|
|
||||||
method=auto
|
|
||||||
- may-fail=false
|
|
||||||
+ may-fail=true
|
|
||||||
+
|
|
||||||
+ [ipv6]
|
|
||||||
+ method=auto
|
|
||||||
+ may-fail=true
|
|
||||||
|
|
||||||
"""
|
|
||||||
),
|
|
||||||
@@ -6298,6 +6312,9 @@ iface lo inet loopback
|
|
||||||
|
|
||||||
auto eth1000
|
|
||||||
iface eth1000 inet dhcp
|
|
||||||
+
|
|
||||||
+# control-alias eth1000
|
|
||||||
+iface eth1000 inet6 dhcp
|
|
||||||
"""
|
|
||||||
self.assertEqual(expected.lstrip(), contents.lstrip())
|
|
||||||
|
|
||||||
@@ -6357,6 +6374,7 @@ class TestNetplanNetRendering:
|
|
||||||
ethernets:
|
|
||||||
eth1000:
|
|
||||||
dhcp4: true
|
|
||||||
+ dhcp6: true
|
|
||||||
match:
|
|
||||||
macaddress: 07-1c-c6-75-a4-be
|
|
||||||
set-name: eth1000
|
|
||||||
@@ -7856,7 +7874,7 @@ class TestNetworkdNetRendering(CiTestCase):
|
|
||||||
Name=eth1000
|
|
||||||
MACAddress=07-1c-c6-75-a4-be
|
|
||||||
[Network]
|
|
||||||
- DHCP=ipv4"""
|
|
||||||
+ DHCP=yes"""
|
|
||||||
).rstrip(" ")
|
|
||||||
|
|
||||||
expected = self.create_conf_dict(expected.splitlines())
|
|
@ -0,0 +1,90 @@
|
|||||||
|
From 5d820c9e6025b46a6b4e443d9934ff83a8ad1afa 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
|
@ -1,113 +0,0 @@
|
|||||||
From c0df864e373e1e34bf23c4869acdf7d20aea7aaf Mon Sep 17 00:00:00 2001
|
|
||||||
From: Ani Sinha <anisinha@redhat.com>
|
|
||||||
Date: Thu, 7 Dec 2023 02:39:51 +0530
|
|
||||||
Subject: [PATCH] net/nm: check for presence of ifcfg files when nm connection
|
|
||||||
files are absent (#4645)
|
|
||||||
|
|
||||||
On systems that use network manager to manage connections and activate network
|
|
||||||
interfaces, they may also use ifcfg files for configuring
|
|
||||||
interfaces using ifcfg-rh network manager plugin. When network manager is used
|
|
||||||
as the activator, we need to also check for the presence of ifcfg interface
|
|
||||||
config file when the network manager connection file is absent and if ifcfg-rh
|
|
||||||
plugin is present.
|
|
||||||
Hence, with this change, network manager activator first tries to use network
|
|
||||||
manager connection files to bring up or bring down the interface. If the
|
|
||||||
connection files are not present and if ifcfg-rh plugin is present, it tries to
|
|
||||||
use ifcfg files for the interface. If the plugin or the ifcfg files are not
|
|
||||||
present, the activator fails to activate or deactivate the interface and it
|
|
||||||
bails out with warning log.
|
|
||||||
|
|
||||||
Fixes: GH-4640
|
|
||||||
|
|
||||||
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
|
||||||
(cherry picked from commit d1d5166895da471cff3606c70d4e8ab6eec1c006)
|
|
||||||
---
|
|
||||||
cloudinit/net/activators.py | 7 +++++++
|
|
||||||
cloudinit/net/network_manager.py | 33 ++++++++++++++++++++++++++++++--
|
|
||||||
2 files changed, 38 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/cloudinit/net/activators.py b/cloudinit/net/activators.py
|
|
||||||
index e69da40d..dd858862 100644
|
|
||||||
--- a/cloudinit/net/activators.py
|
|
||||||
+++ b/cloudinit/net/activators.py
|
|
||||||
@@ -117,6 +117,13 @@ class NetworkManagerActivator(NetworkActivator):
|
|
||||||
from cloudinit.net.network_manager import conn_filename
|
|
||||||
|
|
||||||
filename = conn_filename(device_name)
|
|
||||||
+ if filename is None:
|
|
||||||
+ LOG.warning(
|
|
||||||
+ "Unable to find an interface config file. "
|
|
||||||
+ "Unable to bring up interface."
|
|
||||||
+ )
|
|
||||||
+ return False
|
|
||||||
+
|
|
||||||
cmd = ["nmcli", "connection", "load", filename]
|
|
||||||
if _alter_interface(cmd, device_name):
|
|
||||||
cmd = ["nmcli", "connection", "up", "filename", filename]
|
|
||||||
diff --git a/cloudinit/net/network_manager.py b/cloudinit/net/network_manager.py
|
|
||||||
index 8a99eb3a..76a0ac15 100644
|
|
||||||
--- a/cloudinit/net/network_manager.py
|
|
||||||
+++ b/cloudinit/net/network_manager.py
|
|
||||||
@@ -17,10 +17,12 @@ from typing import Optional
|
|
||||||
from cloudinit import subp, util
|
|
||||||
from cloudinit.net import is_ipv6_address, renderer, subnet_is_ipv6
|
|
||||||
from cloudinit.net.network_state import NetworkState
|
|
||||||
+from cloudinit.net.sysconfig import available_nm_ifcfg_rh
|
|
||||||
|
|
||||||
NM_RUN_DIR = "/etc/NetworkManager"
|
|
||||||
NM_LIB_DIR = "/usr/lib/NetworkManager"
|
|
||||||
NM_CFG_FILE = "/etc/NetworkManager/NetworkManager.conf"
|
|
||||||
+IFCFG_CFG_FILE = "/etc/sysconfig/network-scripts"
|
|
||||||
NM_IPV6_ADDR_GEN_CONF = """# This is generated by cloud-init. Do not edit.
|
|
||||||
#
|
|
||||||
[.config]
|
|
||||||
@@ -442,7 +444,7 @@ class Renderer(renderer.Renderer):
|
|
||||||
for con_id, conn in self.connections.items():
|
|
||||||
if not conn.valid():
|
|
||||||
continue
|
|
||||||
- name = conn_filename(con_id, target)
|
|
||||||
+ name = nm_conn_filename(con_id, target)
|
|
||||||
util.write_file(name, conn.dump(), 0o600)
|
|
||||||
|
|
||||||
# Select EUI64 to be used by default by NM for creating the address
|
|
||||||
@@ -452,12 +454,39 @@ class Renderer(renderer.Renderer):
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
-def conn_filename(con_id, target=None):
|
|
||||||
+def nm_conn_filename(con_id, target=None):
|
|
||||||
target_con_dir = subp.target_path(target, NM_RUN_DIR)
|
|
||||||
con_file = f"cloud-init-{con_id}.nmconnection"
|
|
||||||
return f"{target_con_dir}/system-connections/{con_file}"
|
|
||||||
|
|
||||||
|
|
||||||
+def sysconfig_conn_filename(devname, target=None):
|
|
||||||
+ target_con_dir = subp.target_path(target, IFCFG_CFG_FILE)
|
|
||||||
+ con_file = f"ifcfg-{devname}"
|
|
||||||
+ return f"{target_con_dir}/{con_file}"
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+def conn_filename(devname):
|
|
||||||
+ """
|
|
||||||
+ This function returns the name of the interface config file.
|
|
||||||
+ It first checks for presence of network manager connection file.
|
|
||||||
+ If absent and ifcfg-rh plugin for network manager is available,
|
|
||||||
+ it returns the name of the ifcfg file if it is present. If the
|
|
||||||
+ plugin is not present or the plugin is present but ifcfg file is
|
|
||||||
+ not, it returns None.
|
|
||||||
+ This function is called from NetworkManagerActivator class in
|
|
||||||
+ activators.py.
|
|
||||||
+ """
|
|
||||||
+ conn_file = nm_conn_filename(devname)
|
|
||||||
+ # If the network manager connection file is absent, also check for
|
|
||||||
+ # presence of ifcfg files for the same interface (if nm-ifcfg-rh plugin is
|
|
||||||
+ # present, network manager can handle ifcfg files). If both network manager
|
|
||||||
+ # connection file and ifcfg files are absent, return None.
|
|
||||||
+ if not os.path.isfile(conn_file) and available_nm_ifcfg_rh():
|
|
||||||
+ conn_file = sysconfig_conn_filename(devname)
|
|
||||||
+ return conn_file if os.path.isfile(conn_file) else None
|
|
||||||
+
|
|
||||||
+
|
|
||||||
def cloud_init_nm_conf_filename(target=None):
|
|
||||||
target_con_dir = subp.target_path(target, NM_RUN_DIR)
|
|
||||||
conf_file = "30-cloud-init-ip6-addr-gen-mode.conf"
|
|
@ -1,38 +0,0 @@
|
|||||||
From e5258b60a3dbf44ef1faac91db2b45dab09de0b5 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Brett Holman <brett.holman@canonical.com>
|
|
||||||
Date: Tue, 16 Jan 2024 12:43:17 -0700
|
|
||||||
Subject: [PATCH] test(jsonschema): Pin jsonschema version (#4781)
|
|
||||||
|
|
||||||
Release 4.21.0 broke tests
|
|
||||||
|
|
||||||
(cherry picked from commit 034a5cdf10582da0492321f861b2b8b42182a54e)
|
|
||||||
---
|
|
||||||
requirements.txt | 2 +-
|
|
||||||
test-requirements.txt | 2 +-
|
|
||||||
2 files changed, 2 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/requirements.txt b/requirements.txt
|
|
||||||
index edec46a7..a095de18 100644
|
|
||||||
--- a/requirements.txt
|
|
||||||
+++ b/requirements.txt
|
|
||||||
@@ -28,7 +28,7 @@ requests
|
|
||||||
jsonpatch
|
|
||||||
|
|
||||||
# For validating cloud-config sections per schema definitions
|
|
||||||
-jsonschema
|
|
||||||
+jsonschema<=4.20.0
|
|
||||||
|
|
||||||
# Used by DataSourceVMware to inspect the host's network configuration during
|
|
||||||
# the "setup()" function.
|
|
||||||
diff --git a/test-requirements.txt b/test-requirements.txt
|
|
||||||
index 19488b94..46a98b4c 100644
|
|
||||||
--- a/test-requirements.txt
|
|
||||||
+++ b/test-requirements.txt
|
|
||||||
@@ -9,6 +9,6 @@ pytest!=7.3.2
|
|
||||||
pytest-cov
|
|
||||||
pytest-mock
|
|
||||||
setuptools
|
|
||||||
-jsonschema
|
|
||||||
+jsonschema<=4.20.0
|
|
||||||
responses
|
|
||||||
passlib
|
|
@ -1,121 +0,0 @@
|
|||||||
From 9e8fbb736d5e8db8bcf0fbc35a76bdad9251990a Mon Sep 17 00:00:00 2001
|
|
||||||
From: d1r3ct0r <calvin.mwadime@canonical.com>
|
|
||||||
Date: Sat, 20 Jan 2024 02:11:47 +0300
|
|
||||||
Subject: [PATCH] fix(clean): stop warning when running clean command (#4761)
|
|
||||||
|
|
||||||
When the clean command is run, runparts is called and README in
|
|
||||||
/etc/cloud/clean.d is not executable which leads to a warning.
|
|
||||||
|
|
||||||
No longer deliver the README in our deb package, move content
|
|
||||||
to our online docs. Continue to deliver the /etc/cloud/clean.d
|
|
||||||
directory as it is used by installers like subiquity.
|
|
||||||
|
|
||||||
Fixes: GH-4760
|
|
||||||
(cherry picked from commit da08a260965e35fa63def1cd8b8b472f7c354ffe)
|
|
||||||
|
|
||||||
There is a downstream only change that is squashed with the upstream commit.
|
|
||||||
The spec file under .distro/ has been updated so as to not include
|
|
||||||
/etc/cloud/clean.d/README file. Otherwise, we shall see errors like the
|
|
||||||
following during the build process:
|
|
||||||
|
|
||||||
error: File not found: /builddir/build/.../etc/cloud/clean.d/README
|
|
||||||
|
|
||||||
After a rebase, we can only maintain the downstream spec file change as
|
|
||||||
the rest of it is clean cherry-pick from upstream.
|
|
||||||
|
|
||||||
X-downstream-only: true
|
|
||||||
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
|
||||||
---
|
|
||||||
config/clean.d/README | 18 ------------------
|
|
||||||
doc/rtd/reference/cli.rst | 27 +++++++++++++++++++++++++++
|
|
||||||
packages/redhat/cloud-init.spec.in | 1 -
|
|
||||||
packages/suse/cloud-init.spec.in | 1 -
|
|
||||||
4 files changed, 27 insertions(+), 20 deletions(-)
|
|
||||||
delete mode 100644 config/clean.d/README
|
|
||||||
|
|
||||||
diff --git a/config/clean.d/README b/config/clean.d/README
|
|
||||||
deleted file mode 100644
|
|
||||||
index 9b0feebe..00000000
|
|
||||||
--- a/config/clean.d/README
|
|
||||||
+++ /dev/null
|
|
||||||
@@ -1,18 +0,0 @@
|
|
||||||
--- cloud-init's clean.d run-parts directory --
|
|
||||||
-
|
|
||||||
-This directory is provided for third party applications which need
|
|
||||||
-additional configuration artifact cleanup from the filesystem when
|
|
||||||
-the command `cloud-init clean` is invoked.
|
|
||||||
-
|
|
||||||
-The `cloud-init clean` operation is typically performed by image creators
|
|
||||||
-when preparing a golden image for clone and redeployment. The clean command
|
|
||||||
-removes any cloud-init semaphores, allowing cloud-init to treat the next
|
|
||||||
-boot of this image as the "first boot". When the image is next booted
|
|
||||||
-cloud-init will performing all initial configuration based on any valid
|
|
||||||
-datasource meta-data and user-data.
|
|
||||||
-
|
|
||||||
-Any executable scripts in this subdirectory will be invoked in lexicographical
|
|
||||||
-order with run-parts by the command: sudo cloud-init clean.
|
|
||||||
-
|
|
||||||
-Typical format of such scripts would be a ##-<some-app> like the following:
|
|
||||||
- /etc/cloud/clean.d/99-live-installer
|
|
||||||
diff --git a/doc/rtd/reference/cli.rst b/doc/rtd/reference/cli.rst
|
|
||||||
index 04e05c55..c36775a8 100644
|
|
||||||
--- a/doc/rtd/reference/cli.rst
|
|
||||||
+++ b/doc/rtd/reference/cli.rst
|
|
||||||
@@ -83,6 +83,33 @@ re-run all stages as it did on first boot.
|
|
||||||
config files for ssh daemon. Argument `network` removes all generated
|
|
||||||
config files for network. `all` removes config files of all types.
|
|
||||||
|
|
||||||
+.. note::
|
|
||||||
+
|
|
||||||
+ Cloud-init provides the directory :file:`/etc/cloud/clean.d/` for third party
|
|
||||||
+ applications which need additional configuration artifact cleanup from
|
|
||||||
+ the fileystem when the `clean` command is invoked.
|
|
||||||
+
|
|
||||||
+ The :command:`clean` operation is typically performed by image creators
|
|
||||||
+ when preparing a golden image for clone and redeployment. The clean command
|
|
||||||
+ removes any cloud-init semaphores, allowing cloud-init to treat the next
|
|
||||||
+ boot of this image as the "first boot". When the image is next booted
|
|
||||||
+ cloud-init will performing all initial configuration based on any valid
|
|
||||||
+ datasource meta-data and user-data.
|
|
||||||
+
|
|
||||||
+ Any executable scripts in this subdirectory will be invoked in lexicographical
|
|
||||||
+ order with run-parts when running the :command:`clean` command.
|
|
||||||
+
|
|
||||||
+ Typical format of such scripts would be a ##-<some-app> like the following:
|
|
||||||
+ :file:`/etc/cloud/clean.d/99-live-installer`
|
|
||||||
+
|
|
||||||
+ An example of a script is:
|
|
||||||
+
|
|
||||||
+ .. code-block:: bash
|
|
||||||
+
|
|
||||||
+ sudo rm -rf /var/lib/installer_imgs/
|
|
||||||
+ sudo rm -rf /var/log/installer/
|
|
||||||
+
|
|
||||||
+
|
|
||||||
.. _cli_collect_logs:
|
|
||||||
|
|
||||||
:command:`collect-logs`
|
|
||||||
diff --git a/packages/redhat/cloud-init.spec.in b/packages/redhat/cloud-init.spec.in
|
|
||||||
index 97e95096..accfb1b6 100644
|
|
||||||
--- a/packages/redhat/cloud-init.spec.in
|
|
||||||
+++ b/packages/redhat/cloud-init.spec.in
|
|
||||||
@@ -190,7 +190,6 @@ fi
|
|
||||||
# Configs
|
|
||||||
%config(noreplace) %{_sysconfdir}/cloud/cloud.cfg
|
|
||||||
%dir %{_sysconfdir}/cloud/clean.d
|
|
||||||
-%config(noreplace) %{_sysconfdir}/cloud/clean.d/README
|
|
||||||
%dir %{_sysconfdir}/cloud/cloud.cfg.d
|
|
||||||
%config(noreplace) %{_sysconfdir}/cloud/cloud.cfg.d/*.cfg
|
|
||||||
%config(noreplace) %{_sysconfdir}/cloud/cloud.cfg.d/README
|
|
||||||
diff --git a/packages/suse/cloud-init.spec.in b/packages/suse/cloud-init.spec.in
|
|
||||||
index 62a9129b..fae3c12b 100644
|
|
||||||
--- a/packages/suse/cloud-init.spec.in
|
|
||||||
+++ b/packages/suse/cloud-init.spec.in
|
|
||||||
@@ -115,7 +115,6 @@ version_pys=$(cd "%{buildroot}" && find . -name version.py -type f)
|
|
||||||
|
|
||||||
# Configs
|
|
||||||
%dir %{_sysconfdir}/cloud/clean.d
|
|
||||||
-%config(noreplace) %{_sysconfdir}/cloud/clean.d/README
|
|
||||||
%config(noreplace) %{_sysconfdir}/cloud/cloud.cfg
|
|
||||||
%dir %{_sysconfdir}/cloud/cloud.cfg.d
|
|
||||||
%config(noreplace) %{_sysconfdir}/cloud/cloud.cfg.d/*.cfg
|
|
@ -1,108 +0,0 @@
|
|||||||
From 808cd6f434a4ede1441cc1f5781abf59f53c4153 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: 95: Deprecate the users ssh-authorized-keys property (#5162)
|
|
||||||
RH-Jira: RHEL-45262
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
||||||
RH-Commit: [1/3] 27d6f99519a28ae91037fe47f9ef654b7fbd6236 (anisinha/cloud-init)
|
|
||||||
|
|
||||||
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 8b10fe70..670ef4c2 100644
|
|
||||||
--- a/cloudinit/config/schemas/schema-cloud-config-v1.json
|
|
||||||
+++ b/cloudinit/config/schemas/schema-cloud-config-v1.json
|
|
||||||
@@ -272,6 +272,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``.",
|
|
||||||
"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 f4da0989..8b119025 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
|
|
||||||
|
|
@ -1,147 +0,0 @@
|
|||||||
From 395d0ee0f8f7a226cb04d0f4f2c587fb567275c6 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Ani Sinha <anisinha@redhat.com>
|
|
||||||
Date: Fri, 4 Oct 2024 02:38:23 +0530
|
|
||||||
Subject: [PATCH 1/2] Fix metric setting for ifcfg network connections for rhel
|
|
||||||
(#5777)
|
|
||||||
|
|
||||||
RH-Author: xiachen <xiachen@redhat.com>
|
|
||||||
RH-MergeRequest: 111: Fix metric setting for ifcfg network connections for rhel (#5777)
|
|
||||||
RH-Jira: RHEL-61224
|
|
||||||
RH-Acked-by: Ani Sinha <anisinha@redhat.com>
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Commit: [1/2] b69558d0d021f102e6fbcd9639a455f63624184f (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
|
|
||||||
|
|
||||||
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
|
||||||
(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 7eb430ed..b50a6a8a 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 2d716f4b..4673e4ea 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"""
|
|
||||||
@@ -1521,7 +1521,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"""
|
|
||||||
@@ -5725,24 +5725,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
|
|
||||||
|
|
@ -1,44 +0,0 @@
|
|||||||
From 7f3b0ff968409a880596e04aece4e4c504fb9c64 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Brett Holman <brett.holman@canonical.com>
|
|
||||||
Date: Mon, 29 Jan 2024 12:03:36 -0700
|
|
||||||
Subject: [PATCH] ci: Pin pytest<8.0.0. (#4816)
|
|
||||||
|
|
||||||
The latest pytest release broke some tests in non-obvious ways. Pin
|
|
||||||
the version for now so that CI passes.
|
|
||||||
|
|
||||||
(cherry picked from commit 7c96c9cd9318e816ce4564b58a2c98271363c447)
|
|
||||||
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
|
||||||
---
|
|
||||||
integration-requirements.txt | 2 +-
|
|
||||||
test-requirements.txt | 2 +-
|
|
||||||
2 files changed, 2 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/integration-requirements.txt b/integration-requirements.txt
|
|
||||||
index 1f8b54a5..c0792d63 100644
|
|
||||||
--- a/integration-requirements.txt
|
|
||||||
+++ b/integration-requirements.txt
|
|
||||||
@@ -7,7 +7,7 @@ pycloudlib>=5.10.0,<1!6
|
|
||||||
# test/unittests/conftest.py to be loaded by our integration-tests tox env
|
|
||||||
# resulting in an unmet dependency issue:
|
|
||||||
# https://github.com/pytest-dev/pytest/issues/11104
|
|
||||||
-pytest!=7.3.2
|
|
||||||
+pytest!=7.3.2,<8.0.0
|
|
||||||
|
|
||||||
packaging
|
|
||||||
passlib
|
|
||||||
diff --git a/test-requirements.txt b/test-requirements.txt
|
|
||||||
index 46a98b4c..3d2480fd 100644
|
|
||||||
--- a/test-requirements.txt
|
|
||||||
+++ b/test-requirements.txt
|
|
||||||
@@ -4,7 +4,7 @@
|
|
||||||
# test/unittests/conftest.py to be loaded by our integration-tests tox env
|
|
||||||
# resulting in an unmet dependency issue:
|
|
||||||
# https://github.com/pytest-dev/pytest/issues/11104
|
|
||||||
-pytest!=7.3.2
|
|
||||||
+pytest!=7.3.2,<8.0.0
|
|
||||||
|
|
||||||
pytest-cov
|
|
||||||
pytest-mock
|
|
||||||
--
|
|
||||||
2.39.3
|
|
||||||
|
|
@ -1,248 +0,0 @@
|
|||||||
From 59196e4b797d3e6a34e833d0516dfa0cf6afa3ee 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: 116: Prevent NM from handling DNS when network interfaces have DNS config (#5846)
|
|
||||||
RH-Jira: RHEL-65768
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
||||||
RH-Commit: [1/1] 247ac2b34d3858a03507d29399f3414a4f4db263 (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 | 28 +++++--
|
|
||||||
tests/unittests/test_net.py | 158 ++++++++++++++++++++++++++++++++++++
|
|
||||||
2 files changed, 181 insertions(+), 5 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
|
|
||||||
index e4a65187..4898a2fd 100644
|
|
||||||
--- a/cloudinit/net/sysconfig.py
|
|
||||||
+++ b/cloudinit/net/sysconfig.py
|
|
||||||
@@ -905,17 +905,35 @@ class Renderer(renderer.Renderer):
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def _render_networkmanager_conf(network_state, templates=None):
|
|
||||||
+ iface_dns = False
|
|
||||||
content = networkmanager_conf.NetworkManagerConf("")
|
|
||||||
-
|
|
||||||
- # If DNS server information is provided, configure
|
|
||||||
- # NetworkManager to not manage dns, so that /etc/resolv.conf
|
|
||||||
- # does not get clobbered.
|
|
||||||
+ # check if there is interface specific DNS information configured
|
|
||||||
+ for iface in network_state.iter_interfaces():
|
|
||||||
+ for subnet in iface["subnets"]:
|
|
||||||
+ 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 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 ddb45dc6..47b36d05 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
|
|
||||||
|
|
@ -1,65 +0,0 @@
|
|||||||
From cc31dc321ae35995ceff93e67aaf0b0c660aa890 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Ani Sinha <anisinha@redhat.com>
|
|
||||||
Date: Tue, 12 Mar 2024 12:52:10 +0530
|
|
||||||
Subject: [PATCH] Retain exit code in cloud-init status for recoverable errors
|
|
||||||
|
|
||||||
RH-Author: Ani Sinha <None>
|
|
||||||
RH-MergeRequest: 71: Retain exit code in cloud-init status for recoverable errors
|
|
||||||
RH-Jira: RHEL-28549
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Acked-by: Cathy Avery <cavery@redhat.com>
|
|
||||||
RH-Commit: [1/1] 00934ade88c481c012bc1947fa44e5ed59f82858 (anisinha/cloud-init)
|
|
||||||
|
|
||||||
Version 23.4 of cloud-init changed the status code reported by cloud-init for
|
|
||||||
recoverable errors from 0 to 2. Please see the commit
|
|
||||||
70acb7f2a30d58 ("Add support for cloud-init "degraded" state (#4500)")
|
|
||||||
|
|
||||||
This change has the potential to break customers who are expecting a 0 status
|
|
||||||
and where warnings can be expected. Hence, revert the status code from 2 to 0
|
|
||||||
even in case of recoverable errors. This retains the old behavior and hence
|
|
||||||
avoids breaking scripts and software stack that expects 0 on the end user side.
|
|
||||||
|
|
||||||
Cannonical has made a similar change downstream for similar reasons. Please see
|
|
||||||
https://bugs.launchpad.net/ubuntu/+source/cloud-init/+bug/2048522
|
|
||||||
and the corresponding downstream patch:
|
|
||||||
https://github.com/canonical/cloud-init/pull/4747/commits/adce34bfd214e4eecdf87329486f30f0898dd303
|
|
||||||
|
|
||||||
This patch has limited risk as it narrowly only restores the old status
|
|
||||||
code for recoverable errors and does not modify anything else.
|
|
||||||
|
|
||||||
X-downstream-only: true
|
|
||||||
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
|
||||||
---
|
|
||||||
cloudinit/cmd/status.py | 2 +-
|
|
||||||
tests/unittests/cmd/test_status.py | 2 +-
|
|
||||||
2 files changed, 2 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/cloudinit/cmd/status.py b/cloudinit/cmd/status.py
|
|
||||||
index f5ee9c11..849c80bc 100644
|
|
||||||
--- a/cloudinit/cmd/status.py
|
|
||||||
+++ b/cloudinit/cmd/status.py
|
|
||||||
@@ -225,7 +225,7 @@ def handle_status_args(name, args) -> int:
|
|
||||||
return 1
|
|
||||||
# Recoverable error
|
|
||||||
elif details.status in UXAppStatusDegradedMap.values():
|
|
||||||
- return 2
|
|
||||||
+ return 0
|
|
||||||
return 0
|
|
||||||
|
|
||||||
|
|
||||||
diff --git a/tests/unittests/cmd/test_status.py b/tests/unittests/cmd/test_status.py
|
|
||||||
index 6c85a59a..567b517a 100644
|
|
||||||
--- a/tests/unittests/cmd/test_status.py
|
|
||||||
+++ b/tests/unittests/cmd/test_status.py
|
|
||||||
@@ -636,7 +636,7 @@ PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin
|
|
||||||
},
|
|
||||||
None,
|
|
||||||
MyArgs(long=False, wait=False, format="json"),
|
|
||||||
- 2,
|
|
||||||
+ 0,
|
|
||||||
{
|
|
||||||
"boot_status_code": "enabled-by-kernel-cmdline",
|
|
||||||
"datasource": "nocloud",
|
|
||||||
--
|
|
||||||
2.39.3
|
|
||||||
|
|
@ -1,242 +0,0 @@
|
|||||||
From 72b2deeafd9276d15f20831f01b2f8c44616f33d Mon Sep 17 00:00:00 2001
|
|
||||||
From: Brett Holman <brett.holman@canonical.com>
|
|
||||||
Date: Tue, 23 Jan 2024 11:47:35 -0700
|
|
||||||
Subject: [PATCH] Revert "Use grep for faster parsing of cloud config in
|
|
||||||
ds-identify (#4327)"
|
|
||||||
|
|
||||||
RH-Author: Ani Sinha <None>
|
|
||||||
RH-MergeRequest: 67: Revert "Use grep for faster parsing of cloud config in ds-identify (#4327)"
|
|
||||||
RH-Jira: RHEL-22255
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
||||||
RH-Commit: [1/1] 5997598254cd16ea7f26d87212b0f09920fcdf50 (anisinha/cloud-init)
|
|
||||||
|
|
||||||
This reverts commit 816e05d4830f5e789f1f85ef926e2849156bff3a.
|
|
||||||
|
|
||||||
Reopens LP: 2030729
|
|
||||||
Fixes GH-4794
|
|
||||||
|
|
||||||
(cherry picked from commit 8ff94fe9493ad88344eb8bbf2f023c6ba2db5206)
|
|
||||||
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
|
||||||
---
|
|
||||||
tests/unittests/test_ds_identify.py | 146 +---------------------------
|
|
||||||
tools/ds-identify | 31 +++---
|
|
||||||
2 files changed, 15 insertions(+), 162 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/tests/unittests/test_ds_identify.py b/tests/unittests/test_ds_identify.py
|
|
||||||
index ca206fb5..ba0bf779 100644
|
|
||||||
--- a/tests/unittests/test_ds_identify.py
|
|
||||||
+++ b/tests/unittests/test_ds_identify.py
|
|
||||||
@@ -57,146 +57,6 @@ BLKID_UEFI_UBUNTU = [
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
-DEFAULT_CLOUD_CONFIG = """\
|
|
||||||
-# The top level settings are used as module
|
|
||||||
-# and base configuration.
|
|
||||||
-# A set of users which may be applied and/or used by various modules
|
|
||||||
-# when a 'default' entry is found it will reference the 'default_user'
|
|
||||||
-# from the distro configuration specified below
|
|
||||||
-users:
|
|
||||||
- - default
|
|
||||||
-
|
|
||||||
-# If this is set, 'root' will not be able to ssh in and they
|
|
||||||
-# will get a message to login instead as the default $user
|
|
||||||
-disable_root: true
|
|
||||||
-
|
|
||||||
-# This will cause the set+update hostname module to not operate (if true)
|
|
||||||
-preserve_hostname: false
|
|
||||||
-
|
|
||||||
-# If you use datasource_list array, keep array items in a single line.
|
|
||||||
-# If you use multi line array, ds-identify script won't read array items.
|
|
||||||
-# Example datasource config
|
|
||||||
-# datasource:
|
|
||||||
-# Ec2:
|
|
||||||
-# metadata_urls: [ 'blah.com' ]
|
|
||||||
-# timeout: 5 # (defaults to 50 seconds)
|
|
||||||
-# max_wait: 10 # (defaults to 120 seconds)
|
|
||||||
-
|
|
||||||
-# The modules that run in the 'init' stage
|
|
||||||
-cloud_init_modules:
|
|
||||||
- - migrator
|
|
||||||
- - seed_random
|
|
||||||
- - bootcmd
|
|
||||||
- - write-files
|
|
||||||
- - growpart
|
|
||||||
- - resizefs
|
|
||||||
- - disk_setup
|
|
||||||
- - mounts
|
|
||||||
- - set_hostname
|
|
||||||
- - update_hostname
|
|
||||||
- - update_etc_hosts
|
|
||||||
- - ca-certs
|
|
||||||
- - rsyslog
|
|
||||||
- - users-groups
|
|
||||||
- - ssh
|
|
||||||
-
|
|
||||||
-# The modules that run in the 'config' stage
|
|
||||||
-cloud_config_modules:
|
|
||||||
- - wireguard
|
|
||||||
- - snap
|
|
||||||
- - ubuntu_autoinstall
|
|
||||||
- - ssh-import-id
|
|
||||||
- - keyboard
|
|
||||||
- - locale
|
|
||||||
- - set-passwords
|
|
||||||
- - grub-dpkg
|
|
||||||
- - apt-pipelining
|
|
||||||
- - apt-configure
|
|
||||||
- - ubuntu-advantage
|
|
||||||
- - ntp
|
|
||||||
- - timezone
|
|
||||||
- - disable-ec2-metadata
|
|
||||||
- - runcmd
|
|
||||||
- - byobu
|
|
||||||
-
|
|
||||||
-# The modules that run in the 'final' stage
|
|
||||||
-cloud_final_modules:
|
|
||||||
- - package-update-upgrade-install
|
|
||||||
- - fan
|
|
||||||
- - landscape
|
|
||||||
- - lxd
|
|
||||||
- - ubuntu-drivers
|
|
||||||
- - write-files-deferred
|
|
||||||
- - puppet
|
|
||||||
- - chef
|
|
||||||
- - ansible
|
|
||||||
- - mcollective
|
|
||||||
- - salt-minion
|
|
||||||
- - reset_rmc
|
|
||||||
- - refresh_rmc_and_interface
|
|
||||||
- - rightscale_userdata
|
|
||||||
- - scripts-vendor
|
|
||||||
- - scripts-per-once
|
|
||||||
- - scripts-per-boot
|
|
||||||
- - scripts-per-instance
|
|
||||||
- - scripts-user
|
|
||||||
- - ssh-authkey-fingerprints
|
|
||||||
- - keys-to-console
|
|
||||||
- - install-hotplug
|
|
||||||
- - phone-home
|
|
||||||
- - final-message
|
|
||||||
- - power-state-change
|
|
||||||
-
|
|
||||||
-# System and/or distro specific settings
|
|
||||||
-# (not accessible to handlers/transforms)
|
|
||||||
-system_info:
|
|
||||||
- # This will affect which distro class gets used
|
|
||||||
- distro: ubuntu
|
|
||||||
- # Default user name + that default users groups (if added/used)
|
|
||||||
- default_user:
|
|
||||||
- name: ubuntu
|
|
||||||
- lock_passwd: True
|
|
||||||
- gecos: Ubuntu
|
|
||||||
- groups: [adm, audio, cdrom, floppy, lxd, netdev, plugdev, sudo, video]
|
|
||||||
- sudo: ["ALL=(ALL) NOPASSWD:ALL"]
|
|
||||||
- shell: /bin/bash
|
|
||||||
- network:
|
|
||||||
- renderers: ['netplan', 'eni', 'sysconfig']
|
|
||||||
- activators: ['netplan', 'eni', 'network-manager', 'networkd']
|
|
||||||
- # Automatically discover the best ntp_client
|
|
||||||
- ntp_client: auto
|
|
||||||
- # Other config here will be given to the distro class and/or path classes
|
|
||||||
- paths:
|
|
||||||
- cloud_dir: /var/lib/cloud/
|
|
||||||
- templates_dir: /etc/cloud/templates/
|
|
||||||
- package_mirrors:
|
|
||||||
- - arches: [i386, amd64]
|
|
||||||
- failsafe:
|
|
||||||
- primary: http://archive.ubuntu.com/ubuntu
|
|
||||||
- security: http://security.ubuntu.com/ubuntu
|
|
||||||
- search:
|
|
||||||
- primary:
|
|
||||||
- - http://%(ec2_region)s.ec2.archive.ubuntu.com/ubuntu/
|
|
||||||
- - http://%(availability_zone)s.clouds.archive.ubuntu.com/ubuntu/
|
|
||||||
- - http://%(region)s.clouds.archive.ubuntu.com/ubuntu/
|
|
||||||
- security: []
|
|
||||||
- - arches: [arm64, armel, armhf]
|
|
||||||
- failsafe:
|
|
||||||
- primary: http://ports.ubuntu.com/ubuntu-ports
|
|
||||||
- security: http://ports.ubuntu.com/ubuntu-ports
|
|
||||||
- search:
|
|
||||||
- primary:
|
|
||||||
- - http://%(ec2_region)s.ec2.ports.ubuntu.com/ubuntu-ports/
|
|
||||||
- - http://%(availability_zone)s.clouds.ports.ubuntu.com/ubuntu-ports/
|
|
||||||
- - http://%(region)s.clouds.ports.ubuntu.com/ubuntu-ports/
|
|
||||||
- security: []
|
|
||||||
- - arches: [default]
|
|
||||||
- failsafe:
|
|
||||||
- primary: http://ports.ubuntu.com/ubuntu-ports
|
|
||||||
- security: http://ports.ubuntu.com/ubuntu-ports
|
|
||||||
- ssh_svcname: ssh
|
|
||||||
-"""
|
|
||||||
-
|
|
||||||
POLICY_FOUND_ONLY = "search,found=all,maybe=none,notfound=disabled"
|
|
||||||
POLICY_FOUND_OR_MAYBE = "search,found=all,maybe=all,notfound=disabled"
|
|
||||||
DI_DEFAULT_POLICY = "search,found=all,maybe=all,notfound=disabled"
|
|
||||||
@@ -279,10 +139,6 @@ class DsIdentifyBase(CiTestCase):
|
|
||||||
if files is None:
|
|
||||||
files = {}
|
|
||||||
|
|
||||||
- cloudcfg = "etc/cloud/cloud.cfg"
|
|
||||||
- if cloudcfg not in files:
|
|
||||||
- files[cloudcfg] = DEFAULT_CLOUD_CONFIG
|
|
||||||
-
|
|
||||||
if rootd is None:
|
|
||||||
rootd = self.tmp_dir()
|
|
||||||
|
|
||||||
@@ -1305,7 +1161,7 @@ VALID_CFG = {
|
|
||||||
# Also include a datasource list of more than just
|
|
||||||
# [NoCloud, None], because that would automatically select
|
|
||||||
# NoCloud without checking
|
|
||||||
- "etc/cloud/cloud.cfg": dedent(
|
|
||||||
+ "/etc/cloud/cloud.cfg": dedent(
|
|
||||||
"""\
|
|
||||||
datasource_list: [ Azure, Openstack, NoCloud, None ]
|
|
||||||
datasource:
|
|
||||||
diff --git a/tools/ds-identify b/tools/ds-identify
|
|
||||||
index 7a537278..ec2cc18a 100755
|
|
||||||
--- a/tools/ds-identify
|
|
||||||
+++ b/tools/ds-identify
|
|
||||||
@@ -777,24 +777,21 @@ check_config() {
|
|
||||||
if [ "$1" = "$files" -a ! -f "$1" ]; then
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
- local line="" ret="" found=0 found_fn="" oifs="$IFS" out=""
|
|
||||||
- out=$(grep "$key\"\?:" "$@" 2>/dev/null)
|
|
||||||
- IFS=${CR}
|
|
||||||
- for line in $out; do
|
|
||||||
- # drop '# comment'
|
|
||||||
- line=${line%%#*}
|
|
||||||
- # if more than one file was 'grep'ed, then grep will output filename:
|
|
||||||
- # but if only one file, line will not be prefixed.
|
|
||||||
- if [ $# -eq 1 ]; then
|
|
||||||
- found_fn="$1"
|
|
||||||
- else
|
|
||||||
- found_fn="${line%%:*}"
|
|
||||||
- line=${line#*:}
|
|
||||||
- fi
|
|
||||||
- ret=${line#*: };
|
|
||||||
- found=$((found+1))
|
|
||||||
+ local fname="" line="" ret="" found=0 found_fn=""
|
|
||||||
+ # shellcheck disable=2094
|
|
||||||
+ for fname in "$@"; do
|
|
||||||
+ [ -f "$fname" ] || continue
|
|
||||||
+ while read line; do
|
|
||||||
+ line=${line%%#*}
|
|
||||||
+ case "$line" in
|
|
||||||
+ $key:\ *|"${key}":)
|
|
||||||
+ ret=${line#*:};
|
|
||||||
+ ret=${ret# };
|
|
||||||
+ found=$((found+1))
|
|
||||||
+ found_fn="$fname";;
|
|
||||||
+ esac
|
|
||||||
+ done <"$fname"
|
|
||||||
done
|
|
||||||
- IFS="$oifs"
|
|
||||||
if [ $found -ne 0 ]; then
|
|
||||||
_RET="$ret"
|
|
||||||
_RET_fname="$found_fn"
|
|
||||||
--
|
|
||||||
2.39.3
|
|
||||||
|
|
@ -1,190 +0,0 @@
|
|||||||
From 87db4f8680222d2579d0ffb5fe507231f88d8aa5 Mon Sep 17 00:00:00 2001
|
|
||||||
From: PengpengSun <40026211+PengpengSun@users.noreply.github.com>
|
|
||||||
Date: Sat, 10 Aug 2024 03:32:40 +0800
|
|
||||||
Subject: [PATCH] Revert "fix(vmware): Set IPv6 to dhcp when there is no IPv6
|
|
||||||
addr (#5471)" (#5596)
|
|
||||||
|
|
||||||
RH-Author: xiachen <xiachen@redhat.com>
|
|
||||||
RH-MergeRequest: 108: Revert "fix(vmware): Set IPv6 to dhcp when there is no IPv6 addr (#5471)" (#5596)
|
|
||||||
RH-Jira: RHEL-54373
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
||||||
RH-Commit: [1/1] 96cccfca3d29c95d9c491d5995b7aa96adec4621 (xiachen/cloud-init-centos)
|
|
||||||
|
|
||||||
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 25d3b093..b53ea96c 100644
|
|
||||||
--- a/tests/unittests/sources/vmware/test_vmware_config_file.py
|
|
||||||
+++ b/tests/unittests/sources/vmware/test_vmware_config_file.py
|
|
||||||
@@ -240,45 +240,27 @@ class TestVmwareConfigFile(CiTestCase):
|
|
||||||
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
|
|
||||||
@@ -303,7 +285,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(
|
|
||||||
@@ -363,7 +344,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(
|
|
||||||
@@ -371,18 +351,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")
|
|
||||||
@@ -469,10 +447,7 @@ class TestVmwareNetConfig(CiTestCase):
|
|
||||||
"type": "static",
|
|
||||||
"address": "10.20.87.154",
|
|
||||||
"netmask": "255.255.252.0",
|
|
||||||
- },
|
|
||||||
- {
|
|
||||||
- "type": "dhcp6",
|
|
||||||
- },
|
|
||||||
+ }
|
|
||||||
],
|
|
||||||
}
|
|
||||||
],
|
|
||||||
@@ -523,10 +498,7 @@ class TestVmwareNetConfig(CiTestCase):
|
|
||||||
"metric": 10000,
|
|
||||||
}
|
|
||||||
],
|
|
||||||
- },
|
|
||||||
- {
|
|
||||||
- "type": "dhcp6",
|
|
||||||
- },
|
|
||||||
+ }
|
|
||||||
],
|
|
||||||
}
|
|
||||||
],
|
|
||||||
@@ -586,10 +558,7 @@ class TestVmwareNetConfig(CiTestCase):
|
|
||||||
"metric": 10000,
|
|
||||||
}
|
|
||||||
],
|
|
||||||
- },
|
|
||||||
- {
|
|
||||||
- "type": "dhcp6",
|
|
||||||
- },
|
|
||||||
+ }
|
|
||||||
],
|
|
||||||
}
|
|
||||||
],
|
|
||||||
@@ -634,10 +603,7 @@ class TestVmwareNetConfig(CiTestCase):
|
|
||||||
"address": "10.20.87.154",
|
|
||||||
"netmask": "255.255.252.0",
|
|
||||||
"gateway": "10.20.87.253",
|
|
||||||
- },
|
|
||||||
- {
|
|
||||||
- "type": "dhcp6",
|
|
||||||
- },
|
|
||||||
+ }
|
|
||||||
],
|
|
||||||
}
|
|
||||||
],
|
|
||||||
--
|
|
||||||
2.39.3
|
|
||||||
|
|
@ -1,140 +0,0 @@
|
|||||||
From 96b10adc942f5117e35584d28ba88071849e8e29 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Ani Sinha <anisinha@redhat.com>
|
|
||||||
Date: Thu, 27 Jun 2024 18:38:22 +0530
|
|
||||||
Subject: [PATCH 1/2] Support metalink in yum repository config (#5444)
|
|
||||||
|
|
||||||
RH-Author: xiachen <xiachen@redhat.com>
|
|
||||||
RH-MergeRequest: 97: Support metalink in yum repository config (#5444)
|
|
||||||
RH-Jira: RHEL-44916
|
|
||||||
RH-Acked-by: Ani Sinha <anisinha@redhat.com>
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Commit: [1/1] 4671fd3a3f6842f1f590d5a89a429facd0d8bb4d (xiachen/cloud-init-centos)
|
|
||||||
|
|
||||||
'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 d2c2912f..1f27d1fb 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_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_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
|
|
||||||
|
|
@ -1,145 +0,0 @@
|
|||||||
From d27ac077dac3474fea3c7bb1a19afe50ecbcc64d Mon Sep 17 00:00:00 2001
|
|
||||||
From: Ani Sinha <anisinha@redhat.com>
|
|
||||||
Date: Thu, 18 Jul 2024 13:36:39 +0530
|
|
||||||
Subject: [PATCH 2/2] Support setting mirrorlist in yum repository config
|
|
||||||
(#5522)
|
|
||||||
|
|
||||||
RH-Author: xiachen <xiachen@redhat.com>
|
|
||||||
RH-MergeRequest: 104: Support setting mirrorlist in yum repository config (#5522)
|
|
||||||
RH-Jira: RHEL-49674
|
|
||||||
RH-Acked-by: Ani Sinha <anisinha@redhat.com>
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Commit: [1/1] 4605a0304c6bed6614990b7194465230afa79778 (xiachen/cloud-init-centos)
|
|
||||||
|
|
||||||
'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 4fb7fd93..c5f46f37 100644
|
|
||||||
--- a/cloudinit/config/schemas/schema-cloud-config-v1.json
|
|
||||||
+++ b/cloudinit/config/schemas/schema-cloud-config-v1.json
|
|
||||||
@@ -3447,6 +3447,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."
|
|
||||||
@@ -3484,6 +3489,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 1f27d1fb..000792b4 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_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
|
|
||||||
|
|
@ -1,235 +0,0 @@
|
|||||||
From c34f5c4275c3ef7bee9a99e87bf6e37c5886b160 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Ani Sinha <anisinha@redhat.com>
|
|
||||||
Date: Wed, 29 May 2024 03:34:38 +0530
|
|
||||||
Subject: [PATCH 6/6] Update pylint version to support python 3.12 (#5338)
|
|
||||||
|
|
||||||
RH-Author: Ani Sinha <anisinha@redhat.com>
|
|
||||||
RH-MergeRequest: 92: Update pylint version to support python 3.12
|
|
||||||
RH-Jira: RHEL-44598
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
||||||
RH-Commit: [3/3] d6185e0a126e1589260ee59709fe933b5a780b78 (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)
|
|
||||||
|
|
||||||
Conflicts:
|
|
||||||
cloudinit/sources/DataSourceWSL.py (does not exist)
|
|
||||||
cloudinit/util.py (doc added upstream)
|
|
||||||
---
|
|
||||||
cloudinit/config/cc_mounts.py | 4 ++++
|
|
||||||
cloudinit/distros/bsd.py | 2 ++
|
|
||||||
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 4efa2a29..d445b440 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 761cf5c4..77e0385f 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 a5678907..b7f3f3d8 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 11c14e20..eb0304c3 100644
|
|
||||||
--- a/cloudinit/sources/DataSourceAzure.py
|
|
||||||
+++ b/cloudinit/sources/DataSourceAzure.py
|
|
||||||
@@ -51,7 +51,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 9e6bfbd1..384e4074 100644
|
|
||||||
--- a/cloudinit/sources/DataSourceEc2.py
|
|
||||||
+++ b/cloudinit/sources/DataSourceEc2.py
|
|
||||||
@@ -312,6 +312,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()
|
|
||||||
@@ -345,7 +347,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 fa729b7d..ec211a00 100644
|
|
||||||
--- a/tests/integration_tests/conftest.py
|
|
||||||
+++ b/tests/integration_tests/conftest.py
|
|
||||||
@@ -241,7 +241,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."""
|
|
||||||
@@ -250,7 +250,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."""
|
|
||||||
@@ -259,7 +259,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 0a15203c..e26e466c 100644
|
|
||||||
--- a/tests/integration_tests/util.py
|
|
||||||
+++ b/tests/integration_tests/util.py
|
|
||||||
@@ -182,7 +182,7 @@ def wait_for_cloud_init(client: IntegrationInstance, num_retries: int = 30):
|
|
||||||
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 a9444ec5..c9ce5daa 100644
|
|
||||||
--- a/tests/unittests/config/test_cc_ntp.py
|
|
||||||
+++ b/tests/unittests/config/test_cc_ntp.py
|
|
||||||
@@ -248,6 +248,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
|
|
||||||
@@ -263,6 +264,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 c0b19d3c..30a50236 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 519ef63c..de1326d4 100644
|
|
||||||
--- a/tests/unittests/test_util.py
|
|
||||||
+++ b/tests/unittests/test_util.py
|
|
||||||
@@ -1677,6 +1677,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 5f01a9a8..5199ca13 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
|
|
||||||
|
|
@ -1,51 +0,0 @@
|
|||||||
From 52c04e1a523a450dfce70bc441963eb6a026eb59 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Ani Sinha <anisinha@redhat.com>
|
|
||||||
Date: Thu, 20 Jun 2024 11:18:40 +0530
|
|
||||||
Subject: [PATCH 3/6] doc: update examples to reflect alternative ways to
|
|
||||||
provide `sudo` option (#5418)
|
|
||||||
|
|
||||||
RH-Author: Ani Sinha <anisinha@redhat.com>
|
|
||||||
RH-MergeRequest: 90: fix(jsonschema): Add missing sudo definition (#5418)
|
|
||||||
RH-Jira: RHEL-44337
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
||||||
RH-Commit: [2/2] 62eac6d731cb725c32cd0beac0219ecc2b407198 (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
|
|
||||||
|
|
@ -1,166 +0,0 @@
|
|||||||
From c933187af44a5de1d6eafde5dcd48e8ac369cf34 Mon Sep 17 00:00:00 2001
|
|
||||||
From: James Falcon <james.falcon@canonical.com>
|
|
||||||
Date: Thu, 18 Apr 2024 20:21:14 -0500
|
|
||||||
Subject: [PATCH 2/3] docs: Add deprecated system_info to schema (#5168)
|
|
||||||
|
|
||||||
RH-Author: Ani Sinha <anisinha@redhat.com>
|
|
||||||
RH-MergeRequest: 95: Deprecate the users ssh-authorized-keys property (#5162)
|
|
||||||
RH-Jira: RHEL-45262
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
||||||
RH-Commit: [2/3] c4ea6f45ee0997e2f749c290fb8f2ceb8c05c691 (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)
|
|
||||||
|
|
||||||
Conflicts:
|
|
||||||
cloudinit/config/schemas/schema-cloud-config-v1.json
|
|
||||||
- due to change fdefe08ad19cea5eb ("fix: Fix typos (#4850)") not
|
|
||||||
present in downstream.
|
|
||||||
doc/examples/cloud-config-user-groups.txt
|
|
||||||
- due to change 0aa17cd10bdd6 ("docs: set the home directory using homedir, not home (#5101)")
|
|
||||||
not present downstream.
|
|
||||||
tests/unittests/sources/test_vultr.py
|
|
||||||
- due to change 144782a838 ("test: Remove side effects from tests (#5074)") not present
|
|
||||||
downstream.
|
|
||||||
---
|
|
||||||
.../schemas/schema-cloud-config-v1.json | 7 ++++++
|
|
||||||
doc/examples/cloud-config-apt.txt | 23 -------------------
|
|
||||||
doc/examples/cloud-config-user-groups.txt | 12 ++--------
|
|
||||||
tests/data/user_data.1.txt | 10 --------
|
|
||||||
tests/unittests/runs/test_merge_run.py | 16 ++++++++++++-
|
|
||||||
5 files changed, 24 insertions(+), 44 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/cloudinit/config/schemas/schema-cloud-config-v1.json b/cloudinit/config/schemas/schema-cloud-config-v1.json
|
|
||||||
index 670ef4c2..97cf2b74 100644
|
|
||||||
--- a/cloudinit/config/schemas/schema-cloud-config-v1.json
|
|
||||||
+++ b/cloudinit/config/schemas/schema-cloud-config-v1.json
|
|
||||||
@@ -513,6 +513,12 @@
|
|
||||||
},
|
|
||||||
"merge_type": {
|
|
||||||
"$ref": "#/$defs/merge_defintion"
|
|
||||||
+ },
|
|
||||||
+ "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"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
@@ -3905,6 +3911,7 @@
|
|
||||||
"ssh_pwauth": {},
|
|
||||||
"ssh_quiet_keygen": {},
|
|
||||||
"swap": {},
|
|
||||||
+ "system_info": {},
|
|
||||||
"timezone": {},
|
|
||||||
"ubuntu_advantage": {},
|
|
||||||
"updates": {},
|
|
||||||
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 afc256ec..251c5ae5 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)
|
|
||||||
--
|
|
||||||
2.39.3
|
|
||||||
|
|
@ -1,207 +0,0 @@
|
|||||||
From c21351ad9da5aebcb252aa36cbfa92ac16fa9746 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Florian Apolloner <florian@apolloner.eu>
|
|
||||||
Date: Fri, 5 Jan 2024 19:07:12 +0100
|
|
||||||
Subject: [PATCH 2/3] feat: apply global DNS to interfaces in network-manager
|
|
||||||
(#4723)
|
|
||||||
|
|
||||||
RH-Author: Cathy Avery <cavery@redhat.com>
|
|
||||||
RH-MergeRequest: 72: Fixes for cloud-init fails to configure DNS/search domains for network-config v1
|
|
||||||
RH-Jira: RHEL-20964
|
|
||||||
RH-Acked-by: Ani Sinha <anisinha@redhat.com>
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Commit: [2/2] 1d2b10133ec2558e9665f21f53e4b1a898e283a8 (cavery/cloud-init-c-9-s)
|
|
||||||
|
|
||||||
Sometimes DNS settings in cloud configs are specified globally and
|
|
||||||
not per interface / subnet. This results in a configuration without
|
|
||||||
proper nameservers. This was fixed for netplan in d29eeccd and is
|
|
||||||
now also applied to the network-manager renderer.
|
|
||||||
|
|
||||||
Co-authored-by: James Falcon <james.falcon@canonical.com>
|
|
||||||
(cherry picked from commit 0d787d0a262f70ff848b315633742aa8fc45a1de)
|
|
||||||
Signed-off-by: Cathy Avery <cavery@redhat.com>
|
|
||||||
---
|
|
||||||
cloudinit/net/network_manager.py | 52 ++++++++++++++---------
|
|
||||||
tests/unittests/net/test_net_rendering.py | 3 ++
|
|
||||||
tests/unittests/test_net.py | 11 +++++
|
|
||||||
tools/.github-cla-signers | 1 +
|
|
||||||
4 files changed, 47 insertions(+), 20 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/cloudinit/net/network_manager.py b/cloudinit/net/network_manager.py
|
|
||||||
index bd6e6d75..0ba210b7 100644
|
|
||||||
--- a/cloudinit/net/network_manager.py
|
|
||||||
+++ b/cloudinit/net/network_manager.py
|
|
||||||
@@ -246,7 +246,7 @@ class NMConnection:
|
|
||||||
"""
|
|
||||||
return addr.replace("-", ":").upper()
|
|
||||||
|
|
||||||
- def render_interface(self, iface, renderer):
|
|
||||||
+ def render_interface(self, iface, network_state, renderer):
|
|
||||||
"""
|
|
||||||
Integrate information from network state interface information
|
|
||||||
into the connection. Most of the work is done here.
|
|
||||||
@@ -311,7 +311,6 @@ class NMConnection:
|
|
||||||
found_dns_search = []
|
|
||||||
|
|
||||||
# Deal with Layer 3 configuration
|
|
||||||
- use_top_level_dns = "dns" in iface
|
|
||||||
for subnet in iface["subnets"]:
|
|
||||||
family = "ipv6" if subnet_is_ipv6(subnet) else "ipv4"
|
|
||||||
|
|
||||||
@@ -322,26 +321,39 @@ class NMConnection:
|
|
||||||
self.config[family]["gateway"] = subnet["gateway"]
|
|
||||||
for route in subnet["routes"]:
|
|
||||||
self._add_route(route)
|
|
||||||
- if not use_top_level_dns and "dns_nameservers" in subnet:
|
|
||||||
- for nameserver in subnet["dns_nameservers"]:
|
|
||||||
- found_nameservers.append(nameserver)
|
|
||||||
- if not use_top_level_dns and "dns_search" in subnet:
|
|
||||||
- found_dns_search.append(subnet["dns_search"])
|
|
||||||
+ # Add subnet-level DNS
|
|
||||||
+ if "dns_nameservers" in subnet:
|
|
||||||
+ found_nameservers.extend(subnet["dns_nameservers"])
|
|
||||||
+ if "dns_search" in subnet:
|
|
||||||
+ found_dns_search.extend(subnet["dns_search"])
|
|
||||||
if family == "ipv4" and "mtu" in subnet:
|
|
||||||
ipv4_mtu = subnet["mtu"]
|
|
||||||
|
|
||||||
- # Now add our DNS search domains. We add them later because we
|
|
||||||
- # only want them if an IP family has already been defined
|
|
||||||
- if use_top_level_dns:
|
|
||||||
- for nameserver in iface["dns"]["nameservers"]:
|
|
||||||
- self._add_nameserver(nameserver)
|
|
||||||
- if iface["dns"]["search"]:
|
|
||||||
- self._add_dns_search(iface["dns"]["search"])
|
|
||||||
- else:
|
|
||||||
- for nameserver in found_nameservers:
|
|
||||||
- self._add_nameserver(nameserver)
|
|
||||||
- for dns_search in found_dns_search:
|
|
||||||
- self._add_dns_search(dns_search)
|
|
||||||
+ # Add interface-level DNS
|
|
||||||
+ if "dns" in iface:
|
|
||||||
+ found_nameservers += [
|
|
||||||
+ dns
|
|
||||||
+ for dns in iface["dns"]["nameservers"]
|
|
||||||
+ if dns not in found_nameservers
|
|
||||||
+ ]
|
|
||||||
+ found_dns_search += [
|
|
||||||
+ search
|
|
||||||
+ for search in iface["dns"]["search"]
|
|
||||||
+ if search not in found_dns_search
|
|
||||||
+ ]
|
|
||||||
+
|
|
||||||
+ # We prefer any interface-specific DNS entries, but if we do not
|
|
||||||
+ # have any, add the global DNS to the connection
|
|
||||||
+ if not found_nameservers and network_state.dns_nameservers:
|
|
||||||
+ found_nameservers = network_state.dns_nameservers
|
|
||||||
+ if not found_dns_search and network_state.dns_searchdomains:
|
|
||||||
+ found_dns_search = network_state.dns_searchdomains
|
|
||||||
+
|
|
||||||
+ # Write out all DNS entries to the connection
|
|
||||||
+ for nameserver in found_nameservers:
|
|
||||||
+ self._add_nameserver(nameserver)
|
|
||||||
+ if found_dns_search:
|
|
||||||
+ self._add_dns_search(found_dns_search)
|
|
||||||
|
|
||||||
# we do not want to set may-fail to false for both ipv4 and ipv6 dhcp
|
|
||||||
# at the at the same time. This will make the network configuration
|
|
||||||
@@ -457,7 +469,7 @@ class Renderer(renderer.Renderer):
|
|
||||||
# Now render the actual interface configuration
|
|
||||||
for iface in network_state.iter_interfaces():
|
|
||||||
conn = self.connections[iface["name"]]
|
|
||||||
- conn.render_interface(iface, self)
|
|
||||||
+ conn.render_interface(iface, network_state, self)
|
|
||||||
|
|
||||||
# And finally write the files
|
|
||||||
for con_id, conn in self.connections.items():
|
|
||||||
diff --git a/tests/unittests/net/test_net_rendering.py b/tests/unittests/net/test_net_rendering.py
|
|
||||||
index 06feab89..f340ffc1 100644
|
|
||||||
--- a/tests/unittests/net/test_net_rendering.py
|
|
||||||
+++ b/tests/unittests/net/test_net_rendering.py
|
|
||||||
@@ -88,6 +88,9 @@ def _check_network_manager(network_state: NetworkState, tmp_path: Path):
|
|
||||||
"test_name, renderers",
|
|
||||||
[("no_matching_mac_v2", Renderer.Netplan | Renderer.NetworkManager)],
|
|
||||||
)
|
|
||||||
+@pytest.mark.xfail(
|
|
||||||
+ reason="v2 interface-specific DNS errantly gets applied globally"
|
|
||||||
+)
|
|
||||||
def test_convert(test_name, renderers, tmp_path):
|
|
||||||
network_config = safeyaml.load(
|
|
||||||
Path(ARTIFACT_DIR, f"{test_name}.yaml").read_text()
|
|
||||||
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
|
|
||||||
index 2a99f150..d7c9a414 100644
|
|
||||||
--- a/tests/unittests/test_net.py
|
|
||||||
+++ b/tests/unittests/test_net.py
|
|
||||||
@@ -646,6 +646,7 @@ method=manual
|
|
||||||
may-fail=false
|
|
||||||
address1=172.19.1.34/22
|
|
||||||
route1=0.0.0.0/0,172.19.3.254
|
|
||||||
+dns=172.19.0.12;
|
|
||||||
|
|
||||||
""".lstrip(),
|
|
||||||
),
|
|
||||||
@@ -2797,6 +2798,8 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
|
|
||||||
[ipv4]
|
|
||||||
method=auto
|
|
||||||
may-fail=false
|
|
||||||
+ dns=8.8.8.8;4.4.4.4;8.8.4.4;
|
|
||||||
+ dns-search=barley.maas;wark.maas;foobar.maas;
|
|
||||||
|
|
||||||
"""
|
|
||||||
),
|
|
||||||
@@ -2822,6 +2825,8 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
|
|
||||||
method=manual
|
|
||||||
may-fail=false
|
|
||||||
address1=192.168.200.7/24
|
|
||||||
+ dns=8.8.8.8;4.4.4.4;8.8.4.4;
|
|
||||||
+ dns-search=barley.maas;wark.maas;foobar.maas;
|
|
||||||
|
|
||||||
"""
|
|
||||||
),
|
|
||||||
@@ -2846,6 +2851,8 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
|
|
||||||
[ipv4]
|
|
||||||
method=auto
|
|
||||||
may-fail=false
|
|
||||||
+ dns=8.8.8.8;4.4.4.4;8.8.4.4;
|
|
||||||
+ dns-search=barley.maas;wark.maas;foobar.maas;
|
|
||||||
|
|
||||||
"""
|
|
||||||
),
|
|
||||||
@@ -2930,12 +2937,15 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
|
|
||||||
method=manual
|
|
||||||
may-fail=false
|
|
||||||
address1=192.168.14.2/24
|
|
||||||
+ dns=8.8.8.8;4.4.4.4;8.8.4.4;
|
|
||||||
+ dns-search=barley.maas;wark.maas;foobar.maas;
|
|
||||||
|
|
||||||
[ipv6]
|
|
||||||
method=manual
|
|
||||||
may-fail=false
|
|
||||||
address1=2001:1::1/64
|
|
||||||
route1=::/0,2001:4800:78ff:1b::1
|
|
||||||
+ dns-search=barley.maas;wark.maas;foobar.maas;
|
|
||||||
|
|
||||||
"""
|
|
||||||
),
|
|
||||||
@@ -2990,6 +3000,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
|
|
||||||
[ipv6]
|
|
||||||
method=auto
|
|
||||||
may-fail=false
|
|
||||||
+ dns-search=barley.maas;wark.maas;foobar.maas;
|
|
||||||
|
|
||||||
"""
|
|
||||||
),
|
|
||||||
diff --git a/tools/.github-cla-signers b/tools/.github-cla-signers
|
|
||||||
index dbdb9cfa..f4da0989 100644
|
|
||||||
--- a/tools/.github-cla-signers
|
|
||||||
+++ b/tools/.github-cla-signers
|
|
||||||
@@ -13,6 +13,7 @@ andrewbogott
|
|
||||||
andrewlukoshko
|
|
||||||
ani-sinha
|
|
||||||
antonyc
|
|
||||||
+apollo13
|
|
||||||
aswinrajamannar
|
|
||||||
bdrung
|
|
||||||
beantaxi
|
|
||||||
--
|
|
||||||
2.39.3
|
|
||||||
|
|
@ -1,351 +0,0 @@
|
|||||||
From 6b32b371bfd37759ddce3d7f29d15546500698e6 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Ani Sinha <anisinha@redhat.com>
|
|
||||||
Date: Thu, 20 Jun 2024 22:27:03 +0530
|
|
||||||
Subject: [PATCH 1/6] feat(sysconfig): Add DNS from interface config to
|
|
||||||
resolv.conf (#5401)
|
|
||||||
|
|
||||||
RH-Author: Ani Sinha <anisinha@redhat.com>
|
|
||||||
RH-MergeRequest: 88: feat(sysconfig): Add DNS from interface config to resolv.conf (#5401)
|
|
||||||
RH-Jira: RHEL-17961
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
||||||
RH-Commit: [1/1] f353b73cc0f4bb9e1aee037708a1d3cb23b83cc3 (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 d39f4fe3..7eb430ed 100644
|
|
||||||
--- a/cloudinit/net/sysconfig.py
|
|
||||||
+++ b/cloudinit/net/sysconfig.py
|
|
||||||
@@ -825,20 +825,62 @@ 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
|
|
||||||
content = resolv_conf.ResolvConf("")
|
|
||||||
if existing_dns_path and os.path.isfile(existing_dns_path):
|
|
||||||
content = resolv_conf.ResolvConf(util.load_file(existing_dns_path))
|
|
||||||
- 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 d7c9a414..2d716f4b 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
|
|
||||||
|
|
@ -1,45 +0,0 @@
|
|||||||
From 6a61ce0f0cde11551bfe92835d0b33c7b1022b68 Mon Sep 17 00:00:00 2001
|
|
||||||
From: James Falcon <james.falcon@canonical.com>
|
|
||||||
Date: Thu, 18 Apr 2024 20:27:27 -0500
|
|
||||||
Subject: [PATCH] fix: Add subnet ipv4/ipv6 to network schema (#5191)
|
|
||||||
|
|
||||||
RH-Author: Ani Sinha <anisinha@redhat.com>
|
|
||||||
RH-MergeRequest: 109: fix: Add subnet ipv4/ipv6 to network schema (#5191)
|
|
||||||
RH-Jira: RHEL-54686
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Acked-by: Cathy Avery <cavery@redhat.com>
|
|
||||||
RH-Commit: [1/1] 83692fac8f9af1831970091bdf7c43d0e59f314c (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 64c492a4..f485c784 100644
|
|
||||||
--- a/cloudinit/config/schemas/schema-network-config-v1.json
|
|
||||||
+++ b/cloudinit/config/schemas/schema-network-config-v1.json
|
|
||||||
@@ -523,6 +523,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
|
|
||||||
|
|
@ -1,110 +0,0 @@
|
|||||||
From 2f7f3dc6237ea70825dcb70f71d9718f631a9d95 Mon Sep 17 00:00:00 2001
|
|
||||||
From: James Falcon <james.falcon@canonical.com>
|
|
||||||
Date: Tue, 6 Feb 2024 09:24:37 -0600
|
|
||||||
Subject: [PATCH] fix: Add types to network v1 schema (#4841)
|
|
||||||
|
|
||||||
RH-Author: Cathy Avery <cavery@redhat.com>
|
|
||||||
RH-MergeRequest: 69: fix: Add types to network v1 schema (#4841)
|
|
||||||
RH-Jira: RHEL-21324
|
|
||||||
RH-Acked-by: Ani Sinha <None>
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Commit: [1/1] 59b2b4b07dd9eed956943a22b90af487f18b4cbd (cavery/cloud-init-c-9-s)
|
|
||||||
|
|
||||||
Conflicts:
|
|
||||||
No log argument as we are not including commit e168b4a1383b6eae9c1dc81411d7684fcbbf7df9
|
|
||||||
|
|
||||||
Even though it has conflicted with our documentation, we have allowed
|
|
||||||
nameserver address to a be a string, mtu to be empty, and nameserver
|
|
||||||
search to be missing. Since we have allowed these, expand our schema
|
|
||||||
and documentation accordingly.
|
|
||||||
|
|
||||||
Fixes GH-4710
|
|
||||||
|
|
||||||
(cherry picked from commit b08193b376552ede5d162d8283310adc783d81bf)
|
|
||||||
Signed-off-by: Cathy Avery <cavery@redhat.com>
|
|
||||||
---
|
|
||||||
.../config/schemas/schema-network-config-v1.json | 13 +++++++++----
|
|
||||||
doc/rtd/reference/network-config-format-v1.rst | 4 ++--
|
|
||||||
tests/unittests/config/test_schema.py | 13 +++++++++++++
|
|
||||||
3 files changed, 24 insertions(+), 6 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/cloudinit/config/schemas/schema-network-config-v1.json b/cloudinit/config/schemas/schema-network-config-v1.json
|
|
||||||
index c77885ec..56dc27c9 100644
|
|
||||||
--- a/cloudinit/config/schemas/schema-network-config-v1.json
|
|
||||||
+++ b/cloudinit/config/schemas/schema-network-config-v1.json
|
|
||||||
@@ -24,7 +24,10 @@
|
|
||||||
"description": "The lowercase MAC address of the physical device."
|
|
||||||
},
|
|
||||||
"mtu": {
|
|
||||||
- "type": "integer",
|
|
||||||
+ "type": [
|
|
||||||
+ "integer",
|
|
||||||
+ "null"
|
|
||||||
+ ],
|
|
||||||
"description": "The MTU size in bytes. The ``mtu`` key represents a device's Maximum Transmission Unit, which is the largest size packet or frame, specified in octets (eight-bit bytes), that can be sent in a packet- or frame-based network. Specifying ``mtu`` is optional. Values too small or too large for a device may be ignored by that device."
|
|
||||||
},
|
|
||||||
"subnets": {
|
|
||||||
@@ -384,8 +387,7 @@
|
|
||||||
"additionalProperties": false,
|
|
||||||
"required": [
|
|
||||||
"type",
|
|
||||||
- "address",
|
|
||||||
- "search"
|
|
||||||
+ "address"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"type": {
|
|
||||||
@@ -396,7 +398,10 @@
|
|
||||||
},
|
|
||||||
"address": {
|
|
||||||
"description": "List of IPv4 or IPv6 address of nameservers.",
|
|
||||||
- "type": "array",
|
|
||||||
+ "type": [
|
|
||||||
+ "array",
|
|
||||||
+ "string"
|
|
||||||
+ ],
|
|
||||||
"items": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
diff --git a/doc/rtd/reference/network-config-format-v1.rst b/doc/rtd/reference/network-config-format-v1.rst
|
|
||||||
index d267eb94..42f2dc22 100644
|
|
||||||
--- a/doc/rtd/reference/network-config-format-v1.rst
|
|
||||||
+++ b/doc/rtd/reference/network-config-format-v1.rst
|
|
||||||
@@ -252,8 +252,8 @@ Users can specify a ``nameserver`` type. Nameserver dictionaries include
|
|
||||||
the following keys:
|
|
||||||
|
|
||||||
- ``address``: List of IPv4 or IPv6 address of nameservers.
|
|
||||||
-- ``search``: List of hostnames to include in the :file:`resolv.conf` search
|
|
||||||
- path.
|
|
||||||
+- ``search``: Optional. List of hostnames to include in the :file:`resolv.conf`
|
|
||||||
+ search path.
|
|
||||||
- ``interface``: Optional. Ties the nameserver definition to the specified
|
|
||||||
interface. The value specified here must match the ``name`` of an interface
|
|
||||||
defined in this config. If unspecified, this nameserver will be considered
|
|
||||||
diff --git a/tests/unittests/config/test_schema.py b/tests/unittests/config/test_schema.py
|
|
||||||
index 28f0b39d..52667332 100644
|
|
||||||
--- a/tests/unittests/config/test_schema.py
|
|
||||||
+++ b/tests/unittests/config/test_schema.py
|
|
||||||
@@ -2048,6 +2048,19 @@ class TestNetworkSchema:
|
|
||||||
does_not_raise(),
|
|
||||||
id="bond_with_all_known_properties",
|
|
||||||
),
|
|
||||||
+ pytest.param(
|
|
||||||
+ {
|
|
||||||
+ "network": {
|
|
||||||
+ "version": 1,
|
|
||||||
+ "config": [
|
|
||||||
+ {"type": "physical", "name": "eth0", "mtu": None},
|
|
||||||
+ {"type": "nameserver", "address": "8.8.8.8"},
|
|
||||||
+ ],
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ does_not_raise(),
|
|
||||||
+ id="GH-4710_mtu_none_and_str_address",
|
|
||||||
+ ),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
def test_network_schema(self, src_config, expectation):
|
|
||||||
--
|
|
||||||
2.39.3
|
|
||||||
|
|
@ -1,73 +0,0 @@
|
|||||||
From 8ead44cb39f7726a695aa21a34820f6d40270829 Mon Sep 17 00:00:00 2001
|
|
||||||
From: James Falcon <james.falcon@canonical.com>
|
|
||||||
Date: Mon, 12 Feb 2024 14:48:01 -0600
|
|
||||||
Subject: [PATCH 5/6] fix: Address TIOBE abstract interpretation issues (#4866)
|
|
||||||
|
|
||||||
RH-Author: Ani Sinha <anisinha@redhat.com>
|
|
||||||
RH-MergeRequest: 92: Update pylint version to support python 3.12
|
|
||||||
RH-Jira: RHEL-44598
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
||||||
RH-Commit: [2/3] 3ca11206fa159ab45b2db21e78c4cfaf358b1e01 (anisinha/cloud-init)
|
|
||||||
|
|
||||||
These involve operations on possibly null variables or impossible logic.
|
|
||||||
|
|
||||||
(cherry picked from commit 5e7ef1032a12267a9a518358fbf89da0a88ddb99)
|
|
||||||
---
|
|
||||||
cloudinit/config/cc_lxd.py | 2 +-
|
|
||||||
cloudinit/distros/parsers/ifconfig.py | 6 ++++++
|
|
||||||
cloudinit/util.py | 1 +
|
|
||||||
3 files changed, 8 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/cloudinit/config/cc_lxd.py b/cloudinit/config/cc_lxd.py
|
|
||||||
index cb9fc4f3..9f267b4c 100644
|
|
||||||
--- a/cloudinit/config/cc_lxd.py
|
|
||||||
+++ b/cloudinit/config/cc_lxd.py
|
|
||||||
@@ -432,7 +432,7 @@ def bridge_to_cmd(bridge_cfg):
|
|
||||||
% (bridge_cfg.get("ipv6_address"), bridge_cfg.get("ipv6_netmask"))
|
|
||||||
)
|
|
||||||
|
|
||||||
- if bridge_cfg.get("ipv6_nat", "false") == "true":
|
|
||||||
+ if bridge_cfg.get("ipv6_nat") == "true":
|
|
||||||
cmd_create.append("ipv6.nat=true")
|
|
||||||
|
|
||||||
else:
|
|
||||||
diff --git a/cloudinit/distros/parsers/ifconfig.py b/cloudinit/distros/parsers/ifconfig.py
|
|
||||||
index 516b5eb5..d671df1f 100644
|
|
||||||
--- a/cloudinit/distros/parsers/ifconfig.py
|
|
||||||
+++ b/cloudinit/distros/parsers/ifconfig.py
|
|
||||||
@@ -102,6 +102,7 @@ class Ifconfig:
|
|
||||||
"""
|
|
||||||
ifindex = 0
|
|
||||||
ifs_by_mac = defaultdict(list)
|
|
||||||
+ dev = None
|
|
||||||
for line in text.splitlines():
|
|
||||||
if len(line) == 0:
|
|
||||||
continue
|
|
||||||
@@ -119,6 +120,11 @@ class Ifconfig:
|
|
||||||
dev.index = ifindex
|
|
||||||
self._ifs_by_name[curif] = dev
|
|
||||||
|
|
||||||
+ if not dev:
|
|
||||||
+ # This shouldn't happen with normal ifconfig output, but
|
|
||||||
+ # if it does, ensure we don't Traceback
|
|
||||||
+ continue
|
|
||||||
+
|
|
||||||
toks = line.lower().strip().split()
|
|
||||||
|
|
||||||
if len(toks) > 1 and toks[1].startswith("flags="):
|
|
||||||
diff --git a/cloudinit/util.py b/cloudinit/util.py
|
|
||||||
index 3295735c..5f787c5c 100644
|
|
||||||
--- a/cloudinit/util.py
|
|
||||||
+++ b/cloudinit/util.py
|
|
||||||
@@ -1417,6 +1417,7 @@ def find_devs_with_netbsd(
|
|
||||||
devlist = []
|
|
||||||
label = None
|
|
||||||
_type = None
|
|
||||||
+ mscdlabel_out = ""
|
|
||||||
if criteria:
|
|
||||||
if criteria.startswith("LABEL="):
|
|
||||||
label = criteria.lstrip("LABEL=")
|
|
||||||
--
|
|
||||||
2.39.3
|
|
||||||
|
|
@ -1,66 +0,0 @@
|
|||||||
From 62cec1e38e117fe6b24888862576ac57be14bbda Mon Sep 17 00:00:00 2001
|
|
||||||
From: James Falcon <james.falcon@canonical.com>
|
|
||||||
Date: Tue, 26 Mar 2024 15:55:50 -0500
|
|
||||||
Subject: [PATCH] fix: Always use single datasource if specified (#5098)
|
|
||||||
|
|
||||||
RH-Author: Ani Sinha <anisinha@redhat.com>
|
|
||||||
RH-MergeRequest: 82: fix: Always use single datasource if specified (#5098)
|
|
||||||
RH-Jira: RHEL-36255
|
|
||||||
RH-Acked-by: Cathy Avery <cavery@redhat.com>
|
|
||||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
||||||
RH-Commit: [1/1] 068e97fcc18dd99f1112a9109acdb30fe2880f6e (anisinha/cloud-init)
|
|
||||||
|
|
||||||
This change may require a user to add `None` to the `datasource_list`
|
|
||||||
defined in `/etc/cloud/cloud.cfg[.d]` if they have a customized
|
|
||||||
datasource_list and want the DataSourceNone fallback behavior.
|
|
||||||
|
|
||||||
ds-identify would automatically append "None" to the datasource_list
|
|
||||||
if a single entry was provided in /etc/cloud/cloud.cfg[.d].
|
|
||||||
This wasn't a problem in the past as the python code would detect
|
|
||||||
a single datasource along with None as an indication to automatically
|
|
||||||
use that datasource. Since the python code no longer does that,
|
|
||||||
we should ensure that one specified datasource results in one specified
|
|
||||||
datasource after ds-identify has run.
|
|
||||||
|
|
||||||
Fixes GH-5091
|
|
||||||
|
|
||||||
(cherry picked from commit cdbbd17ae400e432d13f674c18a6f5c873fa328b)
|
|
||||||
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
|
||||||
---
|
|
||||||
tests/unittests/test_ds_identify.py | 2 +-
|
|
||||||
tools/ds-identify | 6 +++++-
|
|
||||||
2 files changed, 6 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/tests/unittests/test_ds_identify.py b/tests/unittests/test_ds_identify.py
|
|
||||||
index ba0bf779..acbf3f03 100644
|
|
||||||
--- a/tests/unittests/test_ds_identify.py
|
|
||||||
+++ b/tests/unittests/test_ds_identify.py
|
|
||||||
@@ -522,7 +522,7 @@ class TestDsIdentify(DsIdentifyBase):
|
|
||||||
mydata = copy.deepcopy(VALID_CFG["Ec2-hvm"])
|
|
||||||
cfgpath = "etc/cloud/cloud.cfg.d/myds.cfg"
|
|
||||||
mydata["files"][cfgpath] = 'datasource_list: ["NoCloud"]\n'
|
|
||||||
- self._check_via_dict(mydata, rc=RC_FOUND, dslist=["NoCloud", DS_NONE])
|
|
||||||
+ self._check_via_dict(mydata, rc=RC_FOUND, dslist=["NoCloud"])
|
|
||||||
|
|
||||||
def test_configured_list_with_none(self):
|
|
||||||
"""When datasource_list already contains None, None is not added.
|
|
||||||
diff --git a/tools/ds-identify b/tools/ds-identify
|
|
||||||
index ec2cc18a..6e49ded3 100755
|
|
||||||
--- a/tools/ds-identify
|
|
||||||
+++ b/tools/ds-identify
|
|
||||||
@@ -1865,7 +1865,11 @@ _main() {
|
|
||||||
# if there is only a single entry in $DI_DSLIST
|
|
||||||
if [ $# -eq 1 ] || [ $# -eq 2 -a "$2" = "None" ] ; then
|
|
||||||
debug 1 "single entry in datasource_list ($DI_DSLIST) use that."
|
|
||||||
- found "$@"
|
|
||||||
+ if [ $# -eq 1 ]; then
|
|
||||||
+ write_result "datasource_list: [ $1 ]"
|
|
||||||
+ else
|
|
||||||
+ found "$@"
|
|
||||||
+ fi
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
--
|
|
||||||
2.39.3
|
|
||||||
|
|
@ -1,246 +0,0 @@
|
|||||||
From 914ac26ebd889b1f5cbb13d55fc011e92fc213c6 Mon Sep 17 00:00:00 2001
|
|
||||||
From: James Falcon <james.falcon@canonical.com>
|
|
||||||
Date: Thu, 18 Jul 2024 09:04:54 -0400
|
|
||||||
Subject: [PATCH 1/2] fix: Clean cache if no datasource fallback (#5499)
|
|
||||||
|
|
||||||
RH-Author: Ani Sinha <anisinha@redhat.com>
|
|
||||||
RH-MergeRequest: 103: fix: Clean cache if no datasource fallback (#5499)
|
|
||||||
RH-Jira: RHEL-49736
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Commit: [1/1] 37eacd97f5e60fae2f71d401c528d508d3db517e (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 0b795624..ace94c9a 100644
|
|
||||||
--- a/cloudinit/stages.py
|
|
||||||
+++ b/cloudinit/stages.py
|
|
||||||
@@ -378,6 +378,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 3fc6558a..23c0dc98 100644
|
|
||||||
--- a/tests/integration_tests/instances.py
|
|
||||||
+++ b/tests/integration_tests/instances.py
|
|
||||||
@@ -88,7 +88,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
|
|
||||||
|
|
@ -1,391 +0,0 @@
|
|||||||
From aaf1d063f198ce09f0d539a85e1a1a2bb834520b Mon Sep 17 00:00:00 2001
|
|
||||||
From: James Falcon <james.falcon@canonical.com>
|
|
||||||
Date: Tue, 2 Jan 2024 11:29:17 -0600
|
|
||||||
Subject: [PATCH 1/3] fix: Correct v2 NetworkManager route rendering (#4637)
|
|
||||||
|
|
||||||
RH-Author: Cathy Avery <cavery@redhat.com>
|
|
||||||
RH-MergeRequest: 72: Fixes for cloud-init fails to configure DNS/search domains for network-config v1
|
|
||||||
RH-Jira: RHEL-20964
|
|
||||||
RH-Acked-by: Ani Sinha <anisinha@redhat.com>
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Commit: [1/2] fb865987dbcf506a674eb9798f9c06859539a696 (cavery/cloud-init-c-9-s)
|
|
||||||
|
|
||||||
fix: Correct v2 NetworkManager route rendering
|
|
||||||
|
|
||||||
Because network v2 route defintions can have mixed v4 and v6 routes, we
|
|
||||||
need to determine the IP family per route rather than per subnet.
|
|
||||||
|
|
||||||
Similar, ensure dns-search is rendered correctly.
|
|
||||||
|
|
||||||
Fixes GH-4518
|
|
||||||
|
|
||||||
(cherry picked from commit c2c100e8c9fd8709539b3ab2b0ee34c66ba3f2f7)
|
|
||||||
Signed-off-by: Cathy Avery <cavery@redhat.com>
|
|
||||||
---
|
|
||||||
cloudinit/net/__init__.py | 2 +
|
|
||||||
cloudinit/net/network_manager.py | 87 +++++++++-------
|
|
||||||
tests/unittests/test_net.py | 165 ++++++++++++++++++++++++++++++-
|
|
||||||
3 files changed, 219 insertions(+), 35 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/cloudinit/net/__init__.py b/cloudinit/net/__init__.py
|
|
||||||
index c0888f52..65e7ff33 100644
|
|
||||||
--- a/cloudinit/net/__init__.py
|
|
||||||
+++ b/cloudinit/net/__init__.py
|
|
||||||
@@ -1287,6 +1287,8 @@ def subnet_is_ipv6(subnet) -> bool:
|
|
||||||
"""Common helper for checking network_state subnets for ipv6."""
|
|
||||||
# 'static6', 'dhcp6', 'ipv6_dhcpv6-stateful', 'ipv6_dhcpv6-stateless' or
|
|
||||||
# 'ipv6_slaac'
|
|
||||||
+ # This function is inappropriate for v2-based routes as routes defined
|
|
||||||
+ # under v2 subnets can contain ipv4 and ipv6 simultaneously
|
|
||||||
if subnet["type"].endswith("6") or subnet["type"] in IPV6_DYNAMIC_TYPES:
|
|
||||||
# This is a request either static6 type or DHCPv6.
|
|
||||||
return True
|
|
||||||
diff --git a/cloudinit/net/network_manager.py b/cloudinit/net/network_manager.py
|
|
||||||
index 76a0ac15..bd6e6d75 100644
|
|
||||||
--- a/cloudinit/net/network_manager.py
|
|
||||||
+++ b/cloudinit/net/network_manager.py
|
|
||||||
@@ -12,10 +12,15 @@ import itertools
|
|
||||||
import logging
|
|
||||||
import os
|
|
||||||
import uuid
|
|
||||||
-from typing import Optional
|
|
||||||
+from typing import List, Optional
|
|
||||||
|
|
||||||
from cloudinit import subp, util
|
|
||||||
-from cloudinit.net import is_ipv6_address, renderer, subnet_is_ipv6
|
|
||||||
+from cloudinit.net import (
|
|
||||||
+ is_ipv6_address,
|
|
||||||
+ is_ipv6_network,
|
|
||||||
+ renderer,
|
|
||||||
+ subnet_is_ipv6,
|
|
||||||
+)
|
|
||||||
from cloudinit.net.network_state import NetworkState
|
|
||||||
from cloudinit.net.sysconfig import available_nm_ifcfg_rh
|
|
||||||
|
|
||||||
@@ -158,11 +163,11 @@ class NMConnection:
|
|
||||||
if self.config[family]["method"] == "auto" and method == "manual":
|
|
||||||
return
|
|
||||||
|
|
||||||
- if (
|
|
||||||
- subnet_type == "ipv6_dhcpv6-stateful"
|
|
||||||
- or subnet_type == "ipv6_dhcpv6-stateless"
|
|
||||||
- or subnet_type == "ipv6_slaac"
|
|
||||||
- ):
|
|
||||||
+ if subnet_type in [
|
|
||||||
+ "ipv6_dhcpv6-stateful",
|
|
||||||
+ "ipv6_dhcpv6-stateless",
|
|
||||||
+ "ipv6_slaac",
|
|
||||||
+ ]:
|
|
||||||
# set ipv4 method to 'disabled' to align with sysconfig renderer.
|
|
||||||
self._set_default("ipv4", "method", "disabled")
|
|
||||||
|
|
||||||
@@ -174,7 +179,8 @@ class NMConnection:
|
|
||||||
Adds a numbered property, such as address<n> or route<n>, ensuring
|
|
||||||
the appropriate value gets used for <n>.
|
|
||||||
"""
|
|
||||||
-
|
|
||||||
+ if not self.config.has_section(section):
|
|
||||||
+ self.config[section] = {}
|
|
||||||
for index in itertools.count(1):
|
|
||||||
key = f"{key_prefix}{index}"
|
|
||||||
if not self.config.has_option(section, key):
|
|
||||||
@@ -189,40 +195,37 @@ class NMConnection:
|
|
||||||
value = subnet["address"] + "/" + str(subnet["prefix"])
|
|
||||||
self._add_numbered(family, "address", value)
|
|
||||||
|
|
||||||
- def _add_route(self, family, route):
|
|
||||||
- """
|
|
||||||
- Adds a ipv[46].route<n> property.
|
|
||||||
- """
|
|
||||||
-
|
|
||||||
+ def _add_route(self, route):
|
|
||||||
+ """Adds a ipv[46].route<n> property."""
|
|
||||||
+ # Because network v2 route definitions can have mixed v4 and v6
|
|
||||||
+ # routes, determine the family per route based on the gateway
|
|
||||||
+ family = "ipv6" if is_ipv6_network(route["gateway"]) else "ipv4"
|
|
||||||
value = route["network"] + "/" + str(route["prefix"])
|
|
||||||
if "gateway" in route:
|
|
||||||
value = value + "," + route["gateway"]
|
|
||||||
self._add_numbered(family, "route", value)
|
|
||||||
|
|
||||||
- def _add_nameserver(self, dns):
|
|
||||||
+ def _add_nameserver(self, dns: str) -> None:
|
|
||||||
"""
|
|
||||||
Extends the ipv[46].dns property with a name server.
|
|
||||||
"""
|
|
||||||
-
|
|
||||||
- # FIXME: the subnet contains IPv4 and IPv6 name server mixed
|
|
||||||
- # together. We might be getting an IPv6 name server while
|
|
||||||
- # we're dealing with an IPv4 subnet. Sort this out by figuring
|
|
||||||
- # out the correct family and making sure a valid section exist.
|
|
||||||
family = "ipv6" if is_ipv6_address(dns) else "ipv4"
|
|
||||||
- self._set_default(family, "method", "disabled")
|
|
||||||
-
|
|
||||||
- self._set_default(family, "dns", "")
|
|
||||||
- self.config[family]["dns"] = self.config[family]["dns"] + dns + ";"
|
|
||||||
+ if self.config.has_section(family):
|
|
||||||
+ self._set_default(family, "dns", "")
|
|
||||||
+ self.config[family]["dns"] = self.config[family]["dns"] + dns + ";"
|
|
||||||
|
|
||||||
- def _add_dns_search(self, family, dns_search):
|
|
||||||
+ def _add_dns_search(self, dns_search: List[str]) -> None:
|
|
||||||
"""
|
|
||||||
Extends the ipv[46].dns-search property with a name server.
|
|
||||||
"""
|
|
||||||
-
|
|
||||||
- self._set_default(family, "dns-search", "")
|
|
||||||
- self.config[family]["dns-search"] = (
|
|
||||||
- self.config[family]["dns-search"] + ";".join(dns_search) + ";"
|
|
||||||
- )
|
|
||||||
+ for family in ["ipv4", "ipv6"]:
|
|
||||||
+ if self.config.has_section(family):
|
|
||||||
+ self._set_default(family, "dns-search", "")
|
|
||||||
+ self.config[family]["dns-search"] = (
|
|
||||||
+ self.config[family]["dns-search"]
|
|
||||||
+ + ";".join(dns_search)
|
|
||||||
+ + ";"
|
|
||||||
+ )
|
|
||||||
|
|
||||||
def con_uuid(self):
|
|
||||||
"""
|
|
||||||
@@ -304,8 +307,11 @@ class NMConnection:
|
|
||||||
|
|
||||||
device_mtu = iface["mtu"]
|
|
||||||
ipv4_mtu = None
|
|
||||||
+ found_nameservers = []
|
|
||||||
+ found_dns_search = []
|
|
||||||
|
|
||||||
# Deal with Layer 3 configuration
|
|
||||||
+ use_top_level_dns = "dns" in iface
|
|
||||||
for subnet in iface["subnets"]:
|
|
||||||
family = "ipv6" if subnet_is_ipv6(subnet) else "ipv4"
|
|
||||||
|
|
||||||
@@ -315,15 +321,28 @@ class NMConnection:
|
|
||||||
if "gateway" in subnet:
|
|
||||||
self.config[family]["gateway"] = subnet["gateway"]
|
|
||||||
for route in subnet["routes"]:
|
|
||||||
- self._add_route(family, route)
|
|
||||||
- if "dns_nameservers" in subnet:
|
|
||||||
+ self._add_route(route)
|
|
||||||
+ if not use_top_level_dns and "dns_nameservers" in subnet:
|
|
||||||
for nameserver in subnet["dns_nameservers"]:
|
|
||||||
- self._add_nameserver(nameserver)
|
|
||||||
- if "dns_search" in subnet:
|
|
||||||
- self._add_dns_search(family, subnet["dns_search"])
|
|
||||||
+ found_nameservers.append(nameserver)
|
|
||||||
+ if not use_top_level_dns and "dns_search" in subnet:
|
|
||||||
+ found_dns_search.append(subnet["dns_search"])
|
|
||||||
if family == "ipv4" and "mtu" in subnet:
|
|
||||||
ipv4_mtu = subnet["mtu"]
|
|
||||||
|
|
||||||
+ # Now add our DNS search domains. We add them later because we
|
|
||||||
+ # only want them if an IP family has already been defined
|
|
||||||
+ if use_top_level_dns:
|
|
||||||
+ for nameserver in iface["dns"]["nameservers"]:
|
|
||||||
+ self._add_nameserver(nameserver)
|
|
||||||
+ if iface["dns"]["search"]:
|
|
||||||
+ self._add_dns_search(iface["dns"]["search"])
|
|
||||||
+ else:
|
|
||||||
+ for nameserver in found_nameservers:
|
|
||||||
+ self._add_nameserver(nameserver)
|
|
||||||
+ for dns_search in found_dns_search:
|
|
||||||
+ self._add_dns_search(dns_search)
|
|
||||||
+
|
|
||||||
# we do not want to set may-fail to false for both ipv4 and ipv6 dhcp
|
|
||||||
# at the at the same time. This will make the network configuration
|
|
||||||
# work only when both ipv4 and ipv6 dhcp succeeds. This may not be
|
|
||||||
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
|
|
||||||
index d9ef493b..2a99f150 100644
|
|
||||||
--- a/tests/unittests/test_net.py
|
|
||||||
+++ b/tests/unittests/test_net.py
|
|
||||||
@@ -2962,9 +2962,9 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
|
|
||||||
may-fail=false
|
|
||||||
address1=192.168.0.2/24
|
|
||||||
gateway=192.168.0.1
|
|
||||||
+ address2=192.168.2.10/24
|
|
||||||
dns=192.168.0.10;10.23.23.134;
|
|
||||||
dns-search=barley.maas;sacchromyces.maas;brettanomyces.maas;
|
|
||||||
- address2=192.168.2.10/24
|
|
||||||
|
|
||||||
"""
|
|
||||||
),
|
|
||||||
@@ -4154,6 +4154,148 @@ iface bond0 inet6 static
|
|
||||||
"""
|
|
||||||
),
|
|
||||||
},
|
|
||||||
+ "v2-mixed-routes": {
|
|
||||||
+ "expected_network_manager": {
|
|
||||||
+ "cloud-init-eth0.nmconnection": textwrap.dedent(
|
|
||||||
+ """\
|
|
||||||
+ # Generated by cloud-init. Changes will be lost.
|
|
||||||
+
|
|
||||||
+ [connection]
|
|
||||||
+ id=cloud-init eth0
|
|
||||||
+ uuid=1dd9a779-d327-56e1-8454-c65e2556c12c
|
|
||||||
+ autoconnect-priority=120
|
|
||||||
+ type=ethernet
|
|
||||||
+ interface-name=eth0
|
|
||||||
+
|
|
||||||
+ [user]
|
|
||||||
+ org.freedesktop.NetworkManager.origin=cloud-init
|
|
||||||
+
|
|
||||||
+ [ethernet]
|
|
||||||
+
|
|
||||||
+ [ipv4]
|
|
||||||
+ method=auto
|
|
||||||
+ may-fail=true
|
|
||||||
+ route1=169.254.42.42/32,62.210.0.1
|
|
||||||
+ route2=169.254.42.43/32,62.210.0.2
|
|
||||||
+ address1=192.168.1.20/16
|
|
||||||
+ dns=8.8.8.8;
|
|
||||||
+ dns-search=lab;home;
|
|
||||||
+
|
|
||||||
+ [ipv6]
|
|
||||||
+ route1=::/0,fe80::dc00:ff:fe20:186
|
|
||||||
+ route2=fe80::dc00:ff:fe20:188/64,fe80::dc00:ff:fe20:187
|
|
||||||
+ method=auto
|
|
||||||
+ may-fail=true
|
|
||||||
+ address1=2001:bc8:1210:232:dc00:ff:fe20:185/64
|
|
||||||
+ dns=FEDC::1;
|
|
||||||
+ dns-search=lab;home;
|
|
||||||
+
|
|
||||||
+ """
|
|
||||||
+ )
|
|
||||||
+ },
|
|
||||||
+ "yaml": textwrap.dedent(
|
|
||||||
+ """\
|
|
||||||
+ version: 2
|
|
||||||
+ ethernets:
|
|
||||||
+ eth0:
|
|
||||||
+ dhcp4: true
|
|
||||||
+ dhcp6: true
|
|
||||||
+ nameservers:
|
|
||||||
+ search: [lab, home]
|
|
||||||
+ addresses: [8.8.8.8, "FEDC::1"]
|
|
||||||
+ routes:
|
|
||||||
+ - to: 169.254.42.42/32
|
|
||||||
+ via: 62.210.0.1
|
|
||||||
+ - via: fe80::dc00:ff:fe20:186
|
|
||||||
+ to: ::/0
|
|
||||||
+ - to: 169.254.42.43/32
|
|
||||||
+ via: 62.210.0.2
|
|
||||||
+ - via: fe80::dc00:ff:fe20:187
|
|
||||||
+ to: fe80::dc00:ff:fe20:188
|
|
||||||
+ addresses:
|
|
||||||
+ - 192.168.1.20/16
|
|
||||||
+ - 2001:bc8:1210:232:dc00:ff:fe20:185/64
|
|
||||||
+ """
|
|
||||||
+ ),
|
|
||||||
+ },
|
|
||||||
+ "v2-dns-no-if-ips": {
|
|
||||||
+ "expected_network_manager": {
|
|
||||||
+ "cloud-init-eth0.nmconnection": textwrap.dedent(
|
|
||||||
+ """\
|
|
||||||
+ # Generated by cloud-init. Changes will be lost.
|
|
||||||
+
|
|
||||||
+ [connection]
|
|
||||||
+ id=cloud-init eth0
|
|
||||||
+ uuid=1dd9a779-d327-56e1-8454-c65e2556c12c
|
|
||||||
+ autoconnect-priority=120
|
|
||||||
+ type=ethernet
|
|
||||||
+ interface-name=eth0
|
|
||||||
+
|
|
||||||
+ [user]
|
|
||||||
+ org.freedesktop.NetworkManager.origin=cloud-init
|
|
||||||
+
|
|
||||||
+ [ethernet]
|
|
||||||
+
|
|
||||||
+ [ipv4]
|
|
||||||
+ method=auto
|
|
||||||
+ may-fail=true
|
|
||||||
+ dns=8.8.8.8;
|
|
||||||
+ dns-search=lab;home;
|
|
||||||
+
|
|
||||||
+ [ipv6]
|
|
||||||
+ method=auto
|
|
||||||
+ may-fail=true
|
|
||||||
+ dns=FEDC::1;
|
|
||||||
+ dns-search=lab;home;
|
|
||||||
+
|
|
||||||
+ """
|
|
||||||
+ )
|
|
||||||
+ },
|
|
||||||
+ "yaml": textwrap.dedent(
|
|
||||||
+ """\
|
|
||||||
+ version: 2
|
|
||||||
+ ethernets:
|
|
||||||
+ eth0:
|
|
||||||
+ dhcp4: true
|
|
||||||
+ dhcp6: true
|
|
||||||
+ nameservers:
|
|
||||||
+ search: [lab, home]
|
|
||||||
+ addresses: [8.8.8.8, "FEDC::1"]
|
|
||||||
+ """
|
|
||||||
+ ),
|
|
||||||
+ },
|
|
||||||
+ "v2-dns-no-dhcp": {
|
|
||||||
+ "expected_network_manager": {
|
|
||||||
+ "cloud-init-eth0.nmconnection": textwrap.dedent(
|
|
||||||
+ """\
|
|
||||||
+ # Generated by cloud-init. Changes will be lost.
|
|
||||||
+
|
|
||||||
+ [connection]
|
|
||||||
+ id=cloud-init eth0
|
|
||||||
+ uuid=1dd9a779-d327-56e1-8454-c65e2556c12c
|
|
||||||
+ autoconnect-priority=120
|
|
||||||
+ type=ethernet
|
|
||||||
+ interface-name=eth0
|
|
||||||
+
|
|
||||||
+ [user]
|
|
||||||
+ org.freedesktop.NetworkManager.origin=cloud-init
|
|
||||||
+
|
|
||||||
+ [ethernet]
|
|
||||||
+
|
|
||||||
+ """
|
|
||||||
+ )
|
|
||||||
+ },
|
|
||||||
+ "yaml": textwrap.dedent(
|
|
||||||
+ """\
|
|
||||||
+ version: 2
|
|
||||||
+ ethernets:
|
|
||||||
+ eth0:
|
|
||||||
+ nameservers:
|
|
||||||
+ search: [lab, home]
|
|
||||||
+ addresses: [8.8.8.8, "FEDC::1"]
|
|
||||||
+ """
|
|
||||||
+ ),
|
|
||||||
+ },
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@@ -6267,6 +6409,27 @@ class TestNetworkManagerRendering(CiTestCase):
|
|
||||||
entry[self.expected_name], self.expected_conf_d, found
|
|
||||||
)
|
|
||||||
|
|
||||||
+ def test_v2_mixed_routes(self):
|
|
||||||
+ entry = NETWORK_CONFIGS["v2-mixed-routes"]
|
|
||||||
+ found = self._render_and_read(network_config=yaml.load(entry["yaml"]))
|
|
||||||
+ self._compare_files_to_expected(
|
|
||||||
+ entry[self.expected_name], self.expected_conf_d, found
|
|
||||||
+ )
|
|
||||||
+
|
|
||||||
+ def test_v2_dns_no_ips(self):
|
|
||||||
+ entry = NETWORK_CONFIGS["v2-dns-no-if-ips"]
|
|
||||||
+ found = self._render_and_read(network_config=yaml.load(entry["yaml"]))
|
|
||||||
+ self._compare_files_to_expected(
|
|
||||||
+ entry[self.expected_name], self.expected_conf_d, found
|
|
||||||
+ )
|
|
||||||
+
|
|
||||||
+ def test_v2_dns_no_dhcp(self):
|
|
||||||
+ entry = NETWORK_CONFIGS["v2-dns-no-dhcp"]
|
|
||||||
+ found = self._render_and_read(network_config=yaml.load(entry["yaml"]))
|
|
||||||
+ self._compare_files_to_expected(
|
|
||||||
+ entry[self.expected_name], self.expected_conf_d, found
|
|
||||||
+ )
|
|
||||||
+
|
|
||||||
|
|
||||||
@mock.patch(
|
|
||||||
"cloudinit.net.is_openvswitch_internal_interface",
|
|
||||||
--
|
|
||||||
2.39.3
|
|
||||||
|
|
@ -1,156 +0,0 @@
|
|||||||
From cf35040b46abb66c7239d156bd92c7267d7c40f7 Mon Sep 17 00:00:00 2001
|
|
||||||
From: PengpengSun <40026211+PengpengSun@users.noreply.github.com>
|
|
||||||
Date: Fri, 29 Mar 2024 22:39:13 +0800
|
|
||||||
Subject: [PATCH] fix: Fall back to cached local ds if no valid ds found
|
|
||||||
(#4997)
|
|
||||||
|
|
||||||
RH-Author: Ani Sinha <anisinha@redhat.com>
|
|
||||||
RH-MergeRequest: 75: fix: Fall back to cached local ds if no valid ds found (#4997)
|
|
||||||
RH-Jira: RHEL-32846
|
|
||||||
RH-Acked-by: Cathy Avery <cavery@redhat.com>
|
|
||||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
||||||
RH-Commit: [1/1] 408c41fd8009255d98c31210ef936f2e68dfde75 (anisinha/cloud-init)
|
|
||||||
|
|
||||||
Rebooting an instance which has finished VMware guest
|
|
||||||
customization with DataSourceVMware will load
|
|
||||||
DataSourceNone due to metadata is NOT available.
|
|
||||||
|
|
||||||
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 1591121d..2d5d42eb 100644
|
|
||||||
--- a/cloudinit/sources/DataSourceVMware.py
|
|
||||||
+++ b/cloudinit/sources/DataSourceVMware.py
|
|
||||||
@@ -197,7 +197,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())
|
|
||||||
@@ -291,6 +291,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 c207b5ed..453801be 100644
|
|
||||||
--- a/cloudinit/sources/__init__.py
|
|
||||||
+++ b/cloudinit/sources/__init__.py
|
|
||||||
@@ -312,6 +312,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.
|
|
||||||
@@ -914,6 +918,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 3b6405f5..0b795624 100644
|
|
||||||
--- a/cloudinit/stages.py
|
|
||||||
+++ b/cloudinit/stages.py
|
|
||||||
@@ -353,20 +353,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
|
|
||||||
|
|
@ -1,306 +0,0 @@
|
|||||||
From f6ebe75761317b65f3b6b4b2b62a5ddd257347d9 Mon Sep 17 00:00:00 2001
|
|
||||||
From: James Falcon <james.falcon@canonical.com>
|
|
||||||
Date: Thu, 10 Oct 2024 23:19:28 -0500
|
|
||||||
Subject: [PATCH 1/2] fix: Render bridges correctly for v2 on sysconfig with
|
|
||||||
set-name (#5674)
|
|
||||||
|
|
||||||
RH-Author: xiachen <xiachen@redhat.com>
|
|
||||||
RH-MergeRequest: 113: fix: Render bridges correctly for v2 on sysconfig with set-name (#5674)
|
|
||||||
RH-Jira: RHEL-38927
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Acked-by: Ani Sinha <anisinha@redhat.com>
|
|
||||||
RH-Commit: [1/2] ee4232eb73f3d27c5644499bacb235371d82bb4e (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 | 30 ++++-------
|
|
||||||
cloudinit/net/sysconfig.py | 24 ++++++---
|
|
||||||
tests/unittests/test_net.py | 96 ++++++++++++++++++++++++++++++++++
|
|
||||||
4 files changed, 128 insertions(+), 28 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/cloudinit/net/eni.py b/cloudinit/net/eni.py
|
|
||||||
index 486fa22d..ac0306d6 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 14c57cdc..226421bd 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,28 +803,15 @@ 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})
|
|
||||||
+ if search:
|
|
||||||
+ name_cmd["search"] = search
|
|
||||||
+ if dns:
|
|
||||||
+ name_cmd["address"] = dns
|
|
||||||
self.handle_nameserver(name_cmd)
|
|
||||||
-
|
|
||||||
- mac_address: Optional[str] = dev_cfg.get("match", {}).get(
|
|
||||||
- "macaddress"
|
|
||||||
- )
|
|
||||||
- if mac_address:
|
|
||||||
- real_if_name = find_interface_name_from_mac(mac_address)
|
|
||||||
- if real_if_name:
|
|
||||||
- iface = real_if_name
|
|
||||||
-
|
|
||||||
self._handle_individual_nameserver(name_cmd, iface)
|
|
||||||
|
|
||||||
def _handle_bond_bridge(self, command, cmd_type=None):
|
|
||||||
diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
|
|
||||||
index b50a6a8a..e4a65187 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
|
|
||||||
@@ -924,7 +924,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()
|
|
||||||
@@ -1005,23 +1007,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 4673e4ea..004da81a 100644
|
|
||||||
--- a/tests/unittests/test_net.py
|
|
||||||
+++ b/tests/unittests/test_net.py
|
|
||||||
@@ -4489,6 +4489,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
|
|
||||||
+ """
|
|
||||||
+ ),
|
|
||||||
+ },
|
|
||||||
+ },
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@@ -5558,6 +5647,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
|
|
||||||
|
|
@ -1,160 +0,0 @@
|
|||||||
From d9328b15d83d0938b949a4376ed3a26e6e7cfcd9 Mon Sep 17 00:00:00 2001
|
|
||||||
From: James Falcon <james.falcon@canonical.com>
|
|
||||||
Date: Fri, 11 Oct 2024 13:58:19 -0500
|
|
||||||
Subject: [PATCH 2/2] fix: Render v2 bridges correctly on network-manager with
|
|
||||||
set-name (#5740)
|
|
||||||
|
|
||||||
RH-Author: xiachen <xiachen@redhat.com>
|
|
||||||
RH-MergeRequest: 113: fix: Render bridges correctly for v2 on sysconfig with set-name (#5674)
|
|
||||||
RH-Jira: RHEL-38927
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Acked-by: Ani Sinha <anisinha@redhat.com>
|
|
||||||
RH-Commit: [2/2] d98d01bd5ca50aee2ca0ef0eeec1b890ec55102d (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 0ba210b7..f50fafa3 100644
|
|
||||||
--- a/cloudinit/net/network_manager.py
|
|
||||||
+++ b/cloudinit/net/network_manager.py
|
|
||||||
@@ -464,11 +464,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 004da81a..ddb45dc6 100644
|
|
||||||
--- a/tests/unittests/test_net.py
|
|
||||||
+++ b/tests/unittests/test_net.py
|
|
||||||
@@ -4577,6 +4577,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
|
|
||||||
+
|
|
||||||
+ """
|
|
||||||
+ ),
|
|
||||||
+ },
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -6722,6 +6810,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
|
|
||||||
|
|
@ -1,42 +0,0 @@
|
|||||||
From 332bb23bcfde801edf792e6c629ec350be07b952 Mon Sep 17 00:00:00 2001
|
|
||||||
From: James Falcon <james.falcon@canonical.com>
|
|
||||||
Date: Tue, 19 Mar 2024 14:24:11 -0500
|
|
||||||
Subject: [PATCH 3/3] fix: Undeprecate 'network' in schema route definition
|
|
||||||
(#5072)
|
|
||||||
|
|
||||||
RH-Author: Ani Sinha <anisinha@redhat.com>
|
|
||||||
RH-MergeRequest: 73: fix: Undeprecate 'network' in schema route definition (#5072)
|
|
||||||
RH-Jira: RHEL-29709
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Acked-by: Cathy Avery <cavery@redhat.com>
|
|
||||||
RH-Commit: [1/1] 61c660be43fd25999bca0cfd66d7b2150fee5a14 (anisinha/cloud-init)
|
|
||||||
|
|
||||||
It is passed through to our v1 schema from OpenStack network_data.json
|
|
||||||
|
|
||||||
Fixes GH-5051
|
|
||||||
|
|
||||||
(cherry picked from commit ff40d1af8a6de3ee27937382ec4ceea931d80a88)
|
|
||||||
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
|
||||||
---
|
|
||||||
cloudinit/config/schemas/schema-network-config-v1.json | 5 +----
|
|
||||||
1 file changed, 1 insertion(+), 4 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/cloudinit/config/schemas/schema-network-config-v1.json b/cloudinit/config/schemas/schema-network-config-v1.json
|
|
||||||
index 56dc27c9..64c492a4 100644
|
|
||||||
--- a/cloudinit/config/schemas/schema-network-config-v1.json
|
|
||||||
+++ b/cloudinit/config/schemas/schema-network-config-v1.json
|
|
||||||
@@ -445,10 +445,7 @@
|
|
||||||
},
|
|
||||||
"network": {
|
|
||||||
"type": "string",
|
|
||||||
- "description": "IPv4 network address with CIDR netmask notation or IPv6 with prefix length. Alias for ``destination`` and only read when ``destination`` key is absent.",
|
|
||||||
- "deprecated": true,
|
|
||||||
- "deprecated_version": "23.3",
|
|
||||||
- "deprecated_description": "Use ``destination`` instead."
|
|
||||||
+ "description": "IPv4 network address with CIDR netmask notation or IPv6 with prefix length. Alias for ``destination`` and only read when ``destination`` key is absent. This exists for OpenStack support. OpenStack route definitions are passed through to v1 config and OpenStack's ``network_data.json`` uses ``network`` instead of ``destination``."
|
|
||||||
},
|
|
||||||
"destination": {
|
|
||||||
"type": "string",
|
|
||||||
--
|
|
||||||
2.39.3
|
|
||||||
|
|
@ -1,66 +0,0 @@
|
|||||||
From ed3c05af60c0d50a4576a63c8638e148e58ebf06 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Ani Sinha <anisinha@redhat.com>
|
|
||||||
Date: Thu, 11 Jul 2024 00:49:58 +0530
|
|
||||||
Subject: [PATCH] fix: add schema rules for 'baseurl' and 'metalink' in yum
|
|
||||||
repo config (#5501)
|
|
||||||
|
|
||||||
RH-Author: Ani Sinha <anisinha@redhat.com>
|
|
||||||
RH-MergeRequest: 101: fix: add schema rules for 'baseurl' and 'metalink' in yum repo config (#5501)
|
|
||||||
RH-Jira: RHEL-46873
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Acked-by: xiachen <xiachen@redhat.com>
|
|
||||||
RH-Commit: [1/1] df01c93fde517e66ce71a66f80ee54d3ed504906 (anisinha/cloud-init)
|
|
||||||
|
|
||||||
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)
|
|
||||||
---
|
|
||||||
.../config/schemas/schema-cloud-config-v1.json | 18 ++++++++++++++++--
|
|
||||||
1 file changed, 16 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/cloudinit/config/schemas/schema-cloud-config-v1.json b/cloudinit/config/schemas/schema-cloud-config-v1.json
|
|
||||||
index 03e723e2..4fb7fd93 100644
|
|
||||||
--- a/cloudinit/config/schemas/schema-cloud-config-v1.json
|
|
||||||
+++ b/cloudinit/config/schemas/schema-cloud-config-v1.json
|
|
||||||
@@ -3442,6 +3442,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."
|
|
||||||
@@ -3469,8 +3474,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
|
|
||||||
|
|
@ -1,58 +0,0 @@
|
|||||||
From fcaff2e02a07af587d8366f61df1685435e32288 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Brett Holman <brett.holman@canonical.com>
|
|
||||||
Date: Wed, 3 Jan 2024 09:11:40 -0700
|
|
||||||
Subject: [PATCH] fix(cloudstack): Use parsed lease file for virtual router in
|
|
||||||
cloudstack
|
|
||||||
|
|
||||||
RH-Author: Ani Sinha <anisinha@redhat.com>
|
|
||||||
RH-MergeRequest: 85: fix(cloudstack): Use parsed lease file for virtual router in cloudstack
|
|
||||||
RH-Jira: RHEL-40217
|
|
||||||
RH-Acked-by: Cathy Avery <cavery@redhat.com>
|
|
||||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
||||||
RH-Commit: [1/1] 9d1353620ee2c773170e424479bb2664116554f4 (anisinha/cloud-init)
|
|
||||||
|
|
||||||
Fixes 5942f4023e2581a
|
|
||||||
|
|
||||||
(cherry picked from commit cb36bf38b823f811a3e938ccffc03d7d13190095)
|
|
||||||
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
|
||||||
---
|
|
||||||
cloudinit/sources/DataSourceCloudStack.py | 22 +++++++++++-----------
|
|
||||||
1 file changed, 11 insertions(+), 11 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/cloudinit/sources/DataSourceCloudStack.py b/cloudinit/sources/DataSourceCloudStack.py
|
|
||||||
index fd2482a3..f752765d 100644
|
|
||||||
--- a/cloudinit/sources/DataSourceCloudStack.py
|
|
||||||
+++ b/cloudinit/sources/DataSourceCloudStack.py
|
|
||||||
@@ -229,18 +229,18 @@ def get_vr_address():
|
|
||||||
)
|
|
||||||
return latest_address
|
|
||||||
|
|
||||||
- # Try dhcp lease files next...
|
|
||||||
+ # Try dhcp lease files next
|
|
||||||
lease_file = dhcp.IscDhclient.get_latest_lease()
|
|
||||||
- if not lease_file:
|
|
||||||
- LOG.debug("No lease file found, using default gateway")
|
|
||||||
- return get_default_gateway()
|
|
||||||
-
|
|
||||||
- lease_file = dhcp.IscDhclient.parse_dhcp_server_from_lease_file(lease_file)
|
|
||||||
- if not latest_address:
|
|
||||||
- # No virtual router found, fallback on default gateway
|
|
||||||
- LOG.debug("No DHCP found, using default gateway")
|
|
||||||
- return get_default_gateway()
|
|
||||||
- return latest_address
|
|
||||||
+ if lease_file:
|
|
||||||
+ latest_address = dhcp.IscDhclient.parse_dhcp_server_from_lease_file(
|
|
||||||
+ lease_file
|
|
||||||
+ )
|
|
||||||
+ if latest_address:
|
|
||||||
+ return latest_address
|
|
||||||
+
|
|
||||||
+ # No virtual router found, fallback to default gateway
|
|
||||||
+ LOG.debug("No DHCP found, using default gateway")
|
|
||||||
+ return get_default_gateway()
|
|
||||||
|
|
||||||
|
|
||||||
# Used to match classes to dependencies
|
|
||||||
--
|
|
||||||
2.39.3
|
|
||||||
|
|
@ -1,132 +0,0 @@
|
|||||||
From 2b74b0eb94edfd7caa42bc0d8affc37311ba041b Mon Sep 17 00:00:00 2001
|
|
||||||
From: Brett Holman <brett.holman@canonical.com>
|
|
||||||
Date: Wed, 3 Jan 2024 09:11:21 -0700
|
|
||||||
Subject: [PATCH 4/6] fix(dhcp): Guard against FileNotFoundError and NameError
|
|
||||||
exceptions
|
|
||||||
|
|
||||||
RH-Author: Ani Sinha <anisinha@redhat.com>
|
|
||||||
RH-MergeRequest: 92: Update pylint version to support python 3.12
|
|
||||||
RH-Jira: RHEL-44598
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
||||||
RH-Commit: [1/3] 730b8de9ceb2c380d3b15573d83691ab95a1487e (anisinha/cloud-init)
|
|
||||||
|
|
||||||
(cherry picked from commit 53eb8555e091474803b724700815adc09aa84f05)
|
|
||||||
---
|
|
||||||
cloudinit/net/dhcp.py | 20 ++++++++++------
|
|
||||||
tests/unittests/net/test_dhcp.py | 40 ++++++++++++++++++++++++++++++++
|
|
||||||
2 files changed, 53 insertions(+), 7 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/cloudinit/net/dhcp.py b/cloudinit/net/dhcp.py
|
|
||||||
index 07c13390..a0aee98c 100644
|
|
||||||
--- a/cloudinit/net/dhcp.py
|
|
||||||
+++ b/cloudinit/net/dhcp.py
|
|
||||||
@@ -5,15 +5,15 @@
|
|
||||||
# This file is part of cloud-init. See LICENSE file for license information.
|
|
||||||
|
|
||||||
import abc
|
|
||||||
-import contextlib
|
|
||||||
import glob
|
|
||||||
import logging
|
|
||||||
import os
|
|
||||||
import re
|
|
||||||
import signal
|
|
||||||
import time
|
|
||||||
+from contextlib import suppress
|
|
||||||
from io import StringIO
|
|
||||||
-from typing import Any, Dict, List
|
|
||||||
+from typing import Any, Dict, List, Optional
|
|
||||||
|
|
||||||
import configobj
|
|
||||||
|
|
||||||
@@ -268,7 +268,7 @@ class IscDhclient(DhcpClient):
|
|
||||||
|
|
||||||
# this function waits for these files to exist, clean previous runs
|
|
||||||
# to avoid false positive in wait_for_files
|
|
||||||
- with contextlib.suppress(FileNotFoundError):
|
|
||||||
+ with suppress(FileNotFoundError):
|
|
||||||
os.remove(pid_file)
|
|
||||||
os.remove(lease_file)
|
|
||||||
|
|
||||||
@@ -514,9 +514,15 @@ class IscDhclient(DhcpClient):
|
|
||||||
return latest_file
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
- def parse_dhcp_server_from_lease_file(lease_file):
|
|
||||||
- with open(lease_file, "r") as fd:
|
|
||||||
- for line in fd:
|
|
||||||
+ def parse_dhcp_server_from_lease_file(lease_file) -> Optional[str]:
|
|
||||||
+ """Parse a lease file for the dhcp server address
|
|
||||||
+
|
|
||||||
+ @param lease_file: Name of a file to be parsed
|
|
||||||
+ @return: An address if found, or None
|
|
||||||
+ """
|
|
||||||
+ latest_address = None
|
|
||||||
+ with suppress(FileNotFoundError), open(lease_file, "r") as file:
|
|
||||||
+ for line in file:
|
|
||||||
if "dhcp-server-identifier" in line:
|
|
||||||
words = line.strip(" ;\r\n").split(" ")
|
|
||||||
if len(words) > 2:
|
|
||||||
@@ -561,7 +567,7 @@ class Udhcpc(DhcpClient):
|
|
||||||
|
|
||||||
tmp_dir = temp_utils.get_tmp_ancestor(needs_exe=True)
|
|
||||||
lease_file = os.path.join(tmp_dir, interface + ".lease.json")
|
|
||||||
- with contextlib.suppress(FileNotFoundError):
|
|
||||||
+ with suppress(FileNotFoundError):
|
|
||||||
os.remove(lease_file)
|
|
||||||
|
|
||||||
# udhcpc needs the interface up to send initial discovery packets
|
|
||||||
diff --git a/tests/unittests/net/test_dhcp.py b/tests/unittests/net/test_dhcp.py
|
|
||||||
index a7b62312..8ec96eef 100644
|
|
||||||
--- a/tests/unittests/net/test_dhcp.py
|
|
||||||
+++ b/tests/unittests/net/test_dhcp.py
|
|
||||||
@@ -32,6 +32,46 @@ LEASE_F = "/run/dhclient.lease"
|
|
||||||
DHCLIENT = "/sbin/dhclient"
|
|
||||||
|
|
||||||
|
|
||||||
+@pytest.mark.parametrize(
|
|
||||||
+ "server_address,lease_file_content",
|
|
||||||
+ (
|
|
||||||
+ pytest.param(None, None, id="no_server_addr_on_absent_lease_file"),
|
|
||||||
+ pytest.param(None, "", id="no_server_addr_on_empty_lease_file"),
|
|
||||||
+ pytest.param(
|
|
||||||
+ None,
|
|
||||||
+ "lease {\n fixed-address: 10.1.2.3;\n}\n",
|
|
||||||
+ id="no_server_addr_when_no_server_ident",
|
|
||||||
+ ),
|
|
||||||
+ pytest.param(
|
|
||||||
+ "10.4.5.6",
|
|
||||||
+ "lease {\n fixed-address: 10.1.2.3;\n"
|
|
||||||
+ " option dhcp-server-identifier 10.4.5.6;\n"
|
|
||||||
+ " option dhcp-renewal-time 1800;\n}\n",
|
|
||||||
+ id="server_addr_found_when_server_ident_present",
|
|
||||||
+ ),
|
|
||||||
+ ),
|
|
||||||
+)
|
|
||||||
+class TestParseDHCPServerFromLeaseFile:
|
|
||||||
+ def test_find_server_address_when_present(
|
|
||||||
+ self, server_address, lease_file_content, tmp_path
|
|
||||||
+ ):
|
|
||||||
+ """Test that we return None in the case of no file or file contains no
|
|
||||||
+ server address, otherwise return the address.
|
|
||||||
+ """
|
|
||||||
+ lease_file = tmp_path / "dhcp.leases"
|
|
||||||
+ if server_address:
|
|
||||||
+ if lease_file_content:
|
|
||||||
+ lease_file.write_text(lease_file_content)
|
|
||||||
+ assert (
|
|
||||||
+ server_address
|
|
||||||
+ == IscDhclient.parse_dhcp_server_from_lease_file(lease_file)
|
|
||||||
+ )
|
|
||||||
+ else:
|
|
||||||
+ assert not IscDhclient.parse_dhcp_server_from_lease_file(
|
|
||||||
+ lease_file
|
|
||||||
+ )
|
|
||||||
+
|
|
||||||
+
|
|
||||||
class TestParseDHCPLeasesFile(CiTestCase):
|
|
||||||
def test_parse_empty_lease_file_errors(self):
|
|
||||||
"""parse_dhcp_lease_file errors when file content is empty."""
|
|
||||||
--
|
|
||||||
2.39.3
|
|
||||||
|
|
@ -1,53 +0,0 @@
|
|||||||
From b7fddab36d805099639358736dab474d2924906b Mon Sep 17 00:00:00 2001
|
|
||||||
From: Brett Holman <brett.holman@canonical.com>
|
|
||||||
Date: Wed, 19 Jun 2024 17:07:56 -0600
|
|
||||||
Subject: [PATCH 2/6] fix(jsonschema): Add missing sudo definition (#5418)
|
|
||||||
|
|
||||||
RH-Author: Ani Sinha <anisinha@redhat.com>
|
|
||||||
RH-MergeRequest: 90: fix(jsonschema): Add missing sudo definition (#5418)
|
|
||||||
RH-Jira: RHEL-44337
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
||||||
RH-Commit: [1/2] 9e56c7ab35744c6530c8cef2f122ffdcc0480d29 (anisinha/cloud-init)
|
|
||||||
|
|
||||||
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 a553c52c..8b10fe70 100644
|
|
||||||
--- a/cloudinit/config/schemas/schema-cloud-config-v1.json
|
|
||||||
+++ b/cloudinit/config/schemas/schema-cloud-config-v1.json
|
|
||||||
@@ -299,6 +299,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
|
|
||||||
|
|
@ -1,35 +0,0 @@
|
|||||||
From 790caeb9a7ead41f5c2dbfc0968ac0fc08a7db70 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Brett Holman <brett.holman@canonical.com>
|
|
||||||
Date: Tue, 5 Dec 2023 16:40:03 -0700
|
|
||||||
Subject: [PATCH 2/2] fix(python3.13): Fix import error for passlib on Python
|
|
||||||
3.13 (#4669)
|
|
||||||
|
|
||||||
RH-Author: xiachen <xiachen@redhat.com>
|
|
||||||
RH-MergeRequest: 111: Fix metric setting for ifcfg network connections for rhel (#5777)
|
|
||||||
RH-Jira: RHEL-61224
|
|
||||||
RH-Acked-by: Ani Sinha <anisinha@redhat.com>
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Commit: [2/2] dc6114a60280bac272bb355f4ea4d4d5d3bc240a (xiachen/cloud-init-centos)
|
|
||||||
|
|
||||||
(cherry picked from commit 09b70436b3a0aae1fe24fdde6e8cdd7ee98d9c15)
|
|
||||||
Signed-off-by: Amy Chen <xiachen@redhat.com>
|
|
||||||
---
|
|
||||||
cloudinit/sources/DataSourceAzure.py | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/cloudinit/sources/DataSourceAzure.py b/cloudinit/sources/DataSourceAzure.py
|
|
||||||
index eb0304c3..93921010 100644
|
|
||||||
--- a/cloudinit/sources/DataSourceAzure.py
|
|
||||||
+++ b/cloudinit/sources/DataSourceAzure.py
|
|
||||||
@@ -58,7 +58,7 @@ try:
|
|
||||||
)
|
|
||||||
except (ImportError, AttributeError):
|
|
||||||
try:
|
|
||||||
- import passlib
|
|
||||||
+ import passlib.hash
|
|
||||||
|
|
||||||
blowfish_hash = passlib.hash.sha512_crypt.hash
|
|
||||||
except ImportError:
|
|
||||||
--
|
|
||||||
2.39.3
|
|
||||||
|
|
@ -1,412 +0,0 @@
|
|||||||
From ce69cd178d9c05827db1ca1654de82dc3f9f521e Mon Sep 17 00:00:00 2001
|
|
||||||
From: Chad Smith <chad.smith@canonical.com>
|
|
||||||
Date: Thu, 27 Jun 2024 18:12:31 -0600
|
|
||||||
Subject: [PATCH 3/3] fix(schema): permit deprecated hyphenated keys under
|
|
||||||
users key (#5456)
|
|
||||||
|
|
||||||
RH-Author: Ani Sinha <anisinha@redhat.com>
|
|
||||||
RH-MergeRequest: 95: Deprecate the users ssh-authorized-keys property (#5162)
|
|
||||||
RH-Jira: RHEL-45262
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
||||||
RH-Commit: [3/3] 76804599a9166796dc52bab2031a706993ad2e3c (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
|
|
||||||
|
|
||||||
(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 97cf2b74..03e723e2 100644
|
|
||||||
--- a/cloudinit/config/schemas/schema-cloud-config-v1.json
|
|
||||||
+++ b/cloudinit/config/schemas/schema-cloud-config-v1.json
|
|
||||||
@@ -178,9 +178,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"
|
|
||||||
],
|
|
||||||
@@ -203,9 +203,7 @@
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"lock-passwd": {
|
|
||||||
- "default": true,
|
|
||||||
"type": "boolean",
|
|
||||||
- "description": "Default: ``true``",
|
|
||||||
"deprecated": true,
|
|
||||||
"deprecated_version": "22.3",
|
|
||||||
"deprecated_description": "Use ``lock_passwd`` instead."
|
|
||||||
@@ -215,16 +213,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``",
|
|
||||||
@@ -234,24 +250,54 @@
|
|
||||||
"description": "Hash of user password applied when user does not exist. This will NOT be applied if the user already exists. To generate this hash, run: mkpasswd --method=SHA-512 --rounds=4096. **Note:** While hashed password is better than plain text, using ``passwd`` in user-data represents a security risk as user-data could be accessible by third-parties depending on your cloud platform.",
|
|
||||||
"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 pre-existing. To generate this hash, run: mkpasswd --method=SHA-512 --rounds=4096. **Note:** While ``hashed_password`` is better than ``plain_text_passwd``, using ``passwd`` in user-data represents a security risk as user-data could be accessible by third-parties depending on your cloud platform.",
|
|
||||||
"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 pre-existing. There are many more secure options than using plain text passwords, such as ``ssh_import_id`` or ``hashed_passwd``. Do not use this in production as user-data and your password can be exposed.",
|
|
||||||
"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 to default SELinux user.",
|
|
||||||
"type": "string"
|
|
||||||
@@ -273,20 +319,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``.",
|
|
||||||
@@ -296,6 +346,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,
|
|
||||||
@@ -398,7 +454,6 @@
|
|
||||||
"properties": {
|
|
||||||
"remove-defaults": {
|
|
||||||
"type": "boolean",
|
|
||||||
- "default": false,
|
|
||||||
"deprecated": true,
|
|
||||||
"deprecated_version": "22.3",
|
|
||||||
"deprecated_description": "Use ``remove_defaults`` instead."
|
|
||||||
@@ -516,9 +571,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."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
@@ -1483,7 +1538,6 @@
|
|
||||||
},
|
|
||||||
"grub-dpkg": {
|
|
||||||
"type": "object",
|
|
||||||
- "description": "An alias for ``grub_dpkg``",
|
|
||||||
"deprecated": true,
|
|
||||||
"deprecated_version": "22.2",
|
|
||||||
"deprecated_description": "Use ``grub_dpkg`` instead."
|
|
||||||
@@ -2082,24 +2136,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."
|
|
||||||
@@ -2798,7 +2846,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 9ba7f178..734dbc53 100644
|
|
||||||
--- a/tests/unittests/config/test_cc_package_update_upgrade_install.py
|
|
||||||
+++ b/tests/unittests/config/test_cc_package_update_upgrade_install.py
|
|
||||||
@@ -192,16 +192,16 @@ class TestPackageUpdateUpgradeSchema:
|
|
||||||
(
|
|
||||||
{"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."
|
|
||||||
),
|
|
||||||
),
|
|
||||||
@@ -209,8 +209,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 52667332..8208affc 100644
|
|
||||||
--- a/tests/unittests/config/test_schema.py
|
|
||||||
+++ b/tests/unittests/config/test_schema.py
|
|
||||||
@@ -2251,9 +2251,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
|
|
||||||
@@ -2264,11 +2264,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
|
|
||||||
|
|
@ -1,185 +0,0 @@
|
|||||||
From 9ee9fe608b906fe4e523cbf7fbe4539f0322ba2f Mon Sep 17 00:00:00 2001
|
|
||||||
From: PengpengSun <40026211+PengpengSun@users.noreply.github.com>
|
|
||||||
Date: Thu, 4 Jul 2024 04:06:39 +0800
|
|
||||||
Subject: [PATCH 2/2] fix(vmware): Set IPv6 to dhcp when there is no IPv6 addr
|
|
||||||
(#5471)
|
|
||||||
|
|
||||||
RH-Author: xiachen <xiachen@redhat.com>
|
|
||||||
RH-MergeRequest: 99: fix(vmware): Set IPv6 to dhcp when there is no IPv6 addr (#5471)
|
|
||||||
RH-Jira: RHEL-46194
|
|
||||||
RH-Acked-by: Ani Sinha <anisinha@redhat.com>
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Commit: [1/1] fbae24c7e7f48239200eaf457d260203fb550845 (xiachen/cloud-init-centos)
|
|
||||||
|
|
||||||
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 b53ea96c..25d3b093 100644
|
|
||||||
--- a/tests/unittests/sources/vmware/test_vmware_config_file.py
|
|
||||||
+++ b/tests/unittests/sources/vmware/test_vmware_config_file.py
|
|
||||||
@@ -240,27 +240,45 @@ class TestVmwareConfigFile(CiTestCase):
|
|
||||||
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
|
|
||||||
@@ -285,6 +303,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(
|
|
||||||
@@ -344,6 +363,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(
|
|
||||||
@@ -351,16 +371,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")
|
|
||||||
@@ -447,7 +469,10 @@ class TestVmwareNetConfig(CiTestCase):
|
|
||||||
"type": "static",
|
|
||||||
"address": "10.20.87.154",
|
|
||||||
"netmask": "255.255.252.0",
|
|
||||||
- }
|
|
||||||
+ },
|
|
||||||
+ {
|
|
||||||
+ "type": "dhcp6",
|
|
||||||
+ },
|
|
||||||
],
|
|
||||||
}
|
|
||||||
],
|
|
||||||
@@ -498,7 +523,10 @@ class TestVmwareNetConfig(CiTestCase):
|
|
||||||
"metric": 10000,
|
|
||||||
}
|
|
||||||
],
|
|
||||||
- }
|
|
||||||
+ },
|
|
||||||
+ {
|
|
||||||
+ "type": "dhcp6",
|
|
||||||
+ },
|
|
||||||
],
|
|
||||||
}
|
|
||||||
],
|
|
||||||
@@ -558,7 +586,10 @@ class TestVmwareNetConfig(CiTestCase):
|
|
||||||
"metric": 10000,
|
|
||||||
}
|
|
||||||
],
|
|
||||||
- }
|
|
||||||
+ },
|
|
||||||
+ {
|
|
||||||
+ "type": "dhcp6",
|
|
||||||
+ },
|
|
||||||
],
|
|
||||||
}
|
|
||||||
],
|
|
||||||
@@ -603,7 +634,10 @@ class TestVmwareNetConfig(CiTestCase):
|
|
||||||
"address": "10.20.87.154",
|
|
||||||
"netmask": "255.255.252.0",
|
|
||||||
"gateway": "10.20.87.253",
|
|
||||||
- }
|
|
||||||
+ },
|
|
||||||
+ {
|
|
||||||
+ "type": "dhcp6",
|
|
||||||
+ },
|
|
||||||
],
|
|
||||||
}
|
|
||||||
],
|
|
||||||
--
|
|
||||||
2.39.3
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
|||||||
Name: cloud-init
|
Name: cloud-init
|
||||||
Version: 23.4
|
Version: 24.4
|
||||||
Release: 22%{?dist}
|
Release: 1%{?dist}
|
||||||
Summary: Cloud instance init scripts
|
Summary: Cloud instance init scripts
|
||||||
License: ASL 2.0 or GPLv3
|
License: ASL 2.0 or GPLv3
|
||||||
URL: http://launchpad.net/cloud-init
|
URL: http://launchpad.net/cloud-init
|
||||||
@ -8,75 +8,11 @@ Source0: https://github.com/canonical/cloud-init/archive/refs/tags/%{vers
|
|||||||
Source1: cloud-init-tmpfiles.conf
|
Source1: cloud-init-tmpfiles.conf
|
||||||
|
|
||||||
# Source-git patches
|
# Source-git patches
|
||||||
Patch1: 0001-Add-initial-redhat-changes.patch
|
Patch1: 0001-downstream-Add-initial-redhat-changes.patch
|
||||||
Patch2: 0002-Do-not-write-NM_CONTROLLED-no-in-generated-interface.patch
|
Patch2: 0002-downstream-Setting-autoconnect-priority-setting-for-.patch
|
||||||
Patch3: 0003-Setting-autoconnect-priority-setting-for-network-scr.patch
|
Patch3: 0004-downstream-Revert-chore-eliminate-redundant-ordering.patch
|
||||||
Patch4: 0004-net-network_manager-do-not-set-may-fail-to-False-for.patch
|
Patch4: 0005-downstream-remove-single-process-optimization.patch
|
||||||
Patch5: 0005-net-allow-dhcp6-configuration-from-generate_fallback.patch
|
Patch5: 0006-fix-don-t-deadlock-when-starting-network-service-wit.patch
|
||||||
Patch6: 0006-net-nm-check-for-presence-of-ifcfg-files-when-nm-con.patch
|
|
||||||
Patch7: 0007-test-jsonschema-Pin-jsonschema-version-4781.patch
|
|
||||||
Patch8: 0008-fix-clean-stop-warning-when-running-clean-command-47.patch
|
|
||||||
# For RHEL-22255 - [Azure][RHEL-9] cloud-init-23.4 cannot read "- Azure" datasource_list format
|
|
||||||
Patch9: ci-Revert-Use-grep-for-faster-parsing-of-cloud-config-i.patch
|
|
||||||
Patch10: ci-Pin-pythes-8.0.0.patch
|
|
||||||
# For RHEL-21324 - [rhel-9] The schema WARNING info for network-config.json is not suitable in cloud-init-23.4
|
|
||||||
Patch11: ci-fix-Add-types-to-network-v1-schema-4841.patch
|
|
||||||
# For RHEL-28549 - [RHEL 9.4] cloud-init 23.4 returns 2 on recoverable errors instead of 0
|
|
||||||
Patch12: ci-Retain-exit-code-in-cloud-init-status-for-recoverabl.patch
|
|
||||||
# For RHEL-20964 - [rhel-9]cloud-init fails to configure DNS/search domains for network-config v1
|
|
||||||
Patch13: ci-fix-Correct-v2-NetworkManager-route-rendering-4637.patch
|
|
||||||
# For RHEL-20964 - [rhel-9]cloud-init fails to configure DNS/search domains for network-config v1
|
|
||||||
Patch14: ci-feat-apply-global-DNS-to-interfaces-in-network-manag.patch
|
|
||||||
# For RHEL-29709 - Suggest to backport patch ff40d1a to undeprecate 'network' in schema route definition
|
|
||||||
Patch15: ci-fix-Undeprecate-network-in-schema-route-definition-5.patch
|
|
||||||
# For RHEL-32846 - [cloud-init][ESXi]VMware datasource resets on every boot causing it to lose network configuration [rhel-9]
|
|
||||||
Patch16: ci-fix-Fall-back-to-cached-local-ds-if-no-valid-ds-foun.patch
|
|
||||||
# For RHEL-36255 - [rhel-9.5] DataSourceNoCloudNet not configurable via config files
|
|
||||||
Patch17: ci-fix-Always-use-single-datasource-if-specified-5098.patch
|
|
||||||
# For RHEL-40217 - [Cloud-init] CloudstackDataSource cannot work with NetworkManager
|
|
||||||
Patch18: ci-fix-cloudstack-Use-parsed-lease-file-for-virtual-rou.patch
|
|
||||||
# For RHEL-17961 - [RHEL-9] cloud-init fails to configure DNS search domains
|
|
||||||
Patch19: ci-feat-sysconfig-Add-DNS-from-interface-config-to-reso.patch
|
|
||||||
# For RHEL-44337 - [rhel-9] fix `SUDO` configuration schema for users and groups
|
|
||||||
Patch20: ci-fix-jsonschema-Add-missing-sudo-definition-5418.patch
|
|
||||||
# For RHEL-44337 - [rhel-9] fix `SUDO` configuration schema for users and groups
|
|
||||||
Patch21: ci-doc-update-examples-to-reflect-alternative-ways-to-p.patch
|
|
||||||
# For RHEL-44598 - fix pylint error and support python 3.12
|
|
||||||
Patch22: ci-fix-dhcp-Guard-against-FileNotFoundError-and-NameErr.patch
|
|
||||||
# For RHEL-44598 - fix pylint error and support python 3.12
|
|
||||||
Patch23: ci-fix-Address-TIOBE-abstract-interpretation-issues-486.patch
|
|
||||||
# For RHEL-44598 - fix pylint error and support python 3.12
|
|
||||||
Patch24: ci-Update-pylint-version-to-support-python-3.12-5338.patch
|
|
||||||
# For RHEL-45262 - Deprecate the users ssh-authorized-keys property and permit deprecated hyphenated keys under users key
|
|
||||||
Patch25: ci-Deprecate-the-users-ssh-authorized-keys-property-516.patch
|
|
||||||
# For RHEL-45262 - Deprecate the users ssh-authorized-keys property and permit deprecated hyphenated keys under users key
|
|
||||||
Patch26: ci-docs-Add-deprecated-system_info-to-schema-5168.patch
|
|
||||||
# For RHEL-45262 - Deprecate the users ssh-authorized-keys property and permit deprecated hyphenated keys under users key
|
|
||||||
Patch27: ci-fix-schema-permit-deprecated-hyphenated-keys-under-u.patch
|
|
||||||
# For RHEL-44916 - [RFE] Support metalink in yum repository config
|
|
||||||
Patch28: ci-Support-metalink-in-yum-repository-config-5444.patch
|
|
||||||
# For RHEL-46194 - [RHEL-9] It leaves the ipv6 networking config as blank in NM keyfile when config dhcp ipv6 with customization spec
|
|
||||||
Patch29: ci-fix-vmware-Set-IPv6-to-dhcp-when-there-is-no-IPv6-ad.patch
|
|
||||||
# For RHEL-46873 - Suggest to update schema to support metalink
|
|
||||||
Patch30: ci-fix-add-schema-rules-for-baseurl-and-metalink-in-yum.patch
|
|
||||||
# For RHEL-49736 - [Cloud-init] [RHEL-9] Password reset feature broken with CloudstackDataSource
|
|
||||||
Patch31: ci-fix-Clean-cache-if-no-datasource-fallback-5499.patch
|
|
||||||
# For RHEL-49674 - Support setting mirrorlist in yum repository config
|
|
||||||
Patch32: ci-Support-setting-mirrorlist-in-yum-repository-config-.patch
|
|
||||||
# For RHEL-54373 - [RHEL9]Revert "fix(vmware): Set IPv6 to dhcp when there is no IPv6 addr (#5471)"
|
|
||||||
Patch33: ci-Revert-fix-vmware-Set-IPv6-to-dhcp-when-there-is-no-.patch
|
|
||||||
# For RHEL-54686 - [RHEL-9.5] cloud-init schema validation fails.
|
|
||||||
Patch34: ci-fix-Add-subnet-ipv4-ipv6-to-network-schema-5191.patch
|
|
||||||
# For RHEL-61224 - Configuring metric for default gateway is not working
|
|
||||||
Patch35: ci-Fix-metric-setting-for-ifcfg-network-connections-for.patch
|
|
||||||
# For RHEL-61224 - Configuring metric for default gateway is not working
|
|
||||||
Patch36: ci-fix-python3.13-Fix-import-error-for-passlib-on-Pytho.patch
|
|
||||||
# For RHEL-38927 - NoCloud - network_config bridges incorrectly configured
|
|
||||||
Patch37: ci-fix-Render-bridges-correctly-for-v2-on-sysconfig-wit.patch
|
|
||||||
# For RHEL-38927 - NoCloud - network_config bridges incorrectly configured
|
|
||||||
Patch38: ci-fix-Render-v2-bridges-correctly-on-network-manager-w.patch
|
|
||||||
# For RHEL-65768 - [RHEL-9] Prevent NM from handling DNS when network interfaces have DNS config
|
|
||||||
Patch39: ci-Prevent-NM-from-handling-DNS-when-network-interfaces.patch
|
|
||||||
|
|
||||||
BuildArch: noarch
|
BuildArch: noarch
|
||||||
|
|
||||||
@ -285,12 +221,17 @@ fi
|
|||||||
%{_datadir}/bash-completion/completions/cloud-init
|
%{_datadir}/bash-completion/completions/cloud-init
|
||||||
%{_bindir}/cloud-id
|
%{_bindir}/cloud-id
|
||||||
%{_systemdgeneratordir}/cloud-init-generator
|
%{_systemdgeneratordir}/cloud-init-generator
|
||||||
%{_sysconfdir}/systemd/system/sshd-keygen@.service.d/disable-sshd-keygen-if-cloud-init-active.conf
|
%{_unitdir}/sshd-keygen@.service.d/disable-sshd-keygen-if-cloud-init-active.conf
|
||||||
|
|
||||||
%dir %{_sysconfdir}/rsyslog.d
|
%dir %{_sysconfdir}/rsyslog.d
|
||||||
%config(noreplace) %{_sysconfdir}/rsyslog.d/21-cloudinit.conf
|
%config(noreplace) %{_sysconfdir}/rsyslog.d/21-cloudinit.conf
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Mon Jan 06 2025 Miroslav Rezanina <mrezanin@redhat.com> - 24.4-1
|
||||||
|
- Rebase to 24.4 [RHEL-66251]
|
||||||
|
- Resolves: RHEL-66251
|
||||||
|
([RHEL-9] Rebase cloud-init to 24.4 version)
|
||||||
|
|
||||||
* Mon Nov 18 2024 Miroslav Rezanina <mrezanin@redhat.com> - 23.4-22
|
* Mon Nov 18 2024 Miroslav Rezanina <mrezanin@redhat.com> - 23.4-22
|
||||||
- ci-Prevent-NM-from-handling-DNS-when-network-interfaces.patch [RHEL-65768]
|
- ci-Prevent-NM-from-handling-DNS-when-network-interfaces.patch [RHEL-65768]
|
||||||
- Resolves: RHEL-65768
|
- Resolves: RHEL-65768
|
||||||
|
2
sources
2
sources
@ -1 +1 @@
|
|||||||
SHA512 (23.4.tar.gz) = e425a957cb38f2be2fcb83693696d0177ad84150f8a55759226d8696344ddd75e33e23a7230c492087784ef96ddd71305bc3462479e2c1a3ed0e704ac0f2d879
|
SHA512 (24.4.tar.gz) = df42fb0c97aba37599e3c9431e1dfffc0a3c0ce6d639fd9a980fe0da190c998da3130ab65e3288eecd193967dbaad41aac3c0040244cf6036db9584a3c87538d
|
||||||
|
Loading…
Reference in New Issue
Block a user