Import OL

This commit is contained in:
eabdullin 2025-03-25 10:44:17 +03:00
parent f15764bc68
commit 43e3561687
37 changed files with 4759 additions and 69 deletions

View File

@ -0,0 +1,50 @@
Enable ec2_utils to stop retrying to get ec2 metadata
Signed-off-by: David Sloboda <david.x.sloboda@oracle.com>
Reviewed-by: Laurence Rochfort <laurence.rochfort@oracle.com>
diff -ruN a/cloudinit/sources/helpers/openstack.py b/cloudinit/sources/helpers/openstack.py
--- a/cloudinit/sources/helpers/openstack.py 2018-04-02 12:51:20.053828637 -0700
+++ b/cloudinit/sources/helpers/openstack.py 2018-04-02 12:33:20.000000000 -0700
@@ -464,6 +464,16 @@
return results
+def should_retry_cb(_request_args, cause):
+ try:
+ code = int(cause.code)
+ if code >= 400:
+ return False
+ except (TypeError, ValueError):
+ # Older versions of requests didn't have a code.
+ pass
+ return True
+
class MetadataReader(BaseReader):
def __init__(self, base_url, ssl_details=None, timeout=5, retries=5):
@@ -489,16 +499,6 @@
return self._versions
def _path_read(self, path, decode=False):
- def should_retry_cb(_request_args, cause):
- try:
- code = int(cause.code)
- if code >= 400:
- return False
- except (TypeError, ValueError):
- # Older versions of requests didn't have a code.
- pass
- return True
-
response = url_helper.readurl(
path,
retries=self.retries,
@@ -519,6 +519,7 @@
ssl_details=self.ssl_details,
timeout=self.timeout,
retries=self.retries,
+ exception_cb=should_retry_cb,
)

View File

@ -0,0 +1,136 @@
From 37a6837813e418486af8cbef436ab82a8be3e3fa Mon Sep 17 00:00:00 2001
From: Darren Archibald <darren.archibald@oracle.com>
Date: Fri, 23 Feb 2024 06:06:30 -0800
Subject: [PATCH] tests/unittests: add a new unit test for network manager net
activator (#4672)
Some changes in behavior in network manager net activator was brought in with
the commit
d1d5166895da ("net/nm: check for presence of ifcfg files when nm connection files are absent")
This change adds some unit tests that exercizes network manager activator's
bring_up_interface() method that tests failure scenarios as well as cases
where an ifcfg file is used to bring the interface up.
Signed-off-by: Ani Sinha <anisinha@redhat.com>
(cherry picked from commit bb474df78bfe45ea5f05907eb710e8d5de764fc8)
Signed-off-by: Darren Archibald <darren.archibald@oracle.com>
---
tests/unittests/test_net_activators.py | 101 +++++++++++++++++++++++++
1 file changed, 101 insertions(+)
diff --git a/tests/unittests/test_net_activators.py b/tests/unittests/test_net_activators.py
index 2a363ec..f95c8a7 100644
--- a/tests/unittests/test_net_activators.py
+++ b/tests/unittests/test_net_activators.py
@@ -288,6 +288,107 @@ class TestActivatorsBringUp:
for call in m_subp.call_args_list:
assert call in expected_call_list
+class TestNetworkManagerActivatorBringUp:
+ @patch("cloudinit.subp.subp", return_value=("", ""))
+ @patch(
+ "cloudinit.net.network_manager.available_nm_ifcfg_rh",
+ return_value=True,
+ )
+ @patch("os.path.isfile")
+ @patch("os.path.exists", return_value=True)
+ def test_bring_up_interface_no_nm_conn(
+ self, m_exists, m_isfile, m_plugin, m_subp
+ ):
+ """
+ There is no network manager connection file but ifcfg-rh plugin is
+ present and ifcfg interface config files are also present. In this
+ case, we should use ifcfg files.
+ """
+
+ def fake_isfile_no_nmconn(filename):
+ return False if filename.endswith(".nmconnection") else True
+
+ m_isfile.side_effect = fake_isfile_no_nmconn
+
+ expected_call_list = [
+ (
+ (
+ [
+ "nmcli",
+ "connection",
+ "load",
+ "".join(
+ [
+ "/etc/sysconfig/network-scripts/ifcfg-eth0",
+ ]
+ ),
+ ],
+ ),
+ {},
+ ),
+ (
+ (
+ [
+ "nmcli",
+ "connection",
+ "up",
+ "filename",
+ "".join(
+ [
+ "/etc/sysconfig/network-scripts/ifcfg-eth0",
+ ]
+ ),
+ ],
+ ),
+ {},
+ ),
+ ]
+
+ index = 0
+ assert NetworkManagerActivator.bring_up_interface("eth0")
+ for call in m_subp.call_args_list:
+ assert call == expected_call_list[index]
+ index += 1
+
+ @patch("cloudinit.subp.subp", return_value=("", ""))
+ @patch(
+ "cloudinit.net.network_manager.available_nm_ifcfg_rh",
+ return_value=False,
+ )
+ @patch("os.path.isfile")
+ @patch("os.path.exists", return_value=True)
+ def test_bring_up_interface_no_plugin_no_nm_conn(
+ self, m_exists, m_isfile, m_plugin, m_subp
+ ):
+ """
+ The ifcfg-rh plugin is absent and nmconnection file is also
+ not present. In this case, we can't use ifcfg file and the
+ interface bring up should fail.
+ """
+
+ def fake_isfile_no_nmconn(filename):
+ return False if filename.endswith(".nmconnection") else True
+
+ m_isfile.side_effect = fake_isfile_no_nmconn
+ assert not NetworkManagerActivator.bring_up_interface("eth0")
+
+ @patch("cloudinit.subp.subp", return_value=("", ""))
+ @patch(
+ "cloudinit.net.network_manager.available_nm_ifcfg_rh",
+ return_value=True,
+ )
+ @patch("os.path.isfile", return_value=False)
+ @patch("os.path.exists", return_value=True)
+ def test_bring_up_interface_no_conn_file(
+ self, m_exists, m_isfile, m_plugin, m_subp
+ ):
+ """
+ Neither network manager connection files are present nor
+ ifcfg files are present. Even if ifcfg-rh plugin is present,
+ we can not bring up the interface. So bring_up_interface()
+ should fail.
+ """
+ assert not NetworkManagerActivator.bring_up_interface("eth0")
IF_UP_DOWN_BRING_DOWN_CALL_LIST: list = [
((["ifdown", "eth0"],), {}),
--
2.31.1

View File

@ -0,0 +1,31 @@
From 4964e60ede9445e9891cf8501060ac2751a3ba5f Mon Sep 17 00:00:00 2001
From: Sourav Sharma <sourav.ss.sharma@oracle.com>
Date: Fri, 22 Nov 2024 14:32:05 +0530
Subject: [PATCH] Removes condition specific to OL for write_files_deferred
Github-issue-link: https://github.com/oracle/oracle-linux/issues/156
Orabug: 36958039
Signed-off-by: Sourav Sharma <sourav.ss.sharma@oracle.com>
---
config/cloud.cfg.tmpl | 2 --
1 file changed, 2 deletions(-)
diff --git a/config/cloud.cfg.tmpl b/config/cloud.cfg.tmpl
index c756719..28ee581 100644
--- a/config/cloud.cfg.tmpl
+++ b/config/cloud.cfg.tmpl
@@ -199,9 +199,7 @@ cloud_final_modules:
{% if variant in ["ubuntu", "unknown"] %}
- ubuntu_drivers
{% endif %}
-{% if variant not in ["ol"] %}
- write_files_deferred
-{% endif %}
- puppet
- chef
- ansible
--
2.43.5

View File

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

View File

@ -0,0 +1,145 @@
From 94c0cd9c656877250f7e5cfe05325a42bbdec182 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: 145: Fix metric setting for ifcfg network connections for rhel (#5777)
RH-Jira: RHEL-65018
RH-Acked-by: Ani Sinha <anisinha@redhat.com>
RH-Commit: [1/2] a18205f1ffa455a2ccd836ba6baa12b7da0afbde (xiachen/cloud-init)
Most RHEL systems use Network manager to bring up manage network connections.
Network manager does not recognize "METRIC" option for network connections.
It uses IPV4_ROUTE_METRIC and IPV6_ROUTE_METRIC options. Please see
https://people.freedesktop.org/~lkundrak/nm-docs/nm-settings-ifcfg-rh.html
This change ensures that cloud-init generates ifcfg network connection files
with IPV{4/6}_ROUTE_METRIC options that are compatible with RHEL and
network manager.
Fixes GH-5776
(cherry picked from commit a399f4b0815234e3fe11255178c737902b2d243d)
Signed-off-by: Amy Chen <xiachen@redhat.com>
---
cloudinit/net/sysconfig.py | 21 ++++++++++++++++++---
tests/unittests/test_net.py | 37 ++++++++++++++++++++-----------------
2 files changed, 38 insertions(+), 20 deletions(-)
diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
index 7eb430ed1..b50a6a8a0 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 2d716f4b5..4673e4eaf 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

View File

@ -0,0 +1,248 @@
From 038a391b7016f16a7336d67965762a7dbf3ba662 Mon Sep 17 00:00:00 2001
From: Ani Sinha <anisinha@redhat.com>
Date: Tue, 5 Nov 2024 04:07:36 +0530
Subject: [PATCH] Prevent NM from handling DNS when network interfaces have DNS
config (#5846)
RH-Author: Ani Sinha <anisinha@redhat.com>
RH-MergeRequest: 150: Prevent NM from handling DNS when network interfaces have DNS config (#5846)
RH-Jira: RHEL-65778
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [1/1] b464ef219eba1a0c718dda5ed96b6f88e1273f99
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 e4a65187f..4898a2fd1 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 ddb45dc69..47b36d052 100644
--- a/tests/unittests/test_net.py
+++ b/tests/unittests/test_net.py
@@ -967,6 +967,164 @@ dns = none
),
],
},
+ {
+ "in_data": {
+ "networks": [
+ {
+ "network_id": "dacd568d-5be6-4786-91fe-750c374b78b4",
+ "type": "ipv4",
+ "netmask": "255.255.252.0",
+ "link": "eth0",
+ "routes": [
+ {
+ "netmask": "0.0.0.0",
+ "network": "0.0.0.0",
+ "gateway": "172.19.3.254",
+ }
+ ],
+ "ip_address": "172.19.1.34",
+ "dns_search": ["example3.com"],
+ "dns_nameservers": ["172.19.0.12"],
+ "id": "network0",
+ }
+ ],
+ "links": [
+ {
+ "ethernet_mac_address": "fa:16:3e:ed:9a:59",
+ "mtu": None,
+ "type": "physical",
+ "id": "eth0",
+ },
+ ],
+ },
+ "in_macs": {
+ "fa:16:3e:ed:9a:59": "eth0",
+ },
+ "out_sysconfig_opensuse": [
+ (
+ "etc/sysconfig/network/ifcfg-eth0",
+ """
+# Created by cloud-init automatically, do not edit.
+#
+BOOTPROTO=static
+IPADDR=172.19.1.34
+LLADDR=fa:16:3e:ed:9a:59
+NETMASK=255.255.252.0
+STARTMODE=auto
+""".lstrip(),
+ ),
+ (
+ "etc/resolv.conf",
+ """
+; Created by cloud-init automatically, do not edit.
+;
+nameserver 172.19.0.12
+search example3.com
+""".lstrip(),
+ ),
+ (
+ "etc/NetworkManager/conf.d/99-cloud-init.conf",
+ """
+# Created by cloud-init automatically, do not edit.
+#
+[main]
+dns = none
+""".lstrip(),
+ ),
+ (
+ "etc/udev/rules.d/85-persistent-net-cloud-init.rules",
+ "".join(
+ [
+ 'SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ',
+ 'ATTR{address}=="fa:16:3e:ed:9a:59", NAME="eth0"\n',
+ ]
+ ),
+ ),
+ ],
+ "out_sysconfig_rhel": [
+ (
+ "etc/sysconfig/network-scripts/ifcfg-eth0",
+ """
+# Created by cloud-init automatically, do not edit.
+#
+AUTOCONNECT_PRIORITY=120
+BOOTPROTO=none
+DEFROUTE=yes
+DEVICE=eth0
+DNS1=172.19.0.12
+DOMAIN=example3.com
+GATEWAY=172.19.3.254
+HWADDR=fa:16:3e:ed:9a:59
+IPADDR=172.19.1.34
+NETMASK=255.255.252.0
+ONBOOT=yes
+TYPE=Ethernet
+USERCTL=no
+""".lstrip(),
+ ),
+ (
+ "etc/resolv.conf",
+ """
+; Created by cloud-init automatically, do not edit.
+;
+nameserver 172.19.0.12
+search example3.com
+""".lstrip(),
+ ),
+ (
+ "etc/NetworkManager/conf.d/99-cloud-init.conf",
+ """
+# Created by cloud-init automatically, do not edit.
+#
+[main]
+dns = none
+""".lstrip(),
+ ),
+ (
+ "etc/udev/rules.d/70-persistent-net.rules",
+ "".join(
+ [
+ 'SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ',
+ 'ATTR{address}=="fa:16:3e:ed:9a:59", NAME="eth0"\n',
+ ]
+ ),
+ ),
+ ],
+ "expected_network_manager": [
+ (
+ "".join(
+ [
+ "etc/NetworkManager/system-connections",
+ "/cloud-init-eth0.nmconnection",
+ ]
+ ),
+ """
+# Generated by cloud-init. Changes will be lost.
+
+[connection]
+id=cloud-init eth0
+uuid=1dd9a779-d327-56e1-8454-c65e2556c12c
+autoconnect-priority=120
+type=ethernet
+
+[user]
+org.freedesktop.NetworkManager.origin=cloud-init
+
+[ethernet]
+mac-address=FA:16:3E:ED:9A:59
+
+[ipv4]
+method=manual
+may-fail=false
+address1=172.19.1.34/22
+route1=0.0.0.0/0,172.19.3.254
+dns=172.19.0.12;
+dns-search=example3.com;
+
+""".lstrip(),
+ ),
+ ],
+ },
{
"in_data": {
"services": [{"type": "dns", "address": "172.19.0.12"}],
--
2.39.3

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,306 @@
From 1df31428c87f08c790c300ba402318378cea8d65 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: 147: fix: Render bridges correctly for v2 on sysconfig with set-name (#5674)
RH-Jira: RHEL-65021
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
RH-Acked-by: Ani Sinha <anisinha@redhat.com>
RH-Commit: [1/2] 7f7fce173ee9a3ba719fc36580fbce813c5bfbd0 (xiachen/cloud-init)
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 486fa22dc..ac0306d6a 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 14c57cdcc..226421bd0 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 b50a6a8a0..e4a65187f 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 4673e4eaf..004da81ab 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

View File

@ -0,0 +1,160 @@
From 58904df7d689df6e3d1d4ddf47b5cb5a267006da 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: 147: fix: Render bridges correctly for v2 on sysconfig with set-name (#5674)
RH-Jira: RHEL-65021
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
RH-Acked-by: Ani Sinha <anisinha@redhat.com>
RH-Commit: [2/2] e101d8ff06a379752958a3eb19d209bcb7d1e0ed (xiachen/cloud-init)
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 0ba210b74..f50fafa39 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 004da81ab..ddb45dc69 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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,103 @@
From 75e658591f6187f73eb0baa3291bde01db62cc5e Mon Sep 17 00:00:00 2001
From: Brett Holman <brett.holman@canonical.com>
Date: Fri, 23 Feb 2024 11:16:15 -0700
Subject: [PATCH] fix(nocloud): smbios datasource definition
RH-Author: Ani Sinha <anisinha@redhat.com>
RH-MergeRequest: 154: fix(nocloud): smbios datasource definition
RH-Jira: RHEL-79774
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
RH-Acked-by: Jon Maloy <jmaloy@redhat.com>
RH-Commit: [1/1] 3ce501f6167ffafcb6dea7df37589d348039a371
deprecate nocloud-net name
(cherry picked from commit 66b5ce9d5f94c0c6625972fdfdca3796d365b069)
---
cloudinit/sources/DataSourceNoCloud.py | 39 ++++++++++++++++++++++----
cloudinit/sources/__init__.py | 11 +++++---
2 files changed, 41 insertions(+), 9 deletions(-)
diff --git a/cloudinit/sources/DataSourceNoCloud.py b/cloudinit/sources/DataSourceNoCloud.py
index 55a16638..7581f0a5 100644
--- a/cloudinit/sources/DataSourceNoCloud.py
+++ b/cloudinit/sources/DataSourceNoCloud.py
@@ -11,6 +11,7 @@
import errno
import logging
import os
+from functools import partial
from cloudinit import dmi, sources, util
from cloudinit.net import eni
@@ -368,12 +369,40 @@ class DataSourceNoCloudNet(DataSourceNoCloud):
self.supported_seed_starts = ("http://", "https://")
def ds_detect(self):
- """NoCloud requires "nocloud-net" as the way to specify
- seeding from an http(s) address. This diverges from all other
- datasources in that it does a kernel commandline match on something
- other than the datasource dsname for only DEP_NETWORK.
+ """Check dmi and kernel commandline for dsname
+
+ NoCloud historically used "nocloud-net" as its dsname
+ for network timeframe (DEP_NETWORK), which supports http(s) urls.
+ For backwards compatiblity, check for that dsname.
"""
- return "nocloud-net" == sources.parse_cmdline()
+ log_deprecated = partial(
+ util.deprecate,
+ deprecated="The 'nocloud-net' datasource name",
+ deprecated_version="24.1",
+ extra_message=(
+ "Use 'nocloud' instead, which uses the seedfrom protocol"
+ "scheme (http// or file://) to decide how to run."
+ ),
+ )
+
+ if "nocloud-net" == sources.parse_cmdline():
+ log_deprecated()
+ return True
+
+ serial = sources.parse_cmdline_or_dmi(
+ dmi.read_dmi_data("system-serial-number") or ""
+ ).lower()
+
+ if serial in (self.dsname.lower(), "nocloud-net"):
+ LOG.debug(
+ "Machine is configured by dmi serial number to run on "
+ "single datasource %s.",
+ self,
+ )
+ if serial == "nocloud-net":
+ log_deprecated()
+ return True
+ return False
# Used to match classes to dependencies
diff --git a/cloudinit/sources/__init__.py b/cloudinit/sources/__init__.py
index 453801be..e89af3d0 100644
--- a/cloudinit/sources/__init__.py
+++ b/cloudinit/sources/__init__.py
@@ -1198,10 +1198,13 @@ def parse_cmdline() -> str:
"""Check if command line argument for this datasource was passed
Passing by command line overrides runtime datasource detection
"""
- cmdline = util.get_cmdline()
- ds_parse_0 = re.search(r"ds=([^\s;]+)", cmdline)
- ds_parse_1 = re.search(r"ci\.ds=([^\s;]+)", cmdline)
- ds_parse_2 = re.search(r"ci\.datasource=([^\s;]+)", cmdline)
+ return parse_cmdline_or_dmi(util.get_cmdline())
+
+
+def parse_cmdline_or_dmi(input: str) -> str:
+ ds_parse_0 = re.search(r"(?:^|\s)ds=([^\s;]+)", input)
+ ds_parse_1 = re.search(r"(?:^|\s)ci\.ds=([^\s;]+)", input)
+ ds_parse_2 = re.search(r"(?:^|\s)ci\.datasource=([^\s;]+)", input)
ds = ds_parse_0 or ds_parse_1 or ds_parse_2
deprecated = ds_parse_1 or ds_parse_2
if deprecated:
--
2.48.1

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,44 @@
From e7aba0f0ccd6f023667f41385f25044a94428ed3 Mon Sep 17 00:00:00 2001
From: Darren Archibald <darren.archibald@oracle.com>
Date: Fri, 23 Feb 2024 05:56:06 -0800
Subject: [PATCH] ignore enslaved interface
Changes to ignore all enslaved interfaces.
https://jira.oci.oraclecorp.com/browse/LINUX-1947
Orabug: 30092148
Signed-off-by: Si-Wei Liu <si-wei.liu@oracle.com>
Signed-off-by: Darren Archibald <darren.archibald@oracle.com>
---
cloudinit/net/__init__.py | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/cloudinit/net/__init__.py b/cloudinit/net/__init__.py
index c0888f5..b093796 100644
--- a/cloudinit/net/__init__.py
+++ b/cloudinit/net/__init__.py
@@ -335,6 +335,10 @@ def is_netfail_standby(devname, driver=None):
return True
+def is_slave(devname):
+ return os.path.exists(sys_dev_path(devname, "master"))
+
+
def is_renamed(devname):
"""
/* interface name assignment types (sysfs name_assign_type attribute) */
@@ -1054,6 +1058,9 @@ def get_interfaces(
if is_bridge(name):
filtered_logger("Ignoring bridge interface: %s", name)
continue
+ if is_slave(name):
+ filtered_logger("Ignoring bridge interface: %s", name)
+ continue
if filter_vlan and is_vlan(name):
continue
if is_bond(name):
--
2.31.1

View File

@ -0,0 +1,26 @@
From 8735577c8a683407e94abed0cfccc3aacbb9aa47 Mon Sep 17 00:00:00 2001
From: Si-Wei Liu <si-wei.liu@oracle.com>
Date: Wed, 10 Jun 2020 20:59:29 -0400
Subject: [PATCH] sysconfig: add Oracle Linux variant to known distros
otherwise anything sysconfig breaks on Oracle Linux.
JIRA: https://jira.oci.oraclecorp.com/browse/LINUX-6128
Signed-off-by: Si-Wei Liu <si-wei.liu@oracle.com>
---
cloudinit/net/sysconfig.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
index e94590f..55b7db5 100644
--- a/cloudinit/net/sysconfig.py
+++ b/cloudinit/net/sysconfig.py
@@ -35,6 +35,7 @@
"suse",
"TencentOS",
"virtuozzo",
+ "ol",
]

View File

@ -0,0 +1,81 @@
From 8eff3fdfd9ed477bead953deec3599c93409a415 Mon Sep 17 00:00:00 2001
From: Darren Archibald <darren.archibald@oracle.com>
Date: Fri, 23 Feb 2024 05:33:05 -0800
Subject: [PATCH] DataSourceOracle: _is_iscsi_root() not working with dracut
based initramfs
The _is_iscsi_root() implementation in Oracle datasource today only works
with initramfs-tools on Debian/Ubuntu systems, where initramfs-tools specific
files e.g. /run/net{,6}-*.conf are examined to identify initramfs initiated
network configuration. This partial implementation works with OCI Oracle
Linux (OL) images by chance as the "network-config=..." option in the boot
line happens to satisfy the corresponding network-config conditional
branch (which itself is insufficient in checking disabled network-config) in
cmdline.read_kernel_cmdline_config, and eventually renders _is_iscsi_root()
return true for OL images all across. Apparently this shouldn't be the
case for VM instance with PV boot.
The fix involved is to identify dracut based initramfs config files for
network boot, and also ibft as how it does for initramfs-tools based
initramfs on Ubuntu.
Orabug: 29956753
Signed-off-by: Si-Wei Liu <si-wei.liu@oracle.com>
Signed-off-by: Darren Archibald <darren.archibald@oracle.com>
---
cloudinit/sources/DataSourceOracle.py | 22 +++++++++++++++++++++-
1 file changed, 21 insertions(+), 1 deletion(-)
diff --git a/cloudinit/sources/DataSourceOracle.py b/cloudinit/sources/DataSourceOracle.py
index 07247d7..afae393 100644
--- a/cloudinit/sources/DataSourceOracle.py
+++ b/cloudinit/sources/DataSourceOracle.py
@@ -14,6 +14,8 @@ Notes:
"""
import base64
+import glob
+import os
import ipaddress
import logging
from collections import namedtuple
@@ -31,6 +33,11 @@ from cloudinit.url_helper import UrlError, readurl
LOG = logging.getLogger(__name__)
+DRACUT_TMP_PATH='/var/run/initramfs'
+DRACUT_OLDTMP_PATH='/dev/.initramfs'
+DRACUT_NET_IFACES='net.ifaces'
+DRACUT_IBFT_PATTERN='net.*.has_ibft_config'
+
BUILTIN_DS_CONFIG = {
# Don't use IMDS to configure secondary NICs by default
"configure_secondary_nics": False,
@@ -200,9 +207,22 @@ class DataSourceOracle(sources.DataSource):
def get_public_ssh_keys(self):
return sources.normalize_pubkey_data(self.metadata.get("public_keys"))
+ def _is_dracut_netconfig():
+ for net_ifaces_path in (
+ DRACUT_TMP_PATH + '/' + DRACUT_NET_IFACES,
+ DRACUT_OLDTMP_PATH + '/' + DRACUT_NET_IFACES):
+ if os.path.exists(net_ifaces_path):
+ return True
+
+ if glob.glob(DRACUT_TMP_PATH + '/' + DRACUT_IBFT_PATTERN) + \
+ glob.glob(DRACUT_OLDTMP_PATH + '/' + DRACUT_IBFT_PATTERN):
+ return True
+
+ return False
+
def _is_iscsi_root(self) -> bool:
"""Return whether we are on a iscsi machine."""
- return self._network_config_source.is_applicable()
+ return self._network_config_source.is_applicable() or _is_dracut_netconfig()
def _get_iscsi_config(self) -> dict:
return self._network_config_source.render_config()
--
2.31.1

View File

@ -0,0 +1,78 @@
From 51cdd87ad861d5d47c212258bf00402a4dec2198 Mon Sep 17 00:00:00 2001
From: Darren Archibald <darren.archibald@oracle.com>
Date: Fri, 23 Feb 2024 06:17:54 -0800
Subject: [PATCH] Update cloud-init collect-logs for Oracle Linux
Updating the code to collect triage logs with OL distro specic methods.
Orabug: 30435672
Signed-off-by: Vijay Balakrishna <vijay.balakrishna@oracle.com>
Reviewed-by: Si-Wei Liu <si-wei.liu@oracle.com>
Acked-by: Joe Kennedy <joe.kennedy@oracle.com>
Reviewed-by: Laurence Rochfort <laurence.rochfort@oracle.com
Signed-off-by: Darren Archibald <darren.archibald@oracle.com>
---
cloudinit/cmd/devel/logs.py | 26 ++++++++++++++++----------
cloudinit/util.py | 1 +
2 files changed, 17 insertions(+), 10 deletions(-)
diff --git a/cloudinit/cmd/devel/logs.py b/cloudinit/cmd/devel/logs.py
index 8312218..85d976a 100755
--- a/cloudinit/cmd/devel/logs.py
+++ b/cloudinit/cmd/devel/logs.py
@@ -19,7 +19,7 @@ from cloudinit.cmd.devel import read_cfg_paths
from cloudinit.helpers import Paths
from cloudinit.subp import ProcessExecutionError, subp
from cloudinit.temp_utils import tempdir
-from cloudinit.util import chdir, copy, ensure_dir, write_file
+from cloudinit.util import chdir, copy, ensure_dir, write_file, system_info
CLOUDINIT_LOGS = ["/var/log/cloud-init.log", "/var/log/cloud-init-output.log"]
CLOUDINIT_RUN_DIR = "/run/cloud-init"
@@ -219,15 +219,21 @@ def collect_logs(tarfile, include_userdata: bool, verbosity=0):
msg="cloud-init --version",
verbosity=verbosity,
)
- dpkg_ver = _write_command_output_to_file(
- cmd=["dpkg-query", "--show", "-f=${Version}\n", "cloud-init"],
- filename=os.path.join(log_dir, "dpkg-version"),
- msg="dpkg version",
- verbosity=verbosity,
- )
- if not version:
- version = dpkg_ver if dpkg_ver else "not-available"
- print("version: ", version)
+ if system_info()['variant'] == "ol":
+ rpm_ver = _write_command_output_to_file(
+ ['rpm', '-q', '--queryformat',
+ "[%{VERSION}-%{RELEASE}.%{ARCH}]\n", 'cloud-init'],
+ os.path.join(log_dir, 'rpm-version'),
+ "rpm version", verbosity)
+ if not version:
+ version = rpm_ver if rpm_ver else "not-available"
+ else:
+ dpkg_ver = _write_command_output_to_file(
+ ['dpkg-query', '--show', "-f=${Version}\n", 'cloud-init'],
+ os.path.join(log_dir, 'dpkg-version'),
+ "dpkg version", verbosity)
+ if not version:
+ version = dpkg_ver if dpkg_ver else "not-available"
_debug("collected cloud-init version: %s\n" % version, 1, verbosity)
_stream_command_output_to_file(
cmd=["dmesg"],
diff --git a/cloudinit/util.py b/cloudinit/util.py
index 3295735..db7bb97 100644
--- a/cloudinit/util.py
+++ b/cloudinit/util.py
@@ -660,6 +660,7 @@ def _get_variant(info):
"suse",
"tencentos",
"virtuozzo",
+ "ol",
):
variant = linux_dist
elif linux_dist in ("ubuntu", "linuxmint", "mint"):
--
2.31.1

View File

@ -0,0 +1,112 @@
From 250aa45f74e29b95f81b24811c972369605bd24e Mon Sep 17 00:00:00 2001
From: Vijay Balakrishna <vijay.balakrishna@oracle.com>
Date: Tue, 5 Nov 2019 16:00:21 -0500
Subject: [PATCH] Add static cloud.cfg file for OL7.
Adding OL specific cloud.cfg file to enable updates cloud-init
config file independently, adding newly verified ntp module.
Orabug: 30435672
Signed-off-by: Vijay Balakrishna <vijay.balakrishna@oracle.com>
Signed-off-by: Si-Wei Liu <si-wei.liu@oracle.com>
Acked-by: Joe Kennedy <joe.kennedy@oracle.com>
Reviewed-by: Laurence Rochfort <laurence.rochfort@oracle.com>
---
ol/README.ol | 6 ++++++
ol/cloud.cfg | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 75 insertions(+)
create mode 100644 ol/README.ol
create mode 100644 ol/cloud.cfg
diff --git a/ol/README.ol b/ol/README.ol
new file mode 100644
index 0000000..f59d559
--- /dev/null
+++ b/ol/README.ol
@@ -0,0 +1,6 @@
+The following cloud-init modules are currently unsupported on this OS:
+ - apt_update_upgrade ('apt_update', 'apt_upgrade', 'apt_mirror', 'apt_preserve_sources_list', 'apt_old_mirror', 'apt_sources', 'debconf_selections', 'packages' options)
+ - byobu ('byobu_by_default' option)
+ - chef
+ - grub_dpkg
+ - rh_subscription
diff --git a/ol/cloud.cfg b/ol/cloud.cfg
new file mode 100644
index 0000000..2ee1fb3
--- /dev/null
+++ b/ol/cloud.cfg
@@ -0,0 +1,69 @@
+users:
+ - default
+
+disable_root: 1
+ssh_pwauth: 0
+
+mount_default_fields: [~, ~, 'auto', 'defaults,nofail,x-systemd.requires=cloud-init.service', '0', '2']
+resize_rootfs_tmp: /dev
+ssh_deletekeys: 0
+ssh_genkeytypes: ~
+syslog_fix_perms: ~
+disable_vmware_customization: false
+
+cloud_init_modules:
+ - disk_setup
+ - migrator
+ - bootcmd
+ - write-files
+ - growpart
+ - resizefs
+ - set_hostname
+ - update_hostname
+ - update_etc_hosts
+ - rsyslog
+ - users-groups
+ - ssh
+
+cloud_config_modules:
+ - mounts
+ - locale
+ - set-passwords
+ - ntp
+ - yum-add-repo
+ - package-update-upgrade-install
+ - timezone
+ - puppet
+ - chef
+ - salt-minion
+ - mcollective
+ - disable-ec2-metadata
+ - runcmd
+
+cloud_final_modules:
+ - rightscale_userdata
+ - scripts-per-once
+ - scripts-per-boot
+ - scripts-per-instance
+ - scripts-user
+ - ssh-authkey-fingerprints
+ - keys-to-console
+ - phone-home
+ - final-message
+ - power-state-change
+
+system_info:
+ default_user:
+ name: cloud-user
+ lock_passwd: true
+ gecos: Cloud User
+ groups: [adm, systemd-journal]
+ sudo: ["ALL=(ALL) NOPASSWD:ALL"]
+ shell: /bin/bash
+ distro: rhel
+ paths:
+ cloud_dir: /var/lib/cloud
+ templates_dir: /etc/cloud/templates
+ ssh_svcname: sshd
+
+# vim:syntax=yaml
--
1.8.3.1

View File

@ -0,0 +1,57 @@
From 2b92e042bb8a4510abec38fcfc302d8de1e28f37 Mon Sep 17 00:00:00 2001
From: Darren Archibald <darren.archibald@oracle.com>
Date: Fri, 23 Feb 2024 06:55:32 -0800
Subject: [PATCH] spacewalk: fix CA cert file path for Oracle Linux
Update the CA cert file that is available in Oracle Linux to register with ULN.
Orabug: 30435672
Signed-off-by: Si-Wei Liu <si-wei.liu@oracle.com>
Signed-off-by: Vijay Balakrishna <vijay.balakrishna@oracle.com>
Acked-by: Joe Kennedy <joe.kennedy@oracle.com>
Reviewed-by: Laurence Rochfort <laurence.rochfort@oracle.com>
Signed-off-by: Darren Archibald <darren.archibald@oracle.com>
---
cloudinit/config/cc_spacewalk.py | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/cloudinit/config/cc_spacewalk.py b/cloudinit/config/cc_spacewalk.py
index 08514f2..7248cce 100644
--- a/cloudinit/config/cc_spacewalk.py
+++ b/cloudinit/config/cc_spacewalk.py
@@ -4,7 +4,7 @@
import logging
from textwrap import dedent
-from cloudinit import subp
+from cloudinit import subp, util
from cloudinit.cloud import Cloud
from cloudinit.config import Config
from cloudinit.config.schema import MetaSchema, get_meta_doc
@@ -47,6 +47,7 @@ LOG = logging.getLogger(__name__)
distros = ["redhat", "fedora"]
required_packages = ["rhn-setup"]
def_ca_cert_path = "/usr/share/rhn/RHN-ORG-TRUSTED-SSL-CERT"
+ol_ca_cert_path = "/usr/share/rhn/ULN-CA-CERT"
def is_registered():
@@ -100,9 +101,14 @@ def handle(name: str, cfg: Config, cloud: Cloud, args: list) -> None:
# Need to have this installed before further things will work.
cloud.distro.install_packages(required_packages)
if not is_registered():
+ if util.system_info()['variant'] == "ol":
+ cert = ol_ca_cert_path
+ else:
+ cert = def_ca_cert_path
do_register(
spacewalk_server,
cloud.datasource.get_hostname(fqdn=True).hostname,
+ ca_cert_path=cert,
proxy=cfg.get("proxy"),
activation_key=cfg.get("activation_key"),
)
--
2.31.1

View File

@ -0,0 +1,30 @@
cloud-init service file is missing sshd required services
Orabug: 32183938
in the systemd sshd-keygen.target file, the following services are listed:
[Unit]
Wants=sshd-keygen@rsa.service
Wants=sshd-keygen@ecdsa.service
Wants=sshd-keygen@ed25519.service
Need to add the following to the cloud-init service file:
Before=sshd-keygen@rsa.service
Before=sshd-keygen@ecdsa.service
Before=sshd-keygen@ed25519.service
Signed-off-by: Isaac Chen <isaac.chen@oracle.com>
diff -up cloud-init-19.4/systemd/cloud-init.service.tmpl.orig cloud-init-19.4/systemd/cloud-init.service.tmpl
--- cloud-init-19.4/systemd/cloud-init.service.tmpl.orig 2020-12-10 13:03:19.978023730 -0800
+++ cloud-init-19.4/systemd/cloud-init.service.tmpl 2020-12-10 13:07:35.791879370 -0800
@@ -21,7 +21,9 @@ After=wicked.service
After=dbus.service
{% endif %}
Before=network-online.target
-Before=sshd-keygen.service
+Before=sshd-keygen@rsa.service
+Before=sshd-keygen@ecdsa.service
+Before=sshd-keygen@ed25519.service
Before=sshd.service
{% if variant in ["ubuntu", "unknown", "debian"] %}
Before=sysinit.target

View File

@ -0,0 +1,22 @@
cloud-init service file is missing sshd required services
Orabug: 32183938
This patch is the supplement of patch orabug32183938-009, where changes
to cloud-init.service also need to be added to files in rhel/systemd.
Signed-off-by: Isaac Chen <isaac.chen@oracle.com>
diff -up cloud-init-19.4/systemd/cloud-init.service.tmpl.orig cloud-init-19.4/systemd/cloud-init.service.tmpl
--- cloud-init-19.4/systemd/cloud-init.service.tmpl.orig 2020-12-11 19:59:37.331277979 -0800
+++ cloud-init-19.4/systemd/cloud-init.service.tmpl 2020-12-11 20:00:38.867459043 -0800
@@ -5,7 +5,9 @@
DefaultDependencies=no
{% endif %}
Wants=cloud-init-local.service
-Wants=sshd-keygen.service
+Wants=sshd-keygen@rsa.service
+Wants=sshd-keygen@ecdsa.service
+Wants=sshd-keygen@ed25519.service
Wants=sshd.service
After=cloud-init-local.service
After=systemd-networkd-wait-online.service

View File

@ -0,0 +1,354 @@
From e921be03f802ee154ed1ddf044e276b23af0d2b6 Mon Sep 17 00:00:00 2001
From: Darren Archibald <darren.archibald@oracle.com>
Date: Fri, 23 Feb 2024 07:52:25 -0800
Subject: [PATCH] Add Oracle to distro detection logic in cloud.cfg.tmpl
Oracle Linux is being detected as "ol" variant by cloud-init.
This patch adds "ol" to the list of supported variants, and applies needed settings to it.
You can notice that variant "ol" is being set as distro "rhel" in a couple of places,
that is expected as this designated that base distro for "ol" is "rhel" ( which is true )
The main reason for this change is that cloud-init package dropped hardcoded configs that set OL as rhel
and to make cloud-init behave on OL systems as expected we need to add "ol" designation to supported list.
Orabug: 34845400
Signed-off-by: Alex Burmashev <alexander.burmashev@oracle.com>
Signed-off-by: Darren Archibald <darren.archibald@oracle.com>
---
cloudinit/distros/__init__.py | 1 +
cloudinit/sources/DataSourceRbxCloud.py | 2 +-
config/cloud.cfg.tmpl | 33 ++++++++++++++++++-------
systemd/cloud-config.service.tmpl | 4 +++
systemd/cloud-final.service.tmpl | 4 ++-
systemd/cloud-init-local.service.tmpl | 12 ++++++---
systemd/cloud-init.service.tmpl | 8 ++++--
tests/unittests/test_util.py | 1 +
8 files changed, 48 insertions(+), 17 deletions(-)
diff --git a/cloudinit/distros/__init__.py b/cloudinit/distros/__init__.py
index 79e2623..8f1381b 100644
--- a/cloudinit/distros/__init__.py
+++ b/cloudinit/distros/__init__.py
@@ -78,6 +78,7 @@ OSFAMILIES = {
"rhel",
"rocky",
"virtuozzo",
+ "ol",
],
"suse": [
"opensuse",
diff --git a/cloudinit/sources/DataSourceRbxCloud.py b/cloudinit/sources/DataSourceRbxCloud.py
index 9214f1b..5379132 100644
--- a/cloudinit/sources/DataSourceRbxCloud.py
+++ b/cloudinit/sources/DataSourceRbxCloud.py
@@ -60,7 +60,7 @@ def _sub_arp(cmd):
def gratuitous_arp(items, distro):
source_param = "-S"
- if distro.name in ["fedora", "centos", "rhel"]:
+ if distro.name in ["fedora", "centos", "rhel", "ol"]:
source_param = "-s"
for item in items:
try:
diff --git a/config/cloud.cfg.tmpl b/config/cloud.cfg.tmpl
@@ -39,7 +39,7 @@
- name: root
lock_passwd: false
{% else %}
- - default
+ - default
{% endif %}
{% if variant == "photon" %}
@@ -58,9 +58,9 @@
{% endif %}
{%- if variant in ["alpine", "amazon", "fedora", "OpenCloudOS", "openeuler",
- "openmandriva", "photon", "TencentOS"] or is_rhel %}
+ "openmandriva", "photon", "TencentOS", "ol"] or is_rhel %}
-{% if is_rhel %}
+{% if variant in ["ol"] or is_rhel %}
mount_default_fields: [~, ~, 'auto', 'defaults,nofail,x-systemd.requires=cloud-init.service,_netdev', '0', '2']
{% else %}
mount_default_fields: [~, ~, 'auto', 'defaults,nofail', '0', '2']
@@ -101,7 +101,7 @@
{% endif -%}
-{% if is_rhel %}
+{% if variant in ["ol"] or is_rhel %}
# Default redhat settings:
ssh_deletekeys: true
ssh_genkeytypes: ['rsa', 'ecdsa', 'ed25519']
@@ -149,9 +149,9 @@
{% if variant == "ubuntu" %}
- ubuntu_autoinstall
{% endif %}
-{% if variant not in ["photon"] %}
+{% if variant not in ["photon", "ol"] %}
- ssh_import_id
-{% if not is_rhel %}
+{% if variant not in ["ol"] or is_rhel %}
- keyboard
{% endif %}
- locale
@@ -167,18 +167,20 @@
- ubuntu_advantage
{% endif %}
{% elif variant in ["fedora", "mariner", "openeuler", "openmandriva",
- "photon"] or is_rhel %}
+ "photon", "ol"] or is_rhel %}
{% if is_rhel %}
- rh_subscription
{% endif %}
-{% if variant not in ["mariner", "photon"] %}
+{% if variant not in ["mariner", "photon", "ol"] %}
- spacewalk
{% endif %}
- yum_add_repo
{% elif variant == "suse" %}
- zypper_add_repo
{% endif %}
+{% if variant not in ["ol"] %}
- ntp
+{% endif %}
- timezone
- disable_ec2_metadata
- runcmd
@@ -197,13 +199,17 @@
{% if variant in ["ubuntu", "unknown"] %}
- ubuntu_drivers
{% endif %}
+{% if variant not in ["ol"] %}
- write_files_deferred
+{% endif %}
- puppet
- chef
- ansible
- mcollective
- salt_minion
+{% if variant not in ["ol"] %}
- reset_rmc
+{% endif %}
- rightscale_userdata
- scripts_vendor
- scripts_per_once
@@ -212,7 +218,9 @@
- scripts_user
- ssh_authkey_fingerprints
- keys_to_console
+{% if variant not in ["ol"] %}
- install_hotplug
+{% endif %}
- phone_home
- final_message
- power_state_change
@@ -224,8 +232,10 @@
{% if variant in ["alpine", "amazon", "arch", "debian", "fedora", "freebsd",
"gentoo", "mariner", "netbsd", "openbsd", "OpenCloudOS",
"openeuler", "openmandriva", "photon", "suse", "TencentOS",
- "ubuntu"] or is_rhel %}
+ "ubuntu", "centos", "rhel"] %}
distro: {{ variant }}
+{% elif variant == "ol" %}
+ distro: rhel
{% elif variant == "dragonfly" %}
distro: dragonflybsd
{% else %}
@@ -234,7 +244,9 @@
{% endif %}
# Default user name + that default users groups (if added/used)
default_user:
-{% if variant in usernames %}
+{% if variant == "ol" %}
+ name: cloud-user
+{% elif variant in usernames %}
name: {{ usernames[variant] }}
{% else %}
name: {{ variant }}
@@ -245,7 +257,12 @@
or is_bsd or is_rhel %}
lock_passwd: True
{% endif %}
-{% if variant in gecos %}
+{% if variant == "ol" %}
+ lock_passwd: true
+{% endif %}
+{% if variant == "ol" %}
+ gecos: Cloud User
+{% elif variant in gecos %}
gecos: {{ gecos[variant] }}
{% else %}
gecos: {{ variant }} Cloud User
@@ -254,7 +271,7 @@
groups: [{{ groups[variant] }}]
{% elif is_bsd %}
groups: [wheel]
-{% elif is_rhel %}
+{% elif variant in ["ol"] or is_rhel %}
groups: [adm, systemd-journal]
{% else %}
groups: [wheel, adm, systemd-journal]
@@ -321,7 +338,7 @@
{% endif %}
{% if variant in ["alpine", "amazon", "arch", "debian", "fedora", "gentoo",
"mariner", "OpenCloudOS", "openeuler", "openmandriva",
- "photon", "suse", "TencentOS", "ubuntu", "unknown"]
+ "photon", "suse", "TencentOS", "ubuntu", "unknown", "ol"]
or is_rhel %}
# Other config here will be given to the distro class and/or path classes
paths:
@@ -365,6 +382,6 @@
ssh_svcname: ssh
{% elif variant in ["alpine", "amazon", "arch", "fedora", "gentoo",
"mariner", "OpenCloudOS", "openeuler", "openmandriva",
- "photon", "suse", "TencentOS"] or is_rhel %}
+ "photon", "suse", "TencentOS", "ol"] or is_rhel %}
ssh_svcname: sshd
{% endif %}
diff --git a/systemd/cloud-config.service.tmpl b/systemd/cloud-config.service.tmpl
index 31d9d98..8222c7c 100644
--- a/systemd/cloud-config.service.tmpl
+++ b/systemd/cloud-config.service.tmpl
@@ -2,11 +2,15 @@
[Unit]
Description=Apply the settings specified in cloud-config
After=network-online.target cloud-config.target
+{% if variant not in "ol" %}
After=snapd.seeded.service
+{% endif %}
Before=systemd-user-sessions.service
Wants=network-online.target cloud-config.target
+{% if variant in ["rhel", "ol"] %}
ConditionPathExists=!/etc/cloud/cloud-init.disabled
ConditionKernelCommandLine=!cloud-init=disabled
+{% endif %}
ConditionEnvironment=!KERNEL_CMDLINE=cloud-init=disabled
[Service]
diff --git a/systemd/cloud-final.service.tmpl b/systemd/cloud-final.service.tmpl
index bcf8b00..f84c687 100644
--- a/systemd/cloud-final.service.tmpl
+++ b/systemd/cloud-final.service.tmpl
@@ -7,8 +7,10 @@ After=multi-user.target
Before=apt-daily.service
{% endif %}
Wants=network-online.target cloud-config.service
+{% if variant in ["rhel", "ol"] %}
ConditionPathExists=!/etc/cloud/cloud-init.disabled
ConditionKernelCommandLine=!cloud-init=disabled
+{% endif %}
ConditionEnvironment=!KERNEL_CMDLINE=cloud-init=disabled
@@ -18,7 +20,7 @@ ExecStart=/usr/bin/cloud-init modules --mode=final
RemainAfterExit=yes
TimeoutSec=0
KillMode=process
-{% if variant == "rhel" %}
+{% if variant in ["rhel", "ol"] %}
# Restart NetworkManager if it is present and running.
ExecStartPost=/bin/sh -c 'u=NetworkManager.service; \
out=$(systemctl show --property=SubState $u) || exit; \
diff --git a/systemd/cloud-init-local.service.tmpl b/systemd/cloud-init-local.service.tmpl
index 3a1ca7f..4750c36 100644
--- a/systemd/cloud-init-local.service.tmpl
+++ b/systemd/cloud-init-local.service.tmpl
@@ -1,23 +1,25 @@
## template:jinja
[Unit]
Description=Initial cloud-init job (pre-networking)
-{% if variant in ["ubuntu", "unknown", "debian", "rhel" ] %}
+{% if variant in ["ubuntu", "unknown", "debian", "rhel", "ol" ] %}
DefaultDependencies=no
{% endif %}
Wants=network-pre.target
+{% if variant not in ["ol"] %}
After=hv_kvp_daemon.service
+{% endif %}
After=systemd-remount-fs.service
-{% if variant == "rhel" %}
+{% if variant in ["rhel", "ol"] %}
Requires=dbus.socket
After=dbus.socket
{% endif %}
Before=NetworkManager.service
-{% if variant == "rhel" %}
+{% if variant in ["rhel", "ol"] %}
Before=network.service
{% endif %}
Before=network-pre.target
Before=shutdown.target
-{% if variant == "rhel" %}
+{% if variant in ["rhel", "ol"] %}
Before=firewalld.target
Conflicts=shutdown.target
{% endif %}
@@ -26,8 +28,10 @@ Before=sysinit.target
Conflicts=shutdown.target
{% endif %}
RequiresMountsFor=/var/lib/cloud
+{% if variant in ["rhel", "ol"] %}
ConditionPathExists=!/etc/cloud/cloud-init.disabled
ConditionKernelCommandLine=!cloud-init=disabled
+{% endif %}
ConditionEnvironment=!KERNEL_CMDLINE=cloud-init=disabled
[Service]
diff --git a/systemd/cloud-init.service.tmpl b/systemd/cloud-init.service.tmpl
index 90d45f2..2e1ce48 100644
--- a/systemd/cloud-init.service.tmpl
+++ b/systemd/cloud-init.service.tmpl
@@ -1,7 +1,7 @@
## template:jinja
[Unit]
Description=Initial cloud-init job (metadata service crawler)
-{% if variant not in ["photon", "rhel"] %}
+{% if variant not in ["photon", "rhel", "ol"] %}
DefaultDependencies=no
{% endif %}
Wants=cloud-init-local.service
@@ -10,13 +10,15 @@ Wants=sshd-keygen@ecdsa.service
Wants=sshd-keygen@ed25519.service
Wants=sshd.service
After=cloud-init-local.service
+{% if variant not in ["ol"] %}
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"] %}
+ "suse", "TencentOS", "virtuozzo", "ol"] %}
After=network.service
After=NetworkManager.service
@@ -42,8 +44,10 @@ Conflicts=shutdown.target
Before=shutdown.target
Conflicts=shutdown.target
{% endif %}
+{% if variant in ["rhel", "ol"] %}
ConditionPathExists=!/etc/cloud/cloud-init.disabled
ConditionKernelCommandLine=!cloud-init=disabled
+{% endif %}
ConditionEnvironment=!KERNEL_CMDLINE=cloud-init=disabled
[Service]
diff --git a/tests/unittests/test_util.py b/tests/unittests/test_util.py
index 519ef63..323e7f6 100644
--- a/tests/unittests/test_util.py
+++ b/tests/unittests/test_util.py
@@ -1311,6 +1311,7 @@ class TestGetVariant:
({"system": "linux", "dist": ("sles",)}, "suse"),
({"system": "linux", "dist": ("sle_hpc",)}, "suse"),
({"system": "linux", "dist": ("my_distro",)}, "linux"),
+ ({"system": "linux", "dist": ("ol",)}, "ol"),
({"system": "Windows", "dist": ("dontcare",)}, "windows"),
({"system": "Darwin", "dist": ("dontcare",)}, "darwin"),
({"system": "Freebsd", "dist": ("dontcare",)}, "freebsd"),
--
2.31.1

View File

@ -0,0 +1,30 @@
From ae1b843c7ab8b173ef2ffd9ea02842d1d4455e64 Mon Sep 17 00:00:00 2001
From: Alexander Burmashev <alexander.burmashev@oracle.com>
Date: Fri, 5 May 2023 03:15:06 -0700
Subject: [PATCH] Increase retry value and add timeout for OCI
To be sure there are no failures, and accomodate to current behaviour on some supoported shapes it is needed to set
increased values for retries and timeout.
Orabug: 35329883
Signed-off-by: Alex Burmashev <alexander.burmashev@oracle.com>
---
cloudinit/sources/DataSourceOracle.py | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/cloudinit/sources/DataSourceOracle.py b/cloudinit/sources/DataSourceOracle.py
--- a/cloudinit/sources/DataSourceOracle.py 2023-10-03 22:09:18.480515323 +0000
+++ b/cloudinit/sources/DataSourceOracle.py 2023-10-03 22:21:31.155006874 +0000
@@ -364,11 +364,12 @@
return asset_tag == CHASSIS_ASSET_TAG
-def _fetch(metadata_version: int, path: str, retries: int = 2) -> dict:
+def _fetch(metadata_version: int, path: str, retries: int = 9) -> dict:
return readurl(
url=METADATA_PATTERN.format(version=metadata_version, path=path),
headers=V2_HEADERS if metadata_version > 1 else None,
retries=retries,
+ timeout=20,
)._response.json()

View File

@ -0,0 +1,140 @@
From 6a81b1e0970f37246276009c844baca860f3f913 Mon Sep 17 00:00:00 2001
From: Darren Archibald <darren.archibald@oracle.com>
Date: Fri, 23 Feb 2024 08:04:44 -0800
Subject: [PATCH] DataSourceOracle network getdata updates
Orabug: 35950168
Signed-off-by: Darren Archibald <darren.archibald@oracle.com>
---
cloudinit/sources/DataSourceOracle.py | 78 +++++++++++++--------------
1 file changed, 39 insertions(+), 39 deletions(-)
diff -git a/cloudinit/sources/DataSourceOracle.py b/cloudinit/sources/DataSourceOracle.py
--- a/cloudinit/sources/DataSourceOracle.py 2024-04-03 15:54:08.713716247 -0700
+++ b/cloudinit/sources/DataSourceOracle.py 2024-04-03 15:53:35.426718593 -0700
@@ -20,6 +20,7 @@
import logging
from collections import namedtuple
from typing import Optional, Tuple
+from contextlib import suppress as noop
from cloudinit import atomic_helper, dmi, net, sources, util
from cloudinit.distros.networking import NetworkConfig
@@ -37,6 +38,7 @@
DRACUT_OLDTMP_PATH='/dev/.initramfs'
DRACUT_NET_IFACES='net.ifaces'
DRACUT_IBFT_PATTERN='net.*.has_ibft_config'
+ISCSI_IBFT_PATH='/sys/firmware/acpi/tables/iBFT'
BUILTIN_DS_CONFIG = {
# Don't use IMDS to configure secondary NICs by default
@@ -129,7 +131,7 @@
sources.NetworkConfigSource.INITRAMFS,
)
- _network_config: dict = {"config": [], "version": 1}
+ _network_config = sources.UNSET
def __init__(self, sys_cfg, *args, **kwargs):
super(DataSourceOracle, self).__init__(sys_cfg, *args, **kwargs)
@@ -155,14 +157,16 @@
self.system_uuid = _read_system_uuid()
- network_context = ephemeral.EphemeralDHCPv4(
- self.distro,
- iface=net.find_fallback_nic(),
- connectivity_url_data={
- "url": METADATA_PATTERN.format(version=2, path="instance"),
- "headers": V2_HEADERS,
- },
- )
+ network_context = noop()
+ if not self._is_iscsi_root():
+ network_context = ephemeral.EphemeralDHCPv4(
+ self.distro,
+ iface=net.find_fallback_nic(),
+ connectivity_url_data={
+ "url": METADATA_PATTERN.format(version=2, path="instance"),
+ "headers": V2_HEADERS,
+ },
+ )
fetch_primary_nic = not self._is_iscsi_root()
fetch_secondary_nics = self.ds_cfg.get(
"configure_secondary_nics",
@@ -222,7 +226,7 @@
def _is_iscsi_root(self) -> bool:
"""Return whether we are on a iscsi machine."""
- return self._network_config_source.is_applicable() or _is_dracut_netconfig()
+ return self._network_config_source.is_applicable() or bool(os.path.exists(ISCSI_IBFT_PATH))
def _get_iscsi_config(self) -> dict:
return self._network_config_source.render_config()
@@ -237,39 +241,36 @@
If none is present, then we fall back to fallback configuration.
"""
- if self._has_network_config():
- return self._network_config
-
set_primary = False
- # this is v1
- if self._is_iscsi_root():
- self._network_config = self._get_iscsi_config()
- if not self._has_network_config():
- LOG.warning(
- "Could not obtain network configuration from initramfs. "
- "Falling back to IMDS."
- )
- set_primary = True
- set_secondary = self.ds_cfg.get(
- "configure_secondary_nics",
- BUILTIN_DS_CONFIG["configure_secondary_nics"],
- )
- if set_primary or set_secondary:
- try:
- # Mutate self._network_config to include primary and/or
- # secondary VNICs
- self._add_network_config_from_opc_imds(set_primary)
- except Exception:
- util.logexc(
- LOG,
- "Failed to parse IMDS network configuration!",
+ if self._network_config == sources.UNSET:
+ # this is v1
+ self._network_config = cmdline.read_initramfs_config()
+
+ if not self._network_config:
+ self._network_config = self.distro.generate_fallback_config()
+ set_primary = True
+
+ set_secondary = self.ds_cfg.get(
+ "configure_secondary_nics",
+ BUILTIN_DS_CONFIG["configure_secondary_nics"],
)
- # we need to verify that the nic selected is not a netfail over
- # device and, if it is a netfail master, then we need to avoid
- # emitting any match by mac
- _ensure_netfailover_safe(self._network_config)
+ if set_primary or set_secondary:
+ try:
+ # Mutate self._network_config to include primary and/or
+ # secondary VNICs
+ self._add_network_config_from_opc_imds(set_primary)
+ except Exception:
+ util.logexc(
+ LOG,
+ "Failed to parse IMDS network configuration!",
+ )
+
+ # we need to verify that the nic selected is not a netfail over
+ # device and, if it is a netfail master, then we need to avoid
+ # emitting any match by mac
+ _ensure_netfailover_safe(self._network_config)
return self._network_config

View File

@ -1,43 +1,103 @@
Name: cloud-init
Version: 23.4
Release: 7%{?dist}.5
Summary: Cloud instance init scripts
License: ASL 2.0 or GPLv3
URL: http://launchpad.net/cloud-init
Source0: https://github.com/canonical/cloud-init/archive/refs/tags/%{version}.tar.gz
Source1: cloud-init-tmpfiles.conf
Name: cloud-init
Version: 23.4
Release: 19.0.2%{?dist}.5
Summary: Cloud instance init scripts
License: ASL 2.0 or GPLv3
URL: http://launchpad.net/cloud-init
Source0: https://github.com/canonical/cloud-init/archive/refs/tags/%{version}.tar.gz
Source1: cloud-init-tmpfiles.conf
# Source-git patches
Patch1: 0001-Add-initial-redhat-changes.patch
Patch2: 0002-Do-not-write-NM_CONTROLLED-no-in-generated-interface.patch
Patch3: 0003-Setting-autoconnect-priority-setting-for-network-scr.patch
Patch4: 0004-net-network_manager-do-not-set-may-fail-to-False-for.patch
Patch5: 0005-net-allow-dhcp6-configuration-from-generate_fallback.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
Patch1: 0001-Add-initial-redhat-changes.patch
Patch2: 0002-Do-not-write-NM_CONTROLLED-no-in-generated-interface.patch
Patch3: 0003-Setting-autoconnect-priority-setting-for-network-scr.patch
Patch4: 0004-net-network_manager-do-not-set-may-fail-to-False-for.patch
Patch5: 0005-net-allow-dhcp6-configuration-from-generate_fallback.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
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
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
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
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
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
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
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
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
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
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-65018 - Configuring metric for default gateway is not working [rhel-9.5.z]
Patch35: ci-Fix-metric-setting-for-ifcfg-network-connections-for.patch
# For RHEL-65018 - Configuring metric for default gateway is not working [rhel-9.5.z]
Patch36: ci-fix-python3.13-Fix-import-error-for-passlib-on-Pytho.patch
# For RHEL-65021 - NoCloud - network_config bridges incorrectly configured [rhel-9.5.z]
Patch37: ci-fix-Render-bridges-correctly-for-v2-on-sysconfig-wit.patch
# For RHEL-65021 - NoCloud - network_config bridges incorrectly configured [rhel-9.5.z]
Patch38: ci-fix-Render-v2-bridges-correctly-on-network-manager-w.patch
# For RHEL-65778 - [RHEL-9] Prevent NM from handling DNS when network interfaces have DNS config [rhel-9.5.z]
Patch39: ci-Prevent-NM-from-handling-DNS-when-network-interfaces.patch
# For RHEL-68409 - cloud-init fails to configure DNS and search domain [rhel-9.5.z]
Patch40: ci-refactor-Ensure-internal-DNS-state-same-for-v1-and-v.patch
# For RHEL-79774 - [RHEL 9] Backport support for smbios datasource definition [rhel-9.5.z]
Patch41: ci-fix-nocloud-smbios-datasource-definition.patch
Patch100: 0041-enable-ec2_utils-to-stop-retrying-to-get-ec2-metadata.patch
Patch101: orabug29956753-DataSourceOracle-_is_iscsi_root-not-working-with-dra.patch
Patch102: ignore-enslaved-interface.patch
Patch103: ol-sysconfig-add-Oracle-Linux-variant-to-known-distros.patch
Patch104: 0106-tests-unittests-add-a-new-unit-test-for-network-mana.patch
# Oracle patches
Patch1001: orabug30435672-003-cloud-init-collect-logs.patch
Patch1002: orabug30435672-004-ol-cloud-config.patch
Patch1003: orabug30435672-006-cc_spacewalk.py.patch
Patch1005: orabug32183938-009-missing-sshd-services.patch
Patch1006: orabug32183938-010-missing-sshd-services-in-rhel-systemd.patch
Patch1007: orabug34845400-Add-Oracle-to-distro-detection-logic-in-cloud.cfg.tm.patch
Patch1008: orabug35329883-Increase-retry-value-and-add-timeout-for-OCI.patch
Patch1009: orabug35950168-DataSourceOracle-network-getdata-updates.patch
Patch1010: 1010-orabug36958039-Removes-condition-specific-to-OL-for-write_files_def.patch
BuildArch: noarch
@ -47,48 +107,46 @@ BuildRequires: python3-setuptools
BuildRequires: systemd
# For tests
BuildRequires: iproute
BuildRequires: python3-configobj
BuildRequires: iproute
BuildRequires: python3-configobj
# https://bugzilla.redhat.com/show_bug.cgi?id=1695953
BuildRequires: python3-distro
# https://bugzilla.redhat.com/show_bug.cgi?id=1417029
BuildRequires: python3-httpretty >= 0.8.14-2
BuildRequires: python3-jinja2
BuildRequires: python3-jsonpatch
BuildRequires: python3-oauthlib
BuildRequires: python3-prettytable
BuildRequires: python3-pyserial
BuildRequires: python3-PyYAML
BuildRequires: python3-requests
BuildRequires: python3-six
BuildRequires: python3-distro
BuildRequires: python3-jinja2
BuildRequires: python3-jsonpatch
BuildRequires: python3-oauthlib
BuildRequires: python3-prettytable
BuildRequires: python3-pyserial
BuildRequires: python3-PyYAML
BuildRequires: python3-requests
BuildRequires: python3-six
# dnf is needed to make cc_ntp unit tests work
# https://bugs.launchpad.net/cloud-init/+bug/1721573
BuildRequires: /usr/bin/dnf
BuildRequires: /usr/bin/dnf
Requires: e2fsprogs
Requires: iproute
Requires: libselinux-python3
Requires: policycoreutils-python3
Requires: procps
Requires: python3-configobj
Requires: e2fsprogs
Requires: iproute
Requires: libselinux-python3
Requires: policycoreutils-python3
Requires: procps
Requires: python3-configobj
# https://bugzilla.redhat.com/show_bug.cgi?id=1695953
Requires: python3-distro
Requires: python3-jinja2
Requires: python3-jsonpatch
Requires: python3-oauthlib
Requires: python3-prettytable
Requires: python3-pyserial
Requires: python3-PyYAML
Requires: python3-requests
Requires: python3-six
Requires: shadow-utils
Requires: util-linux
Requires: xfsprogs
Requires: dhcp-client
Requires: python3-distro
Requires: python3-jinja2
Requires: python3-jsonpatch
Requires: python3-oauthlib
Requires: python3-prettytable
Requires: python3-pyserial
Requires: python3-PyYAML
Requires: python3-requests
Requires: python3-six
Requires: shadow-utils
Requires: util-linux
Requires: xfsprogs
Requires: dhcp-client
# https://bugzilla.redhat.com/show_bug.cgi?id=2032524
Requires: gdisk
Requires: openssl
Requires: python3-netifaces
Requires: gdisk
Requires: openssl
Requires: python3-netifaces
%{?systemd_requires}
@ -254,23 +312,130 @@ fi
%config(noreplace) %{_sysconfdir}/rsyslog.d/21-cloudinit.conf
%changelog
* Mon Jun 17 2024 Miroslav Rezanina <mrezanin@redhat.com> - 23.4-7.5
* Tue Mar 18 2025 Darren Archibald <darren.archibald@oracle.com> - 23.4-19.0.2.el9_5.5
- Fixes regression in cloud-init-23.4-19.0.1 with module cc_write_files_deferred [Orabug: 36958039]
- NetworkManagerActivator brings up interface failed when using sysconfig renderer [RHEL-18981]
- Fix Oracle Datasource network and getdata methods for OCI OL [Orabug: 35950168]
- Increase retry value and add timeout for OCI [Orabug: 35329883]
- Fix log file permission [Orabug: 35302969]
- Update detection logic for OL distros in config template [Orabug: 34845400]
- Added missing services in rhel/systemd/cloud-init.service [Orabug: 32183938]
- Added missing services in cloud-init.service.tmpl for sshd [Orabug: 32183938]
- Forward port applicable cloud-init 18.4-2.0.3 changes to cloud-init-18-5 [Orabug: 30435672]
- limit permissions [Orabug: 31352433]
- Changes to ignore all enslaved interfaces [Orabug: 30092148]
- Make Oracle datasource detect dracut based config files [Orabug: 29956753]
- add modified version of enable-ec2_utils-to-stop-retrying-to-get-ec2-metadata.patch:
1. Enable ec2_utils.py having a way to stop retrying to get ec2 metadata
2. Apply stop retrying to get ec2 metadata to helper/openstack.py MetadataReader
Resolves: Oracle-Bug:41660 (Bugzilla)
- added OL to list of known distros
Resolves: rhbz#1427280
Resolves: rhbz#1427280
* Tue Mar 18 2025 Release Engineering <releng@openela.org> - 23.4.0.2
- Apply OpenELA fixes
* Mon Feb 24 2025 Jon Maloy <jmaloy@redhat.com> - 23.4-19.el9_5.5
- ci-fix-nocloud-smbios-datasource-definition.patch [RHEL-79774]
- Resolves: RHEL-79774
([RHEL 9] Backport support for smbios datasource definition [rhel-9.5.z])
* Wed Nov 27 2024 Miroslav Rezanina <mrezanin@redhat.com> - 23.4-19.el9_5.4
- ci-refactor-Ensure-internal-DNS-state-same-for-v1-and-v.patch [RHEL-68409]
- Resolves: RHEL-68409
(cloud-init fails to configure DNS and search domain [rhel-9.5.z])
* Mon Nov 18 2024 Miroslav Rezanina <mrezanin@redhat.com> - 23.4-19.el9_5.3
- ci-Prevent-NM-from-handling-DNS-when-network-interfaces.patch [RHEL-65778]
- Resolves: RHEL-65778
([RHEL-9] Prevent NM from handling DNS when network interfaces have DNS config [rhel-9.5.z])
* Wed Nov 06 2024 Miroslav Rezanina <mrezanin@redhat.com> - 23.4-19.el9_5.2
- ci-fix-Render-bridges-correctly-for-v2-on-sysconfig-wit.patch [RHEL-65021]
- ci-fix-Render-v2-bridges-correctly-on-network-manager-w.patch [RHEL-65021]
- Resolves: RHEL-65021
(NoCloud - network_config bridges incorrectly configured [rhel-9.5.z])
* Thu Oct 31 2024 Miroslav Rezanina <mrezanin@redhat.com> - 23.4-19.el9_5.1
- ci-Fix-metric-setting-for-ifcfg-network-connections-for.patch [RHEL-65018]
- ci-fix-python3.13-Fix-import-error-for-passlib-on-Pytho.patch [RHEL-65018]
- Resolves: RHEL-65018
(Configuring metric for default gateway is not working [rhel-9.5.z])
* Mon Aug 26 2024 Miroslav Rezanina <mrezanin@redhat.com> - 23.4-19
- ci-fix-Add-subnet-ipv4-ipv6-to-network-schema-5191.patch [RHEL-54686]
- Resolves: RHEL-54686
([RHEL-9.5] cloud-init schema validation fails.)
* Mon Aug 19 2024 Miroslav Rezanina <mrezanin@redhat.com> - 23.4-18
- ci-Revert-fix-vmware-Set-IPv6-to-dhcp-when-there-is-no-.patch [RHEL-54373]
- Resolves: RHEL-54373
([RHEL9]Revert "fix(vmware): Set IPv6 to dhcp when there is no IPv6 addr (#5471)")
* Thu Jul 25 2024 Miroslav Rezanina <mrezanin@redhat.com> - 23.4-17
- ci-fix-Clean-cache-if-no-datasource-fallback-5499.patch [RHEL-49736]
- ci-Support-setting-mirrorlist-in-yum-repository-config-.patch [RHEL-49674]
- Resolves: RHEL-49736
([Cloud-init] [RHEL-9] Password reset feature broken with CloudstackDataSource)
- Resolves: RHEL-49674
(Support setting mirrorlist in yum repository config)
* Fri Jul 12 2024 Miroslav Rezanina <mrezanin@redhat.com> - 23.4-16
- ci-fix-add-schema-rules-for-baseurl-and-metalink-in-yum.patch [RHEL-46873]
- Resolves: RHEL-46873
(Suggest to update schema to support metalink)
* Mon Jul 08 2024 Miroslav Rezanina <mrezanin@redhat.com> - 23.4-15
- ci-Support-metalink-in-yum-repository-config-5444.patch [RHEL-44916]
- ci-fix-vmware-Set-IPv6-to-dhcp-when-there-is-no-IPv6-ad.patch [RHEL-46194]
- Resolves: RHEL-44916
([RFE] Support metalink in yum repository config)
- Resolves: RHEL-46194
([RHEL-9] It leaves the ipv6 networking config as blank in NM keyfile when config dhcp ipv6 with customization spec)
* Mon Jul 01 2024 Miroslav Rezanina <mrezanin@redhat.com> - 23.4-14
- ci-Deprecate-the-users-ssh-authorized-keys-property-516.patch [RHEL-45262]
- ci-docs-Add-deprecated-system_info-to-schema-5168.patch [RHEL-45262]
- ci-fix-schema-permit-deprecated-hyphenated-keys-under-u.patch [RHEL-45262]
- Resolves: RHEL-45262
(Deprecate the users ssh-authorized-keys property and permit deprecated hyphenated keys under users key)
* Tue Jun 25 2024 Miroslav Rezanina <mrezanin@redhat.com> - 23.4-13
- ci-feat-sysconfig-Add-DNS-from-interface-config-to-reso.patch [RHEL-17961]
- ci-fix-jsonschema-Add-missing-sudo-definition-5418.patch [RHEL-44337]
- ci-doc-update-examples-to-reflect-alternative-ways-to-p.patch [RHEL-44337]
- ci-fix-dhcp-Guard-against-FileNotFoundError-and-NameErr.patch [RHEL-44598]
- ci-fix-Address-TIOBE-abstract-interpretation-issues-486.patch [RHEL-44598]
- ci-Update-pylint-version-to-support-python-3.12-5338.patch [RHEL-44598]
- Resolves: RHEL-17961
([RHEL-9] cloud-init fails to configure DNS search domains)
- Resolves: RHEL-44337
([rhel-9] fix `SUDO` configuration schema for users and groups)
- Resolves: RHEL-44598
(fix pylint error and support python 3.12)
* Mon Jun 17 2024 Miroslav Rezanina <mrezanin@redhat.com> - 23.4-12
- ci-fix-cloudstack-Use-parsed-lease-file-for-virtual-rou.patch [RHEL-40217]
- Resolves: RHEL-40217
([Cloud-init] CloudstackDataSource cannot work with NetworkManager)
- ci-feat-sysconfig-Add-DNS-from-interface-config-to-reso.patch [RHEL-17961]
* Thu May 16 2024 Miroslav Rezanina <mrezanin@redhat.com> - 23.4-7.3
* Thu May 16 2024 Miroslav Rezanina <mrezanin@redhat.com> - 23.4-11
- ci-fix-Always-use-single-datasource-if-specified-5098.patch [RHEL-36255]
- Resolves: RHEL-36255
([rhel-9.5] DataSourceNoCloudNet not configurable via config files)
* Mon Apr 22 2024 Miroslav Rezanina <mrezanin@redhat.com> - 23.4-7.2
* Mon Apr 29 2024 Miroslav Rezanina <mrezanin@redhat.com> - 23.4-10
- ci-Remove-dependency-on-python3-httpretty.patch [RHEL-33973]
- Resolves: RHEL-33973
([RFE] Remove dependency on python3-httpretty)
* Mon Apr 22 2024 Miroslav Rezanina <mrezanin@redhat.com> - 23.4-9
- ci-fix-Fall-back-to-cached-local-ds-if-no-valid-ds-foun.patch [RHEL-32846]
- Resolves: RHEL-32846
([cloud-init][ESXi]VMware datasource resets on every boot causing it to lose network configuration [rhel-9])
* Mon Apr 08 2024 Miroslav Rezanina <mrezanin@redhat.com> - 23.4-7.1
* Mon Apr 08 2024 Miroslav Rezanina <mrezanin@redhat.com> - 23.4-8
- ci-fix-Correct-v2-NetworkManager-route-rendering-4637.patch [RHEL-20964]
- ci-feat-apply-global-DNS-to-interfaces-in-network-manag.patch [RHEL-20964]
- ci-fix-Undeprecate-network-in-schema-route-definition-5.patch [RHEL-29709]
@ -692,7 +857,7 @@ fi
* Thu Apr 13 2017 Charalampos Stratakis <cstratak@redhat.com> 0.7.9-4
- Import to RHEL 7
Resolves: rhbz#1427280
Resolves: rhbz#1427280
* Tue Mar 07 2017 Lars Kellogg-Stedman <lars@redhat.com> 0.7.9-3
- fixes for network config generation