* 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)
This commit is contained in:
parent
3affac864f
commit
f1f4c0a890
235
ci-Update-pylint-version-to-support-python-3.12-5338.patch
Normal file
235
ci-Update-pylint-version-to-support-python-3.12-5338.patch
Normal 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
|
||||
|
@ -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
|
||||
|
351
ci-feat-sysconfig-Add-DNS-from-interface-config-to-reso.patch
Normal file
351
ci-feat-sysconfig-Add-DNS-from-interface-config-to-reso.patch
Normal file
@ -0,0 +1,351 @@
|
||||
From 6b32b371bfd37759ddce3d7f29d15546500698e6 Mon Sep 17 00:00:00 2001
|
||||
From: Ani Sinha <anisinha@redhat.com>
|
||||
Date: Thu, 20 Jun 2024 22:27:03 +0530
|
||||
Subject: [PATCH 1/6] feat(sysconfig): Add DNS from interface config to
|
||||
resolv.conf (#5401)
|
||||
|
||||
RH-Author: Ani Sinha <anisinha@redhat.com>
|
||||
RH-MergeRequest: 88: feat(sysconfig): Add DNS from interface config to resolv.conf (#5401)
|
||||
RH-Jira: RHEL-17961
|
||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Commit: [1/1] f353b73cc0f4bb9e1aee037708a1d3cb23b83cc3 (anisinha/cloud-init)
|
||||
|
||||
sysconfig renderer currently only uses global dns and search domain
|
||||
configuration in order to populate /etc/resolv.conf. This means it ignores
|
||||
interface specific dns configuration completely. This means, when global dns
|
||||
information is absent and only interface specific dns configuration is present,
|
||||
/etc/resolv.conf will not have complete dns information. Fix this so that
|
||||
per interface dns information is also taken into account along with global dns
|
||||
configuration in order to populate /etc/resolv.conf.
|
||||
|
||||
Fixes: GH-5400
|
||||
|
||||
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
||||
(cherry picked from commit 1b8030e0c7fd6fbff7e38ad1e3e6266ae50c83a5)
|
||||
---
|
||||
cloudinit/net/sysconfig.py | 52 +++++++++-
|
||||
tests/unittests/test_net.py | 184 +++++++++++++++++++++++++++++++++++-
|
||||
2 files changed, 230 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
|
||||
index d39f4fe3..7eb430ed 100644
|
||||
--- a/cloudinit/net/sysconfig.py
|
||||
+++ b/cloudinit/net/sysconfig.py
|
||||
@@ -825,20 +825,62 @@ class Renderer(renderer.Renderer):
|
||||
|
||||
@staticmethod
|
||||
def _render_dns(network_state, existing_dns_path=None):
|
||||
- # skip writing resolv.conf if network_state doesn't include any input.
|
||||
+
|
||||
+ found_nameservers = []
|
||||
+ found_dns_search = []
|
||||
+
|
||||
+ for iface in network_state.iter_interfaces():
|
||||
+ for subnet in iface["subnets"]:
|
||||
+ # Add subnet-level DNS
|
||||
+ if "dns_nameservers" in subnet:
|
||||
+ found_nameservers.extend(subnet["dns_nameservers"])
|
||||
+ if "dns_search" in subnet:
|
||||
+ found_dns_search.extend(subnet["dns_search"])
|
||||
+
|
||||
+ # Add interface-level DNS
|
||||
+ if "dns" in iface:
|
||||
+ found_nameservers += [
|
||||
+ dns
|
||||
+ for dns in iface["dns"]["nameservers"]
|
||||
+ if dns not in found_nameservers
|
||||
+ ]
|
||||
+ found_dns_search += [
|
||||
+ search
|
||||
+ for search in iface["dns"]["search"]
|
||||
+ if search not in found_dns_search
|
||||
+ ]
|
||||
+
|
||||
+ # When both global and interface specific entries are present,
|
||||
+ # use them both to generate /etc/resolv.conf eliminating duplicate
|
||||
+ # entries. Otherwise use global or interface specific entries whichever
|
||||
+ # is provided.
|
||||
+ if network_state.dns_nameservers:
|
||||
+ found_nameservers += [
|
||||
+ nameserver
|
||||
+ for nameserver in network_state.dns_nameservers
|
||||
+ if nameserver not in found_nameservers
|
||||
+ ]
|
||||
+ if network_state.dns_searchdomains:
|
||||
+ found_dns_search += [
|
||||
+ search
|
||||
+ for search in network_state.dns_searchdomains
|
||||
+ if search not in found_dns_search
|
||||
+ ]
|
||||
+
|
||||
+ # skip writing resolv.conf if no dns information is provided in conf.
|
||||
if not any(
|
||||
[
|
||||
- len(network_state.dns_nameservers),
|
||||
- len(network_state.dns_searchdomains),
|
||||
+ len(found_nameservers),
|
||||
+ len(found_dns_search),
|
||||
]
|
||||
):
|
||||
return None
|
||||
content = resolv_conf.ResolvConf("")
|
||||
if existing_dns_path and os.path.isfile(existing_dns_path):
|
||||
content = resolv_conf.ResolvConf(util.load_file(existing_dns_path))
|
||||
- for nameserver in network_state.dns_nameservers:
|
||||
+ for nameserver in found_nameservers:
|
||||
content.add_nameserver(nameserver)
|
||||
- for searchdomain in network_state.dns_searchdomains:
|
||||
+ for searchdomain in found_dns_search:
|
||||
content.add_search_domain(searchdomain)
|
||||
header = _make_header(";")
|
||||
content_str = str(content)
|
||||
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
|
||||
index d7c9a414..2d716f4b 100644
|
||||
--- a/tests/unittests/test_net.py
|
||||
+++ b/tests/unittests/test_net.py
|
||||
@@ -516,6 +516,8 @@ OS_SAMPLES = [
|
||||
}
|
||||
],
|
||||
"ip_address": "172.19.1.34",
|
||||
+ "dns_search": ["testweb.com"],
|
||||
+ "dns_nameservers": ["172.19.0.13"],
|
||||
"id": "network0",
|
||||
}
|
||||
],
|
||||
@@ -550,7 +552,9 @@ STARTMODE=auto
|
||||
"""
|
||||
; Created by cloud-init automatically, do not edit.
|
||||
;
|
||||
+nameserver 172.19.0.13
|
||||
nameserver 172.19.0.12
|
||||
+search testweb.com
|
||||
""".lstrip(),
|
||||
),
|
||||
(
|
||||
@@ -582,6 +586,8 @@ AUTOCONNECT_PRIORITY=120
|
||||
BOOTPROTO=none
|
||||
DEFROUTE=yes
|
||||
DEVICE=eth0
|
||||
+DNS1=172.19.0.13
|
||||
+DOMAIN=testweb.com
|
||||
GATEWAY=172.19.3.254
|
||||
HWADDR=fa:16:3e:ed:9a:59
|
||||
IPADDR=172.19.1.34
|
||||
@@ -596,7 +602,174 @@ USERCTL=no
|
||||
"""
|
||||
; Created by cloud-init automatically, do not edit.
|
||||
;
|
||||
+nameserver 172.19.0.13
|
||||
nameserver 172.19.0.12
|
||||
+search testweb.com
|
||||
+""".lstrip(),
|
||||
+ ),
|
||||
+ (
|
||||
+ "etc/NetworkManager/conf.d/99-cloud-init.conf",
|
||||
+ """
|
||||
+# Created by cloud-init automatically, do not edit.
|
||||
+#
|
||||
+[main]
|
||||
+dns = none
|
||||
+""".lstrip(),
|
||||
+ ),
|
||||
+ (
|
||||
+ "etc/udev/rules.d/70-persistent-net.rules",
|
||||
+ "".join(
|
||||
+ [
|
||||
+ 'SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ',
|
||||
+ 'ATTR{address}=="fa:16:3e:ed:9a:59", NAME="eth0"\n',
|
||||
+ ]
|
||||
+ ),
|
||||
+ ),
|
||||
+ ],
|
||||
+ "expected_network_manager": [
|
||||
+ (
|
||||
+ "".join(
|
||||
+ [
|
||||
+ "etc/NetworkManager/system-connections",
|
||||
+ "/cloud-init-eth0.nmconnection",
|
||||
+ ]
|
||||
+ ),
|
||||
+ """
|
||||
+# Generated by cloud-init. Changes will be lost.
|
||||
+
|
||||
+[connection]
|
||||
+id=cloud-init eth0
|
||||
+uuid=1dd9a779-d327-56e1-8454-c65e2556c12c
|
||||
+autoconnect-priority=120
|
||||
+type=ethernet
|
||||
+
|
||||
+[user]
|
||||
+org.freedesktop.NetworkManager.origin=cloud-init
|
||||
+
|
||||
+[ethernet]
|
||||
+mac-address=FA:16:3E:ED:9A:59
|
||||
+
|
||||
+[ipv4]
|
||||
+method=manual
|
||||
+may-fail=false
|
||||
+address1=172.19.1.34/22
|
||||
+route1=0.0.0.0/0,172.19.3.254
|
||||
+dns=172.19.0.13;
|
||||
+dns-search=testweb.com;
|
||||
+
|
||||
+""".lstrip(),
|
||||
+ ),
|
||||
+ ],
|
||||
+ },
|
||||
+ {
|
||||
+ "in_data": {
|
||||
+ "services": [
|
||||
+ {
|
||||
+ "type": "dns",
|
||||
+ "address": "172.19.0.12",
|
||||
+ "search": ["example1.com", "example2.com"],
|
||||
+ }
|
||||
+ ],
|
||||
+ "networks": [
|
||||
+ {
|
||||
+ "network_id": "dacd568d-5be6-4786-91fe-750c374b78b4",
|
||||
+ "type": "ipv4",
|
||||
+ "netmask": "255.255.252.0",
|
||||
+ "link": "eth0",
|
||||
+ "routes": [
|
||||
+ {
|
||||
+ "netmask": "0.0.0.0",
|
||||
+ "network": "0.0.0.0",
|
||||
+ "gateway": "172.19.3.254",
|
||||
+ }
|
||||
+ ],
|
||||
+ "ip_address": "172.19.1.34",
|
||||
+ "dns_search": ["example3.com"],
|
||||
+ "dns_nameservers": ["172.19.0.12"],
|
||||
+ "id": "network0",
|
||||
+ }
|
||||
+ ],
|
||||
+ "links": [
|
||||
+ {
|
||||
+ "ethernet_mac_address": "fa:16:3e:ed:9a:59",
|
||||
+ "mtu": None,
|
||||
+ "type": "physical",
|
||||
+ "id": "eth0",
|
||||
+ },
|
||||
+ ],
|
||||
+ },
|
||||
+ "in_macs": {
|
||||
+ "fa:16:3e:ed:9a:59": "eth0",
|
||||
+ },
|
||||
+ "out_sysconfig_opensuse": [
|
||||
+ (
|
||||
+ "etc/sysconfig/network/ifcfg-eth0",
|
||||
+ """
|
||||
+# Created by cloud-init automatically, do not edit.
|
||||
+#
|
||||
+BOOTPROTO=static
|
||||
+IPADDR=172.19.1.34
|
||||
+LLADDR=fa:16:3e:ed:9a:59
|
||||
+NETMASK=255.255.252.0
|
||||
+STARTMODE=auto
|
||||
+""".lstrip(),
|
||||
+ ),
|
||||
+ (
|
||||
+ "etc/resolv.conf",
|
||||
+ """
|
||||
+; Created by cloud-init automatically, do not edit.
|
||||
+;
|
||||
+nameserver 172.19.0.12
|
||||
+search example3.com example1.com example2.com
|
||||
+""".lstrip(),
|
||||
+ ),
|
||||
+ (
|
||||
+ "etc/NetworkManager/conf.d/99-cloud-init.conf",
|
||||
+ """
|
||||
+# Created by cloud-init automatically, do not edit.
|
||||
+#
|
||||
+[main]
|
||||
+dns = none
|
||||
+""".lstrip(),
|
||||
+ ),
|
||||
+ (
|
||||
+ "etc/udev/rules.d/85-persistent-net-cloud-init.rules",
|
||||
+ "".join(
|
||||
+ [
|
||||
+ 'SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ',
|
||||
+ 'ATTR{address}=="fa:16:3e:ed:9a:59", NAME="eth0"\n',
|
||||
+ ]
|
||||
+ ),
|
||||
+ ),
|
||||
+ ],
|
||||
+ "out_sysconfig_rhel": [
|
||||
+ (
|
||||
+ "etc/sysconfig/network-scripts/ifcfg-eth0",
|
||||
+ """
|
||||
+# Created by cloud-init automatically, do not edit.
|
||||
+#
|
||||
+AUTOCONNECT_PRIORITY=120
|
||||
+BOOTPROTO=none
|
||||
+DEFROUTE=yes
|
||||
+DEVICE=eth0
|
||||
+DNS1=172.19.0.12
|
||||
+DOMAIN=example3.com
|
||||
+GATEWAY=172.19.3.254
|
||||
+HWADDR=fa:16:3e:ed:9a:59
|
||||
+IPADDR=172.19.1.34
|
||||
+NETMASK=255.255.252.0
|
||||
+ONBOOT=yes
|
||||
+TYPE=Ethernet
|
||||
+USERCTL=no
|
||||
+""".lstrip(),
|
||||
+ ),
|
||||
+ (
|
||||
+ "etc/resolv.conf",
|
||||
+ """
|
||||
+; Created by cloud-init automatically, do not edit.
|
||||
+;
|
||||
+nameserver 172.19.0.12
|
||||
+search example3.com example1.com example2.com
|
||||
""".lstrip(),
|
||||
),
|
||||
(
|
||||
@@ -647,6 +820,7 @@ may-fail=false
|
||||
address1=172.19.1.34/22
|
||||
route1=0.0.0.0/0,172.19.3.254
|
||||
dns=172.19.0.12;
|
||||
+dns-search=example3.com;
|
||||
|
||||
""".lstrip(),
|
||||
),
|
||||
@@ -654,7 +828,13 @@ dns=172.19.0.12;
|
||||
},
|
||||
{
|
||||
"in_data": {
|
||||
- "services": [{"type": "dns", "address": "172.19.0.12"}],
|
||||
+ "services": [
|
||||
+ {
|
||||
+ "type": "dns",
|
||||
+ "address": "172.19.0.12",
|
||||
+ "search": "example.com",
|
||||
+ }
|
||||
+ ],
|
||||
"networks": [
|
||||
{
|
||||
"network_id": "public-ipv4",
|
||||
@@ -715,6 +895,7 @@ STARTMODE=auto
|
||||
; Created by cloud-init automatically, do not edit.
|
||||
;
|
||||
nameserver 172.19.0.12
|
||||
+search example.com
|
||||
""".lstrip(),
|
||||
),
|
||||
(
|
||||
@@ -763,6 +944,7 @@ USERCTL=no
|
||||
; Created by cloud-init automatically, do not edit.
|
||||
;
|
||||
nameserver 172.19.0.12
|
||||
+search example.com
|
||||
""".lstrip(),
|
||||
),
|
||||
(
|
||||
--
|
||||
2.39.3
|
||||
|
@ -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
|
||||
|
132
ci-fix-dhcp-Guard-against-FileNotFoundError-and-NameErr.patch
Normal file
132
ci-fix-dhcp-Guard-against-FileNotFoundError-and-NameErr.patch
Normal 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
|
||||
|
53
ci-fix-jsonschema-Add-missing-sudo-definition-5418.patch
Normal file
53
ci-fix-jsonschema-Add-missing-sudo-definition-5418.patch
Normal 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
|
||||
|
@ -1,6 +1,6 @@
|
||||
Name: cloud-init
|
||||
Version: 23.4
|
||||
Release: 12%{?dist}
|
||||
Release: 13%{?dist}
|
||||
Summary: Cloud instance init scripts
|
||||
License: ASL 2.0 or GPLv3
|
||||
URL: http://launchpad.net/cloud-init
|
||||
@ -35,6 +35,18 @@ Patch16: ci-fix-Fall-back-to-cached-local-ds-if-no-valid-ds-foun.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
|
||||
# For RHEL-17961 - [RHEL-9] cloud-init fails to configure DNS search domains
|
||||
Patch19: ci-feat-sysconfig-Add-DNS-from-interface-config-to-reso.patch
|
||||
# For RHEL-44337 - [rhel-9] fix `SUDO` configuration schema for users and groups
|
||||
Patch20: ci-fix-jsonschema-Add-missing-sudo-definition-5418.patch
|
||||
# For RHEL-44337 - [rhel-9] fix `SUDO` configuration schema for users and groups
|
||||
Patch21: ci-doc-update-examples-to-reflect-alternative-ways-to-p.patch
|
||||
# For RHEL-44598 - fix pylint error and support python 3.12
|
||||
Patch22: ci-fix-dhcp-Guard-against-FileNotFoundError-and-NameErr.patch
|
||||
# For RHEL-44598 - fix pylint error and support python 3.12
|
||||
Patch23: ci-fix-Address-TIOBE-abstract-interpretation-issues-486.patch
|
||||
# For RHEL-44598 - fix pylint error and support python 3.12
|
||||
Patch24: ci-Update-pylint-version-to-support-python-3.12-5338.patch
|
||||
|
||||
BuildArch: noarch
|
||||
|
||||
@ -249,6 +261,20 @@ fi
|
||||
%config(noreplace) %{_sysconfdir}/rsyslog.d/21-cloudinit.conf
|
||||
|
||||
%changelog
|
||||
* 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
|
||||
|
Loading…
Reference in New Issue
Block a user