From 6ed5df0460564a116258e8ba3df0681ed9291b70 Mon Sep 17 00:00:00 2001 From: Miroslav Rezanina Date: Mon, 8 Jul 2024 07:08:12 -0400 Subject: [PATCH] * Mon Jul 08 2024 Miroslav Rezanina - 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) --- ...talink-in-yum-repository-config-5444.patch | 140 +++++++++++++ ...Pv6-to-dhcp-when-there-is-no-IPv6-ad.patch | 185 ++++++++++++++++++ cloud-init.spec | 14 +- 3 files changed, 338 insertions(+), 1 deletion(-) create mode 100644 ci-Support-metalink-in-yum-repository-config-5444.patch create mode 100644 ci-fix-vmware-Set-IPv6-to-dhcp-when-there-is-no-IPv6-ad.patch diff --git a/ci-Support-metalink-in-yum-repository-config-5444.patch b/ci-Support-metalink-in-yum-repository-config-5444.patch new file mode 100644 index 0000000..c6a30a7 --- /dev/null +++ b/ci-Support-metalink-in-yum-repository-config-5444.patch @@ -0,0 +1,140 @@ +From 96b10adc942f5117e35584d28ba88071849e8e29 Mon Sep 17 00:00:00 2001 +From: Ani Sinha +Date: Thu, 27 Jun 2024 18:38:22 +0530 +Subject: [PATCH 1/2] Support metalink in yum repository config (#5444) + +RH-Author: xiachen +RH-MergeRequest: 97: Support metalink in yum repository config (#5444) +RH-Jira: RHEL-44916 +RH-Acked-by: Ani Sinha +RH-Acked-by: Emanuele Giuseppe Esposito +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 +Co-authored-by: Ben Gray +(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 + diff --git a/ci-fix-vmware-Set-IPv6-to-dhcp-when-there-is-no-IPv6-ad.patch b/ci-fix-vmware-Set-IPv6-to-dhcp-when-there-is-no-IPv6-ad.patch new file mode 100644 index 0000000..615e767 --- /dev/null +++ b/ci-fix-vmware-Set-IPv6-to-dhcp-when-there-is-no-IPv6-ad.patch @@ -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 +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 +RH-Acked-by: Emanuele Giuseppe Esposito +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 + diff --git a/cloud-init.spec b/cloud-init.spec index 6977116..6f9b793 100644 --- a/cloud-init.spec +++ b/cloud-init.spec @@ -1,6 +1,6 @@ Name: cloud-init Version: 23.4 -Release: 14%{?dist} +Release: 15%{?dist} Summary: Cloud instance init scripts License: ASL 2.0 or GPLv3 URL: http://launchpad.net/cloud-init @@ -53,6 +53,10 @@ Patch25: ci-Deprecate-the-users-ssh-authorized-keys-property-516.patch 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 BuildArch: noarch @@ -267,6 +271,14 @@ fi %config(noreplace) %{_sysconfdir}/rsyslog.d/21-cloudinit.conf %changelog +* Mon Jul 08 2024 Miroslav Rezanina - 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 - 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]