* Tue Apr 07 2026 Miroslav Rezanina <mrezanin@redhat.com> - 24.4-7.el10_2.1

- ci-fix-Pass-interface-string-to-get_newest_lease-6648.patch [RHEL-159033]
- ci-fix-cloudstack-Improve-domain-name-DHCP-lease-lookup.patch [RHEL-159033]
- ci-downstream-fix-test_cloudstack.py-since-pytest-fixtu.patch [RHEL-159033]
- Resolves: RHEL-159033
  ([GSS][Secure Support] [RHEL-10] cloud-init requests lease before DHCP can provide one [rhel-10.2.z])
This commit is contained in:
Miroslav Rezanina 2026-04-07 09:17:59 +02:00
parent b142d5f0f3
commit 17e3136ff3
4 changed files with 306 additions and 1 deletions

View File

@ -0,0 +1,96 @@
From 0c0b91bb94308c97514cd0464c0911f7c4b1ddbc Mon Sep 17 00:00:00 2001
From: Ani Sinha <anisinha@redhat.com>
Date: Mon, 23 Mar 2026 13:50:11 +0530
Subject: [PATCH 4/4] downstream: fix test_cloudstack.py since pytest fixtures
cannot be used
RH-Author: Ani Sinha <anisinha@redhat.com>
RH-MergeRequest: 135: fix(cloudstack): Improve domain-name DHCP lease lookup
RH-Jira: RHEL-159033
RH-Acked-by: xiachen <xiachen@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [3/3] af3ac74a3a2389d1a989571f124c76d33ad264e8 (anisinha/cloud-init)
pytest.mark.parametrize decorator cannot be used for functions inside classes
that are derived from unittest.TestCase[1]. Here, the test class is derived
from CiTestCase which in turn is derived from TestCase class which is again
itself derived from unittest.TestCase. This was removed from the upstream
commit 589c9461db1 ("Fix: Add Ephemeral Network for CloudStackLocal DS (#6144)")
which we are not backporting. Hence, we change the test code such that the
main test function is called for each of the previously declared parameterized
values.
This patch should not be needed after a rebase when 589c9461db1 pulled in
through rebase.
X-downstream-only: true
1. https://stackoverflow.com/questions/63720118/pytest-parametrize-i-am-getting-missing-required-positional-arguments
Signed-off-by: Ani Sinha <anisinha@redhat.com>
---
tests/unittests/sources/test_cloudstack.py | 45 ++++++++++++----------
1 file changed, 24 insertions(+), 21 deletions(-)
diff --git a/tests/unittests/sources/test_cloudstack.py b/tests/unittests/sources/test_cloudstack.py
index 0f9870665..f3b08a475 100644
--- a/tests/unittests/sources/test_cloudstack.py
+++ b/tests/unittests/sources/test_cloudstack.py
@@ -328,31 +328,34 @@ class TestCloudStackHostname(CiTestCase):
result = ds.get_hostname(fqdn=True)
self.assertTupleEqual(expected, result)
- @pytest.mark.parametrize(
- "lease_key,expected_domain",
- [
- ("DOMAINNAME", "example.com"),
- ("Domain", "example.com"),
- ("domain-name", "example.com"),
- ],
- )
def test__get_domainname_supports_all_casing_variants(
- self, lease_key, expected_domain
+ self,
):
"""Ensure _get_domainname works with DOMAINNAME, Domain and
domain-name."""
- # Mock the helper to return the domain only when the exact key is asked
- with patch(
- "cloudinit.net.dhcp.networkd_get_option_from_leases"
- ) as m_get:
- m_get.side_effect = lambda key, extra_keys=None: (
- "example.com " if key == lease_key else None
- )
-
- ds = DataSourceCloudStack(
- {}, distro=MockDistro(), paths=helpers.Paths({})
- )
- assert ds._get_domainname() == expected_domain
+ cases = [
+ ("DOMAINNAME", "example.com"),
+ ("Domain", "example.com"),
+ ("domain-name", "example.com"),
+ ]
+
+ def testit(lease_key, expected_domain):
+ # Mock the helper to return the domain only when
+ # the exact key is asked
+ with patch(
+ "cloudinit.net.dhcp.networkd_get_option_from_leases"
+ ) as m_get:
+ m_get.side_effect = lambda key, extra_keys=None: (
+ "example.com " if key == lease_key else None
+ )
+
+ ds = DataSourceCloudStack(
+ {}, distro=MockDistro(), paths=helpers.Paths({})
+ )
+ assert ds._get_domainname() == expected_domain
+
+ for lease_key, expected_domain in cases:
+ testit(lease_key, expected_domain)
@pytest.mark.usefixtures("dhclient_exists")
--
2.47.3

View File

@ -0,0 +1,40 @@
From 20a3d2274134fa7336b3803882004e2f70a756de Mon Sep 17 00:00:00 2001
From: Leah <76408777+goldberl@users.noreply.github.com>
Date: Tue, 6 Jan 2026 15:01:59 -0500
Subject: [PATCH 2/4] fix: Pass interface string to get_newest_lease() (#6648)
RH-Author: Ani Sinha <anisinha@redhat.com>
RH-MergeRequest: 135: fix(cloudstack): Improve domain-name DHCP lease lookup
RH-Jira: RHEL-159033
RH-Acked-by: xiachen <xiachen@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [1/3] 5f74c14b51432facb96647410ed6a6ec52c99935 (anisinha/cloud-init)
In DataSourceCloudStack.py, get_newest_lease() is currently being
passed a Distro object, causing a Python type error. This PR
changes the Distro object to the interface string to fix this error.
(cherry picked from commit e02b739fc094eb8b56391705c2989f4aecbe139b)
Signed-off-by: Ani Sinha <anisinha@redhat.com>
---
cloudinit/sources/DataSourceCloudStack.py | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/cloudinit/sources/DataSourceCloudStack.py b/cloudinit/sources/DataSourceCloudStack.py
index 61bf94f51..6d19077cd 100644
--- a/cloudinit/sources/DataSourceCloudStack.py
+++ b/cloudinit/sources/DataSourceCloudStack.py
@@ -314,7 +314,9 @@ def get_vr_address(distro):
return latest_address
with suppress(FileNotFoundError):
- latest_lease = distro.dhcp_client.get_newest_lease(distro)
+ latest_lease = distro.dhcp_client.get_newest_lease(
+ distro.fallback_interface
+ )
if latest_lease:
LOG.debug(
"Found SERVER_ADDRESS '%s' via ephemeral %s lease ",
--
2.47.3

View File

@ -0,0 +1,156 @@
From 5b771aa7ba9853f17a051348d0a5ce3e9b945d9f Mon Sep 17 00:00:00 2001
From: CodeBleu <400979+CodeBleu@users.noreply.github.com>
Date: Tue, 20 Jan 2026 13:52:54 -0500
Subject: [PATCH 3/4] fix(cloudstack): Improve domain-name DHCP lease lookup
(Cloudstack) (#6554)
RH-Author: Ani Sinha <anisinha@redhat.com>
RH-MergeRequest: 135: fix(cloudstack): Improve domain-name DHCP lease lookup
RH-Jira: RHEL-159033
RH-Acked-by: xiachen <xiachen@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [2/3] f9e1f775d40bd402eb10e3e74a4e88045a48036d (anisinha/cloud-init)
* Adding case-insensitive options for systemd-networkd leases ("DOMAINNAME", "Domain", "domain-name").
* Falling back gracefully from systemd leases to ISC dhclient leases.
* Including dhcpcd ephemeral leases as an additional fallback.
* Returning an empty string when no domain name found instead of None for non-fatal missing cases.
(cherry picked from commit d2bf883931723cfdc9f529eba5395d83059d09c6)
Signed-off-by: Ani Sinha <anisinha@redhat.com>
---
cloudinit/sources/DataSourceCloudStack.py | 50 +++++++++++-----------
tests/unittests/sources/test_cloudstack.py | 27 ++++++++++++
2 files changed, 53 insertions(+), 24 deletions(-)
diff --git a/cloudinit/sources/DataSourceCloudStack.py b/cloudinit/sources/DataSourceCloudStack.py
index 6d19077cd..98189c23c 100644
--- a/cloudinit/sources/DataSourceCloudStack.py
+++ b/cloudinit/sources/DataSourceCloudStack.py
@@ -23,6 +23,7 @@ from cloudinit import sources, subp
from cloudinit import url_helper as uhelp
from cloudinit import util
from cloudinit.net import dhcp
+from cloudinit.net.dhcp import NoDHCPLeaseError
from cloudinit.sources.helpers import ec2
LOG = logging.getLogger(__name__)
@@ -97,46 +98,47 @@ class DataSourceCloudStack(sources.DataSource):
self.cfg = {}
def _get_domainname(self):
+ """Try obtaining a "domain-name" DHCP lease parameter:
+ - From systemd-networkd lease (case-insensitive)
+ - From ISC dhclient
+ - From dhcpcd (ephemeral)
+ - Return empty string if not found (non-fatal)
"""
- Try obtaining a "domain-name" DHCP lease parameter:
- - From systemd-networkd lease
- - From dhclient lease
- """
+
LOG.debug("Try obtaining domain name from networkd leases")
- domainname = dhcp.networkd_get_option_from_leases("DOMAINNAME")
- if domainname:
- return domainname
+ for key in ["DOMAINNAME", "Domain", "domain-name"]:
+ domainname = dhcp.networkd_get_option_from_leases(key)
+ if domainname:
+ return domainname.strip()
+
LOG.debug(
- "Could not obtain FQDN from networkd leases. "
- "Falling back to ISC dhclient"
+ "Could not obtain FQDN from networkd leases. Falling back to "
+ "ISC dhclient"
)
-
- # some distros might use isc-dhclient for network setup via their
- # network manager. If this happens, the lease is more recent than the
- # ephemeral lease, so use it first.
with suppress(dhcp.NoDHCPLeaseMissingDhclientError):
domain_name = dhcp.IscDhclient().get_key_from_latest_lease(
self.distro, "domain-name"
)
if domain_name:
- return domain_name
+ return domain_name.strip()
LOG.debug(
- "Could not obtain FQDN from ISC dhclient leases. "
- "Falling back to %s",
+ "Could not obtain FQDN from ISC dhclient leases. Falling back to "
+ "%s",
self.distro.dhcp_client.client_name,
)
-
- # If no distro leases were found, check the ephemeral lease that
- # cloud-init set up.
- with suppress(FileNotFoundError):
+ try:
latest_lease = self.distro.dhcp_client.get_newest_lease(
self.distro.fallback_interface
)
- domain_name = latest_lease.get("domain-name") or None
- return domain_name
- LOG.debug("No dhcp leases found")
- return None
+ domain_name = latest_lease.get("domain-name")
+ if domain_name:
+ return domain_name.strip()
+ except (NoDHCPLeaseError, FileNotFoundError, AttributeError):
+ pass
+
+ LOG.debug("No domain name found in any DHCP lease; returning empty")
+ return ""
def get_hostname(
self,
diff --git a/tests/unittests/sources/test_cloudstack.py b/tests/unittests/sources/test_cloudstack.py
index a64d80f37..0f9870665 100644
--- a/tests/unittests/sources/test_cloudstack.py
+++ b/tests/unittests/sources/test_cloudstack.py
@@ -1,5 +1,6 @@
# This file is part of cloud-init. See LICENSE file for license information.
from textwrap import dedent
+from unittest.mock import patch
import pytest
@@ -327,6 +328,32 @@ class TestCloudStackHostname(CiTestCase):
result = ds.get_hostname(fqdn=True)
self.assertTupleEqual(expected, result)
+ @pytest.mark.parametrize(
+ "lease_key,expected_domain",
+ [
+ ("DOMAINNAME", "example.com"),
+ ("Domain", "example.com"),
+ ("domain-name", "example.com"),
+ ],
+ )
+ def test__get_domainname_supports_all_casing_variants(
+ self, lease_key, expected_domain
+ ):
+ """Ensure _get_domainname works with DOMAINNAME, Domain and
+ domain-name."""
+ # Mock the helper to return the domain only when the exact key is asked
+ with patch(
+ "cloudinit.net.dhcp.networkd_get_option_from_leases"
+ ) as m_get:
+ m_get.side_effect = lambda key, extra_keys=None: (
+ "example.com " if key == lease_key else None
+ )
+
+ ds = DataSourceCloudStack(
+ {}, distro=MockDistro(), paths=helpers.Paths({})
+ )
+ assert ds._get_domainname() == expected_domain
+
@pytest.mark.usefixtures("dhclient_exists")
class TestCloudStackPasswordFetching(CiTestCase):
--
2.47.3

View File

@ -6,7 +6,7 @@
Name: cloud-init
Version: 24.4
Release: 7%{?dist}
Release: 7%{?dist}.1
Summary: Cloud instance init scripts
License: Apache-2.0 OR GPL-3.0-only
URL: https://github.com/canonical/cloud-init
@ -32,6 +32,12 @@ Patch11: ci-feat-aliyun-datasource-support-crawl-metadata-at-onc.patch
Patch12: ci-fix-Don-t-attempt-to-identify-non-x86-OpenStack-inst.patch
# For RHEL-100617 - CVE-2024-6174 cloud-init: From CVEorg collector [rhel-10.1]
Patch13: ci-fix-strict-disable-in-ds-identify-on-no-datasources-.patch
# For RHEL-159033 - [GSS][Secure Support] [RHEL-10] cloud-init requests lease before DHCP can provide one [rhel-10.2.z]
Patch14: ci-fix-Pass-interface-string-to-get_newest_lease-6648.patch
# For RHEL-159033 - [GSS][Secure Support] [RHEL-10] cloud-init requests lease before DHCP can provide one [rhel-10.2.z]
Patch15: ci-fix-cloudstack-Improve-domain-name-DHCP-lease-lookup.patch
# For RHEL-159033 - [GSS][Secure Support] [RHEL-10] cloud-init requests lease before DHCP can provide one [rhel-10.2.z]
Patch16: ci-downstream-fix-test_cloudstack.py-since-pytest-fixtu.patch
BuildArch: noarch
@ -237,6 +243,13 @@ fi
%changelog
* Tue Apr 07 2026 Miroslav Rezanina <mrezanin@redhat.com> - 24.4-7.el10_2.1
- ci-fix-Pass-interface-string-to-get_newest_lease-6648.patch [RHEL-159033]
- ci-fix-cloudstack-Improve-domain-name-DHCP-lease-lookup.patch [RHEL-159033]
- ci-downstream-fix-test_cloudstack.py-since-pytest-fixtu.patch [RHEL-159033]
- Resolves: RHEL-159033
([GSS][Secure Support] [RHEL-10] cloud-init requests lease before DHCP can provide one [rhel-10.2.z])
* Wed Dec 10 2025 Miroslav Rezanina <mrezanin@redhat.com> - 24.4-7
- ci-downstream-Do-not-override-changes-in-disable-sshd-k.patch [RHEL-128097]
- Resolves: RHEL-128097