diff --git a/.cloud-init.metadata b/.cloud-init.metadata
index 061dfea..71b0e4f 100644
--- a/.cloud-init.metadata
+++ b/.cloud-init.metadata
@@ -1 +1 @@
-e73116733f5636eb4bc1a5e47e802c3635b9bfa2 SOURCES/23.4.tar.gz
+e4cae51a93e075070ffbdf720abe0e8886ac910a SOURCES/24.4.tar.gz
diff --git a/.gitignore b/.gitignore
index 7fc7ce6..e903212 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1 @@
-SOURCES/23.4.tar.gz
+SOURCES/24.4.tar.gz
diff --git a/SOURCES/0001-Add-initial-redhat-changes.patch b/SOURCES/0001-downstream-Add-initial-redhat-changes.patch
similarity index 60%
rename from SOURCES/0001-Add-initial-redhat-changes.patch
rename to SOURCES/0001-downstream-Add-initial-redhat-changes.patch
index 5024340..f514a52 100644
--- a/SOURCES/0001-Add-initial-redhat-changes.patch
+++ b/SOURCES/0001-downstream-Add-initial-redhat-changes.patch
@@ -1,11 +1,25 @@
-From 03345a88b8b0008a4a81e010d46290f5ba643ebc Mon Sep 17 00:00:00 2001
-From: Ani Sinha <anisinha@redhat.com>
-Date: Wed, 13 Dec 2023 11:54:55 +0530
-Subject: [PATCH] Add initial redhat changes
+From d05f201a13e2fdbd86c89647884ca08ae7d98b3a Mon Sep 17 00:00:00 2001
+From: Camilla Conte <cconte@redhat.com>
+Date: Fri, 3 Mar 2023 15:44:48 +0000
+Subject: [PATCH] downstream: Add initial redhat changes
 
 Adding minimal set of changes necessary for successful build of the package
 on RHEL/CentOS 9 Stream koji.
 
+Additional Changes on top of changes in 24.4 rebase:
+- Merged all trivial downstream configuration commits
+- Merged downstream patches
+  - c1a69d5e5 Remove dependency on python3-httpretty
+  - 69688c9cc Add warning during upgrade from an old version with null ssh_genkeytypes config
+  - bce114c96 Inform user when cloud-init generated config files are left during uninstalling
+  - 76de87b4e Rename render-cloudcfg -> render-template in spec file
+
+Additional changes on top of changes in 23.4 rebase:
+ - Updated VERSION, TARSHA512, MARKER and BUILD_TARGET_RHEL parameters in
+   Makefile.common in .dist/
+ - In spec file, change the location of "disable-sshd-keygen-if-cloud-init-active.conf"
+   from /etc/systemd/system to /usr/lib/systemd/system
+
 Additional changes on top of the changes in 23.1.1 rebase:
  - Updated VERSION, TARSHA512, MARKER and BUILD_TARGET_RHEL parameters in
    Makefile.common in .dist/
@@ -43,16 +57,16 @@ missing rhel/ static files and "" instead of '' in setup.py
 X-downstram-only: true
 Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
 Signed-off-by: Ani Sinha <anisinha@redhat.com>
+(cherry picked from commit 03345a88b8b0008a4a81e010d46290f5ba643ebc)
 ---
- cloudinit/settings.py            |  5 +++--
- tests/unittests/cmd/test_main.py | 15 +++++++++------
- 2 files changed, 12 insertions(+), 8 deletions(-)
+ cloudinit/settings.py | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
 
 diff --git a/cloudinit/settings.py b/cloudinit/settings.py
-index 592e144d..5ced21bd 100644
+index a73f25118..ea7ac283f 100644
 --- a/cloudinit/settings.py
 +++ b/cloudinit/settings.py
-@@ -54,13 +54,14 @@ CFG_BUILTIN = {
+@@ -56,14 +56,15 @@ CFG_BUILTIN = {
      ],
      "def_log_file": "/var/log/cloud-init.log",
      "log_cfgs": [],
@@ -62,6 +76,7 @@ index 592e144d..5ced21bd 100644
      "system_info": {
          "paths": {
              "cloud_dir": "/var/lib/cloud",
+             "docs_dir": "/usr/share/doc/cloud-init/",
              "templates_dir": "/etc/cloud/templates/",
          },
 -        "distro": "ubuntu",
@@ -69,31 +84,3 @@ index 592e144d..5ced21bd 100644
          "network": {"renderers": None},
      },
      "vendor_data": {"enabled": True, "prefix": []},
-diff --git a/tests/unittests/cmd/test_main.py b/tests/unittests/cmd/test_main.py
-index ab427115..19d26ebe 100644
---- a/tests/unittests/cmd/test_main.py
-+++ b/tests/unittests/cmd/test_main.py
-@@ -119,14 +119,17 @@ class TestMain(FilesystemMockingTestCase):
-                 {
-                     "def_log_file": "/var/log/cloud-init.log",
-                     "log_cfgs": [],
--                    "syslog_fix_perms": [
--                        "syslog:adm",
--                        "root:adm",
--                        "root:wheel",
--                        "root:root",
--                    ],
-                     "vendor_data": {"enabled": True, "prefix": []},
-                     "vendor_data2": {"enabled": True, "prefix": []},
-+                    "syslog_fix_perms": [],
-+                    "mount_default_fields": [
-+                        None,
-+                        None,
-+                        "auto",
-+                        "defaults,nofail",
-+                        "0",
-+                        "2",
-+                    ],
-                 }
-             )
-             updated_cfg.pop("system_info")
diff --git a/SOURCES/0002-Do-not-write-NM_CONTROLLED-no-in-generated-interface.patch b/SOURCES/0002-Do-not-write-NM_CONTROLLED-no-in-generated-interface.patch
deleted file mode 100644
index 7a224d1..0000000
--- a/SOURCES/0002-Do-not-write-NM_CONTROLLED-no-in-generated-interface.patch
+++ /dev/null
@@ -1,564 +0,0 @@
-From 5129908caa1867c7f584ec8d38607cf56b20521a Mon Sep 17 00:00:00 2001
-From: Eduardo Otubo <otubo@redhat.com>
-Date: Fri, 7 May 2021 13:36:06 +0200
-Subject: [PATCH] Do not write NM_CONTROLLED=no in generated interface config
- files
-
-Conflicts 20.3:
- - Not appplying patch on cloudinit/net/sysconfig.py since it now has a
-mechanism to identify if cloud-init is running on RHEL, having the
-correct settings for NM_CONTROLLED.
-
-Merged patches (21.1):
-- ecbace48 sysconfig: Don't write BOOTPROTO=dhcp for ipv6 dhcp
-- a1a00383 include 'NOZEROCONF=yes' in /etc/sysconfig/network
-X-downstream-only: true
-Signed-off-by: Eduardo Otubo <otubo@redhat.com>
-Signed-off-by: Ryan McCabe <rmccabe@redhat.com>
-
-Signed-off-by: Ani Sinha <anisinha@redhat.com>
----
- cloudinit/net/sysconfig.py                    | 12 ++++-
- tests/unittests/cmd/devel/test_net_convert.py |  1 -
- tests/unittests/distros/test_netconfig.py     |  8 ---
- tests/unittests/test_net.py                   | 53 -------------------
- 4 files changed, 10 insertions(+), 64 deletions(-)
-
-diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
-index 7570a5e3..f01c4236 100644
---- a/cloudinit/net/sysconfig.py
-+++ b/cloudinit/net/sysconfig.py
-@@ -317,7 +317,6 @@ class Renderer(renderer.Renderer):
-         "rhel": {
-             "ONBOOT": True,
-             "USERCTL": False,
--            "NM_CONTROLLED": False,
-             "BOOTPROTO": "none",
-         },
-         "suse": {"BOOTPROTO": "static", "STARTMODE": "auto"},
-@@ -1030,7 +1029,16 @@ class Renderer(renderer.Renderer):
-         # Distros configuring /etc/sysconfig/network as a file e.g. Centos
-         if sysconfig_path.endswith("network"):
-             util.ensure_dir(os.path.dirname(sysconfig_path))
--            netcfg = [_make_header(), "NETWORKING=yes"]
-+            netcfg = []
-+            for line in util.load_file(sysconfig_path, quiet=True).split("\n"):
-+                if "cloud-init" in line:
-+                    break
-+                if not line.startswith(
-+                    ("NETWORKING=", "IPV6_AUTOCONF=", "NETWORKING_IPV6=")
-+                ):
-+                    netcfg.append(line)
-+            # Now generate the cloud-init portion of sysconfig/network
-+            netcfg.extend([_make_header(), "NETWORKING=yes"])
-             if network_state.use_ipv6:
-                 netcfg.append("NETWORKING_IPV6=yes")
-                 netcfg.append("IPV6_AUTOCONF=no")
-diff --git a/tests/unittests/cmd/devel/test_net_convert.py b/tests/unittests/cmd/devel/test_net_convert.py
-index fb72963f..7b9121b2 100644
---- a/tests/unittests/cmd/devel/test_net_convert.py
-+++ b/tests/unittests/cmd/devel/test_net_convert.py
-@@ -62,7 +62,6 @@ SAMPLE_SYSCONFIG_CONTENT = """\
- #
- BOOTPROTO=dhcp
- DEVICE=eth0
--NM_CONTROLLED=no
- ONBOOT=yes
- TYPE=Ethernet
- USERCTL=no
-diff --git a/tests/unittests/distros/test_netconfig.py b/tests/unittests/distros/test_netconfig.py
-index 7ba430f2..962ff7fb 100644
---- a/tests/unittests/distros/test_netconfig.py
-+++ b/tests/unittests/distros/test_netconfig.py
-@@ -723,7 +723,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
-                 GATEWAY=192.168.1.254
-                 IPADDR=192.168.1.5
-                 NETMASK=255.255.255.0
--                NM_CONTROLLED=no
-                 ONBOOT=yes
-                 TYPE=Ethernet
-                 USERCTL=no
-@@ -733,7 +732,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
-                 """\
-                 BOOTPROTO=dhcp
-                 DEVICE=eth1
--                NM_CONTROLLED=no
-                 ONBOOT=yes
-                 TYPE=Ethernet
-                 USERCTL=no
-@@ -764,7 +762,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
-                 IPV6_AUTOCONF=no
-                 IPV6_DEFAULTGW=2607:f0d0:1002:0011::1
-                 IPV6_FORCE_ACCEPT_RA=no
--                NM_CONTROLLED=no
-                 ONBOOT=yes
-                 TYPE=Ethernet
-                 USERCTL=no
-@@ -774,7 +771,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
-                 """\
-                 BOOTPROTO=dhcp
-                 DEVICE=eth1
--                NM_CONTROLLED=no
-                 ONBOOT=yes
-                 TYPE=Ethernet
-                 USERCTL=no
-@@ -821,7 +817,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
-                 HWADDR=00:16:3e:60:7c:df
-                 IPADDR=192.10.1.2
-                 NETMASK=255.255.255.0
--                NM_CONTROLLED=no
-                 ONBOOT=yes
-                 TYPE=Ethernet
-                 USERCTL=no
-@@ -833,7 +828,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
-                 DEVICE=infra0
-                 IPADDR=10.0.1.2
-                 NETMASK=255.255.0.0
--                NM_CONTROLLED=no
-                 ONBOOT=yes
-                 PHYSDEV=eth0
-                 USERCTL=no
-@@ -869,7 +863,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
-                 DEVICE=eth0
-                 IPADDR=192.10.1.2
-                 NETMASK=255.255.255.0
--                NM_CONTROLLED=no
-                 ONBOOT=yes
-                 TYPE=Ethernet
-                 USERCTL=no
-@@ -881,7 +874,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
-                 DEVICE=eth0.1001
-                 IPADDR=10.0.1.2
-                 NETMASK=255.255.0.0
--                NM_CONTROLLED=no
-                 ONBOOT=yes
-                 PHYSDEV=eth0
-                 USERCTL=no
-diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
-index c5509536..052b0674 100644
---- a/tests/unittests/test_net.py
-+++ b/tests/unittests/test_net.py
-@@ -585,7 +585,6 @@ GATEWAY=172.19.3.254
- HWADDR=fa:16:3e:ed:9a:59
- IPADDR=172.19.1.34
- NETMASK=255.255.252.0
--NM_CONTROLLED=no
- ONBOOT=yes
- TYPE=Ethernet
- USERCTL=no
-@@ -750,7 +749,6 @@ IPADDR=172.19.1.34
- IPADDR1=10.0.0.10
- NETMASK=255.255.252.0
- NETMASK1=255.255.255.0
--NM_CONTROLLED=no
- ONBOOT=yes
- TYPE=Ethernet
- USERCTL=no
-@@ -912,7 +910,6 @@ IPV6_AUTOCONF=no
- IPV6_DEFAULTGW=2001:DB8::1
- IPV6_FORCE_ACCEPT_RA=no
- NETMASK=255.255.252.0
--NM_CONTROLLED=no
- ONBOOT=yes
- TYPE=Ethernet
- USERCTL=no
-@@ -1143,7 +1140,6 @@ NETWORK_CONFIGS = {
-                 BOOTPROTO=none
-                 DEVICE=eth1
-                 HWADDR=cf:d6:af:48:e8:80
--                NM_CONTROLLED=no
-                 ONBOOT=yes
-                 TYPE=Ethernet
-                 USERCTL=no"""
-@@ -1162,7 +1158,6 @@ NETWORK_CONFIGS = {
-                 IPADDR=192.168.21.3
-                 NETMASK=255.255.255.0
-                 METRIC=10000
--                NM_CONTROLLED=no
-                 ONBOOT=yes
-                 TYPE=Ethernet
-                 USERCTL=no"""
-@@ -1319,7 +1314,6 @@ NETWORK_CONFIGS = {
-                 BOOTPROTO=none
-                 DEVICE=eth1
-                 HWADDR=cf:d6:af:48:e8:80
--                NM_CONTROLLED=no
-                 ONBOOT=yes
-                 TYPE=Ethernet
-                 USERCTL=no"""
-@@ -1338,7 +1332,6 @@ NETWORK_CONFIGS = {
-                 IPADDR=192.168.21.3
-                 NETMASK=255.255.255.0
-                 METRIC=10000
--                NM_CONTROLLED=no
-                 ONBOOT=yes
-                 TYPE=Ethernet
-                 USERCTL=no"""
-@@ -1581,7 +1574,6 @@ NETWORK_CONFIGS = {
-                 IPV6_AUTOCONF=no
-                 IPV6_FORCE_ACCEPT_RA=no
-                 NETMASK=255.255.255.0
--                NM_CONTROLLED=no
-                 ONBOOT=yes
-                 TYPE=Ethernet
-                 USERCTL=no
-@@ -1725,7 +1717,6 @@ NETWORK_CONFIGS = {
-                 DHCPV6C=yes
-                 IPV6INIT=yes
-                 DEVICE=iface0
--                NM_CONTROLLED=no
-                 ONBOOT=yes
-                 TYPE=Ethernet
-                 USERCTL=no
-@@ -1816,7 +1807,6 @@ NETWORK_CONFIGS = {
-                 IPV6INIT=yes
-                 IPV6_FORCE_ACCEPT_RA=yes
-                 DEVICE=iface0
--                NM_CONTROLLED=no
-                 ONBOOT=yes
-                 TYPE=Ethernet
-                 USERCTL=no
-@@ -1892,7 +1882,6 @@ NETWORK_CONFIGS = {
-                 IPV6INIT=yes
-                 IPV6_FORCE_ACCEPT_RA=no
-                 DEVICE=iface0
--                NM_CONTROLLED=no
-                 ONBOOT=yes
-                 TYPE=Ethernet
-                 USERCTL=no
-@@ -1956,7 +1945,6 @@ NETWORK_CONFIGS = {
-                 IPV6_AUTOCONF=yes
-                 IPV6INIT=yes
-                 DEVICE=iface0
--                NM_CONTROLLED=no
-                 ONBOOT=yes
-                 TYPE=Ethernet
-                 USERCTL=no
-@@ -2014,7 +2002,6 @@ NETWORK_CONFIGS = {
-             IPV6_AUTOCONF=no
-             IPV6_FORCE_ACCEPT_RA=no
-             DEVICE=iface0
--            NM_CONTROLLED=no
-             ONBOOT=yes
-             TYPE=Ethernet
-             USERCTL=no
-@@ -2071,7 +2058,6 @@ NETWORK_CONFIGS = {
-             IPV6_AUTOCONF=yes
-             IPV6INIT=yes
-             DEVICE=iface0
--            NM_CONTROLLED=no
-             ONBOOT=yes
-             TYPE=Ethernet
-             USERCTL=no
-@@ -2157,7 +2143,6 @@ NETWORK_CONFIGS = {
-             IPV6_FAILURE_FATAL=yes
-             IPV6_FORCE_ACCEPT_RA=yes
-             DEVICE=iface0
--            NM_CONTROLLED=no
-             ONBOOT=yes
-             TYPE=Ethernet
-             USERCTL=no
-@@ -2198,7 +2183,6 @@ NETWORK_CONFIGS = {
-                 """\
-                 BOOTPROTO=dhcp
-                 DEVICE=iface0
--                NM_CONTROLLED=no
-                 ONBOOT=yes
-                 TYPE=Ethernet
-                 USERCTL=no
-@@ -2275,7 +2259,6 @@ NETWORK_CONFIGS = {
-                 BOOTPROTO=dhcp
-                 DEVICE=iface0
-                 ETHTOOL_OPTS="wol g"
--                NM_CONTROLLED=no
-                 ONBOOT=yes
-                 TYPE=Ethernet
-                 USERCTL=no
-@@ -2619,7 +2602,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
-                 DHCPV6C=yes
-                 IPV6INIT=yes
-                 MACADDR=aa:bb:cc:dd:ee:ff
--                NM_CONTROLLED=no
-                 ONBOOT=yes
-                 TYPE=Bond
-                 USERCTL=no"""
-@@ -2629,7 +2611,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
-                 BOOTPROTO=dhcp
-                 DEVICE=bond0.200
-                 DHCLIENT_SET_DEFAULT_ROUTE=no
--                NM_CONTROLLED=no
-                 ONBOOT=yes
-                 PHYSDEV=bond0
-                 USERCTL=no
-@@ -2649,7 +2630,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
-                 IPV6_DEFAULTGW=2001:4800:78ff:1b::1
-                 MACADDR=bb:bb:bb:bb:bb:aa
-                 NETMASK=255.255.255.0
--                NM_CONTROLLED=no
-                 ONBOOT=yes
-                 PRIO=22
-                 STP=no
-@@ -2661,7 +2641,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
-                 BOOTPROTO=none
-                 DEVICE=eth0
-                 HWADDR=c0:d6:9f:2c:e8:80
--                NM_CONTROLLED=no
-                 ONBOOT=yes
-                 TYPE=Ethernet
-                 USERCTL=no"""
-@@ -2680,7 +2659,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
-                 MTU=1500
-                 NETMASK=255.255.255.0
-                 NETMASK1=255.255.255.0
--                NM_CONTROLLED=no
-                 ONBOOT=yes
-                 PHYSDEV=eth0
-                 USERCTL=no
-@@ -2692,7 +2670,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
-                 DEVICE=eth1
-                 HWADDR=aa:d6:9f:2c:e8:80
-                 MASTER=bond0
--                NM_CONTROLLED=no
-                 ONBOOT=yes
-                 SLAVE=yes
-                 TYPE=Ethernet
-@@ -2704,7 +2681,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
-                 DEVICE=eth2
-                 HWADDR=c0:bb:9f:2c:e8:80
-                 MASTER=bond0
--                NM_CONTROLLED=no
-                 ONBOOT=yes
-                 SLAVE=yes
-                 TYPE=Ethernet
-@@ -2716,7 +2692,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
-                 BRIDGE=br0
-                 DEVICE=eth3
-                 HWADDR=66:bb:9f:2c:e8:80
--                NM_CONTROLLED=no
-                 ONBOOT=yes
-                 TYPE=Ethernet
-                 USERCTL=no"""
-@@ -2727,7 +2702,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
-                 BRIDGE=br0
-                 DEVICE=eth4
-                 HWADDR=98:bb:9f:2c:e8:80
--                NM_CONTROLLED=no
-                 ONBOOT=yes
-                 TYPE=Ethernet
-                 USERCTL=no"""
-@@ -2738,7 +2712,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
-                 DEVICE=eth5
-                 DHCLIENT_SET_DEFAULT_ROUTE=no
-                 HWADDR=98:bb:9f:2c:e8:8a
--                NM_CONTROLLED=no
-                 ONBOOT=no
-                 TYPE=Ethernet
-                 USERCTL=no"""
-@@ -2751,7 +2724,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
-                 IPADDR=192.168.200.7
-                 MTU=9000
-                 NETMASK=255.255.255.0
--                NM_CONTROLLED=no
-                 ONBOOT=yes
-                 TYPE=InfiniBand
-                 USERCTL=no"""
-@@ -3473,7 +3445,6 @@ iface bond0 inet6 static
-         MTU=9000
-         NETMASK=255.255.255.0
-         NETMASK1=255.255.255.0
--        NM_CONTROLLED=no
-         ONBOOT=yes
-         TYPE=Bond
-         USERCTL=no
-@@ -3485,7 +3456,6 @@ iface bond0 inet6 static
-         DEVICE=bond0s0
-         HWADDR=aa:bb:cc:dd:e8:00
-         MASTER=bond0
--        NM_CONTROLLED=no
-         ONBOOT=yes
-         SLAVE=yes
-         TYPE=Ethernet
-@@ -3513,7 +3483,6 @@ iface bond0 inet6 static
-         DEVICE=bond0s1
-         HWADDR=aa:bb:cc:dd:e8:01
-         MASTER=bond0
--        NM_CONTROLLED=no
-         ONBOOT=yes
-         SLAVE=yes
-         TYPE=Ethernet
-@@ -3662,7 +3631,6 @@ iface bond0 inet6 static
-                 BOOTPROTO=none
-                 DEVICE=en0
-                 HWADDR=aa:bb:cc:dd:e8:00
--                NM_CONTROLLED=no
-                 ONBOOT=yes
-                 TYPE=Ethernet
-                 USERCTL=no"""
-@@ -3683,7 +3651,6 @@ iface bond0 inet6 static
-                 MTU=2222
-                 NETMASK=255.255.255.0
-                 NETMASK1=255.255.255.0
--                NM_CONTROLLED=no
-                 ONBOOT=yes
-                 PHYSDEV=en0
-                 USERCTL=no
-@@ -3811,7 +3778,6 @@ iface bond0 inet6 static
-                 DEVICE=br0
-                 IPADDR=192.168.2.2
-                 NETMASK=255.255.255.0
--                NM_CONTROLLED=no
-                 ONBOOT=yes
-                 PRIO=22
-                 STP=no
-@@ -3829,7 +3795,6 @@ iface bond0 inet6 static
-                 IPV6INIT=yes
-                 IPV6_AUTOCONF=no
-                 IPV6_FORCE_ACCEPT_RA=no
--                NM_CONTROLLED=no
-                 ONBOOT=yes
-                 TYPE=Ethernet
-                 USERCTL=no
-@@ -3845,7 +3810,6 @@ iface bond0 inet6 static
-                 IPV6INIT=yes
-                 IPV6_AUTOCONF=no
-                 IPV6_FORCE_ACCEPT_RA=no
--                NM_CONTROLLED=no
-                 ONBOOT=yes
-                 TYPE=Ethernet
-                 USERCTL=no
-@@ -4030,7 +3994,6 @@ iface bond0 inet6 static
-                 HWADDR=52:54:00:12:34:00
-                 IPADDR=192.168.1.2
-                 NETMASK=255.255.255.0
--                NM_CONTROLLED=no
-                 ONBOOT=no
-                 TYPE=Ethernet
-                 USERCTL=no
-@@ -4042,7 +4005,6 @@ iface bond0 inet6 static
-                 DEVICE=eth1
-                 HWADDR=52:54:00:12:34:aa
-                 MTU=1480
--                NM_CONTROLLED=no
-                 ONBOOT=yes
-                 TYPE=Ethernet
-                 USERCTL=no
-@@ -4053,7 +4015,6 @@ iface bond0 inet6 static
-                 BOOTPROTO=none
-                 DEVICE=eth2
-                 HWADDR=52:54:00:12:34:ff
--                NM_CONTROLLED=no
-                 ONBOOT=no
-                 TYPE=Ethernet
-                 USERCTL=no
-@@ -4138,7 +4099,6 @@ iface bond0 inet6 static
-                 BOOTPROTO=none
-                 DEVICE=eth0
-                 HWADDR=cf:d6:af:48:e8:80
--                NM_CONTROLLED=no
-                 ONBOOT=yes
-                 TYPE=Ethernet
-                 USERCTL=no"""
-@@ -4736,7 +4696,6 @@ class TestRhelSysConfigRendering(CiTestCase):
- BOOTPROTO=dhcp
- DEVICE=eth1000
- HWADDR=07-1c-c6-75-a4-be
--NM_CONTROLLED=no
- ONBOOT=yes
- TYPE=Ethernet
- USERCTL=no
-@@ -4948,7 +4907,6 @@ GATEWAY=10.0.2.2
- HWADDR=52:54:00:12:34:00
- IPADDR=10.0.2.15
- NETMASK=255.255.255.0
--NM_CONTROLLED=no
- ONBOOT=yes
- TYPE=Ethernet
- USERCTL=no
-@@ -4979,7 +4937,6 @@ HWADDR=fa:16:3e:25:b4:59
- IPADDR=51.68.89.122
- MTU=1500
- NETMASK=255.255.240.0
--NM_CONTROLLED=no
- ONBOOT=yes
- TYPE=Ethernet
- USERCTL=no
-@@ -4993,7 +4950,6 @@ DEVICE=eth1
- DHCLIENT_SET_DEFAULT_ROUTE=no
- HWADDR=fa:16:3e:b1:ca:29
- MTU=9000
--NM_CONTROLLED=no
- ONBOOT=yes
- TYPE=Ethernet
- USERCTL=no
-@@ -5018,7 +4974,6 @@ USERCTL=no
- #
- BOOTPROTO=dhcp
- DEVICE=eth0
--NM_CONTROLLED=no
- ONBOOT=yes
- TYPE=Ethernet
- USERCTL=no
-@@ -5251,7 +5206,6 @@ USERCTL=no
-                    IPV6_FORCE_ACCEPT_RA=no
-                    IPV6_DEFAULTGW=2001:db8::1
-                    NETMASK=255.255.255.0
--                   NM_CONTROLLED=no
-                    ONBOOT=yes
-                    TYPE=Ethernet
-                    USERCTL=no
-@@ -5283,7 +5237,6 @@ USERCTL=no
-                 """\
-                 BOOTPROTO=none
-                 DEVICE=eno1
--                NM_CONTROLLED=no
-                 ONBOOT=yes
-                 TYPE=Ethernet
-                 USERCTL=no
-@@ -5296,7 +5249,6 @@ USERCTL=no
-                 IPADDR=192.6.1.9
-                 MTU=1495
-                 NETMASK=255.255.255.0
--                NM_CONTROLLED=no
-                 ONBOOT=yes
-                 PHYSDEV=eno1
-                 USERCTL=no
-@@ -5332,7 +5284,6 @@ USERCTL=no
-                 IPADDR=10.101.8.65
-                 MTU=1334
-                 NETMASK=255.255.255.192
--                NM_CONTROLLED=no
-                 ONBOOT=yes
-                 TYPE=Bond
-                 USERCTL=no
-@@ -5344,7 +5295,6 @@ USERCTL=no
-                 BOOTPROTO=none
-                 DEVICE=enp0s0
-                 MASTER=bond0
--                NM_CONTROLLED=no
-                 ONBOOT=yes
-                 SLAVE=yes
-                 TYPE=Bond
-@@ -5357,7 +5307,6 @@ USERCTL=no
-                 BOOTPROTO=none
-                 DEVICE=enp0s1
-                 MASTER=bond0
--                NM_CONTROLLED=no
-                 ONBOOT=yes
-                 SLAVE=yes
-                 TYPE=Bond
-@@ -5388,7 +5337,6 @@ USERCTL=no
-                 DEVICE=eno1
-                 HWADDR=07-1c-c6-75-a4-be
-                 METRIC=100
--                NM_CONTROLLED=no
-                 ONBOOT=yes
-                 TYPE=Ethernet
-                 USERCTL=no
-@@ -5479,7 +5427,6 @@ USERCTL=no
-                 IPV6_FORCE_ACCEPT_RA=no
-                 MTU=1400
-                 NETMASK=255.255.248.0
--                NM_CONTROLLED=no
-                 ONBOOT=yes
-                 TYPE=Ethernet
-                 USERCTL=no
diff --git a/SOURCES/0003-Setting-autoconnect-priority-setting-for-network-scr.patch b/SOURCES/0002-downstream-Setting-autoconnect-priority-setting-for-.patch
similarity index 62%
rename from SOURCES/0003-Setting-autoconnect-priority-setting-for-network-scr.patch
rename to SOURCES/0002-downstream-Setting-autoconnect-priority-setting-for-.patch
index 3a1513b..fd7cfd1 100644
--- a/SOURCES/0003-Setting-autoconnect-priority-setting-for-network-scr.patch
+++ b/SOURCES/0002-downstream-Setting-autoconnect-priority-setting-for-.patch
@@ -1,7 +1,8 @@
-From 8a2fcbbcfdfc1df6f6c18f96588154f40083a239 Mon Sep 17 00:00:00 2001
+From 991690944e86cfe4f9b11862455f5a451f7080d3 Mon Sep 17 00:00:00 2001
 From: Ani Sinha <anisinha@redhat.com>
 Date: Wed, 13 Dec 2023 11:55:16 +0530
-Subject: [PATCH] Setting autoconnect priority setting for network-scripts
+Subject: [PATCH] downstream: Setting autoconnect priority setting for
+ network-scripts
 
 Squashed the following three downstream only commits from RHEL 9.3:
 
@@ -53,15 +54,17 @@ fixes: 0a2c6b6118ff ("net/sysconfig: do not use the highest autoconnect priority
 fixes: c589da20eb92 ("Setting highest autoconnect priority for network-scripts")
 
 Signed-off-by: Ani Sinha <anisinha@redhat.com>
+(cherry picked from commit 8a2fcbbcfdfc1df6f6c18f96588154f40083a239)
 ---
  cloudinit/net/sysconfig.py                    |  1 +
  tests/unittests/cmd/devel/test_net_convert.py |  1 +
  tests/unittests/distros/test_netconfig.py     |  8 +++
- tests/unittests/test_net.py                   | 53 +++++++++++++++++++
- 4 files changed, 63 insertions(+)
+ tests/unittests/net/network_configs.py        | 57 +++++++++++++++++++
+ tests/unittests/test_net.py                   | 18 ++++++
+ 5 files changed, 85 insertions(+)
 
 diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
-index f01c4236..d39f4fe3 100644
+index d75012d26..2151db3ab 100644
 --- a/cloudinit/net/sysconfig.py
 +++ b/cloudinit/net/sysconfig.py
 @@ -318,6 +318,7 @@ class Renderer(renderer.Renderer):
@@ -73,7 +76,7 @@ index f01c4236..d39f4fe3 100644
          "suse": {"BOOTPROTO": "static", "STARTMODE": "auto"},
      }
 diff --git a/tests/unittests/cmd/devel/test_net_convert.py b/tests/unittests/cmd/devel/test_net_convert.py
-index 7b9121b2..288e3e37 100644
+index 39e049227..ed970e413 100644
 --- a/tests/unittests/cmd/devel/test_net_convert.py
 +++ b/tests/unittests/cmd/devel/test_net_convert.py
 @@ -60,6 +60,7 @@ DHCP=ipv4
@@ -85,10 +88,10 @@ index 7b9121b2..288e3e37 100644
  DEVICE=eth0
  ONBOOT=yes
 diff --git a/tests/unittests/distros/test_netconfig.py b/tests/unittests/distros/test_netconfig.py
-index 962ff7fb..4c624079 100644
+index b447757be..3768623f2 100644
 --- a/tests/unittests/distros/test_netconfig.py
 +++ b/tests/unittests/distros/test_netconfig.py
-@@ -717,6 +717,7 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
+@@ -711,6 +711,7 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
          expected_cfgs = {
              self.ifcfg_path("eth0"): dedent(
                  """\
@@ -96,7 +99,7 @@ index 962ff7fb..4c624079 100644
                  BOOTPROTO=none
                  DEFROUTE=yes
                  DEVICE=eth0
-@@ -730,6 +731,7 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
+@@ -724,6 +725,7 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
              ),
              self.ifcfg_path("eth1"): dedent(
                  """\
@@ -104,7 +107,7 @@ index 962ff7fb..4c624079 100644
                  BOOTPROTO=dhcp
                  DEVICE=eth1
                  ONBOOT=yes
-@@ -754,6 +756,7 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
+@@ -748,6 +750,7 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
          expected_cfgs = {
              self.ifcfg_path("eth0"): dedent(
                  """\
@@ -112,7 +115,7 @@ index 962ff7fb..4c624079 100644
                  BOOTPROTO=none
                  DEFROUTE=yes
                  DEVICE=eth0
-@@ -769,6 +772,7 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
+@@ -763,6 +766,7 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
              ),
              self.ifcfg_path("eth1"): dedent(
                  """\
@@ -120,7 +123,7 @@ index 962ff7fb..4c624079 100644
                  BOOTPROTO=dhcp
                  DEVICE=eth1
                  ONBOOT=yes
-@@ -812,6 +816,7 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
+@@ -806,6 +810,7 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
          expected_cfgs = {
              self.ifcfg_path("eth0"): dedent(
                  """\
@@ -128,7 +131,7 @@ index 962ff7fb..4c624079 100644
                  BOOTPROTO=none
                  DEVICE=eth0
                  HWADDR=00:16:3e:60:7c:df
-@@ -824,6 +829,7 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
+@@ -818,6 +823,7 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
              ),
              self.ifcfg_path("infra0"): dedent(
                  """\
@@ -136,7 +139,7 @@ index 962ff7fb..4c624079 100644
                  BOOTPROTO=none
                  DEVICE=infra0
                  IPADDR=10.0.1.2
-@@ -859,6 +865,7 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
+@@ -853,6 +859,7 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
          expected_cfgs = {
              self.ifcfg_path("eth0"): dedent(
                  """\
@@ -144,7 +147,7 @@ index 962ff7fb..4c624079 100644
                  BOOTPROTO=none
                  DEVICE=eth0
                  IPADDR=192.10.1.2
-@@ -870,6 +877,7 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
+@@ -864,6 +871,7 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
              ),
              self.ifcfg_path("eth0.1001"): dedent(
                  """\
@@ -152,35 +155,11 @@ index 962ff7fb..4c624079 100644
                  BOOTPROTO=none
                  DEVICE=eth0.1001
                  IPADDR=10.0.1.2
-diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
-index 052b0674..cef4fa2d 100644
---- a/tests/unittests/test_net.py
-+++ b/tests/unittests/test_net.py
-@@ -578,6 +578,7 @@ dns = none
-                 """
- # Created by cloud-init automatically, do not edit.
- #
-+AUTOCONNECT_PRIORITY=120
- BOOTPROTO=none
- DEFROUTE=yes
- DEVICE=eth0
-@@ -740,6 +741,7 @@ dns = none
-                 """
- # Created by cloud-init automatically, do not edit.
- #
-+AUTOCONNECT_PRIORITY=120
- BOOTPROTO=none
- DEFROUTE=yes
- DEVICE=eth0
-@@ -897,6 +899,7 @@ dns = none
-                 """
- # Created by cloud-init automatically, do not edit.
- #
-+AUTOCONNECT_PRIORITY=120
- BOOTPROTO=none
- DEFROUTE=yes
- DEVICE=eth0
-@@ -1137,6 +1140,7 @@ NETWORK_CONFIGS = {
+diff --git a/tests/unittests/net/network_configs.py b/tests/unittests/net/network_configs.py
+index 6e870f6ed..dd0bf73d2 100644
+--- a/tests/unittests/net/network_configs.py
++++ b/tests/unittests/net/network_configs.py
+@@ -184,6 +184,7 @@ NETWORK_CONFIGS = {
          "expected_sysconfig_rhel": {
              "ifcfg-eth1": textwrap.dedent(
                  """\
@@ -188,7 +167,7 @@ index 052b0674..cef4fa2d 100644
                  BOOTPROTO=none
                  DEVICE=eth1
                  HWADDR=cf:d6:af:48:e8:80
-@@ -1146,6 +1150,7 @@ NETWORK_CONFIGS = {
+@@ -193,6 +194,7 @@ NETWORK_CONFIGS = {
              ),
              "ifcfg-eth99": textwrap.dedent(
                  """\
@@ -196,7 +175,7 @@ index 052b0674..cef4fa2d 100644
                  BOOTPROTO=dhcp
                  DEFROUTE=yes
                  DEVICE=eth99
-@@ -1311,6 +1316,7 @@ NETWORK_CONFIGS = {
+@@ -357,6 +359,7 @@ NETWORK_CONFIGS = {
          "expected_sysconfig_rhel": {
              "ifcfg-eth1": textwrap.dedent(
                  """\
@@ -204,7 +183,7 @@ index 052b0674..cef4fa2d 100644
                  BOOTPROTO=none
                  DEVICE=eth1
                  HWADDR=cf:d6:af:48:e8:80
-@@ -1320,6 +1326,7 @@ NETWORK_CONFIGS = {
+@@ -366,6 +369,7 @@ NETWORK_CONFIGS = {
              ),
              "ifcfg-eth99": textwrap.dedent(
                  """\
@@ -212,7 +191,7 @@ index 052b0674..cef4fa2d 100644
                  BOOTPROTO=dhcp
                  DEFROUTE=yes
                  DEVICE=eth99
-@@ -1566,6 +1573,7 @@ NETWORK_CONFIGS = {
+@@ -622,6 +626,7 @@ NETWORK_CONFIGS = {
          "expected_sysconfig_rhel": {
              "ifcfg-iface0": textwrap.dedent(
                  """\
@@ -220,7 +199,15 @@ index 052b0674..cef4fa2d 100644
                  BOOTPROTO=none
                  DEVICE=iface0
                  IPADDR=192.168.14.2
-@@ -1712,6 +1720,7 @@ NETWORK_CONFIGS = {
+@@ -738,6 +743,7 @@ NETWORK_CONFIGS = {
+         "expected_sysconfig_rhel": {
+             "ifcfg-iface0": textwrap.dedent(
+                 """\
++                AUTOCONNECT_PRIORITY=120
+                 BOOTPROTO=none
+                 DEVICE=iface0
+                 IPADDR=192.168.14.2
+@@ -893,6 +899,7 @@ NETWORK_CONFIGS = {
          "expected_sysconfig_rhel": {
              "ifcfg-iface0": textwrap.dedent(
                  """\
@@ -228,7 +215,7 @@ index 052b0674..cef4fa2d 100644
                  BOOTPROTO=none
                  DEVICE=iface0
                  DHCPV6C=yes
-@@ -1801,6 +1810,7 @@ NETWORK_CONFIGS = {
+@@ -982,6 +989,7 @@ NETWORK_CONFIGS = {
          "expected_sysconfig_rhel": {
              "ifcfg-iface0": textwrap.dedent(
                  """\
@@ -236,7 +223,7 @@ index 052b0674..cef4fa2d 100644
                  BOOTPROTO=none
                  DEVICE=iface0
                  DHCPV6C=yes
-@@ -1876,6 +1886,7 @@ NETWORK_CONFIGS = {
+@@ -1057,6 +1065,7 @@ NETWORK_CONFIGS = {
          "expected_sysconfig_rhel": {
              "ifcfg-iface0": textwrap.dedent(
                  """\
@@ -244,7 +231,7 @@ index 052b0674..cef4fa2d 100644
                  BOOTPROTO=none
                  DEVICE=iface0
                  DHCPV6C=yes
-@@ -1940,6 +1951,7 @@ NETWORK_CONFIGS = {
+@@ -1123,6 +1132,7 @@ NETWORK_CONFIGS = {
          "expected_sysconfig_rhel": {
              "ifcfg-iface0": textwrap.dedent(
                  """\
@@ -252,7 +239,7 @@ index 052b0674..cef4fa2d 100644
                  BOOTPROTO=none
                  DEVICE=iface0
                  IPV6_AUTOCONF=yes
-@@ -1995,6 +2007,7 @@ NETWORK_CONFIGS = {
+@@ -1188,6 +1198,7 @@ NETWORK_CONFIGS = {
          "expected_sysconfig_rhel": {
              "ifcfg-iface0": textwrap.dedent(
                  """\
@@ -260,7 +247,7 @@ index 052b0674..cef4fa2d 100644
              BOOTPROTO=none
              DEVICE=iface0
              IPV6ADDR=2001:1::1/64
-@@ -2051,6 +2064,7 @@ NETWORK_CONFIGS = {
+@@ -1246,6 +1257,7 @@ NETWORK_CONFIGS = {
          "expected_sysconfig_rhel": {
              "ifcfg-iface0": textwrap.dedent(
                  """\
@@ -268,7 +255,7 @@ index 052b0674..cef4fa2d 100644
              BOOTPROTO=none
              DEVICE=iface0
              DHCPV6C=yes
-@@ -2135,6 +2149,7 @@ NETWORK_CONFIGS = {
+@@ -1332,6 +1344,7 @@ NETWORK_CONFIGS = {
          "expected_sysconfig_rhel": {
              "ifcfg-iface0": textwrap.dedent(
                  """\
@@ -276,7 +263,7 @@ index 052b0674..cef4fa2d 100644
              BOOTPROTO=none
              DEVICE=iface0
              DHCPV6C=yes
-@@ -2181,6 +2196,7 @@ NETWORK_CONFIGS = {
+@@ -1378,6 +1391,7 @@ NETWORK_CONFIGS = {
          "expected_sysconfig_rhel": {
              "ifcfg-iface0": textwrap.dedent(
                  """\
@@ -284,7 +271,7 @@ index 052b0674..cef4fa2d 100644
                  BOOTPROTO=dhcp
                  DEVICE=iface0
                  ONBOOT=yes
-@@ -2256,6 +2272,7 @@ NETWORK_CONFIGS = {
+@@ -1453,6 +1467,7 @@ NETWORK_CONFIGS = {
          "expected_sysconfig_rhel": {
              "ifcfg-iface0": textwrap.dedent(
                  """\
@@ -292,7 +279,7 @@ index 052b0674..cef4fa2d 100644
                  BOOTPROTO=dhcp
                  DEVICE=iface0
                  ETHTOOL_OPTS="wol g"
-@@ -2591,6 +2608,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
+@@ -1788,6 +1803,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
          "expected_sysconfig_rhel": {
              "ifcfg-bond0": textwrap.dedent(
                  """\
@@ -300,7 +287,7 @@ index 052b0674..cef4fa2d 100644
                  BONDING_MASTER=yes
                  BONDING_OPTS="mode=active-backup """
                  """xmit_hash_policy=layer3+4 """
-@@ -2608,6 +2626,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
+@@ -1805,6 +1821,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
              ),
              "ifcfg-bond0.200": textwrap.dedent(
                  """\
@@ -308,7 +295,7 @@ index 052b0674..cef4fa2d 100644
                  BOOTPROTO=dhcp
                  DEVICE=bond0.200
                  DHCLIENT_SET_DEFAULT_ROUTE=no
-@@ -2619,6 +2638,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
+@@ -1816,6 +1833,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
              "ifcfg-br0": textwrap.dedent(
                  """\
                  AGEING=250
@@ -316,7 +303,7 @@ index 052b0674..cef4fa2d 100644
                  BOOTPROTO=none
                  DEFROUTE=yes
                  DEVICE=br0
-@@ -2638,6 +2658,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
+@@ -1835,6 +1853,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
              ),
              "ifcfg-eth0": textwrap.dedent(
                  """\
@@ -324,7 +311,7 @@ index 052b0674..cef4fa2d 100644
                  BOOTPROTO=none
                  DEVICE=eth0
                  HWADDR=c0:d6:9f:2c:e8:80
-@@ -2647,6 +2668,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
+@@ -1844,6 +1863,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
              ),
              "ifcfg-eth0.101": textwrap.dedent(
                  """\
@@ -332,7 +319,7 @@ index 052b0674..cef4fa2d 100644
                  BOOTPROTO=none
                  DEFROUTE=yes
                  DEVICE=eth0.101
-@@ -2666,6 +2688,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
+@@ -1863,6 +1883,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
              ),
              "ifcfg-eth1": textwrap.dedent(
                  """\
@@ -340,7 +327,7 @@ index 052b0674..cef4fa2d 100644
                  BOOTPROTO=none
                  DEVICE=eth1
                  HWADDR=aa:d6:9f:2c:e8:80
-@@ -2677,6 +2700,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
+@@ -1874,6 +1895,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
              ),
              "ifcfg-eth2": textwrap.dedent(
                  """\
@@ -348,7 +335,7 @@ index 052b0674..cef4fa2d 100644
                  BOOTPROTO=none
                  DEVICE=eth2
                  HWADDR=c0:bb:9f:2c:e8:80
-@@ -2688,6 +2712,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
+@@ -1885,6 +1907,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
              ),
              "ifcfg-eth3": textwrap.dedent(
                  """\
@@ -356,7 +343,7 @@ index 052b0674..cef4fa2d 100644
                  BOOTPROTO=none
                  BRIDGE=br0
                  DEVICE=eth3
-@@ -2698,6 +2723,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
+@@ -1895,6 +1918,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
              ),
              "ifcfg-eth4": textwrap.dedent(
                  """\
@@ -364,7 +351,7 @@ index 052b0674..cef4fa2d 100644
                  BOOTPROTO=none
                  BRIDGE=br0
                  DEVICE=eth4
-@@ -2708,6 +2734,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
+@@ -1905,6 +1929,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
              ),
              "ifcfg-eth5": textwrap.dedent(
                  """\
@@ -372,7 +359,7 @@ index 052b0674..cef4fa2d 100644
                  BOOTPROTO=dhcp
                  DEVICE=eth5
                  DHCLIENT_SET_DEFAULT_ROUTE=no
-@@ -2718,6 +2745,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
+@@ -1915,6 +1940,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
              ),
              "ifcfg-ib0": textwrap.dedent(
                  """\
@@ -380,15 +367,79 @@ index 052b0674..cef4fa2d 100644
                  BOOTPROTO=none
                  DEVICE=ib0
                  HWADDR=a0:00:02:20:fe:80:00:00:00:00:00:00:ec:0d:9a:03:00:15:e2:c1
-@@ -3422,6 +3450,7 @@ iface bond0 inet6 static
+@@ -2575,6 +2601,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
+             ),
+             "ifcfg-eth0": textwrap.dedent(
+                 """\
++                AUTOCONNECT_PRIORITY=120
+                 BOOTPROTO=none
+                 DEVICE=eth0
+                 HWADDR=c0:d6:9f:2c:e8:80
+@@ -2584,6 +2611,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
+             ),
+             "ifcfg-eth0.101": textwrap.dedent(
+                 """\
++                AUTOCONNECT_PRIORITY=120
+                 BOOTPROTO=none
+                 DEFROUTE=yes
+                 DEVICE=eth0.101
+@@ -2603,6 +2631,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
+             ),
+             "ifcfg-eth1": textwrap.dedent(
+                 """\
++                AUTOCONNECT_PRIORITY=120
+                 BOOTPROTO=none
+                 DEVICE=eth1
+                 HWADDR=aa:d6:9f:2c:e8:80
+@@ -2614,6 +2643,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
+             ),
+             "ifcfg-eth2": textwrap.dedent(
+                 """\
++                AUTOCONNECT_PRIORITY=120
+                 BOOTPROTO=none
+                 DEVICE=eth2
+                 HWADDR=c0:bb:9f:2c:e8:80
+@@ -2625,6 +2655,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
+             ),
+             "ifcfg-eth3": textwrap.dedent(
+                 """\
++                AUTOCONNECT_PRIORITY=120
+                 BOOTPROTO=none
+                 BRIDGE=br0
+                 DEVICE=eth3
+@@ -2635,6 +2666,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
+             ),
+             "ifcfg-eth4": textwrap.dedent(
+                 """\
++                AUTOCONNECT_PRIORITY=120
+                 BOOTPROTO=none
+                 BRIDGE=br0
+                 DEVICE=eth4
+@@ -2645,6 +2677,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
+             ),
+             "ifcfg-eth5": textwrap.dedent(
+                 """\
++                AUTOCONNECT_PRIORITY=120
+                 BOOTPROTO=dhcp
+                 DEVICE=eth5
+                 DHCLIENT_SET_DEFAULT_ROUTE=no
+@@ -2655,6 +2688,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
+             ),
+             "ifcfg-ib0": textwrap.dedent(
+                 """\
++                AUTOCONNECT_PRIORITY=120
+                 BOOTPROTO=none
+                 DEVICE=ib0
+                 HWADDR=a0:00:02:20:fe:80:00:00:00:00:00:00:ec:0d:9a:03:00:15:e2:c1
+@@ -3232,6 +3266,7 @@ iface bond0 inet6 static
          "expected_sysconfig_rhel": {
              "ifcfg-bond0": textwrap.dedent(
                  """\
 +        AUTOCONNECT_PRIORITY=120
          BONDING_MASTER=yes
-         BONDING_OPTS="mode=active-backup xmit_hash_policy=layer3+4 """
-                 """miimon=100 num_grat_arp=5 """
-@@ -3452,6 +3481,7 @@ iface bond0 inet6 static
+         BONDING_OPTS="mode=active-backup miimon=100 """
+                 """downdelay=10 updelay=20 primary=bond0s0"
+@@ -3258,6 +3293,7 @@ iface bond0 inet6 static
              ),
              "ifcfg-bond0s0": textwrap.dedent(
                  """\
@@ -396,7 +447,7 @@ index 052b0674..cef4fa2d 100644
          BOOTPROTO=none
          DEVICE=bond0s0
          HWADDR=aa:bb:cc:dd:e8:00
-@@ -3479,6 +3509,7 @@ iface bond0 inet6 static
+@@ -3285,6 +3321,7 @@ iface bond0 inet6 static
              ),
              "ifcfg-bond0s1": textwrap.dedent(
                  """\
@@ -404,7 +455,31 @@ index 052b0674..cef4fa2d 100644
          BOOTPROTO=none
          DEVICE=bond0s1
          HWADDR=aa:bb:cc:dd:e8:01
-@@ -3628,6 +3659,7 @@ iface bond0 inet6 static
+@@ -3585,6 +3622,7 @@ iface bond0 inet6 static
+         "expected_sysconfig_rhel": {
+             "ifcfg-bond0": textwrap.dedent(
+                 """\
++        AUTOCONNECT_PRIORITY=120
+         BONDING_MASTER=yes
+         BONDING_OPTS="mode=active-backup xmit_hash_policy=layer3+4 """
+                 """miimon=100 num_grat_arp=5 """
+@@ -3615,6 +3653,7 @@ iface bond0 inet6 static
+             ),
+             "ifcfg-bond0s0": textwrap.dedent(
+                 """\
++        AUTOCONNECT_PRIORITY=120
+         BOOTPROTO=none
+         DEVICE=bond0s0
+         HWADDR=aa:bb:cc:dd:e8:00
+@@ -3642,6 +3681,7 @@ iface bond0 inet6 static
+             ),
+             "ifcfg-bond0s1": textwrap.dedent(
+                 """\
++        AUTOCONNECT_PRIORITY=120
+         BOOTPROTO=none
+         DEVICE=bond0s1
+         HWADDR=aa:bb:cc:dd:e8:01
+@@ -3789,6 +3829,7 @@ iface bond0 inet6 static
          "expected_sysconfig_rhel": {
              "ifcfg-en0": textwrap.dedent(
                  """\
@@ -412,7 +487,7 @@ index 052b0674..cef4fa2d 100644
                  BOOTPROTO=none
                  DEVICE=en0
                  HWADDR=aa:bb:cc:dd:e8:00
-@@ -3637,6 +3669,7 @@ iface bond0 inet6 static
+@@ -3798,6 +3839,7 @@ iface bond0 inet6 static
              ),
              "ifcfg-en0.99": textwrap.dedent(
                  """\
@@ -420,7 +495,23 @@ index 052b0674..cef4fa2d 100644
                  BOOTPROTO=none
                  DEFROUTE=yes
                  DEVICE=en0.99
-@@ -3774,6 +3807,7 @@ iface bond0 inet6 static
+@@ -3924,6 +3966,7 @@ iface bond0 inet6 static
+         "expected_sysconfig_rhel": {
+             "ifcfg-en0": textwrap.dedent(
+                 """\
++                AUTOCONNECT_PRIORITY=120
+                 BOOTPROTO=none
+                 DEVICE=en0
+                 HWADDR=aa:bb:cc:dd:e8:00
+@@ -3933,6 +3976,7 @@ iface bond0 inet6 static
+             ),
+             "ifcfg-en0.99": textwrap.dedent(
+                 """\
++                AUTOCONNECT_PRIORITY=120
+                 BOOTPROTO=none
+                 DEFROUTE=yes
+                 DEVICE=en0.99
+@@ -4098,6 +4142,7 @@ iface bond0 inet6 static
          "expected_sysconfig_rhel": {
              "ifcfg-br0": textwrap.dedent(
                  """\
@@ -428,7 +519,7 @@ index 052b0674..cef4fa2d 100644
                  BOOTPROTO=none
                  DEVICE=br0
                  IPADDR=192.168.2.2
-@@ -3787,6 +3821,7 @@ iface bond0 inet6 static
+@@ -4111,6 +4156,7 @@ iface bond0 inet6 static
              ),
              "ifcfg-eth0": textwrap.dedent(
                  """\
@@ -436,7 +527,7 @@ index 052b0674..cef4fa2d 100644
                  BOOTPROTO=none
                  BRIDGE=br0
                  DEVICE=eth0
-@@ -3802,6 +3837,7 @@ iface bond0 inet6 static
+@@ -4126,6 +4172,7 @@ iface bond0 inet6 static
              ),
              "ifcfg-eth1": textwrap.dedent(
                  """\
@@ -444,7 +535,7 @@ index 052b0674..cef4fa2d 100644
                  BOOTPROTO=none
                  BRIDGE=br0
                  DEVICE=eth1
-@@ -3989,6 +4025,7 @@ iface bond0 inet6 static
+@@ -4313,6 +4360,7 @@ iface bond0 inet6 static
          "expected_sysconfig_rhel": {
              "ifcfg-eth0": textwrap.dedent(
                  """\
@@ -452,7 +543,7 @@ index 052b0674..cef4fa2d 100644
                  BOOTPROTO=none
                  DEVICE=eth0
                  HWADDR=52:54:00:12:34:00
-@@ -4001,6 +4038,7 @@ iface bond0 inet6 static
+@@ -4325,6 +4373,7 @@ iface bond0 inet6 static
              ),
              "ifcfg-eth1": textwrap.dedent(
                  """\
@@ -460,7 +551,7 @@ index 052b0674..cef4fa2d 100644
                  BOOTPROTO=none
                  DEVICE=eth1
                  HWADDR=52:54:00:12:34:aa
-@@ -4012,6 +4050,7 @@ iface bond0 inet6 static
+@@ -4336,6 +4385,7 @@ iface bond0 inet6 static
              ),
              "ifcfg-eth2": textwrap.dedent(
                  """\
@@ -468,7 +559,15 @@ index 052b0674..cef4fa2d 100644
                  BOOTPROTO=none
                  DEVICE=eth2
                  HWADDR=52:54:00:12:34:ff
-@@ -4096,6 +4135,7 @@ iface bond0 inet6 static
+@@ -4505,6 +4555,7 @@ iface bond0 inet6 static
+                 """\
+                 # Created by cloud-init automatically, do not edit.
+                 #
++                AUTOCONNECT_PRIORITY=120
+                 BOOTPROTO=none
+                 DEFROUTE=yes
+                 DEVICE=interface0
+@@ -4583,6 +4634,7 @@ iface bond0 inet6 static
          "expected_sysconfig_rhel": {
              "ifcfg-eth0": textwrap.dedent(
                  """\
@@ -476,15 +575,99 @@ index 052b0674..cef4fa2d 100644
                  BOOTPROTO=none
                  DEVICE=eth0
                  HWADDR=cf:d6:af:48:e8:80
-@@ -4693,6 +4733,7 @@ class TestRhelSysConfigRendering(CiTestCase):
+@@ -4734,6 +4786,7 @@ iface bond0 inet6 static
+                 """\
+                 # Created by cloud-init automatically, do not edit.
+                 #
++                AUTOCONNECT_PRIORITY=120
+                 BOOTPROTO=none
+                 DEVICE=eth0
+                 DNS1=8.8.8.8
+@@ -4945,6 +4998,7 @@ iface bond0 inet6 static
+                 """\
+                 # Created by cloud-init automatically, do not edit.
+                 #
++                AUTOCONNECT_PRIORITY=120
+                 BOOTPROTO=none
+                 DEVICE=baremetal
+                 IPV6ADDR=fc00:1:1::2/64
+@@ -4960,6 +5014,7 @@ iface bond0 inet6 static
+                 """\
+                 # Created by cloud-init automatically, do not edit.
+                 #
++                AUTOCONNECT_PRIORITY=120
+                 BOOTPROTO=none
+                 BRIDGE=baremetal
+                 DEVICE=baremetal0
+@@ -4973,6 +5028,7 @@ iface bond0 inet6 static
+                 """\
+                 # Created by cloud-init automatically, do not edit.
+                 #
++                AUTOCONNECT_PRIORITY=120
+                 BOOTPROTO=none
+                 DEVICE=provisioning
+                 IPV6ADDR=fc00:1:2::2/64
+@@ -4988,6 +5044,7 @@ iface bond0 inet6 static
+                 """\
+                 # Created by cloud-init automatically, do not edit.
+                 #
++                AUTOCONNECT_PRIORITY=120
+                 BOOTPROTO=none
+                 BRIDGE=provisioning
+                 DEVICE=provisioning0
+diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
+index 531302f70..d95ee2979 100644
+--- a/tests/unittests/test_net.py
++++ b/tests/unittests/test_net.py
+@@ -612,6 +612,7 @@ dns = none
+                 """
+ # Created by cloud-init automatically, do not edit.
+ #
++AUTOCONNECT_PRIORITY=120
+ BOOTPROTO=none
+ DEFROUTE=yes
+ DEVICE=eth0
+@@ -777,6 +778,7 @@ dns = none
+                 """
+ # Created by cloud-init automatically, do not edit.
+ #
++AUTOCONNECT_PRIORITY=120
+ BOOTPROTO=none
+ DEFROUTE=yes
+ DEVICE=eth0
+@@ -951,6 +953,7 @@ dns = none
+                 """
+ # Created by cloud-init automatically, do not edit.
+ #
++AUTOCONNECT_PRIORITY=120
+ BOOTPROTO=none
+ DEFROUTE=yes
+ DEVICE=eth0
+@@ -1074,6 +1077,7 @@ dns = none
+                 """
+ # Created by cloud-init automatically, do not edit.
+ #
++AUTOCONNECT_PRIORITY=120
+ BOOTPROTO=none
+ DEFROUTE=yes
+ DEVICE=eth0
+@@ -1266,6 +1270,7 @@ dns = none
+                 """
+ # Created by cloud-init automatically, do not edit.
+ #
++AUTOCONNECT_PRIORITY=120
+ BOOTPROTO=none
+ DEFROUTE=yes
+ DEVICE=eth0
+@@ -1934,6 +1939,7 @@ class TestRhelSysConfigRendering:
              expected_content = """
  # Created by cloud-init automatically, do not edit.
  #
 +AUTOCONNECT_PRIORITY=120
  BOOTPROTO=dhcp
  DEVICE=eth1000
- HWADDR=07-1c-c6-75-a4-be
-@@ -4900,6 +4941,7 @@ USERCTL=no
+ DHCPV6C=yes
+@@ -2143,6 +2149,7 @@ USERCTL=no
          expected = """\
  # Created by cloud-init automatically, do not edit.
  #
@@ -492,7 +675,7 @@ index 052b0674..cef4fa2d 100644
  BOOTPROTO=none
  DEFROUTE=yes
  DEVICE=interface0
-@@ -4929,6 +4971,7 @@ USERCTL=no
+@@ -2172,6 +2179,7 @@ USERCTL=no
          expected_i1 = """\
  # Created by cloud-init automatically, do not edit.
  #
@@ -500,7 +683,7 @@ index 052b0674..cef4fa2d 100644
  BOOTPROTO=none
  DEFROUTE=yes
  DEVICE=eth0
-@@ -4945,6 +4988,7 @@ USERCTL=no
+@@ -2188,6 +2196,7 @@ USERCTL=no
          expected_i2 = """\
  # Created by cloud-init automatically, do not edit.
  #
@@ -508,7 +691,7 @@ index 052b0674..cef4fa2d 100644
  BOOTPROTO=dhcp
  DEVICE=eth1
  DHCLIENT_SET_DEFAULT_ROUTE=no
-@@ -4972,6 +5016,7 @@ USERCTL=no
+@@ -2215,6 +2224,7 @@ USERCTL=no
          expected = """\
  # Created by cloud-init automatically, do not edit.
  #
@@ -516,7 +699,7 @@ index 052b0674..cef4fa2d 100644
  BOOTPROTO=dhcp
  DEVICE=eth0
  ONBOOT=yes
-@@ -5191,6 +5236,7 @@ USERCTL=no
+@@ -2396,6 +2406,7 @@ USERCTL=no
              "expected_sysconfig": {
                  "ifcfg-ens3": textwrap.dedent(
                      """\
@@ -524,7 +707,7 @@ index 052b0674..cef4fa2d 100644
                     BOOTPROTO=none
                     DEFROUTE=yes
                     DEVICE=ens3
-@@ -5235,6 +5281,7 @@ USERCTL=no
+@@ -2442,6 +2453,7 @@ USERCTL=no
          expected = {
              "ifcfg-eno1": textwrap.dedent(
                  """\
@@ -532,7 +715,7 @@ index 052b0674..cef4fa2d 100644
                  BOOTPROTO=none
                  DEVICE=eno1
                  ONBOOT=yes
-@@ -5244,6 +5291,7 @@ USERCTL=no
+@@ -2451,6 +2463,7 @@ USERCTL=no
              ),
              "ifcfg-eno1.1000": textwrap.dedent(
                  """\
@@ -540,7 +723,7 @@ index 052b0674..cef4fa2d 100644
                  BOOTPROTO=none
                  DEVICE=eno1.1000
                  IPADDR=192.6.1.9
-@@ -5276,6 +5324,7 @@ USERCTL=no
+@@ -2483,6 +2496,7 @@ USERCTL=no
          expected = {
              "ifcfg-bond0": textwrap.dedent(
                  """\
@@ -548,7 +731,7 @@ index 052b0674..cef4fa2d 100644
                  BONDING_MASTER=yes
                  BONDING_SLAVE0=enp0s0
                  BONDING_SLAVE1=enp0s1
-@@ -5291,6 +5340,7 @@ USERCTL=no
+@@ -2498,6 +2512,7 @@ USERCTL=no
              ),
              "ifcfg-enp0s0": textwrap.dedent(
                  """\
@@ -556,7 +739,7 @@ index 052b0674..cef4fa2d 100644
                  BONDING_MASTER=yes
                  BOOTPROTO=none
                  DEVICE=enp0s0
-@@ -5303,6 +5353,7 @@ USERCTL=no
+@@ -2510,6 +2525,7 @@ USERCTL=no
              ),
              "ifcfg-enp0s1": textwrap.dedent(
                  """\
@@ -564,15 +747,15 @@ index 052b0674..cef4fa2d 100644
                  BONDING_MASTER=yes
                  BOOTPROTO=none
                  DEVICE=enp0s1
-@@ -5333,6 +5384,7 @@ USERCTL=no
-         expected = {
-             "ifcfg-eno1": textwrap.dedent(
-                 """\
-+                AUTOCONNECT_PRIORITY=120
-                 BOOTPROTO=dhcp
-                 DEVICE=eno1
-                 HWADDR=07-1c-c6-75-a4-be
-@@ -5411,6 +5463,7 @@ USERCTL=no
+@@ -2541,6 +2557,7 @@ USERCTL=no
+             expected = {
+                 "ifcfg-eno1": textwrap.dedent(
+                     """\
++                    AUTOCONNECT_PRIORITY=120
+                     BOOTPROTO=dhcp
+                     DEVICE=eno1
+                     HWADDR=07-1c-c6-75-a4-be
+@@ -2621,6 +2638,7 @@ USERCTL=no
                  """\
                  # Created by cloud-init automatically, do not edit.
                  #
diff --git a/SOURCES/0004-downstream-Revert-chore-eliminate-redundant-ordering.patch b/SOURCES/0004-downstream-Revert-chore-eliminate-redundant-ordering.patch
new file mode 100644
index 0000000..ca5db8d
--- /dev/null
+++ b/SOURCES/0004-downstream-Revert-chore-eliminate-redundant-ordering.patch
@@ -0,0 +1,85 @@
+From 46e39514415041f51468b3e40059891dd42f028a Mon Sep 17 00:00:00 2001
+From: Ani Sinha <anisinha@redhat.com>
+Date: Fri, 6 Dec 2024 16:53:25 +0530
+Subject: [PATCH] downstream: Revert "chore: eliminate redundant ordering
+ dependencies (#5819)"
+
+This reverts commit 0680d03304c34fc4c3081f29d99f140d507dd923.
+
+The reversal is necessary because the original change was meant to work with
+the 'single process optimization' patch. Since we are reverting the
+'single process optimization' (see next patch), we should revert this as well.
+
+Moreover, without the reversal, we get the following error from
+cloud-init-local:
+
+Traceback (most recent call last):
+  File "/usr/lib/python3.9/site-packages/cloudinit/config/cc_set_hostname.py", line 86, in handle
+    cloud.distro.set_hostname(hostname, fqdn)
+  File "/usr/lib/python3.9/site-packages/cloudinit/distros/__init__.py", line 395, in set_hostname
+    self._write_hostname(writeable_hostname, self.hostname_conf_fn)
+  File "/usr/lib/python3.9/site-packages/cloudinit/distros/rhel.py", line 119, in _write_hostname
+    subp.subp(["hostnamectl", "set-hostname", str(hostname)])
+  File "/usr/lib/python3.9/site-packages/cloudinit/subp.py", line 291, in subp
+    raise ProcessExecutionError(
+cloudinit.subp.ProcessExecutionError: Unexpected error while running command.
+Command: ['hostnamectl', 'set-hostname', 'kvm-cloudinit-test']
+Exit code: 1
+Reason: -
+Stdout:
+Stderr: Failed to connect to bus: No such file or directory
+
+Jira: https://issues.redhat.com/browse/RHEL-70365
+X-downstream-only: true
+Signed-off-by: Ani Sinha <anisinha@redhat.com>
+---
+ systemd/cloud-init-local.service.tmpl | 5 +++++
+ systemd/cloud-init-main.service.tmpl  | 6 ++++++
+ 2 files changed, 11 insertions(+)
+
+diff --git a/systemd/cloud-init-local.service.tmpl b/systemd/cloud-init-local.service.tmpl
+index e6a300fd4..f6a6cce41 100644
+--- a/systemd/cloud-init-local.service.tmpl
++++ b/systemd/cloud-init-local.service.tmpl
+@@ -7,6 +7,10 @@ DefaultDependencies=no
+ {% endif %}
+ Wants=network-pre.target
+ After=hv_kvp_daemon.service
++{% if variant in ["almalinux", "cloudlinux", "rhel"] %}
++Requires=dbus.socket
++After=dbus.socket
++{% endif %}
+ Before=network-pre.target
+ Before=shutdown.target
+ {% if variant in ["almalinux", "cloudlinux", "rhel"] %}
+@@ -16,6 +20,7 @@ Before=firewalld.target
+ Before=sysinit.target
+ {% endif %}
+ Conflicts=shutdown.target
++RequiresMountsFor=/var/lib/cloud
+ ConditionPathExists=!/etc/cloud/cloud-init.disabled
+ ConditionKernelCommandLine=!cloud-init=disabled
+ ConditionEnvironment=!KERNEL_CMDLINE=cloud-init=disabled
+diff --git a/systemd/cloud-init-main.service.tmpl b/systemd/cloud-init-main.service.tmpl
+index b80f324fe..7a42a5746 100644
+--- a/systemd/cloud-init-main.service.tmpl
++++ b/systemd/cloud-init-main.service.tmpl
+@@ -8,12 +8,18 @@
+ # https://www.freedesktop.org/software/systemd/man/latest/systemd-remount-fs.service.html
+ [Unit]
+ Description=Cloud-init: Single Process
++Wants=network-pre.target
+ {% if variant in ["almalinux", "cloudlinux", "ubuntu", "unknown", "debian", "rhel"] %}
+ DefaultDependencies=no
+ {% endif %}
+ {% if variant in ["almalinux", "cloudlinux", "rhel"] %}
+ Requires=dbus.socket
+ After=dbus.socket
++Before=network.service
++Before=firewalld.target
++{% endif %}
++{% if variant in ["ubuntu", "unknown", "debian"] %}
++Before=sysinit.target
+ {% endif %}
+ 
+ After=systemd-remount-fs.service
diff --git a/SOURCES/0004-net-network_manager-do-not-set-may-fail-to-False-for.patch b/SOURCES/0004-net-network_manager-do-not-set-may-fail-to-False-for.patch
deleted file mode 100644
index f8de026..0000000
--- a/SOURCES/0004-net-network_manager-do-not-set-may-fail-to-False-for.patch
+++ /dev/null
@@ -1,140 +0,0 @@
-From 5fa8113a9efaa90f293b95477c4fa44e3d4b6537 Mon Sep 17 00:00:00 2001
-From: Ani Sinha <anisinha@redhat.com>
-Date: Thu, 23 Nov 2023 12:27:51 +0530
-Subject: [PATCH] net/network_manager: do not set "may-fail" to False for both
- ipv4 and ipv6 dhcp
-
-If "may-fail" is set to False in the Network Manager keyfile for both ipv4
-and ipv6 for dhcp configuration, it essentially means both ipv4 and ipv6 network
-initialization using dhcp must succeed for the overall network configuration to
-succeed. This means, for environments where only ipv4 or ipv6 is available but
-not both and we need to configure both ipv4 and ipv6 dhcp, the overall
-network configuration will fail. This is not what we want. When both ipv4
-and ipv6 dhcp are configured, it is enough for the overall configuration to
-succeed if any one succeeds.
-Therefore, set "may-fail" to True for both ipv4 and ipv6 if and only if both
-ipv4 and ipv6 are configured as dhcp in the Network Manager keyfile and
-"may-fail" is set to False for both. If both ipv4 and ipv6 are configured
-in the keyfile and if for any of them "may-fail" is already set to True,then
-do nothing.
-All other cases remain same as before.
-
-Please see discussions in PR #4474.
-
-Co-authored-by: James Falcon <james.falcon@canonical.com>
-Signed-off-by: Ani Sinha <anisinha@redhat.com>
-(cherry picked from commit 29dd5ace73ad60c7452c39b840045fb47fe0711f)
----
- cloudinit/net/network_manager.py | 59 ++++++++++++++++++++++++++++++++
- tests/unittests/test_net.py      |  8 ++---
- 2 files changed, 63 insertions(+), 4 deletions(-)
-
-diff --git a/cloudinit/net/network_manager.py b/cloudinit/net/network_manager.py
-index 8374cfcc..8a99eb3a 100644
---- a/cloudinit/net/network_manager.py
-+++ b/cloudinit/net/network_manager.py
-@@ -71,6 +71,57 @@ class NMConnection:
-         if not self.config.has_option(section, option):
-             self.config[section][option] = value
- 
-+    def _config_option_is_set(self, section, option):
-+        """
-+        Checks if a config option is set. Returns True if it is,
-+        else returns False.
-+        """
-+        return self.config.has_section(section) and self.config.has_option(
-+            section, option
-+        )
-+
-+    def _get_config_option(self, section, option):
-+        """
-+        Returns the value of a config option if its set,
-+        else returns None.
-+        """
-+        if self._config_option_is_set(section, option):
-+            return self.config[section][option]
-+        else:
-+            return None
-+
-+    def _change_set_config_option(self, section, option, value):
-+        """
-+        Overrides the value of a config option if its already set.
-+        Else, if the config option is not set, it does nothing.
-+        """
-+        if self._config_option_is_set(section, option):
-+            self.config[section][option] = value
-+
-+    def _set_mayfail_true_if_both_false_dhcp(self):
-+        """
-+        If for both ipv4 and ipv6, 'may-fail' is set to be False,
-+        set it to True for both of them.
-+        """
-+        for family in ["ipv4", "ipv6"]:
-+            if self._get_config_option(family, "may-fail") != "false":
-+                # if either ipv4 or ipv6 sections are not set/configured,
-+                # or if both are configured but for either ipv4 or ipv6,
-+                # 'may-fail' is not 'false', do not do anything.
-+                return
-+            if self._get_config_option(family, "method") not in [
-+                "dhcp",
-+                "auto",
-+            ]:
-+                # if both v4 and v6 are not dhcp, do not do anything.
-+                return
-+
-+        # If we landed here, it means both ipv4 and ipv6 are configured
-+        # with dhcp/auto and both have 'may-fail' set to 'false'. So set
-+        # both to 'true'.
-+        for family in ["ipv4", "ipv6"]:
-+            self._change_set_config_option(family, "may-fail", "true")
-+
-     def _set_ip_method(self, family, subnet_type):
-         """
-         Ensures there's appropriate [ipv4]/[ipv6] for given family
-@@ -271,6 +322,14 @@ class NMConnection:
-             if family == "ipv4" and "mtu" in subnet:
-                 ipv4_mtu = subnet["mtu"]
- 
-+        # we do not want to set may-fail to false for both ipv4 and ipv6 dhcp
-+        # at the at the same time. This will make the network configuration
-+        # work only when both ipv4 and ipv6 dhcp succeeds. This may not be
-+        # what we want. If we have configured both ipv4 and ipv6 dhcp, any one
-+        # succeeding should be enough. Therefore, if "may-fail" is set to
-+        # False for both ipv4 and ipv6 dhcp, set them both to True.
-+        self._set_mayfail_true_if_both_false_dhcp()
-+
-         if ipv4_mtu is None:
-             ipv4_mtu = device_mtu
-         if not ipv4_mtu == device_mtu:
-diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
-index cef4fa2d..fb4c863c 100644
---- a/tests/unittests/test_net.py
-+++ b/tests/unittests/test_net.py
-@@ -1477,11 +1477,11 @@ NETWORK_CONFIGS = {
- 
-                 [ipv4]
-                 method=auto
--                may-fail=false
-+                may-fail=true
- 
-                 [ipv6]
-                 method=auto
--                may-fail=false
-+                may-fail=true
- 
-                 """
-             ),
-@@ -1650,11 +1650,11 @@ NETWORK_CONFIGS = {
- 
-                 [ipv6]
-                 method=auto
--                may-fail=false
-+                may-fail=true
- 
-                 [ipv4]
-                 method=auto
--                may-fail=false
-+                may-fail=true
- 
-                 """
-             ),
diff --git a/SOURCES/0005-downstream-remove-single-process-optimization.patch b/SOURCES/0005-downstream-remove-single-process-optimization.patch
new file mode 100644
index 0000000..8c3555c
--- /dev/null
+++ b/SOURCES/0005-downstream-remove-single-process-optimization.patch
@@ -0,0 +1,266 @@
+From 84d1141690d4fe5d88878d2eb60e03d06ba3d422 Mon Sep 17 00:00:00 2001
+From: Ani Sinha <anisinha@redhat.com>
+Date: Tue, 3 Dec 2024 09:29:15 +0530
+Subject: [PATCH] downstream: remove single process optimization
+
+This optimization is a big change in behavior, patch it out.
+Patch is taken from
+https://github.com/canonical/cloud-init/blob/ubuntu/noble/debian/patches/no-single-process.patch
+
+X-downstream-only: true
+Signed-off-by: Ani Sinha <anisinha@redhat.com>
+---
+ cloudinit/cmd/status.py                       |  3 +-
+ cloudinit/config/cc_mounts.py                 |  2 +-
+ .../schemas/schema-cloud-config-v1.json       |  4 +-
+ systemd/cloud-config.service                  |  9 +---
+ systemd/cloud-config.target                   |  4 +-
+ systemd/cloud-final.service                   | 10 +---
+ systemd/cloud-init-local.service.tmpl         | 10 +---
+ systemd/cloud-init-main.service.tmpl          | 48 -------------------
+ ...k.service.tmpl => cloud-init.service.tmpl} | 12 +----
+ tests/unittests/config/test_cc_mounts.py      |  4 +-
+ 10 files changed, 15 insertions(+), 91 deletions(-)
+ delete mode 100644 systemd/cloud-init-main.service.tmpl
+ rename systemd/{cloud-init-network.service.tmpl => cloud-init.service.tmpl} (69%)
+
+diff --git a/cloudinit/cmd/status.py b/cloudinit/cmd/status.py
+index 0dfb9b2f7..fbd772e52 100644
+--- a/cloudinit/cmd/status.py
++++ b/cloudinit/cmd/status.py
+@@ -318,9 +318,8 @@ def systemd_failed(wait: bool) -> bool:
+     for service in [
+         "cloud-final.service",
+         "cloud-config.service",
+-        "cloud-init-network.service",
++        "cloud-init.service",
+         "cloud-init-local.service",
+-        "cloud-init-main.service",
+     ]:
+         try:
+             stdout = query_systemctl(
+diff --git a/cloudinit/config/cc_mounts.py b/cloudinit/config/cc_mounts.py
+index cec092902..cb36bdb87 100644
+--- a/cloudinit/config/cc_mounts.py
++++ b/cloudinit/config/cc_mounts.py
+@@ -521,7 +521,7 @@ def handle(name: str, cfg: Config, cloud: Cloud, args: list) -> None:
+     # fs_spec, fs_file, fs_vfstype, fs_mntops, fs-freq, fs_passno
+     uses_systemd = cloud.distro.uses_systemd()
+     default_mount_options = (
+-        "defaults,nofail,x-systemd.after=cloud-init-network.service,_netdev"
++        "defaults,nofail,x-systemd.after=cloud-init.service,_netdev"
+         if uses_systemd
+         else "defaults,nobootwait"
+     )
+diff --git a/cloudinit/config/schemas/schema-cloud-config-v1.json b/cloudinit/config/schemas/schema-cloud-config-v1.json
+index fffa04b52..7d5c87c60 100644
+--- a/cloudinit/config/schemas/schema-cloud-config-v1.json
++++ b/cloudinit/config/schemas/schema-cloud-config-v1.json
+@@ -2029,12 +2029,12 @@
+         },
+         "mount_default_fields": {
+           "type": "array",
+-          "description": "Default mount configuration for any mount entry with less than 6 options provided. When specified, 6 items are required and represent ``/etc/fstab`` entries. Default: ``defaults,nofail,x-systemd.after=cloud-init-network.service,_netdev``.",
++          "description": "Default mount configuration for any mount entry with less than 6 options provided. When specified, 6 items are required and represent ``/etc/fstab`` entries. Default: ``defaults,nofail,x-systemd.after=cloud-init.service,_netdev``.",
+           "default": [
+             null,
+             null,
+             "auto",
+-            "defaults,nofail,x-systemd.after=cloud-init-network.service",
++            "defaults,nofail,x-systemd.after=cloud-init.service",
+             "0",
+             "2"
+           ],
+diff --git a/systemd/cloud-config.service b/systemd/cloud-config.service
+index 54599b346..79ff733a4 100644
+--- a/systemd/cloud-config.service
++++ b/systemd/cloud-config.service
+@@ -9,14 +9,7 @@ ConditionEnvironment=!KERNEL_CMDLINE=cloud-init=disabled
+ 
+ [Service]
+ Type=oneshot
+-# This service is a shim which preserves systemd ordering while allowing a
+-# single Python process to run cloud-init's logic. This works by communicating
+-# with the cloud-init process over a unix socket to tell the process that this
+-# stage can start, and then wait on a return socket until the cloud-init
+-# process has completed this stage. The output from the return socket is piped
+-# into a shell so that the process can send a completion message (defaults to
+-# "done", otherwise includes an error message) and an exit code to systemd.
+-ExecStart=sh -c 'echo "start" | netcat -Uu -W1 /run/cloud-init/share/config.sock -s /run/cloud-init/share/config-return.sock | sh'
++ExecStart=/usr/bin/cloud-init modules --mode=config
+ RemainAfterExit=yes
+ TimeoutSec=0
+ 
+diff --git a/systemd/cloud-config.target b/systemd/cloud-config.target
+index be754bbd1..2d65e3433 100644
+--- a/systemd/cloud-config.target
++++ b/systemd/cloud-config.target
+@@ -14,5 +14,5 @@
+ 
+ [Unit]
+ Description=Cloud-config availability
+-Wants=cloud-init-local.service cloud-init-network.service
+-After=cloud-init-local.service cloud-init-network.service
++Wants=cloud-init-local.service cloud-init.service
++After=cloud-init-local.service cloud-init.service
+diff --git a/systemd/cloud-final.service b/systemd/cloud-final.service
+index c48f95c4f..1489eb356 100644
+--- a/systemd/cloud-final.service
++++ b/systemd/cloud-final.service
+@@ -12,16 +12,10 @@ ConditionEnvironment=!KERNEL_CMDLINE=cloud-init=disabled
+ 
+ [Service]
+ Type=oneshot
+-# This service is a shim which preserves systemd ordering while allowing a
+-# single Python process to run cloud-init's logic. This works by communicating
+-# with the cloud-init process over a unix socket to tell the process that this
+-# stage can start, and then wait on a return socket until the cloud-init
+-# process has completed this stage. The output from the return socket is piped
+-# into a shell so that the process can send a completion message (defaults to
+-# "done", otherwise includes an error message) and an exit code to systemd.
+-ExecStart=sh -c 'echo "start" | netcat -Uu -W1 /run/cloud-init/share/final.sock -s /run/cloud-init/share/final-return.sock | sh'
++ExecStart=/usr/bin/cloud-init modules --mode=final
+ RemainAfterExit=yes
+ TimeoutSec=0
++KillMode=process
+ TasksMax=infinity
+ 
+ # Output needs to appear in instance console output
+diff --git a/systemd/cloud-init-local.service.tmpl b/systemd/cloud-init-local.service.tmpl
+index f6a6cce41..a3859dfeb 100644
+--- a/systemd/cloud-init-local.service.tmpl
++++ b/systemd/cloud-init-local.service.tmpl
+@@ -11,6 +11,7 @@ After=hv_kvp_daemon.service
+ Requires=dbus.socket
+ After=dbus.socket
+ {% endif %}
++After=systemd-remount-fs.service
+ Before=network-pre.target
+ Before=shutdown.target
+ {% if variant in ["almalinux", "cloudlinux", "rhel"] %}
+@@ -30,14 +31,7 @@ Type=oneshot
+ {% if variant in ["almalinux", "cloudlinux", "rhel"] %}
+ ExecStartPre=/sbin/restorecon /run/cloud-init
+ {% endif %}
+-# This service is a shim which preserves systemd ordering while allowing a
+-# single Python process to run cloud-init's logic. This works by communicating
+-# with the cloud-init process over a unix socket to tell the process that this
+-# stage can start, and then wait on a return socket until the cloud-init
+-# process has completed this stage. The output from the return socket is piped
+-# into a shell so that the process can send a completion message (defaults to
+-# "done", otherwise includes an error message) and an exit code to systemd.
+-ExecStart=sh -c 'echo "start" | netcat -Uu -W1 /run/cloud-init/share/local.sock -s /run/cloud-init/share/local-return.sock | sh'
++ExecStart=/usr/bin/cloud-init init --local
+ RemainAfterExit=yes
+ TimeoutSec=0
+ 
+diff --git a/systemd/cloud-init-main.service.tmpl b/systemd/cloud-init-main.service.tmpl
+deleted file mode 100644
+index 7a42a5746..000000000
+--- a/systemd/cloud-init-main.service.tmpl
++++ /dev/null
+@@ -1,48 +0,0 @@
+-## template:jinja
+-# systemd ordering resources
+-# ==========================
+-# https://systemd.io/NETWORK_ONLINE/
+-# https://docs.cloud-init.io/en/latest/explanation/boot.html
+-# https://www.freedesktop.org/wiki/Software/systemd/NetworkTarget/
+-# https://www.freedesktop.org/software/systemd/man/latest/systemd.special.html
+-# https://www.freedesktop.org/software/systemd/man/latest/systemd-remount-fs.service.html
+-[Unit]
+-Description=Cloud-init: Single Process
+-Wants=network-pre.target
+-{% if variant in ["almalinux", "cloudlinux", "ubuntu", "unknown", "debian", "rhel"] %}
+-DefaultDependencies=no
+-{% endif %}
+-{% if variant in ["almalinux", "cloudlinux", "rhel"] %}
+-Requires=dbus.socket
+-After=dbus.socket
+-Before=network.service
+-Before=firewalld.target
+-{% endif %}
+-{% if variant in ["ubuntu", "unknown", "debian"] %}
+-Before=sysinit.target
+-{% endif %}
+-
+-After=systemd-remount-fs.service
+-Before=cloud-init-local.service
+-Before=shutdown.target
+-Conflicts=shutdown.target
+-RequiresMountsFor=/var/lib/cloud
+-ConditionPathExists=!/etc/cloud/cloud-init.disabled
+-ConditionKernelCommandLine=!cloud-init=disabled
+-ConditionEnvironment=!KERNEL_CMDLINE=cloud-init=disabled
+-
+-[Service]
+-Type=notify
+-ExecStart=/usr/bin/cloud-init --all-stages
+-KillMode=process
+-TasksMax=infinity
+-TimeoutStartSec=infinity
+-{% if variant in ["almalinux", "cloudlinux", "rhel"] %}
+-ExecStartPre=/sbin/restorecon /run/cloud-init
+-{% endif %}
+-
+-# Output needs to appear in instance console output
+-StandardOutput=journal+console
+-
+-[Install]
+-WantedBy=cloud-init.target
+diff --git a/systemd/cloud-init-network.service.tmpl b/systemd/cloud-init.service.tmpl
+similarity index 69%
+rename from systemd/cloud-init-network.service.tmpl
+rename to systemd/cloud-init.service.tmpl
+index af09fff35..939544313 100644
+--- a/systemd/cloud-init-network.service.tmpl
++++ b/systemd/cloud-init.service.tmpl
+@@ -9,15 +9,14 @@ Wants=cloud-init-local.service
+ Wants=sshd-keygen.service
+ Wants=sshd.service
+ After=cloud-init-local.service
+-{% if variant not in ["ubuntu"] %}
+ After=systemd-networkd-wait-online.service
+-{% endif %}
+ {% if variant in ["ubuntu", "unknown", "debian"] %}
+ After=networking.service
+ {% endif %}
+ {% if variant in ["almalinux", "centos", "cloudlinux", "eurolinux", "fedora",
+                   "miraclelinux", "openeuler", "OpenCloudOS", "openmandriva", "rhel", "rocky",
+                   "suse", "TencentOS", "virtuozzo"] %}
++
+ After=NetworkManager.service
+ After=NetworkManager-wait-online.service
+ {% endif %}
+@@ -46,14 +45,7 @@ ConditionEnvironment=!KERNEL_CMDLINE=cloud-init=disabled
+ 
+ [Service]
+ Type=oneshot
+-# This service is a shim which preserves systemd ordering while allowing a
+-# single Python process to run cloud-init's logic. This works by communicating
+-# with the cloud-init process over a unix socket to tell the process that this
+-# stage can start, and then wait on a return socket until the cloud-init
+-# process has completed this stage. The output from the return socket is piped
+-# into a shell so that the process can send a completion message (defaults to
+-# "done", otherwise includes an error message) and an exit code to systemd.
+-ExecStart=sh -c 'echo "start" | netcat -Uu -W1 /run/cloud-init/share/network.sock -s /run/cloud-init/share/network-return.sock | sh'
++ExecStart=/usr/bin/cloud-init init
+ RemainAfterExit=yes
+ TimeoutSec=0
+ 
+diff --git a/tests/unittests/config/test_cc_mounts.py b/tests/unittests/config/test_cc_mounts.py
+index 0e6d83793..f710d8a4f 100644
+--- a/tests/unittests/config/test_cc_mounts.py
++++ b/tests/unittests/config/test_cc_mounts.py
+@@ -566,9 +566,9 @@ class TestFstabHandling:
+             LABEL=keepme	none	ext4	defaults	0	0
+             LABEL=UEFI
+             /dev/sda4	/mnt2	auto	nofail,comment=cloudconfig	1	2
+-            /dev/sda5	/mnt3	auto	defaults,nofail,x-systemd.after=cloud-init-network.service,_netdev,comment=cloudconfig	0	2
++            /dev/sda5	/mnt3	auto	defaults,nofail,x-systemd.after=cloud-init.service,_netdev,comment=cloudconfig	0	2
+             /dev/sda1	/mnt	xfs	auto,comment=cloudconfig	0	2
+-            /dev/sda3	/mnt4	btrfs	defaults,nofail,x-systemd.after=cloud-init-network.service,_netdev,comment=cloudconfig	0	2
++            /dev/sda3	/mnt4	btrfs	defaults,nofail,x-systemd.after=cloud-init.service,_netdev,comment=cloudconfig	0	2
+             /dev/sdb1	none	swap	sw,comment=cloudconfig	0	0
+             """  # noqa: E501
+             ).strip()
diff --git a/SOURCES/0005-net-allow-dhcp6-configuration-from-generate_fallback.patch b/SOURCES/0005-net-allow-dhcp6-configuration-from-generate_fallback.patch
deleted file mode 100644
index 56a4ca7..0000000
--- a/SOURCES/0005-net-allow-dhcp6-configuration-from-generate_fallback.patch
+++ /dev/null
@@ -1,172 +0,0 @@
-From 54e87eaad7841270e530beff2dcfe68292ae87ef Mon Sep 17 00:00:00 2001
-From: Ani Sinha <anisinha@redhat.com>
-Date: Tue, 21 Nov 2023 13:57:15 +0530
-Subject: [PATCH] net: allow dhcp6 configuration from
- generate_fallback_configuration()
-
-This will make sure on Azure we can use both dhcp4 and dhcp6 when IMDS is not
-used. This is useful in situations where only ipv6 network is available and
-there is no dhcp4 running.
-
-This change is mostly a reversal of commit 29ed5f5b646ee and therefore,
-re-application of the commit 518047aea9 with some small changes.
-
-The issue that caused the reversal of 518047aea9 is fixed by the earlier commit:
-cab0eaf290af7 ("net/network_manager: do not set "may-fail" to False for both ipv4 and ipv6 dhcp")
-
-Fixes GH-4439
-
-Signed-off-by: Ani Sinha <anisinha@redhat.com>
-(cherry picked from commit 0264e969166846b2f5cf87ccdb051a3a795eca15)
----
- cloudinit/net/__init__.py        |  7 ++++++-
- tests/unittests/net/test_init.py |  4 ++++
- tests/unittests/test_net.py      | 24 +++++++++++++++++++++---
- 3 files changed, 31 insertions(+), 4 deletions(-)
-
-diff --git a/cloudinit/net/__init__.py b/cloudinit/net/__init__.py
-index bf21633b..c0888f52 100644
---- a/cloudinit/net/__init__.py
-+++ b/cloudinit/net/__init__.py
-@@ -571,7 +571,12 @@ def generate_fallback_config(config_driver=None):
-         match = {
-             "macaddress": read_sys_net_safe(target_name, "address").lower()
-         }
--    cfg = {"dhcp4": True, "set-name": target_name, "match": match}
-+    cfg = {
-+        "dhcp4": True,
-+        "dhcp6": True,
-+        "set-name": target_name,
-+        "match": match,
-+    }
-     if config_driver:
-         driver = device_driver(target_name)
-         if driver:
-diff --git a/tests/unittests/net/test_init.py b/tests/unittests/net/test_init.py
-index 561d5151..60a44186 100644
---- a/tests/unittests/net/test_init.py
-+++ b/tests/unittests/net/test_init.py
-@@ -261,6 +261,7 @@ class TestGenerateFallbackConfig(CiTestCase):
-                 "eth1": {
-                     "match": {"macaddress": mac},
-                     "dhcp4": True,
-+                    "dhcp6": True,
-                     "set-name": "eth1",
-                 }
-             },
-@@ -278,6 +279,7 @@ class TestGenerateFallbackConfig(CiTestCase):
-                 "eth0": {
-                     "match": {"macaddress": mac},
-                     "dhcp4": True,
-+                    "dhcp6": True,
-                     "set-name": "eth0",
-                 }
-             },
-@@ -293,6 +295,7 @@ class TestGenerateFallbackConfig(CiTestCase):
-             "ethernets": {
-                 "eth0": {
-                     "dhcp4": True,
-+                    "dhcp6": True,
-                     "match": {"macaddress": mac},
-                     "set-name": "eth0",
-                 }
-@@ -359,6 +362,7 @@ class TestGenerateFallbackConfig(CiTestCase):
-             "ethernets": {
-                 "ens3": {
-                     "dhcp4": True,
-+                    "dhcp6": True,
-                     "match": {"name": "ens3"},
-                     "set-name": "ens3",
-                 }
-diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
-index fb4c863c..d9ef493b 100644
---- a/tests/unittests/test_net.py
-+++ b/tests/unittests/test_net.py
-@@ -4339,6 +4339,7 @@ class TestGenerateFallbackConfig(CiTestCase):
-             "ethernets": {
-                 "eth0": {
-                     "dhcp4": True,
-+                    "dhcp6": True,
-                     "set-name": "eth0",
-                     "match": {
-                         "macaddress": "00:11:22:33:44:55",
-@@ -4423,6 +4424,9 @@ iface lo inet loopback
- 
- auto eth0
- iface eth0 inet dhcp
-+
-+# control-alias eth0
-+iface eth0 inet6 dhcp
- """
-         self.assertEqual(expected.lstrip(), contents.lstrip())
- 
-@@ -4512,6 +4516,9 @@ iface lo inet loopback
- 
- auto eth1
- iface eth1 inet dhcp
-+
-+# control-alias eth1
-+iface eth1 inet6 dhcp
- """
-         self.assertEqual(expected.lstrip(), contents.lstrip())
- 
-@@ -4736,7 +4743,9 @@ class TestRhelSysConfigRendering(CiTestCase):
- AUTOCONNECT_PRIORITY=120
- BOOTPROTO=dhcp
- DEVICE=eth1000
-+DHCPV6C=yes
- HWADDR=07-1c-c6-75-a4-be
-+IPV6INIT=yes
- ONBOOT=yes
- TYPE=Ethernet
- USERCTL=no
-@@ -5646,7 +5655,8 @@ class TestOpenSuseSysConfigRendering(CiTestCase):
-             expected_content = """
- # Created by cloud-init automatically, do not edit.
- #
--BOOTPROTO=dhcp4
-+BOOTPROTO=dhcp
-+DHCLIENT6_MODE=managed
- LLADDR=07-1c-c6-75-a4-be
- STARTMODE=auto
- """.lstrip()
-@@ -6032,7 +6042,11 @@ class TestNetworkManagerRendering(CiTestCase):
- 
-                 [ipv4]
-                 method=auto
--                may-fail=false
-+                may-fail=true
-+
-+                [ipv6]
-+                method=auto
-+                may-fail=true
- 
-                 """
-                 ),
-@@ -6298,6 +6312,9 @@ iface lo inet loopback
- 
- auto eth1000
- iface eth1000 inet dhcp
-+
-+# control-alias eth1000
-+iface eth1000 inet6 dhcp
- """
-         self.assertEqual(expected.lstrip(), contents.lstrip())
- 
-@@ -6357,6 +6374,7 @@ class TestNetplanNetRendering:
-                   ethernets:
-                     eth1000:
-                       dhcp4: true
-+                      dhcp6: true
-                       match:
-                         macaddress: 07-1c-c6-75-a4-be
-                       set-name: eth1000
-@@ -7856,7 +7874,7 @@ class TestNetworkdNetRendering(CiTestCase):
-             Name=eth1000
-             MACAddress=07-1c-c6-75-a4-be
-             [Network]
--            DHCP=ipv4"""
-+            DHCP=yes"""
-         ).rstrip(" ")
- 
-         expected = self.create_conf_dict(expected.splitlines())
diff --git a/SOURCES/0006-fix-don-t-deadlock-when-starting-network-service-wit.patch b/SOURCES/0006-fix-don-t-deadlock-when-starting-network-service-wit.patch
new file mode 100644
index 0000000..e9bb4f8
--- /dev/null
+++ b/SOURCES/0006-fix-don-t-deadlock-when-starting-network-service-wit.patch
@@ -0,0 +1,90 @@
+From 5d820c9e6025b46a6b4e443d9934ff83a8ad1afa Mon Sep 17 00:00:00 2001
+From: Brett Holman <brett.holman@canonical.com>
+Date: Tue, 17 Dec 2024 19:28:56 -0700
+Subject: [PATCH] fix: don't deadlock when starting network service with
+ systemctl (#5935)
+
+(cherry picked from commit bc26e15fd09b65a38ddd8cbafc5379cb19960d2b)
+Signed-off-by: Ani Sinha <anisinha@redhat.com>
+---
+ cloudinit/config/cc_set_passwords.py          | 20 ++++++++++++++++---
+ cloudinit/distros/__init__.py                 |  4 ++--
+ .../unittests/config/test_cc_set_passwords.py |  4 +++-
+ 3 files changed, 22 insertions(+), 6 deletions(-)
+
+diff --git a/cloudinit/config/cc_set_passwords.py b/cloudinit/config/cc_set_passwords.py
+index 8cb6a1ec5..22547d0fd 100644
+--- a/cloudinit/config/cc_set_passwords.py
++++ b/cloudinit/config/cc_set_passwords.py
+@@ -45,9 +45,9 @@ def get_users_by_type(users_list: list, pw_type: str) -> list:
+     )
+ 
+ 
+-def _restart_ssh_daemon(distro, service):
++def _restart_ssh_daemon(distro: Distro, service: str, *extra_args: str):
+     try:
+-        distro.manage_service("restart", service)
++        distro.manage_service("restart", service, *extra_args)
+         LOG.debug("Restarted the SSH daemon.")
+     except subp.ProcessExecutionError as e:
+         LOG.warning(
+@@ -104,7 +104,21 @@ def handle_ssh_pwauth(pw_auth, distro: Distro):
+             ]
+         ).stdout.strip()
+         if state.lower() in ["active", "activating", "reloading"]:
+-            _restart_ssh_daemon(distro, service)
++            # This module runs Before=sshd.service. What that means is that
++            # the code can only get to this point if a user manually starts the
++            # network stage. While this isn't a well-supported use-case, this
++            # does cause a deadlock if started via systemd directly:
++            # "systemctl start cloud-init.service". Prevent users from causing
++            # this deadlock by forcing systemd to ignore dependencies when
++            # restarting. Note that this deadlock is not possible in newer
++            # versions of cloud-init, since starting the second service doesn't
++            # run the second stage in 24.3+. This code therefore exists solely
++            # for backwards compatibility so that users who think that they
++            # need to manually start cloud-init (why?) with systemd (again,
++            # why?) can do so.
++            _restart_ssh_daemon(
++                distro, service, "--job-mode=ignore-dependencies"
++            )
+     else:
+         _restart_ssh_daemon(distro, service)
+ 
+diff --git a/cloudinit/distros/__init__.py b/cloudinit/distros/__init__.py
+index 183df368a..34c0836e8 100644
+--- a/cloudinit/distros/__init__.py
++++ b/cloudinit/distros/__init__.py
+@@ -142,7 +142,7 @@ class Distro(persistence.CloudInitPickleMixin, metaclass=abc.ABCMeta):
+     shadow_empty_locked_passwd_patterns = ["^{username}::", "^{username}:!:"]
+     tz_zone_dir = "/usr/share/zoneinfo"
+     default_owner = "root:root"
+-    init_cmd = ["service"]  # systemctl, service etc
++    init_cmd: List[str] = ["service"]  # systemctl, service etc
+     renderer_configs: Mapping[str, MutableMapping[str, Any]] = {}
+     _preferred_ntp_clients = None
+     networking_cls: Type[Networking] = LinuxNetworking
+@@ -1373,7 +1373,7 @@ class Distro(persistence.CloudInitPickleMixin, metaclass=abc.ABCMeta):
+                 "try-reload": [service, "restart"],
+                 "status": [service, "status"],
+             }
+-        cmd = list(init_cmd) + list(cmds[action])
++        cmd = init_cmd + cmds[action] + list(extra_args)
+         return subp.subp(cmd, capture=True, rcs=rcs)
+ 
+     def set_keymap(self, layout: str, model: str, variant: str, options: str):
+diff --git a/tests/unittests/config/test_cc_set_passwords.py b/tests/unittests/config/test_cc_set_passwords.py
+index c068f62d8..a706917d7 100644
+--- a/tests/unittests/config/test_cc_set_passwords.py
++++ b/tests/unittests/config/test_cc_set_passwords.py
+@@ -27,7 +27,9 @@ SYSTEMD_CHECK_CALL = mock.call(
+     ["systemctl", "show", "--property", "ActiveState", "--value", "ssh"]
+ )
+ SYSTEMD_RESTART_CALL = mock.call(
+-    ["systemctl", "restart", "ssh"], capture=True, rcs=None
++    ["systemctl", "restart", "ssh", "--job-mode=ignore-dependencies"],
++    capture=True,
++    rcs=None,
+ )
+ SERVICE_RESTART_CALL = mock.call(
+     ["service", "ssh", "restart"], capture=True, rcs=None
diff --git a/SOURCES/0006-net-nm-check-for-presence-of-ifcfg-files-when-nm-con.patch b/SOURCES/0006-net-nm-check-for-presence-of-ifcfg-files-when-nm-con.patch
deleted file mode 100644
index 40c2490..0000000
--- a/SOURCES/0006-net-nm-check-for-presence-of-ifcfg-files-when-nm-con.patch
+++ /dev/null
@@ -1,113 +0,0 @@
-From c0df864e373e1e34bf23c4869acdf7d20aea7aaf Mon Sep 17 00:00:00 2001
-From: Ani Sinha <anisinha@redhat.com>
-Date: Thu, 7 Dec 2023 02:39:51 +0530
-Subject: [PATCH] net/nm: check for presence of ifcfg files when nm connection
- files are absent (#4645)
-
-On systems that use network manager to manage connections and activate network
-interfaces, they may also use ifcfg files for configuring
-interfaces using ifcfg-rh network manager plugin. When network manager is used
-as the activator, we need to also check for the presence of ifcfg interface
-config file when the network manager connection file is absent and if ifcfg-rh
-plugin is present.
-Hence, with this change, network manager activator first tries to use network
-manager connection files to bring up or bring down the interface. If the
-connection files are not present and if ifcfg-rh plugin is present, it tries to
-use ifcfg files for the interface. If the plugin or the ifcfg files are not
-present, the activator fails to activate or deactivate the interface and it
-bails out with warning log.
-
-Fixes: GH-4640
-
-Signed-off-by: Ani Sinha <anisinha@redhat.com>
-(cherry picked from commit d1d5166895da471cff3606c70d4e8ab6eec1c006)
----
- cloudinit/net/activators.py      |  7 +++++++
- cloudinit/net/network_manager.py | 33 ++++++++++++++++++++++++++++++--
- 2 files changed, 38 insertions(+), 2 deletions(-)
-
-diff --git a/cloudinit/net/activators.py b/cloudinit/net/activators.py
-index e69da40d..dd858862 100644
---- a/cloudinit/net/activators.py
-+++ b/cloudinit/net/activators.py
-@@ -117,6 +117,13 @@ class NetworkManagerActivator(NetworkActivator):
-         from cloudinit.net.network_manager import conn_filename
- 
-         filename = conn_filename(device_name)
-+        if filename is None:
-+            LOG.warning(
-+                "Unable to find an interface config file. "
-+                "Unable to bring up interface."
-+            )
-+            return False
-+
-         cmd = ["nmcli", "connection", "load", filename]
-         if _alter_interface(cmd, device_name):
-             cmd = ["nmcli", "connection", "up", "filename", filename]
-diff --git a/cloudinit/net/network_manager.py b/cloudinit/net/network_manager.py
-index 8a99eb3a..76a0ac15 100644
---- a/cloudinit/net/network_manager.py
-+++ b/cloudinit/net/network_manager.py
-@@ -17,10 +17,12 @@ from typing import Optional
- from cloudinit import subp, util
- from cloudinit.net import is_ipv6_address, renderer, subnet_is_ipv6
- from cloudinit.net.network_state import NetworkState
-+from cloudinit.net.sysconfig import available_nm_ifcfg_rh
- 
- NM_RUN_DIR = "/etc/NetworkManager"
- NM_LIB_DIR = "/usr/lib/NetworkManager"
- NM_CFG_FILE = "/etc/NetworkManager/NetworkManager.conf"
-+IFCFG_CFG_FILE = "/etc/sysconfig/network-scripts"
- NM_IPV6_ADDR_GEN_CONF = """# This is generated by cloud-init. Do not edit.
- #
- [.config]
-@@ -442,7 +444,7 @@ class Renderer(renderer.Renderer):
-         for con_id, conn in self.connections.items():
-             if not conn.valid():
-                 continue
--            name = conn_filename(con_id, target)
-+            name = nm_conn_filename(con_id, target)
-             util.write_file(name, conn.dump(), 0o600)
- 
-         # Select EUI64 to be used by default by NM for creating the address
-@@ -452,12 +454,39 @@ class Renderer(renderer.Renderer):
-         )
- 
- 
--def conn_filename(con_id, target=None):
-+def nm_conn_filename(con_id, target=None):
-     target_con_dir = subp.target_path(target, NM_RUN_DIR)
-     con_file = f"cloud-init-{con_id}.nmconnection"
-     return f"{target_con_dir}/system-connections/{con_file}"
- 
- 
-+def sysconfig_conn_filename(devname, target=None):
-+    target_con_dir = subp.target_path(target, IFCFG_CFG_FILE)
-+    con_file = f"ifcfg-{devname}"
-+    return f"{target_con_dir}/{con_file}"
-+
-+
-+def conn_filename(devname):
-+    """
-+    This function returns the name of the interface config file.
-+    It first checks for presence of network manager connection file.
-+    If absent and ifcfg-rh plugin for network manager is available,
-+    it returns the name of the ifcfg file if it is present. If the
-+    plugin is not present or the plugin is present but ifcfg file is
-+    not, it returns None.
-+    This function is called from NetworkManagerActivator class in
-+    activators.py.
-+    """
-+    conn_file = nm_conn_filename(devname)
-+    # If the network manager connection file is absent, also check for
-+    # presence of ifcfg files for the same interface (if nm-ifcfg-rh plugin is
-+    # present, network manager can handle ifcfg files). If both network manager
-+    # connection file and ifcfg files are absent, return None.
-+    if not os.path.isfile(conn_file) and available_nm_ifcfg_rh():
-+        conn_file = sysconfig_conn_filename(devname)
-+    return conn_file if os.path.isfile(conn_file) else None
-+
-+
- def cloud_init_nm_conf_filename(target=None):
-     target_con_dir = subp.target_path(target, NM_RUN_DIR)
-     conf_file = "30-cloud-init-ip6-addr-gen-mode.conf"
diff --git a/SOURCES/0007-test-jsonschema-Pin-jsonschema-version-4781.patch b/SOURCES/0007-test-jsonschema-Pin-jsonschema-version-4781.patch
deleted file mode 100644
index ad7e5d6..0000000
--- a/SOURCES/0007-test-jsonschema-Pin-jsonschema-version-4781.patch
+++ /dev/null
@@ -1,38 +0,0 @@
-From e5258b60a3dbf44ef1faac91db2b45dab09de0b5 Mon Sep 17 00:00:00 2001
-From: Brett Holman <brett.holman@canonical.com>
-Date: Tue, 16 Jan 2024 12:43:17 -0700
-Subject: [PATCH] test(jsonschema): Pin jsonschema version (#4781)
-
-Release 4.21.0 broke tests
-
-(cherry picked from commit 034a5cdf10582da0492321f861b2b8b42182a54e)
----
- requirements.txt      | 2 +-
- test-requirements.txt | 2 +-
- 2 files changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/requirements.txt b/requirements.txt
-index edec46a7..a095de18 100644
---- a/requirements.txt
-+++ b/requirements.txt
-@@ -28,7 +28,7 @@ requests
- jsonpatch
- 
- # For validating cloud-config sections per schema definitions
--jsonschema
-+jsonschema<=4.20.0
- 
- # Used by DataSourceVMware to inspect the host's network configuration during
- # the "setup()" function.
-diff --git a/test-requirements.txt b/test-requirements.txt
-index 19488b94..46a98b4c 100644
---- a/test-requirements.txt
-+++ b/test-requirements.txt
-@@ -9,6 +9,6 @@ pytest!=7.3.2
- pytest-cov
- pytest-mock
- setuptools
--jsonschema
-+jsonschema<=4.20.0
- responses
- passlib
diff --git a/SOURCES/0008-fix-clean-stop-warning-when-running-clean-command-47.patch b/SOURCES/0008-fix-clean-stop-warning-when-running-clean-command-47.patch
deleted file mode 100644
index 72884d5..0000000
--- a/SOURCES/0008-fix-clean-stop-warning-when-running-clean-command-47.patch
+++ /dev/null
@@ -1,121 +0,0 @@
-From 9e8fbb736d5e8db8bcf0fbc35a76bdad9251990a Mon Sep 17 00:00:00 2001
-From: d1r3ct0r <calvin.mwadime@canonical.com>
-Date: Sat, 20 Jan 2024 02:11:47 +0300
-Subject: [PATCH] fix(clean): stop warning when running clean command (#4761)
-
-When the clean command is run, runparts is called and README in
-/etc/cloud/clean.d is not executable which leads to a warning.
-
-No longer deliver the README in our deb package, move content
-to our online docs. Continue to deliver the /etc/cloud/clean.d
-directory as it is used by installers like subiquity.
-
-Fixes: GH-4760
-(cherry picked from commit da08a260965e35fa63def1cd8b8b472f7c354ffe)
-
-There is a downstream only change that is squashed with the upstream commit.
-The spec file under .distro/ has been updated so as to not include
-/etc/cloud/clean.d/README file. Otherwise, we shall see errors like the
-following during the build process:
-
-error: File not found: /builddir/build/.../etc/cloud/clean.d/README
-
-After a rebase, we can only maintain the downstream spec file change as
-the rest of it is clean cherry-pick from upstream.
-
-X-downstream-only: true
-Signed-off-by: Ani Sinha <anisinha@redhat.com>
----
- config/clean.d/README              | 18 ------------------
- doc/rtd/reference/cli.rst          | 27 +++++++++++++++++++++++++++
- packages/redhat/cloud-init.spec.in |  1 -
- packages/suse/cloud-init.spec.in   |  1 -
- 4 files changed, 27 insertions(+), 20 deletions(-)
- delete mode 100644 config/clean.d/README
-
-diff --git a/config/clean.d/README b/config/clean.d/README
-deleted file mode 100644
-index 9b0feebe..00000000
---- a/config/clean.d/README
-+++ /dev/null
-@@ -1,18 +0,0 @@
---- cloud-init's clean.d run-parts directory --
--
--This directory is provided for third party applications which need
--additional configuration artifact cleanup from the filesystem when
--the command `cloud-init clean` is invoked.
--
--The `cloud-init clean` operation is typically performed by image creators
--when preparing a golden image for clone and redeployment. The clean command
--removes any cloud-init semaphores, allowing cloud-init to treat the next
--boot of this image as the "first boot". When the image is next booted
--cloud-init will performing all initial configuration based on any valid
--datasource meta-data and user-data.
--
--Any executable scripts in this subdirectory will be invoked in lexicographical
--order with run-parts by the command: sudo cloud-init clean.
--
--Typical format of such scripts would be a ##-<some-app> like the following:
--  /etc/cloud/clean.d/99-live-installer
-diff --git a/doc/rtd/reference/cli.rst b/doc/rtd/reference/cli.rst
-index 04e05c55..c36775a8 100644
---- a/doc/rtd/reference/cli.rst
-+++ b/doc/rtd/reference/cli.rst
-@@ -83,6 +83,33 @@ re-run all stages as it did on first boot.
-   config files for ssh daemon. Argument `network` removes all generated
-   config files for network. `all` removes config files of all types.
- 
-+.. note::
-+
-+   Cloud-init provides the directory :file:`/etc/cloud/clean.d/` for third party
-+   applications which need additional configuration artifact cleanup from
-+   the fileystem when the `clean` command is invoked.
-+
-+   The :command:`clean` operation is typically performed by image creators
-+   when preparing a golden image for clone and redeployment. The clean command
-+   removes any cloud-init semaphores, allowing cloud-init to treat the next
-+   boot of this image as the "first boot". When the image is next booted
-+   cloud-init will performing all initial configuration based on any valid
-+   datasource meta-data and user-data.
-+
-+   Any executable scripts in this subdirectory will be invoked in lexicographical
-+   order with run-parts when running the :command:`clean` command.
-+
-+   Typical format of such scripts would be a ##-<some-app> like the following:
-+   :file:`/etc/cloud/clean.d/99-live-installer`
-+
-+   An example of a script is:
-+
-+   .. code-block:: bash
-+
-+      sudo rm -rf /var/lib/installer_imgs/
-+      sudo rm -rf /var/log/installer/
-+
-+
- .. _cli_collect_logs:
- 
- :command:`collect-logs`
-diff --git a/packages/redhat/cloud-init.spec.in b/packages/redhat/cloud-init.spec.in
-index 97e95096..accfb1b6 100644
---- a/packages/redhat/cloud-init.spec.in
-+++ b/packages/redhat/cloud-init.spec.in
-@@ -190,7 +190,6 @@ fi
- # Configs
- %config(noreplace)      %{_sysconfdir}/cloud/cloud.cfg
- %dir                    %{_sysconfdir}/cloud/clean.d
--%config(noreplace)      %{_sysconfdir}/cloud/clean.d/README
- %dir                    %{_sysconfdir}/cloud/cloud.cfg.d
- %config(noreplace)      %{_sysconfdir}/cloud/cloud.cfg.d/*.cfg
- %config(noreplace)      %{_sysconfdir}/cloud/cloud.cfg.d/README
-diff --git a/packages/suse/cloud-init.spec.in b/packages/suse/cloud-init.spec.in
-index 62a9129b..fae3c12b 100644
---- a/packages/suse/cloud-init.spec.in
-+++ b/packages/suse/cloud-init.spec.in
-@@ -115,7 +115,6 @@ version_pys=$(cd "%{buildroot}" && find . -name version.py -type f)
- 
- # Configs
- %dir                    %{_sysconfdir}/cloud/clean.d
--%config(noreplace)      %{_sysconfdir}/cloud/clean.d/README
- %config(noreplace) %{_sysconfdir}/cloud/cloud.cfg
- %dir               %{_sysconfdir}/cloud/cloud.cfg.d
- %config(noreplace) %{_sysconfdir}/cloud/cloud.cfg.d/*.cfg
diff --git a/SOURCES/ci-Deprecate-the-users-ssh-authorized-keys-property-516.patch b/SOURCES/ci-Deprecate-the-users-ssh-authorized-keys-property-516.patch
deleted file mode 100644
index 6ded6b4..0000000
--- a/SOURCES/ci-Deprecate-the-users-ssh-authorized-keys-property-516.patch
+++ /dev/null
@@ -1,108 +0,0 @@
-From 808cd6f434a4ede1441cc1f5781abf59f53c4153 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Anders=20Bj=C3=B6rklund?= <anders.f.bjorklund@gmail.com>
-Date: Mon, 22 Apr 2024 17:52:44 +0200
-Subject: [PATCH 1/3] Deprecate the users ssh-authorized-keys property (#5162)
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-RH-Author: Ani Sinha <anisinha@redhat.com>
-RH-MergeRequest: 95: Deprecate the users ssh-authorized-keys property (#5162)
-RH-Jira: RHEL-45262
-RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
-RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
-RH-Commit: [1/3] 27d6f99519a28ae91037fe47f9ef654b7fbd6236 (anisinha/cloud-init)
-
-Deprecate the users ssh-authorized-keys property
-
-Signed-off-by: Anders F Björklund <anders.f.bjorklund@gmail.com>
-(cherry picked from commit 5205b4dd74eb2168ebbeba56579b6f116a272937)
----
- .../schemas/schema-cloud-config-v1.json       | 16 ++++++++++
- .../unittests/config/test_cc_users_groups.py  | 30 +++++++++++++++++++
- tools/.github-cla-signers                     |  1 +
- 3 files changed, 47 insertions(+)
-
-diff --git a/cloudinit/config/schemas/schema-cloud-config-v1.json b/cloudinit/config/schemas/schema-cloud-config-v1.json
-index 8b10fe70..670ef4c2 100644
---- a/cloudinit/config/schemas/schema-cloud-config-v1.json
-+++ b/cloudinit/config/schemas/schema-cloud-config-v1.json
-@@ -272,6 +272,22 @@
-           },
-           "minItems": 1
-         },
-+        "ssh-authorized-keys": {
-+          "allOf": [
-+            {
-+              "type": "array",
-+              "items": {
-+                "type": "string"
-+              },
-+              "minItems": 1
-+            },
-+            {
-+              "deprecated": true,
-+              "deprecated_version": "18.3",
-+              "deprecated_description": "Use ``ssh_authorized_keys`` instead."
-+            }
-+          ]
-+        },
-         "ssh_import_id": {
-           "description": "List of SSH IDs to import for user. Can not be combined with ``ssh_redirect_user``.",
-           "type": "array",
-diff --git a/tests/unittests/config/test_cc_users_groups.py b/tests/unittests/config/test_cc_users_groups.py
-index 3300b77b..53e231e1 100644
---- a/tests/unittests/config/test_cc_users_groups.py
-+++ b/tests/unittests/config/test_cc_users_groups.py
-@@ -503,6 +503,36 @@ class TestUsersGroupsSchema:
-                 ),
-                 True,
-             ),
-+            (
-+                {
-+                    "users": [
-+                        {
-+                            "name": "lima",
-+                            "uid": "1000",
-+                            "homedir": "/home/lima.linux",
-+                            "shell": "/bin/bash",
-+                            "sudo": "ALL=(ALL) NOPASSWD:ALL",
-+                            "lock_passwd": True,
-+                            "ssh-authorized-keys": ["ssh-ed25519 ..."],
-+                        }
-+                    ]
-+                },
-+                pytest.raises(
-+                    SchemaValidationError,
-+                    match=(
-+                        "Cloud config schema deprecations: "
-+                        "users.0.ssh-authorized-keys: "
-+                        " Deprecated in version 18.3."
-+                        " Use ``ssh_authorized_keys`` instead."
-+                        ", "
-+                        "users.0.uid: "
-+                        " Changed in version 22.3."
-+                        " The use of ``string`` type is deprecated."
-+                        " Use an ``integer`` instead."
-+                    ),
-+                ),
-+                False,
-+            ),
-         ],
-     )
-     @skipUnlessJsonSchema()
-diff --git a/tools/.github-cla-signers b/tools/.github-cla-signers
-index f4da0989..8b119025 100644
---- a/tools/.github-cla-signers
-+++ b/tools/.github-cla-signers
-@@ -3,6 +3,7 @@ aciba90
- acourdavAkamai
- ader1990
- adobley
-+afbjorklund
- ajmyyra
- akutz
- AlexBaranowski
--- 
-2.39.3
-
diff --git a/SOURCES/ci-Pin-pythes-8.0.0.patch b/SOURCES/ci-Pin-pythes-8.0.0.patch
deleted file mode 100644
index cdb8413..0000000
--- a/SOURCES/ci-Pin-pythes-8.0.0.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-From 7f3b0ff968409a880596e04aece4e4c504fb9c64 Mon Sep 17 00:00:00 2001
-From: Brett Holman <brett.holman@canonical.com>
-Date: Mon, 29 Jan 2024 12:03:36 -0700
-Subject: [PATCH] ci: Pin pytest<8.0.0. (#4816)
-
-The latest pytest release broke some tests in non-obvious ways. Pin
-the version for now so that CI passes.
-
-(cherry picked from commit 7c96c9cd9318e816ce4564b58a2c98271363c447)
-Signed-off-by: Ani Sinha <anisinha@redhat.com>
----
- integration-requirements.txt | 2 +-
- test-requirements.txt        | 2 +-
- 2 files changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/integration-requirements.txt b/integration-requirements.txt
-index 1f8b54a5..c0792d63 100644
---- a/integration-requirements.txt
-+++ b/integration-requirements.txt
-@@ -7,7 +7,7 @@ pycloudlib>=5.10.0,<1!6
- # test/unittests/conftest.py to be loaded by our integration-tests tox env
- # resulting in an unmet dependency issue:
- # https://github.com/pytest-dev/pytest/issues/11104
--pytest!=7.3.2
-+pytest!=7.3.2,<8.0.0
- 
- packaging
- passlib
-diff --git a/test-requirements.txt b/test-requirements.txt
-index 46a98b4c..3d2480fd 100644
---- a/test-requirements.txt
-+++ b/test-requirements.txt
-@@ -4,7 +4,7 @@
- # test/unittests/conftest.py to be loaded by our integration-tests tox env
- # resulting in an unmet dependency issue:
- # https://github.com/pytest-dev/pytest/issues/11104
--pytest!=7.3.2
-+pytest!=7.3.2,<8.0.0
- 
- pytest-cov
- pytest-mock
--- 
-2.39.3
-
diff --git a/SOURCES/ci-Retain-exit-code-in-cloud-init-status-for-recoverabl.patch b/SOURCES/ci-Retain-exit-code-in-cloud-init-status-for-recoverabl.patch
deleted file mode 100644
index dd63da2..0000000
--- a/SOURCES/ci-Retain-exit-code-in-cloud-init-status-for-recoverabl.patch
+++ /dev/null
@@ -1,65 +0,0 @@
-From cc31dc321ae35995ceff93e67aaf0b0c660aa890 Mon Sep 17 00:00:00 2001
-From: Ani Sinha <anisinha@redhat.com>
-Date: Tue, 12 Mar 2024 12:52:10 +0530
-Subject: [PATCH] Retain exit code in cloud-init status for recoverable errors
-
-RH-Author: Ani Sinha <None>
-RH-MergeRequest: 71: Retain exit code in cloud-init status for recoverable errors
-RH-Jira: RHEL-28549
-RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
-RH-Acked-by: Cathy Avery <cavery@redhat.com>
-RH-Commit: [1/1] 00934ade88c481c012bc1947fa44e5ed59f82858 (anisinha/cloud-init)
-
-Version 23.4 of cloud-init changed the status code reported by cloud-init for
-recoverable errors from 0 to 2. Please see the commit
-70acb7f2a30d58 ("Add support for cloud-init "degraded" state (#4500)")
-
-This change has the potential to break customers who are expecting a 0 status
-and where warnings can be expected. Hence, revert the status code from 2 to 0
-even in case of recoverable errors. This retains the old behavior and hence
-avoids breaking scripts and software stack that expects 0 on the end user side.
-
-Cannonical has made a similar change downstream for similar reasons. Please see
-https://bugs.launchpad.net/ubuntu/+source/cloud-init/+bug/2048522
-and the corresponding downstream patch:
-https://github.com/canonical/cloud-init/pull/4747/commits/adce34bfd214e4eecdf87329486f30f0898dd303
-
-This patch has limited risk as it narrowly only restores the old status
-code for recoverable errors and does not modify anything else.
-
-X-downstream-only: true
-Signed-off-by: Ani Sinha <anisinha@redhat.com>
----
- cloudinit/cmd/status.py            | 2 +-
- tests/unittests/cmd/test_status.py | 2 +-
- 2 files changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/cloudinit/cmd/status.py b/cloudinit/cmd/status.py
-index f5ee9c11..849c80bc 100644
---- a/cloudinit/cmd/status.py
-+++ b/cloudinit/cmd/status.py
-@@ -225,7 +225,7 @@ def handle_status_args(name, args) -> int:
-         return 1
-     # Recoverable error
-     elif details.status in UXAppStatusDegradedMap.values():
--        return 2
-+        return 0
-     return 0
- 
- 
-diff --git a/tests/unittests/cmd/test_status.py b/tests/unittests/cmd/test_status.py
-index 6c85a59a..567b517a 100644
---- a/tests/unittests/cmd/test_status.py
-+++ b/tests/unittests/cmd/test_status.py
-@@ -636,7 +636,7 @@ PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin
-                 },
-                 None,
-                 MyArgs(long=False, wait=False, format="json"),
--                2,
-+                0,
-                 {
-                     "boot_status_code": "enabled-by-kernel-cmdline",
-                     "datasource": "nocloud",
--- 
-2.39.3
-
diff --git a/SOURCES/ci-Revert-Use-grep-for-faster-parsing-of-cloud-config-i.patch b/SOURCES/ci-Revert-Use-grep-for-faster-parsing-of-cloud-config-i.patch
deleted file mode 100644
index 850913f..0000000
--- a/SOURCES/ci-Revert-Use-grep-for-faster-parsing-of-cloud-config-i.patch
+++ /dev/null
@@ -1,242 +0,0 @@
-From 72b2deeafd9276d15f20831f01b2f8c44616f33d Mon Sep 17 00:00:00 2001
-From: Brett Holman <brett.holman@canonical.com>
-Date: Tue, 23 Jan 2024 11:47:35 -0700
-Subject: [PATCH] Revert "Use grep for faster parsing of cloud config in
- ds-identify (#4327)"
-
-RH-Author: Ani Sinha <None>
-RH-MergeRequest: 67: Revert "Use grep for faster parsing of cloud config in ds-identify (#4327)"
-RH-Jira: RHEL-22255
-RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
-RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
-RH-Commit: [1/1] 5997598254cd16ea7f26d87212b0f09920fcdf50 (anisinha/cloud-init)
-
-This reverts commit 816e05d4830f5e789f1f85ef926e2849156bff3a.
-
-Reopens LP: 2030729
-Fixes GH-4794
-
-(cherry picked from commit 8ff94fe9493ad88344eb8bbf2f023c6ba2db5206)
-Signed-off-by: Ani Sinha <anisinha@redhat.com>
----
- tests/unittests/test_ds_identify.py | 146 +---------------------------
- tools/ds-identify                   |  31 +++---
- 2 files changed, 15 insertions(+), 162 deletions(-)
-
-diff --git a/tests/unittests/test_ds_identify.py b/tests/unittests/test_ds_identify.py
-index ca206fb5..ba0bf779 100644
---- a/tests/unittests/test_ds_identify.py
-+++ b/tests/unittests/test_ds_identify.py
-@@ -57,146 +57,6 @@ BLKID_UEFI_UBUNTU = [
- ]
- 
- 
--DEFAULT_CLOUD_CONFIG = """\
--# The top level settings are used as module
--# and base configuration.
--# A set of users which may be applied and/or used by various modules
--# when a 'default' entry is found it will reference the 'default_user'
--# from the distro configuration specified below
--users:
--   - default
--
--# If this is set, 'root' will not be able to ssh in and they
--# will get a message to login instead as the default $user
--disable_root: true
--
--# This will cause the set+update hostname module to not operate (if true)
--preserve_hostname: false
--
--# If you use datasource_list array, keep array items in a single line.
--# If you use multi line array, ds-identify script won't read array items.
--# Example datasource config
--# datasource:
--#    Ec2:
--#      metadata_urls: [ 'blah.com' ]
--#      timeout: 5 # (defaults to 50 seconds)
--#      max_wait: 10 # (defaults to 120 seconds)
--
--# The modules that run in the 'init' stage
--cloud_init_modules:
-- - migrator
-- - seed_random
-- - bootcmd
-- - write-files
-- - growpart
-- - resizefs
-- - disk_setup
-- - mounts
-- - set_hostname
-- - update_hostname
-- - update_etc_hosts
-- - ca-certs
-- - rsyslog
-- - users-groups
-- - ssh
--
--# The modules that run in the 'config' stage
--cloud_config_modules:
-- - wireguard
-- - snap
-- - ubuntu_autoinstall
-- - ssh-import-id
-- - keyboard
-- - locale
-- - set-passwords
-- - grub-dpkg
-- - apt-pipelining
-- - apt-configure
-- - ubuntu-advantage
-- - ntp
-- - timezone
-- - disable-ec2-metadata
-- - runcmd
-- - byobu
--
--# The modules that run in the 'final' stage
--cloud_final_modules:
-- - package-update-upgrade-install
-- - fan
-- - landscape
-- - lxd
-- - ubuntu-drivers
-- - write-files-deferred
-- - puppet
-- - chef
-- - ansible
-- - mcollective
-- - salt-minion
-- - reset_rmc
-- - refresh_rmc_and_interface
-- - rightscale_userdata
-- - scripts-vendor
-- - scripts-per-once
-- - scripts-per-boot
-- - scripts-per-instance
-- - scripts-user
-- - ssh-authkey-fingerprints
-- - keys-to-console
-- - install-hotplug
-- - phone-home
-- - final-message
-- - power-state-change
--
--# System and/or distro specific settings
--# (not accessible to handlers/transforms)
--system_info:
--   # This will affect which distro class gets used
--   distro: ubuntu
--   # Default user name + that default users groups (if added/used)
--   default_user:
--     name: ubuntu
--     lock_passwd: True
--     gecos: Ubuntu
--     groups: [adm, audio, cdrom, floppy, lxd, netdev, plugdev, sudo, video]
--     sudo: ["ALL=(ALL) NOPASSWD:ALL"]
--     shell: /bin/bash
--   network:
--     renderers: ['netplan', 'eni', 'sysconfig']
--     activators: ['netplan', 'eni', 'network-manager', 'networkd']
--   # Automatically discover the best ntp_client
--   ntp_client: auto
--   # Other config here will be given to the distro class and/or path classes
--   paths:
--      cloud_dir: /var/lib/cloud/
--      templates_dir: /etc/cloud/templates/
--   package_mirrors:
--     - arches: [i386, amd64]
--       failsafe:
--         primary: http://archive.ubuntu.com/ubuntu
--         security: http://security.ubuntu.com/ubuntu
--       search:
--         primary:
--           - http://%(ec2_region)s.ec2.archive.ubuntu.com/ubuntu/
--           - http://%(availability_zone)s.clouds.archive.ubuntu.com/ubuntu/
--           - http://%(region)s.clouds.archive.ubuntu.com/ubuntu/
--         security: []
--     - arches: [arm64, armel, armhf]
--       failsafe:
--         primary: http://ports.ubuntu.com/ubuntu-ports
--         security: http://ports.ubuntu.com/ubuntu-ports
--       search:
--         primary:
--           - http://%(ec2_region)s.ec2.ports.ubuntu.com/ubuntu-ports/
--           - http://%(availability_zone)s.clouds.ports.ubuntu.com/ubuntu-ports/
--           - http://%(region)s.clouds.ports.ubuntu.com/ubuntu-ports/
--         security: []
--     - arches: [default]
--       failsafe:
--         primary: http://ports.ubuntu.com/ubuntu-ports
--         security: http://ports.ubuntu.com/ubuntu-ports
--   ssh_svcname: ssh
--"""
--
- POLICY_FOUND_ONLY = "search,found=all,maybe=none,notfound=disabled"
- POLICY_FOUND_OR_MAYBE = "search,found=all,maybe=all,notfound=disabled"
- DI_DEFAULT_POLICY = "search,found=all,maybe=all,notfound=disabled"
-@@ -279,10 +139,6 @@ class DsIdentifyBase(CiTestCase):
-         if files is None:
-             files = {}
- 
--        cloudcfg = "etc/cloud/cloud.cfg"
--        if cloudcfg not in files:
--            files[cloudcfg] = DEFAULT_CLOUD_CONFIG
--
-         if rootd is None:
-             rootd = self.tmp_dir()
- 
-@@ -1305,7 +1161,7 @@ VALID_CFG = {
-             # Also include a datasource list of more than just
-             # [NoCloud, None], because that would automatically select
-             # NoCloud without checking
--            "etc/cloud/cloud.cfg": dedent(
-+            "/etc/cloud/cloud.cfg": dedent(
-                 """\
-                 datasource_list: [ Azure, Openstack, NoCloud, None ]
-                 datasource:
-diff --git a/tools/ds-identify b/tools/ds-identify
-index 7a537278..ec2cc18a 100755
---- a/tools/ds-identify
-+++ b/tools/ds-identify
-@@ -777,24 +777,21 @@ check_config() {
-     if [ "$1" = "$files" -a ! -f "$1" ]; then
-         return 1
-     fi
--    local line="" ret="" found=0 found_fn="" oifs="$IFS" out=""
--    out=$(grep "$key\"\?:" "$@" 2>/dev/null)
--    IFS=${CR}
--    for line in $out; do
--        # drop '# comment'
--        line=${line%%#*}
--        # if more than one file was 'grep'ed, then grep will output filename:
--        # but if only one file, line will not be prefixed.
--        if [ $# -eq 1 ]; then
--            found_fn="$1"
--        else
--            found_fn="${line%%:*}"
--            line=${line#*:}
--        fi
--        ret=${line#*: };
--        found=$((found+1))
-+    local fname="" line="" ret="" found=0 found_fn=""
-+    # shellcheck disable=2094
-+    for fname in "$@"; do
-+        [ -f "$fname" ] || continue
-+        while read line; do
-+            line=${line%%#*}
-+            case "$line" in
-+                $key:\ *|"${key}":)
-+                    ret=${line#*:};
-+                    ret=${ret# };
-+                    found=$((found+1))
-+                    found_fn="$fname";;
-+            esac
-+        done <"$fname"
-     done
--    IFS="$oifs"
-     if [ $found -ne 0 ]; then
-         _RET="$ret"
-         _RET_fname="$found_fn"
--- 
-2.39.3
-
diff --git a/SOURCES/ci-Revert-fix-vmware-Set-IPv6-to-dhcp-when-there-is-no-.patch b/SOURCES/ci-Revert-fix-vmware-Set-IPv6-to-dhcp-when-there-is-no-.patch
deleted file mode 100644
index a70513b..0000000
--- a/SOURCES/ci-Revert-fix-vmware-Set-IPv6-to-dhcp-when-there-is-no-.patch
+++ /dev/null
@@ -1,190 +0,0 @@
-From 87db4f8680222d2579d0ffb5fe507231f88d8aa5 Mon Sep 17 00:00:00 2001
-From: PengpengSun <40026211+PengpengSun@users.noreply.github.com>
-Date: Sat, 10 Aug 2024 03:32:40 +0800
-Subject: [PATCH] Revert "fix(vmware): Set IPv6 to dhcp when there is no IPv6
- addr (#5471)" (#5596)
-
-RH-Author: xiachen <xiachen@redhat.com>
-RH-MergeRequest: 108: Revert "fix(vmware): Set IPv6 to dhcp when there is no IPv6 addr (#5471)" (#5596)
-RH-Jira: RHEL-54373
-RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
-RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
-RH-Commit: [1/1] 96cccfca3d29c95d9c491d5995b7aa96adec4621 (xiachen/cloud-init-centos)
-
-This reverts commit 2b6fe6403db769de14f7c7b7e4aa65f5bea8f3e0.
-
-When there is no IPv6 set to dhcp explicitly, NetworkManager keyfile
-defaults to method=auto, may-fail=true. When there is Ipv6 set to dhcp
-explictily, NetworkManager keyfile will be set to
-method=auto, may-fail=false. The default settings are what we want, so
-revert the previous change to keep IPv6 not set explicitly.
-
-(cherry picked from commit 65014b97420b41dcb6e7ea17c66bb2539f9b09fc)
-Signed-off-by: Amy Chen <xiachen@redhat.com>
----
- .../sources/helpers/vmware/imc/config_nic.py  |  2 +-
- .../sources/vmware/test_vmware_config_file.py | 68 +++++--------------
- 2 files changed, 18 insertions(+), 52 deletions(-)
-
-diff --git a/cloudinit/sources/helpers/vmware/imc/config_nic.py b/cloudinit/sources/helpers/vmware/imc/config_nic.py
-index 254518af..b07214a2 100644
---- a/cloudinit/sources/helpers/vmware/imc/config_nic.py
-+++ b/cloudinit/sources/helpers/vmware/imc/config_nic.py
-@@ -207,7 +207,7 @@ class NicConfigurator:
-         """
- 
-         if not nic.staticIpv6:
--            return ([{"type": "dhcp6"}], [])
-+            return ([], [])
- 
-         subnet_list = []
-         # Static Ipv6
-diff --git a/tests/unittests/sources/vmware/test_vmware_config_file.py b/tests/unittests/sources/vmware/test_vmware_config_file.py
-index 25d3b093..b53ea96c 100644
---- a/tests/unittests/sources/vmware/test_vmware_config_file.py
-+++ b/tests/unittests/sources/vmware/test_vmware_config_file.py
-@@ -240,45 +240,27 @@ class TestVmwareConfigFile(CiTestCase):
-             elif cfg.get("name") == nic2.get("name"):
-                 nic2.update(cfg)
- 
--        # Test NIC1
-         self.assertEqual("physical", nic1.get("type"), "type of NIC1")
-         self.assertEqual("NIC1", nic1.get("name"), "name of NIC1")
-         self.assertEqual(
-             "00:50:56:a6:8c:08", nic1.get("mac_address"), "mac address of NIC1"
-         )
-         subnets = nic1.get("subnets")
--        self.assertEqual(2, len(subnets), "number of subnets for NIC1")
--        subnet_ipv4 = subnets[0]
--        self.assertEqual(
--            "dhcp", subnet_ipv4.get("type"), "Ipv4 DHCP type for NIC1"
--        )
--        self.assertEqual(
--            "auto", subnet_ipv4.get("control"), "NIC1 Control type"
--        )
--        subnet_ipv6 = subnets[1]
--        self.assertEqual(
--            "dhcp6", subnet_ipv6.get("type"), "Ipv6 DHCP type for NIC1"
--        )
-+        self.assertEqual(1, len(subnets), "number of subnets for NIC1")
-+        subnet = subnets[0]
-+        self.assertEqual("dhcp", subnet.get("type"), "DHCP type for NIC1")
-+        self.assertEqual("auto", subnet.get("control"), "NIC1 Control type")
- 
--        # Test NIC2
-         self.assertEqual("physical", nic2.get("type"), "type of NIC2")
-         self.assertEqual("NIC2", nic2.get("name"), "name of NIC2")
-         self.assertEqual(
-             "00:50:56:a6:5a:de", nic2.get("mac_address"), "mac address of NIC2"
-         )
-         subnets = nic2.get("subnets")
--        self.assertEqual(2, len(subnets), "number of subnets for NIC2")
--        subnet_ipv4 = subnets[0]
--        self.assertEqual(
--            "dhcp", subnet_ipv4.get("type"), "Ipv4 DHCP type for NIC2"
--        )
--        self.assertEqual(
--            "auto", subnet_ipv4.get("control"), "NIC2 Control type"
--        )
--        subnet_ipv6 = subnets[1]
--        self.assertEqual(
--            "dhcp6", subnet_ipv6.get("type"), "Ipv6 DHCP type for NIC2"
--        )
-+        self.assertEqual(1, len(subnets), "number of subnets for NIC2")
-+        subnet = subnets[0]
-+        self.assertEqual("dhcp", subnet.get("type"), "DHCP type for NIC2")
-+        self.assertEqual("auto", subnet.get("control"), "NIC2 Control type")
- 
-     def test_get_nics_list_static(self):
-         """Tests if NicConfigurator properly calculates network subnets
-@@ -303,7 +285,6 @@ class TestVmwareConfigFile(CiTestCase):
-                 elif cfg.get("name") == nic2.get("name"):
-                     nic2.update(cfg)
- 
--        # Test NIC1
-         self.assertEqual("physical", nic1.get("type"), "type of NIC1")
-         self.assertEqual("NIC1", nic1.get("name"), "name of NIC1")
-         self.assertEqual(
-@@ -363,7 +344,6 @@ class TestVmwareConfigFile(CiTestCase):
-             else:
-                 self.assertEqual(True, False, "invalid gateway %s" % (gateway))
- 
--        # Test NIC2
-         self.assertEqual("physical", nic2.get("type"), "type of NIC2")
-         self.assertEqual("NIC2", nic2.get("name"), "name of NIC2")
-         self.assertEqual(
-@@ -371,18 +351,16 @@ class TestVmwareConfigFile(CiTestCase):
-         )
- 
-         subnets = nic2.get("subnets")
--        self.assertEqual(2, len(subnets), "Number of subnets for NIC2")
-+        self.assertEqual(1, len(subnets), "Number of subnets for NIC2")
- 
--        subnet_ipv4 = subnets[0]
--        self.assertEqual("static", subnet_ipv4.get("type"), "Subnet type")
-+        subnet = subnets[0]
-+        self.assertEqual("static", subnet.get("type"), "Subnet type")
-         self.assertEqual(
--            "192.168.6.102", subnet_ipv4.get("address"), "Subnet address"
-+            "192.168.6.102", subnet.get("address"), "Subnet address"
-         )
-         self.assertEqual(
--            "255.255.0.0", subnet_ipv4.get("netmask"), "Subnet netmask"
-+            "255.255.0.0", subnet.get("netmask"), "Subnet netmask"
-         )
--        subnet_ipv6 = subnets[1]
--        self.assertEqual("dhcp6", subnet_ipv6.get("type"), "Subnet type")
- 
-     def test_custom_script(self):
-         cf = ConfigFile("tests/data/vmware/cust-dhcp-2nic.cfg")
-@@ -469,10 +447,7 @@ class TestVmwareNetConfig(CiTestCase):
-                             "type": "static",
-                             "address": "10.20.87.154",
-                             "netmask": "255.255.252.0",
--                        },
--                        {
--                            "type": "dhcp6",
--                        },
-+                        }
-                     ],
-                 }
-             ],
-@@ -523,10 +498,7 @@ class TestVmwareNetConfig(CiTestCase):
-                                     "metric": 10000,
-                                 }
-                             ],
--                        },
--                        {
--                            "type": "dhcp6",
--                        },
-+                        }
-                     ],
-                 }
-             ],
-@@ -586,10 +558,7 @@ class TestVmwareNetConfig(CiTestCase):
-                                     "metric": 10000,
-                                 }
-                             ],
--                        },
--                        {
--                            "type": "dhcp6",
--                        },
-+                        }
-                     ],
-                 }
-             ],
-@@ -634,10 +603,7 @@ class TestVmwareNetConfig(CiTestCase):
-                             "address": "10.20.87.154",
-                             "netmask": "255.255.252.0",
-                             "gateway": "10.20.87.253",
--                        },
--                        {
--                            "type": "dhcp6",
--                        },
-+                        }
-                     ],
-                 }
-             ],
--- 
-2.39.3
-
diff --git a/SOURCES/ci-Support-metalink-in-yum-repository-config-5444.patch b/SOURCES/ci-Support-metalink-in-yum-repository-config-5444.patch
deleted file mode 100644
index c6a30a7..0000000
--- a/SOURCES/ci-Support-metalink-in-yum-repository-config-5444.patch
+++ /dev/null
@@ -1,140 +0,0 @@
-From 96b10adc942f5117e35584d28ba88071849e8e29 Mon Sep 17 00:00:00 2001
-From: Ani Sinha <anisinha@redhat.com>
-Date: Thu, 27 Jun 2024 18:38:22 +0530
-Subject: [PATCH 1/2] Support metalink in yum repository config (#5444)
-
-RH-Author: xiachen <xiachen@redhat.com>
-RH-MergeRequest: 97: Support metalink in yum repository config (#5444)
-RH-Jira: RHEL-44916
-RH-Acked-by: Ani Sinha <anisinha@redhat.com>
-RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
-RH-Commit: [1/1] 4671fd3a3f6842f1f590d5a89a429facd0d8bb4d (xiachen/cloud-init-centos)
-
-'metalink' config can be specified instead or along with 'baseurl' in the yum
-repository config. Add support for specifying metalink instead of 'baseurl'.
-
-Fixes GH-5359
-
-Signed-off-by: Ani Sinha <anisinha@redhat.com>
-Co-authored-by: Ben Gray <ben.gray@clearcapital.com>
-(cherry picked from commit 525026061404ef09baebb85631d9af3b0a4d8930)
----
- cloudinit/config/cc_yum_add_repo.py           | 24 ++++++------
- doc/examples/cloud-config-yum-repo.txt        |  3 +-
- .../unittests/config/test_cc_yum_add_repo.py  | 38 +++++++++++++++++++
- 3 files changed, 51 insertions(+), 14 deletions(-)
-
-diff --git a/cloudinit/config/cc_yum_add_repo.py b/cloudinit/config/cc_yum_add_repo.py
-index 1ab5008f..4fd66250 100644
---- a/cloudinit/config/cc_yum_add_repo.py
-+++ b/cloudinit/config/cc_yum_add_repo.py
-@@ -210,24 +210,22 @@ def handle(name: str, cfg: Config, cloud: Cloud, args: list) -> None:
-                 n_repo_config[k] = v
-         repo_config = n_repo_config
-         missing_required = 0
--        for req_field in ["baseurl"]:
-+        req_fields = ["baseurl", "metalink"]
-+        for req_field in req_fields:
-             if req_field not in repo_config:
--                LOG.warning(
--                    "Repository %s does not contain a %s"
--                    " configuration 'required' entry",
--                    repo_id,
--                    req_field,
--                )
-                 missing_required += 1
--        if not missing_required:
--            repo_configs[canon_repo_id] = repo_config
--            repo_locations[canon_repo_id] = repo_fn_pth
--        else:
-+
-+        if missing_required == len(req_fields):
-             LOG.warning(
--                "Repository %s is missing %s required fields, skipping!",
-+                "Repository %s should contain atleast one of the"
-+                " following configuration entries: %s, skipping!",
-                 repo_id,
--                missing_required,
-+                ", ".join(req_fields),
-             )
-+        else:
-+            repo_configs[canon_repo_id] = repo_config
-+            repo_locations[canon_repo_id] = repo_fn_pth
-+
-     for (c_repo_id, path) in repo_locations.items():
-         repo_blob = _format_repository_config(
-             c_repo_id, repo_configs.get(c_repo_id)
-diff --git a/doc/examples/cloud-config-yum-repo.txt b/doc/examples/cloud-config-yum-repo.txt
-index e8f2bbb4..6a4037e2 100644
---- a/doc/examples/cloud-config-yum-repo.txt
-+++ b/doc/examples/cloud-config-yum-repo.txt
-@@ -11,8 +11,9 @@ yum_repos:
-     # Any repository configuration options
-     # See: man yum.conf
-     #
--    # This one is required!
-+    # At least one of 'baseurl' or 'metalink' is required!
-     baseurl: http://download.fedoraproject.org/pub/epel/testing/5/$basearch
-+    metalink: https://mirrors.fedoraproject.org/metalink?repo=epel-$releasever&arch=$basearch&infra=$infra&content=$contentdir
-     enabled: false
-     failovermethod: priority
-     gpgcheck: true
-diff --git a/tests/unittests/config/test_cc_yum_add_repo.py b/tests/unittests/config/test_cc_yum_add_repo.py
-index d2c2912f..1f27d1fb 100644
---- a/tests/unittests/config/test_cc_yum_add_repo.py
-+++ b/tests/unittests/config/test_cc_yum_add_repo.py
-@@ -31,6 +31,7 @@ class TestConfig(helpers.FilesystemMockingTestCase):
-             "yum_repos": {
-                 "epel-testing": {
-                     "name": "Extra Packages for Enterprise Linux 5 - Testing",
-+                    # At least one of baseurl or metalink must be present.
-                     # Missing this should cause the repo not to be written
-                     # 'baseurl': 'http://blah.org/pub/epel/testing/5/$barch',
-                     "enabled": False,
-@@ -46,6 +47,43 @@ class TestConfig(helpers.FilesystemMockingTestCase):
-             IOError, util.load_file, "/etc/yum.repos.d/epel_testing.repo"
-         )
- 
-+    def test_metalink_config(self):
-+        cfg = {
-+            "yum_repos": {
-+                "epel-testing": {
-+                    "name": "Extra Packages for Enterprise Linux 5 - Testing",
-+                    "metalink": "http://blah.org/pub/epel/testing/5/$basearch",
-+                    "enabled": False,
-+                    "gpgcheck": True,
-+                    "gpgkey": "file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL",
-+                    "failovermethod": "priority",
-+                },
-+            },
-+        }
-+        self.patchUtils(self.tmp)
-+        self.patchOS(self.tmp)
-+        cc_yum_add_repo.handle("yum_add_repo", cfg, None, [])
-+        contents = util.load_file("/etc/yum.repos.d/epel-testing.repo")
-+        parser = configparser.ConfigParser()
-+        parser.read_string(contents)
-+        expected = {
-+            "epel-testing": {
-+                "name": "Extra Packages for Enterprise Linux 5 - Testing",
-+                "failovermethod": "priority",
-+                "gpgkey": "file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL",
-+                "enabled": "0",
-+                "metalink": "http://blah.org/pub/epel/testing/5/$basearch",
-+                "gpgcheck": "1",
-+            }
-+        }
-+        for section in expected:
-+            self.assertTrue(
-+                parser.has_section(section),
-+                "Contains section {0}".format(section),
-+            )
-+            for k, v in expected[section].items():
-+                self.assertEqual(parser.get(section, k), v)
-+
-     def test_write_config(self):
-         cfg = {
-             "yum_repos": {
--- 
-2.39.3
-
diff --git a/SOURCES/ci-Support-setting-mirrorlist-in-yum-repository-config-.patch b/SOURCES/ci-Support-setting-mirrorlist-in-yum-repository-config-.patch
deleted file mode 100644
index ec67a9d..0000000
--- a/SOURCES/ci-Support-setting-mirrorlist-in-yum-repository-config-.patch
+++ /dev/null
@@ -1,145 +0,0 @@
-From d27ac077dac3474fea3c7bb1a19afe50ecbcc64d Mon Sep 17 00:00:00 2001
-From: Ani Sinha <anisinha@redhat.com>
-Date: Thu, 18 Jul 2024 13:36:39 +0530
-Subject: [PATCH 2/2] Support setting mirrorlist in yum repository config
- (#5522)
-
-RH-Author: xiachen <xiachen@redhat.com>
-RH-MergeRequest: 104: Support setting mirrorlist in yum repository config (#5522)
-RH-Jira: RHEL-49674
-RH-Acked-by: Ani Sinha <anisinha@redhat.com>
-RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
-RH-Commit: [1/1] 4605a0304c6bed6614990b7194465230afa79778 (xiachen/cloud-init-centos)
-
-'mirrorlist' config can be specified instead or along with 'baseurl' in the yum
-repository config. Add support for specifying mirrorlist instead of 'baseurl'.
-
-Fixes GH-5520
-Signed-off-by: Ani Sinha <anisinha@redhat.com>
-(cherry picked from commit 0b4084374440d2a5a9968129e0460a1a009d9830)
-Signed-off-by: Amy Chen <xiachen@redhat.com>
----
- cloudinit/config/cc_yum_add_repo.py           |  2 +-
- .../schemas/schema-cloud-config-v1.json       | 10 +++++
- doc/examples/cloud-config-yum-repo.txt        |  3 +-
- .../unittests/config/test_cc_yum_add_repo.py  | 40 ++++++++++++++++++-
- 4 files changed, 52 insertions(+), 3 deletions(-)
-
-diff --git a/cloudinit/config/cc_yum_add_repo.py b/cloudinit/config/cc_yum_add_repo.py
-index 4fd66250..3870d24e 100644
---- a/cloudinit/config/cc_yum_add_repo.py
-+++ b/cloudinit/config/cc_yum_add_repo.py
-@@ -210,7 +210,7 @@ def handle(name: str, cfg: Config, cloud: Cloud, args: list) -> None:
-                 n_repo_config[k] = v
-         repo_config = n_repo_config
-         missing_required = 0
--        req_fields = ["baseurl", "metalink"]
-+        req_fields = ["baseurl", "metalink", "mirrorlist"]
-         for req_field in req_fields:
-             if req_field not in repo_config:
-                 missing_required += 1
-diff --git a/cloudinit/config/schemas/schema-cloud-config-v1.json b/cloudinit/config/schemas/schema-cloud-config-v1.json
-index 4fb7fd93..c5f46f37 100644
---- a/cloudinit/config/schemas/schema-cloud-config-v1.json
-+++ b/cloudinit/config/schemas/schema-cloud-config-v1.json
-@@ -3447,6 +3447,11 @@
-                   "format": "uri",
-                   "description": "Specifies a URL to a metalink file for the repomd.xml"
-                 },
-+                "mirrorlist": {
-+                  "type": "string",
-+                  "format": "uri",
-+                  "description": "Specifies a URL to a file containing a baseurls list"
-+                },
-                 "name": {
-                   "type": "string",
-                   "description": "Optional human-readable name of the yum repo."
-@@ -3484,6 +3489,11 @@
-                   "required": [
-                     "metalink"
-                   ]
-+                },
-+                {
-+                  "required": [
-+                    "mirrorlist"
-+                  ]
-                 }
-               ]
-             }
-diff --git a/doc/examples/cloud-config-yum-repo.txt b/doc/examples/cloud-config-yum-repo.txt
-index 6a4037e2..cee26677 100644
---- a/doc/examples/cloud-config-yum-repo.txt
-+++ b/doc/examples/cloud-config-yum-repo.txt
-@@ -11,9 +11,10 @@ yum_repos:
-     # Any repository configuration options
-     # See: man yum.conf
-     #
--    # At least one of 'baseurl' or 'metalink' is required!
-+    # At least one of 'baseurl' or 'metalink' or 'mirrorlist' is required!
-     baseurl: http://download.fedoraproject.org/pub/epel/testing/5/$basearch
-     metalink: https://mirrors.fedoraproject.org/metalink?repo=epel-$releasever&arch=$basearch&infra=$infra&content=$contentdir
-+    mirrorlist: https://mirrors.fedoraproject.org/metalink?repo=fedora-$releasever&
-     enabled: false
-     failovermethod: priority
-     gpgcheck: true
-diff --git a/tests/unittests/config/test_cc_yum_add_repo.py b/tests/unittests/config/test_cc_yum_add_repo.py
-index 1f27d1fb..000792b4 100644
---- a/tests/unittests/config/test_cc_yum_add_repo.py
-+++ b/tests/unittests/config/test_cc_yum_add_repo.py
-@@ -31,7 +31,8 @@ class TestConfig(helpers.FilesystemMockingTestCase):
-             "yum_repos": {
-                 "epel-testing": {
-                     "name": "Extra Packages for Enterprise Linux 5 - Testing",
--                    # At least one of baseurl or metalink must be present.
-+                    # At least one of baseurl or metalink or mirrorlist
-+                    # must be present.
-                     # Missing this should cause the repo not to be written
-                     # 'baseurl': 'http://blah.org/pub/epel/testing/5/$barch',
-                     "enabled": False,
-@@ -84,6 +85,43 @@ class TestConfig(helpers.FilesystemMockingTestCase):
-             for k, v in expected[section].items():
-                 self.assertEqual(parser.get(section, k), v)
- 
-+    def test_mirrorlist_config(self):
-+        cfg = {
-+            "yum_repos": {
-+                "epel-testing": {
-+                    "name": "Extra Packages for Enterprise Linux 5 - Testing",
-+                    "mirrorlist": "http://mirrors.blah.org/metalink?repo=rhel-$releasever",
-+                    "enabled": False,
-+                    "gpgcheck": True,
-+                    "gpgkey": "file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL",
-+                    "failovermethod": "priority",
-+                },
-+            },
-+        }
-+        self.patchUtils(self.tmp)
-+        self.patchOS(self.tmp)
-+        cc_yum_add_repo.handle("yum_add_repo", cfg, None, [])
-+        contents = util.load_file("/etc/yum.repos.d/epel-testing.repo")
-+        parser = configparser.ConfigParser()
-+        parser.read_string(contents)
-+        expected = {
-+            "epel-testing": {
-+                "name": "Extra Packages for Enterprise Linux 5 - Testing",
-+                "failovermethod": "priority",
-+                "gpgkey": "file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL",
-+                "enabled": "0",
-+                "mirrorlist": "http://mirrors.blah.org/metalink?repo=rhel-$releasever",
-+                "gpgcheck": "1",
-+            }
-+        }
-+        for section in expected:
-+            self.assertTrue(
-+                parser.has_section(section),
-+                "Contains section {0}".format(section),
-+            )
-+            for k, v in expected[section].items():
-+                self.assertEqual(parser.get(section, k), v)
-+
-     def test_write_config(self):
-         cfg = {
-             "yum_repos": {
--- 
-2.39.3
-
diff --git a/SOURCES/ci-Update-pylint-version-to-support-python-3.12-5338.patch b/SOURCES/ci-Update-pylint-version-to-support-python-3.12-5338.patch
deleted file mode 100644
index a9154e9..0000000
--- a/SOURCES/ci-Update-pylint-version-to-support-python-3.12-5338.patch
+++ /dev/null
@@ -1,235 +0,0 @@
-From c34f5c4275c3ef7bee9a99e87bf6e37c5886b160 Mon Sep 17 00:00:00 2001
-From: Ani Sinha <anisinha@redhat.com>
-Date: Wed, 29 May 2024 03:34:38 +0530
-Subject: [PATCH 6/6] Update pylint version to support python 3.12 (#5338)
-
-RH-Author: Ani Sinha <anisinha@redhat.com>
-RH-MergeRequest: 92: Update pylint version to support python 3.12
-RH-Jira: RHEL-44598
-RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
-RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
-RH-Commit: [3/3] d6185e0a126e1589260ee59709fe933b5a780b78 (anisinha/cloud-init)
-
-Fedora 39 and above comes with python version 3.12. When running `tox -e pylint`
-on cloud-init, we may experience issue such as the one reported here:
-https://github.com/pylint-dev/pylint/issues/8782
-
-Minimum version of pylint required in order to support python 3.12 is 3.0.2.
-Please see https://github.com/pylint-dev/astroid/issues/2201 . Upon further
-experimentation, it is seen that we need minimum pylint version 3.2.0 for
-cloud-init. Update tox.ini in order to use this pylint version.
-
-Signed-off-by: Ani Sinha <anisinha@redhat.com>
-(cherry picked from commit 5ad609ffdf4bb76c5665e12e34e1867b72bd4435)
-
- Conflicts:
-	cloudinit/sources/DataSourceWSL.py (does not exist)
-	cloudinit/util.py (doc added upstream)
----
- cloudinit/config/cc_mounts.py         | 4 ++++
- cloudinit/distros/bsd.py              | 2 ++
- cloudinit/distros/netbsd.py           | 2 +-
- cloudinit/sources/DataSourceAzure.py  | 2 +-
- cloudinit/sources/DataSourceEc2.py    | 3 ++-
- cloudinit/sources/DataSourceLXD.py    | 2 +-
- tests/integration_tests/conftest.py   | 6 +++---
- tests/integration_tests/util.py       | 2 +-
- tests/unittests/config/test_cc_ntp.py | 2 ++
- tests/unittests/sources/test_gce.py   | 1 +
- tests/unittests/test_util.py          | 2 ++
- tox.ini                               | 2 +-
- 12 files changed, 21 insertions(+), 9 deletions(-)
-
-diff --git a/cloudinit/config/cc_mounts.py b/cloudinit/config/cc_mounts.py
-index 4efa2a29..d445b440 100644
---- a/cloudinit/config/cc_mounts.py
-+++ b/cloudinit/config/cc_mounts.py
-@@ -304,6 +304,10 @@ def create_swapfile(fname: str, size: str) -> None:
-                 "bs=1M",
-                 "count=%s" % size,
-             ]
-+        else:
-+            raise subp.ProcessExecutionError(
-+                "Missing dependency: 'dd' and 'fallocate' are not available"
-+            )
- 
-         try:
-             subp.subp(cmd, capture=True)
-diff --git a/cloudinit/distros/bsd.py b/cloudinit/distros/bsd.py
-index 761cf5c4..77e0385f 100644
---- a/cloudinit/distros/bsd.py
-+++ b/cloudinit/distros/bsd.py
-@@ -120,6 +120,8 @@ class BSD(distros.Distro):
-             if not self.pkg_cmd_upgrade_prefix:
-                 return
-             cmd = self.pkg_cmd_upgrade_prefix
-+        else:
-+            cmd = []
- 
-         if args and isinstance(args, str):
-             cmd.append(args)
-diff --git a/cloudinit/distros/netbsd.py b/cloudinit/distros/netbsd.py
-index a5678907..b7f3f3d8 100644
---- a/cloudinit/distros/netbsd.py
-+++ b/cloudinit/distros/netbsd.py
-@@ -12,7 +12,7 @@ import cloudinit.distros.bsd
- from cloudinit import subp, util
- 
- try:
--    import crypt
-+    import crypt  # pylint: disable=W4901
- 
-     salt = crypt.METHOD_BLOWFISH  # pylint: disable=E1101
-     blowfish_hash: Any = functools.partial(
-diff --git a/cloudinit/sources/DataSourceAzure.py b/cloudinit/sources/DataSourceAzure.py
-index 11c14e20..eb0304c3 100644
---- a/cloudinit/sources/DataSourceAzure.py
-+++ b/cloudinit/sources/DataSourceAzure.py
-@@ -51,7 +51,7 @@ from cloudinit.sources.helpers.azure import (
- from cloudinit.url_helper import UrlError
- 
- try:
--    import crypt
-+    import crypt  # pylint: disable=W4901
- 
-     blowfish_hash: Any = functools.partial(
-         crypt.crypt, salt=f"$6${util.rand_str(strlen=16)}"
-diff --git a/cloudinit/sources/DataSourceEc2.py b/cloudinit/sources/DataSourceEc2.py
-index 9e6bfbd1..384e4074 100644
---- a/cloudinit/sources/DataSourceEc2.py
-+++ b/cloudinit/sources/DataSourceEc2.py
-@@ -312,6 +312,8 @@ class DataSourceEc2(sources.DataSource):
-         return None
- 
-     def wait_for_metadata_service(self):
-+        urls = []
-+        start_time = 0
-         mcfg = self.ds_cfg
- 
-         url_params = self.get_url_params()
-@@ -345,7 +347,6 @@ class DataSourceEc2(sources.DataSource):
-             and self.cloud_name not in IDMSV2_SUPPORTED_CLOUD_PLATFORMS
-         ):
-             # if we can't get a token, use instance-id path
--            urls = []
-             url2base = {}
-             url_path = "{ver}/meta-data/instance-id".format(
-                 ver=self.min_metadata_version
-diff --git a/cloudinit/sources/DataSourceLXD.py b/cloudinit/sources/DataSourceLXD.py
-index cd316101..4c95b907 100644
---- a/cloudinit/sources/DataSourceLXD.py
-+++ b/cloudinit/sources/DataSourceLXD.py
-@@ -331,7 +331,7 @@ class MetaDataKeys(Flag):
-     CONFIG = auto()
-     DEVICES = auto()
-     META_DATA = auto()
--    ALL = CONFIG | DEVICES | META_DATA
-+    ALL = CONFIG | DEVICES | META_DATA  # pylint: disable=E1131
- 
- 
- class _MetaDataReader:
-diff --git a/tests/integration_tests/conftest.py b/tests/integration_tests/conftest.py
-index fa729b7d..ec211a00 100644
---- a/tests/integration_tests/conftest.py
-+++ b/tests/integration_tests/conftest.py
-@@ -241,7 +241,7 @@ def _client(
- 
- 
- @pytest.fixture
--def client(
-+def client(  # pylint: disable=W0135
-     request, fixture_utils, session_cloud, setup_image
- ) -> Iterator[IntegrationInstance]:
-     """Provide a client that runs for every test."""
-@@ -250,7 +250,7 @@ def client(
- 
- 
- @pytest.fixture(scope="module")
--def module_client(
-+def module_client(  # pylint: disable=W0135
-     request, fixture_utils, session_cloud, setup_image
- ) -> Iterator[IntegrationInstance]:
-     """Provide a client that runs once per module."""
-@@ -259,7 +259,7 @@ def module_client(
- 
- 
- @pytest.fixture(scope="class")
--def class_client(
-+def class_client(  # pylint: disable=W0135
-     request, fixture_utils, session_cloud, setup_image
- ) -> Iterator[IntegrationInstance]:
-     """Provide a client that runs once per class."""
-diff --git a/tests/integration_tests/util.py b/tests/integration_tests/util.py
-index 0a15203c..e26e466c 100644
---- a/tests/integration_tests/util.py
-+++ b/tests/integration_tests/util.py
-@@ -182,7 +182,7 @@ def wait_for_cloud_init(client: IntegrationInstance, num_retries: int = 30):
-         except Exception as e:
-             last_exception = e
-         time.sleep(1)
--    raise Exception(
-+    raise Exception(  # pylint: disable=W0719
-         "cloud-init status did not return successfully."
-     ) from last_exception
- 
-diff --git a/tests/unittests/config/test_cc_ntp.py b/tests/unittests/config/test_cc_ntp.py
-index a9444ec5..c9ce5daa 100644
---- a/tests/unittests/config/test_cc_ntp.py
-+++ b/tests/unittests/config/test_cc_ntp.py
-@@ -248,6 +248,7 @@ class TestNtp(FilesystemMockingTestCase):
-                     )
- 
-     def _get_expected_pools(self, pools, distro, client):
-+        expected_pools = None
-         if client in ["ntp", "chrony"]:
-             if client == "ntp" and distro == "alpine":
-                 # NTP for Alpine Linux is Busybox's ntp which does not
-@@ -263,6 +264,7 @@ class TestNtp(FilesystemMockingTestCase):
-         return expected_pools
- 
-     def _get_expected_servers(self, servers, distro, client):
-+        expected_servers = None
-         if client in ["ntp", "chrony"]:
-             if client == "ntp" and distro == "alpine":
-                 # NTP for Alpine Linux is Busybox's ntp which only supports
-diff --git a/tests/unittests/sources/test_gce.py b/tests/unittests/sources/test_gce.py
-index c0b19d3c..30a50236 100644
---- a/tests/unittests/sources/test_gce.py
-+++ b/tests/unittests/sources/test_gce.py
-@@ -101,6 +101,7 @@ class TestDataSourceGCE(test_helpers.ResponsesTestCase):
-             gce_meta = GCE_META
- 
-         def _request_callback(request):
-+            recursive = False
-             url_path = urlparse(request.url).path
-             if url_path.startswith("/computeMetadata/v1/"):
-                 path = url_path.split("/computeMetadata/v1/")[1:][0]
-diff --git a/tests/unittests/test_util.py b/tests/unittests/test_util.py
-index 519ef63c..de1326d4 100644
---- a/tests/unittests/test_util.py
-+++ b/tests/unittests/test_util.py
-@@ -1677,6 +1677,8 @@ class TestRedirectOutputPreexecFn:
-             args = (test_string, None)
-         elif request.param == "errfmt":
-             args = (None, test_string)
-+        else:
-+            args = (None, None)
-         with mock.patch(M_PATH + "subprocess.Popen") as m_popen:
-             util.redirect_output(*args)
- 
-diff --git a/tox.ini b/tox.ini
-index 5f01a9a8..5199ca13 100644
---- a/tox.ini
-+++ b/tox.ini
-@@ -25,7 +25,7 @@ hypothesis==6.31.6
- hypothesis_jsonschema==0.20.1
- isort==5.10.1
- mypy==0.950
--pylint==2.13.9
-+pylint==3.2.0
- pytest==7.0.1
- ruff==0.0.285
- types-jsonschema==4.4.2
--- 
-2.39.3
-
diff --git a/SOURCES/ci-Use-log_with_downgradable_level-for-user-password-wa.patch b/SOURCES/ci-Use-log_with_downgradable_level-for-user-password-wa.patch
new file mode 100644
index 0000000..9c664bc
--- /dev/null
+++ b/SOURCES/ci-Use-log_with_downgradable_level-for-user-password-wa.patch
@@ -0,0 +1,97 @@
+From 8a2e39a44ee0b6154fbb58eeb624d460b3489302 Mon Sep 17 00:00:00 2001
+From: Ani Sinha <anisinha@redhat.com>
+Date: Fri, 10 Jan 2025 23:32:52 +0530
+Subject: [PATCH 1/2] Use log_with_downgradable_level for user password
+ warnings (#5927)
+
+RH-Author: xiachen <xiachen@redhat.com>
+RH-MergeRequest: 121: Use log_with_downgradable_level for user password warnings (#5927)
+RH-Jira: RHEL-71122
+RH-Acked-by: Ani Sinha <anisinha@redhat.com>
+RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
+RH-Commit: [1/2] 313b086475c07865898c9a29991fa8bf5359fea6 (xiachen/cloud-init-centos)
+
+Introduction of new WARNING level logs could be problematic for stable
+downstream distros. Customers using these distros would then see a new and
+unexpected behavior change or a new WARNING log that can confuse them. So for
+handling user account passwords, use log_with_downgradable_level() helper api
+instead so that downstream distros can maintain stability while also making
+progressive changes in upstream towards improved user experience.
+Downstream distros can convert these logs to DEBUG level by setting
+DEPRECATION_INFO_BOUNDARY to a value older than the cloud-init version at which
+these logs were first introduced (24.3). Please see the documentation for
+log_with_downgradable_level().
+
+Signed-off-by: Ani Sinha <anisinha@redhat.com>
+(cherry picked from commit 38acce473626dc749dfb8bf3602e294df554c781)
+Signed-off-by: Amy Chen <xiachen@redhat.com>
+---
+ cloudinit/distros/__init__.py | 30 ++++++++++++++++++++----------
+ 1 file changed, 20 insertions(+), 10 deletions(-)
+
+diff --git a/cloudinit/distros/__init__.py b/cloudinit/distros/__init__.py
+index 34c0836e8..020d2201d 100644
+--- a/cloudinit/distros/__init__.py
++++ b/cloudinit/distros/__init__.py
+@@ -50,6 +50,7 @@ from cloudinit.distros.package_management.package_manager import PackageManager
+ from cloudinit.distros.package_management.utils import known_package_managers
+ from cloudinit.distros.parsers import hosts
+ from cloudinit.features import ALLOW_EC2_MIRRORS_ON_NON_AWS_INSTANCE_TYPES
++from cloudinit.lifecycle import log_with_downgradable_level
+ from cloudinit.net import activators, dhcp, renderers
+ from cloudinit.net.netops import NetOps
+ from cloudinit.net.network_state import parse_net_config_data
+@@ -900,10 +901,13 @@ class Distro(persistence.CloudInitPickleMixin, metaclass=abc.ABCMeta):
+                     password_key = "passwd"
+                     # Only "plain_text_passwd" and "hashed_passwd"
+                     # are valid for an existing user.
+-                    LOG.warning(
+-                        "'passwd' in user-data is ignored for existing "
+-                        "user %s",
+-                        name,
++                    log_with_downgradable_level(
++                        logger=LOG,
++                        version="24.3",
++                        requested_level=logging.WARNING,
++                        msg="'passwd' in user-data is ignored "
++                        "for existing user %s",
++                        args=name,
+                     )
+ 
+                 # As no password specified for the existing user in user-data
+@@ -941,20 +945,26 @@ class Distro(persistence.CloudInitPickleMixin, metaclass=abc.ABCMeta):
+         elif pre_existing_user:
+             # Pre-existing user with no existing password and none
+             # explicitly set in user-data.
+-            LOG.warning(
+-                "Not unlocking blank password for existing user %s."
++            log_with_downgradable_level(
++                logger=LOG,
++                version="24.3",
++                requested_level=logging.WARNING,
++                msg="Not unlocking blank password for existing user %s."
+                 " 'lock_passwd: false' present in user-data but no existing"
+                 " password set and no 'plain_text_passwd'/'hashed_passwd'"
+                 " provided in user-data",
+-                name,
++                args=name,
+             )
+         else:
+             # No password (whether blank or otherwise) explicitly set
+-            LOG.warning(
+-                "Not unlocking password for user %s. 'lock_passwd: false'"
++            log_with_downgradable_level(
++                logger=LOG,
++                version="24.3",
++                requested_level=logging.WARNING,
++                msg="Not unlocking password for user %s. 'lock_passwd: false'"
+                 " present in user-data but no 'passwd'/'plain_text_passwd'/"
+                 "'hashed_passwd' provided in user-data",
+-                name,
++                args=name,
+             )
+ 
+         # Configure doas access
+-- 
+2.48.1
+
diff --git a/SOURCES/ci-doc-update-examples-to-reflect-alternative-ways-to-p.patch b/SOURCES/ci-doc-update-examples-to-reflect-alternative-ways-to-p.patch
deleted file mode 100644
index 8a68c53..0000000
--- a/SOURCES/ci-doc-update-examples-to-reflect-alternative-ways-to-p.patch
+++ /dev/null
@@ -1,51 +0,0 @@
-From 52c04e1a523a450dfce70bc441963eb6a026eb59 Mon Sep 17 00:00:00 2001
-From: Ani Sinha <anisinha@redhat.com>
-Date: Thu, 20 Jun 2024 11:18:40 +0530
-Subject: [PATCH 3/6] doc: update examples to reflect alternative ways to
- provide `sudo` option (#5418)
-
-RH-Author: Ani Sinha <anisinha@redhat.com>
-RH-MergeRequest: 90: fix(jsonschema): Add missing sudo definition (#5418)
-RH-Jira: RHEL-44337
-RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
-RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
-RH-Commit: [2/2] 62eac6d731cb725c32cd0beac0219ecc2b407198 (anisinha/cloud-init)
-
-For creating users and groups, it is possible to pass a `sudo` option to the
-config file that accepts a sudo rule. The option can be a sudo rule string,
-a list of sudo rule strings or `False` to explicitly deny sudo usage. Update
-examples to show how a list of strings can be used with `sudo` option.
-
-Signed-off-by: Ani Sinha <anisinha@redhat.com>
-(cherry picked from commit cbcb05349e35023ee6e81ccaf13e79adb8f65f63)
----
- doc/examples/cloud-config-user-groups.txt | 6 ++++++
- 1 file changed, 6 insertions(+)
-
-diff --git a/doc/examples/cloud-config-user-groups.txt b/doc/examples/cloud-config-user-groups.txt
-index 87fc52e8..56eb674f 100644
---- a/doc/examples/cloud-config-user-groups.txt
-+++ b/doc/examples/cloud-config-user-groups.txt
-@@ -35,6 +35,10 @@ users:
-     lock_passwd: true
-     ssh_authorized_keys:
-       - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDSL7uWGj8cgWyIOaspgKdVy0cKJ+UTjfv7jBOjG2H/GN8bJVXy72XAvnhM0dUM+CCs8FOf0YlPX+Frvz2hKInrmRhZVwRSL129PasD12MlI3l44u6IwS1o/W86Q+tkQYEljtqDOo0a+cOsaZkvUNzUyEXUwz/lmYa6G4hMKZH4NBj7nbAAF96wsMCoyNwbWryBnDYUr6wMbjRR1J9Pw7Xh7WRC73wy4Va2YuOgbD3V/5ZrFPLbWZW/7TFXVrql04QVbyei4aiFR5n//GvoqwQDNe58LmbzX/xvxyKJYdny2zXmdAhMxbrpFQsfpkJ9E/H5w0yOdSvnWbUoG5xNGoOB csmith@fringe
-+  - name: testuser
-+    gecos: Mr. Test
-+    homedir: /local/testdir
-+    sudo: ["ALL=(ALL) NOPASSWD:ALL"]
-   - name: cloudy
-     gecos: Magic Cloud App Daemon User
-     inactive: '5'
-@@ -100,6 +104,8 @@ users:
- #
- #         Allow a user unrestricted sudo access.
- #             sudo:  ALL=(ALL) NOPASSWD:ALL
-+#                       or
-+#             sudo: ["ALL=(ALL) NOPASSWD:ALL"]
- #
- #         Adding multiple sudo rule strings.
- #             sudo:
--- 
-2.39.3
-
diff --git a/SOURCES/ci-docs-Add-deprecated-system_info-to-schema-5168.patch b/SOURCES/ci-docs-Add-deprecated-system_info-to-schema-5168.patch
deleted file mode 100644
index ad1ae0d..0000000
--- a/SOURCES/ci-docs-Add-deprecated-system_info-to-schema-5168.patch
+++ /dev/null
@@ -1,166 +0,0 @@
-From c933187af44a5de1d6eafde5dcd48e8ac369cf34 Mon Sep 17 00:00:00 2001
-From: James Falcon <james.falcon@canonical.com>
-Date: Thu, 18 Apr 2024 20:21:14 -0500
-Subject: [PATCH 2/3] docs: Add deprecated system_info to schema (#5168)
-
-RH-Author: Ani Sinha <anisinha@redhat.com>
-RH-MergeRequest: 95: Deprecate the users ssh-authorized-keys property (#5162)
-RH-Jira: RHEL-45262
-RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
-RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
-RH-Commit: [2/3] c4ea6f45ee0997e2f749c290fb8f2ceb8c05c691 (anisinha/cloud-init)
-
-In some cases, `system_info` can be passed via user data or vendor data
-to override the system_info in /etc/cloud/cloud.cfg . While this
-technically can work, this is a use case we no longer support and should
-indicate that it is deprecated.
-
-Also remove/update examples.
-
-(cherry picked from commit 7c67f7732f04b41600934818f7d5bcb4d085ed7c)
-
-Conflicts:
-	cloudinit/config/schemas/schema-cloud-config-v1.json
-	  - due to change fdefe08ad19cea5eb ("fix: Fix typos (#4850)") not
-	    present in downstream.
-	doc/examples/cloud-config-user-groups.txt
-	  - due to change 0aa17cd10bdd6 ("docs: set the home directory using homedir, not home (#5101)")
-	    not present downstream.
-	tests/unittests/sources/test_vultr.py
-	  - due to change 144782a838 ("test: Remove side effects from tests (#5074)") not present
-	    downstream.
----
- .../schemas/schema-cloud-config-v1.json       |  7 ++++++
- doc/examples/cloud-config-apt.txt             | 23 -------------------
- doc/examples/cloud-config-user-groups.txt     | 12 ++--------
- tests/data/user_data.1.txt                    | 10 --------
- tests/unittests/runs/test_merge_run.py        | 16 ++++++++++++-
- 5 files changed, 24 insertions(+), 44 deletions(-)
-
-diff --git a/cloudinit/config/schemas/schema-cloud-config-v1.json b/cloudinit/config/schemas/schema-cloud-config-v1.json
-index 670ef4c2..97cf2b74 100644
---- a/cloudinit/config/schemas/schema-cloud-config-v1.json
-+++ b/cloudinit/config/schemas/schema-cloud-config-v1.json
-@@ -513,6 +513,12 @@
-         },
-         "merge_type": {
-           "$ref": "#/$defs/merge_defintion"
-+        },
-+        "system_info": {
-+          "type": "object",
-+          "description": "System and/or distro specific settings. This is not intended to be overridden by user data or vendor data.",
-+          "deprecated": true,
-+          "deprecated_version": "24.2"
-         }
-       }
-     },
-@@ -3905,6 +3911,7 @@
-     "ssh_pwauth": {},
-     "ssh_quiet_keygen": {},
-     "swap": {},
-+    "system_info": {},
-     "timezone": {},
-     "ubuntu_advantage": {},
-     "updates": {},
-diff --git a/doc/examples/cloud-config-apt.txt b/doc/examples/cloud-config-apt.txt
-index dd6a0f6a..04968035 100644
---- a/doc/examples/cloud-config-apt.txt
-+++ b/doc/examples/cloud-config-apt.txt
-@@ -8,29 +8,6 @@
- #   Number: Set pipelining to some number (not recommended)
- apt_pipelining: False
- 
--## apt config via system_info:
--# under the 'system_info', you can customize cloud-init's interaction
--# with apt.
--#  system_info:
--#    apt_get_command: [command, argument, argument]
--#    apt_get_upgrade_subcommand: dist-upgrade
--#
--# apt_get_command:
--#  To specify a different 'apt-get' command, set 'apt_get_command'.
--#  This must be a list, and the subcommand (update, upgrade) is appended to it.
--#  default is:
--#    ['apt-get', '--option=Dpkg::Options::=--force-confold',
--#     '--option=Dpkg::options::=--force-unsafe-io', '--assume-yes', '--quiet']
--#
--# apt_get_upgrade_subcommand: "dist-upgrade"
--#  Specify a different subcommand for 'upgrade. The default is 'dist-upgrade'.
--#  This is the subcommand that is invoked for package_upgrade.
--#
--# apt_get_wrapper:
--#   command: eatmydata
--#   enabled: [True, False, "auto"]
--#
--
- # Install additional packages on first boot
- #
- # Default: none
-diff --git a/doc/examples/cloud-config-user-groups.txt b/doc/examples/cloud-config-user-groups.txt
-index 56eb674f..2cafef88 100644
---- a/doc/examples/cloud-config-user-groups.txt
-+++ b/doc/examples/cloud-config-user-groups.txt
-@@ -143,13 +143,5 @@ users:
- #
- # users[0] (the first user in users) overrides the user directive.
- #
--# The 'default' user above references the distro's config:
--# system_info:
--#   default_user:
--#     name: Ubuntu
--#     plain_text_passwd: 'ubuntu'
--#     home: /home/ubuntu
--#     shell: /bin/bash
--#     lock_passwd: True
--#     gecos: Ubuntu
--#     groups: [adm, cdrom, dip, lxd, sudo]
-+# The 'default' user above references the distro's config set in
-+# /etc/cloud/cloud.cfg.
-diff --git a/tests/data/user_data.1.txt b/tests/data/user_data.1.txt
-index 4c4543de..a1b5aa60 100644
---- a/tests/data/user_data.1.txt
-+++ b/tests/data/user_data.1.txt
-@@ -3,13 +3,3 @@ write_files:
- -   content: blah
-     path: /etc/blah.ini
-     permissions: 493
--
--system_info:
-- package_mirrors:
--   - arches: [i386, amd64, blah]
--     failsafe:
--      primary: http://my.archive.mydomain.com/ubuntu
--      security: http://my.security.mydomain.com/ubuntu
--     search:
--      primary: []
--      security: []
-diff --git a/tests/unittests/runs/test_merge_run.py b/tests/unittests/runs/test_merge_run.py
-index afc256ec..251c5ae5 100644
---- a/tests/unittests/runs/test_merge_run.py
-+++ b/tests/unittests/runs/test_merge_run.py
-@@ -22,7 +22,21 @@ class TestMergeRun(helpers.FilesystemMockingTestCase):
-         cfg = {
-             "datasource_list": ["None"],
-             "cloud_init_modules": ["write_files"],
--            "system_info": {"paths": {"run_dir": new_root}},
-+            "system_info": {
-+                "paths": {"run_dir": new_root},
-+                "package_mirrors": [
-+                    {
-+                        "arches": ["i386", "amd64", "blah"],
-+                        "failsafe": {
-+                            "primary": "http://my.archive.mydomain.com/ubuntu",
-+                            "security": (
-+                                "http://my.security.mydomain.com/ubuntu"
-+                            ),
-+                        },
-+                        "search": {"primary": [], "security": []},
-+                    },
-+                ],
-+            },
-         }
-         ud = helpers.readResource("user_data.1.txt")
-         cloud_cfg = safeyaml.dumps(cfg)
--- 
-2.39.3
-
diff --git a/SOURCES/ci-downstream-Revert-feat-Use-NetworkManager-renderer-b.patch b/SOURCES/ci-downstream-Revert-feat-Use-NetworkManager-renderer-b.patch
new file mode 100644
index 0000000..468a79f
--- /dev/null
+++ b/SOURCES/ci-downstream-Revert-feat-Use-NetworkManager-renderer-b.patch
@@ -0,0 +1,42 @@
+From 409e0cdcd730a0fd064b148147e8b3d5a2fe6c71 Mon Sep 17 00:00:00 2001
+From: Ani Sinha <anisinha@redhat.com>
+Date: Fri, 17 Jan 2025 10:50:03 +0530
+Subject: [PATCH] downstream: Revert "feat: Use NetworkManager renderer by
+ default in RHEL family"
+
+RH-Author: Ani Sinha <anisinha@redhat.com>
+RH-MergeRequest: 120: downstream: Revert "feat: Use NetworkManager renderer by default in RHEL family"
+RH-Jira: RHEL-74334
+RH-Acked-by: xiachen <xiachen@redhat.com>
+RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
+RH-Commit: [1/1] c466d30ee35576293011270591ec24773fc69251 (anisinha/cloud-init)
+
+This reverts commit 97537494d95f733fce260beb5a2d465cccf9f6c7.
+
+c9s has used sysconfig as its default network config renderer for historical
+reasons. It should continue to do so. In RHEL-10, we can move to NM as its
+default renderer. Therefore, revert the upstream change that makes NM as the
+default for RHEL family.
+
+X-downstream-only: true
+Signed-off-by: Ani Sinha <anisinha@redhat.com>
+---
+ config/cloud.cfg.tmpl | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/config/cloud.cfg.tmpl b/config/cloud.cfg.tmpl
+index 82a7e0fe5..b4a6bc936 100644
+--- a/config/cloud.cfg.tmpl
++++ b/config/cloud.cfg.tmpl
+@@ -313,7 +313,7 @@ system_info:
+     activators: ['netplan', 'eni', 'network-manager', 'networkd']
+ {% elif is_rhel %}
+   network:
+-    renderers: ['eni', 'netplan', 'network-manager', 'sysconfig', 'networkd']
++    renderers: ['sysconfig', 'eni', 'netplan', 'network-manager', 'networkd']
+ {% endif %}
+ {% if variant == "photon" %}
+   # If set to true, cloud-init will not use fallback network config.
+-- 
+2.39.3
+
diff --git a/SOURCES/ci-downstream-set-deprecation-boundary-version.patch b/SOURCES/ci-downstream-set-deprecation-boundary-version.patch
new file mode 100644
index 0000000..6e0266e
--- /dev/null
+++ b/SOURCES/ci-downstream-set-deprecation-boundary-version.patch
@@ -0,0 +1,39 @@
+From 35baff0028c247e7bf491dbf8e90b303dc7f5388 Mon Sep 17 00:00:00 2001
+From: Amy Chen <xiachen@redhat.com>
+Date: Thu, 6 Feb 2025 15:52:01 +0800
+Subject: [PATCH 2/2] downstream: set deprecation boundary version
+
+RH-Author: xiachen <xiachen@redhat.com>
+RH-MergeRequest: 121: Use log_with_downgradable_level for user password warnings (#5927)
+RH-Jira: RHEL-71122
+RH-Acked-by: Ani Sinha <anisinha@redhat.com>
+RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
+RH-Commit: [2/2] 9a6858da4c9364eab1e98f34cf3cac011e39e98e (xiachen/cloud-init-centos)
+
+Set features.DEPRECATION_INFO_BOUNDARY to 23.4,
+when the cloud-init version set at the callsite of
+log_with_downgradable_level() is newer than it,
+the log level is downgraded to DEBUG.
+
+X-downstream-only: true
+Signed-off-by: Amy Chen <xiachen@redhat.com>
+---
+ cloudinit/features.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/cloudinit/features.py b/cloudinit/features.py
+index 4f9a59e99..5f8fee62d 100644
+--- a/cloudinit/features.py
++++ b/cloudinit/features.py
+@@ -87,7 +87,7 @@ On Debian and Ubuntu systems, cc_apt_configure will write a deb822 compatible
+ to write /etc/apt/sources.list directly.
+ """
+ 
+-DEPRECATION_INFO_BOUNDARY = "devel"
++DEPRECATION_INFO_BOUNDARY = "23.4"
+ """
+ DEPRECATION_INFO_BOUNDARY is used by distros to configure at which upstream
+ version to start logging deprecations at a level higher than INFO.
+-- 
+2.48.1
+
diff --git a/SOURCES/ci-feat-apply-global-DNS-to-interfaces-in-network-manag.patch b/SOURCES/ci-feat-apply-global-DNS-to-interfaces-in-network-manag.patch
deleted file mode 100644
index bbef09a..0000000
--- a/SOURCES/ci-feat-apply-global-DNS-to-interfaces-in-network-manag.patch
+++ /dev/null
@@ -1,207 +0,0 @@
-From c21351ad9da5aebcb252aa36cbfa92ac16fa9746 Mon Sep 17 00:00:00 2001
-From: Florian Apolloner <florian@apolloner.eu>
-Date: Fri, 5 Jan 2024 19:07:12 +0100
-Subject: [PATCH 2/3] feat: apply global DNS to interfaces in network-manager 
- (#4723)
-
-RH-Author: Cathy Avery <cavery@redhat.com>
-RH-MergeRequest: 72: Fixes for cloud-init fails to configure DNS/search domains for network-config v1
-RH-Jira: RHEL-20964
-RH-Acked-by: Ani Sinha <anisinha@redhat.com>
-RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
-RH-Commit: [2/2] 1d2b10133ec2558e9665f21f53e4b1a898e283a8 (cavery/cloud-init-c-9-s)
-
-Sometimes DNS settings in cloud configs are specified globally and
-not per interface / subnet. This results in a configuration without
-proper nameservers. This was fixed for netplan in d29eeccd and is
-now also applied to the network-manager renderer.
-
-Co-authored-by: James Falcon <james.falcon@canonical.com>
-(cherry picked from commit 0d787d0a262f70ff848b315633742aa8fc45a1de)
-Signed-off-by: Cathy Avery <cavery@redhat.com>
----
- cloudinit/net/network_manager.py          | 52 ++++++++++++++---------
- tests/unittests/net/test_net_rendering.py |  3 ++
- tests/unittests/test_net.py               | 11 +++++
- tools/.github-cla-signers                 |  1 +
- 4 files changed, 47 insertions(+), 20 deletions(-)
-
-diff --git a/cloudinit/net/network_manager.py b/cloudinit/net/network_manager.py
-index bd6e6d75..0ba210b7 100644
---- a/cloudinit/net/network_manager.py
-+++ b/cloudinit/net/network_manager.py
-@@ -246,7 +246,7 @@ class NMConnection:
-         """
-         return addr.replace("-", ":").upper()
- 
--    def render_interface(self, iface, renderer):
-+    def render_interface(self, iface, network_state, renderer):
-         """
-         Integrate information from network state interface information
-         into the connection. Most of the work is done here.
-@@ -311,7 +311,6 @@ class NMConnection:
-         found_dns_search = []
- 
-         # Deal with Layer 3 configuration
--        use_top_level_dns = "dns" in iface
-         for subnet in iface["subnets"]:
-             family = "ipv6" if subnet_is_ipv6(subnet) else "ipv4"
- 
-@@ -322,26 +321,39 @@ class NMConnection:
-                 self.config[family]["gateway"] = subnet["gateway"]
-             for route in subnet["routes"]:
-                 self._add_route(route)
--            if not use_top_level_dns and "dns_nameservers" in subnet:
--                for nameserver in subnet["dns_nameservers"]:
--                    found_nameservers.append(nameserver)
--            if not use_top_level_dns and "dns_search" in subnet:
--                found_dns_search.append(subnet["dns_search"])
-+            # Add subnet-level DNS
-+            if "dns_nameservers" in subnet:
-+                found_nameservers.extend(subnet["dns_nameservers"])
-+            if "dns_search" in subnet:
-+                found_dns_search.extend(subnet["dns_search"])
-             if family == "ipv4" and "mtu" in subnet:
-                 ipv4_mtu = subnet["mtu"]
- 
--        # Now add our DNS search domains. We add them later because we
--        # only want them if an IP family has already been defined
--        if use_top_level_dns:
--            for nameserver in iface["dns"]["nameservers"]:
--                self._add_nameserver(nameserver)
--            if iface["dns"]["search"]:
--                self._add_dns_search(iface["dns"]["search"])
--        else:
--            for nameserver in found_nameservers:
--                self._add_nameserver(nameserver)
--            for dns_search in found_dns_search:
--                self._add_dns_search(dns_search)
-+        # Add interface-level DNS
-+        if "dns" in iface:
-+            found_nameservers += [
-+                dns
-+                for dns in iface["dns"]["nameservers"]
-+                if dns not in found_nameservers
-+            ]
-+            found_dns_search += [
-+                search
-+                for search in iface["dns"]["search"]
-+                if search not in found_dns_search
-+            ]
-+
-+        # We prefer any interface-specific DNS entries, but if we do not
-+        # have any, add the global DNS to the connection
-+        if not found_nameservers and network_state.dns_nameservers:
-+            found_nameservers = network_state.dns_nameservers
-+        if not found_dns_search and network_state.dns_searchdomains:
-+            found_dns_search = network_state.dns_searchdomains
-+
-+        # Write out all DNS entries to the connection
-+        for nameserver in found_nameservers:
-+            self._add_nameserver(nameserver)
-+        if found_dns_search:
-+            self._add_dns_search(found_dns_search)
- 
-         # we do not want to set may-fail to false for both ipv4 and ipv6 dhcp
-         # at the at the same time. This will make the network configuration
-@@ -457,7 +469,7 @@ class Renderer(renderer.Renderer):
-         # Now render the actual interface configuration
-         for iface in network_state.iter_interfaces():
-             conn = self.connections[iface["name"]]
--            conn.render_interface(iface, self)
-+            conn.render_interface(iface, network_state, self)
- 
-         # And finally write the files
-         for con_id, conn in self.connections.items():
-diff --git a/tests/unittests/net/test_net_rendering.py b/tests/unittests/net/test_net_rendering.py
-index 06feab89..f340ffc1 100644
---- a/tests/unittests/net/test_net_rendering.py
-+++ b/tests/unittests/net/test_net_rendering.py
-@@ -88,6 +88,9 @@ def _check_network_manager(network_state: NetworkState, tmp_path: Path):
-     "test_name, renderers",
-     [("no_matching_mac_v2", Renderer.Netplan | Renderer.NetworkManager)],
- )
-+@pytest.mark.xfail(
-+    reason="v2 interface-specific DNS errantly gets applied globally"
-+)
- def test_convert(test_name, renderers, tmp_path):
-     network_config = safeyaml.load(
-         Path(ARTIFACT_DIR, f"{test_name}.yaml").read_text()
-diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
-index 2a99f150..d7c9a414 100644
---- a/tests/unittests/test_net.py
-+++ b/tests/unittests/test_net.py
-@@ -646,6 +646,7 @@ method=manual
- may-fail=false
- address1=172.19.1.34/22
- route1=0.0.0.0/0,172.19.3.254
-+dns=172.19.0.12;
- 
- """.lstrip(),
-             ),
-@@ -2797,6 +2798,8 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
-                 [ipv4]
-                 method=auto
-                 may-fail=false
-+                dns=8.8.8.8;4.4.4.4;8.8.4.4;
-+                dns-search=barley.maas;wark.maas;foobar.maas;
- 
-                 """
-             ),
-@@ -2822,6 +2825,8 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
-                 method=manual
-                 may-fail=false
-                 address1=192.168.200.7/24
-+                dns=8.8.8.8;4.4.4.4;8.8.4.4;
-+                dns-search=barley.maas;wark.maas;foobar.maas;
- 
-                 """
-             ),
-@@ -2846,6 +2851,8 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
-                 [ipv4]
-                 method=auto
-                 may-fail=false
-+                dns=8.8.8.8;4.4.4.4;8.8.4.4;
-+                dns-search=barley.maas;wark.maas;foobar.maas;
- 
-                 """
-             ),
-@@ -2930,12 +2937,15 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
-                 method=manual
-                 may-fail=false
-                 address1=192.168.14.2/24
-+                dns=8.8.8.8;4.4.4.4;8.8.4.4;
-+                dns-search=barley.maas;wark.maas;foobar.maas;
- 
-                 [ipv6]
-                 method=manual
-                 may-fail=false
-                 address1=2001:1::1/64
-                 route1=::/0,2001:4800:78ff:1b::1
-+                dns-search=barley.maas;wark.maas;foobar.maas;
- 
-                 """
-             ),
-@@ -2990,6 +3000,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
-                 [ipv6]
-                 method=auto
-                 may-fail=false
-+                dns-search=barley.maas;wark.maas;foobar.maas;
- 
-                 """
-             ),
-diff --git a/tools/.github-cla-signers b/tools/.github-cla-signers
-index dbdb9cfa..f4da0989 100644
---- a/tools/.github-cla-signers
-+++ b/tools/.github-cla-signers
-@@ -13,6 +13,7 @@ andrewbogott
- andrewlukoshko
- ani-sinha
- antonyc
-+apollo13
- aswinrajamannar
- bdrung
- beantaxi
--- 
-2.39.3
-
diff --git a/SOURCES/ci-feat-sysconfig-Add-DNS-from-interface-config-to-reso.patch b/SOURCES/ci-feat-sysconfig-Add-DNS-from-interface-config-to-reso.patch
deleted file mode 100644
index 20c60fb..0000000
--- a/SOURCES/ci-feat-sysconfig-Add-DNS-from-interface-config-to-reso.patch
+++ /dev/null
@@ -1,351 +0,0 @@
-From 6b32b371bfd37759ddce3d7f29d15546500698e6 Mon Sep 17 00:00:00 2001
-From: Ani Sinha <anisinha@redhat.com>
-Date: Thu, 20 Jun 2024 22:27:03 +0530
-Subject: [PATCH 1/6] feat(sysconfig): Add DNS from interface config to
- resolv.conf (#5401)
-
-RH-Author: Ani Sinha <anisinha@redhat.com>
-RH-MergeRequest: 88: feat(sysconfig): Add DNS from interface config to resolv.conf (#5401)
-RH-Jira: RHEL-17961
-RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
-RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
-RH-Commit: [1/1] f353b73cc0f4bb9e1aee037708a1d3cb23b83cc3 (anisinha/cloud-init)
-
-sysconfig renderer currently only uses global dns and search domain
-configuration in order to populate /etc/resolv.conf. This means it ignores
-interface specific dns configuration completely. This means, when global dns
-information is absent and only interface specific dns configuration is present,
-/etc/resolv.conf will not have complete dns information. Fix this so that
-per interface dns information is also taken into account along with global dns
-configuration in order to populate /etc/resolv.conf.
-
-Fixes: GH-5400
-
-Signed-off-by: Ani Sinha <anisinha@redhat.com>
-(cherry picked from commit 1b8030e0c7fd6fbff7e38ad1e3e6266ae50c83a5)
----
- cloudinit/net/sysconfig.py  |  52 +++++++++-
- tests/unittests/test_net.py | 184 +++++++++++++++++++++++++++++++++++-
- 2 files changed, 230 insertions(+), 6 deletions(-)
-
-diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
-index d39f4fe3..7eb430ed 100644
---- a/cloudinit/net/sysconfig.py
-+++ b/cloudinit/net/sysconfig.py
-@@ -825,20 +825,62 @@ class Renderer(renderer.Renderer):
- 
-     @staticmethod
-     def _render_dns(network_state, existing_dns_path=None):
--        # skip writing resolv.conf if network_state doesn't include any input.
-+
-+        found_nameservers = []
-+        found_dns_search = []
-+
-+        for iface in network_state.iter_interfaces():
-+            for subnet in iface["subnets"]:
-+                # Add subnet-level DNS
-+                if "dns_nameservers" in subnet:
-+                    found_nameservers.extend(subnet["dns_nameservers"])
-+                if "dns_search" in subnet:
-+                    found_dns_search.extend(subnet["dns_search"])
-+
-+            # Add interface-level DNS
-+            if "dns" in iface:
-+                found_nameservers += [
-+                    dns
-+                    for dns in iface["dns"]["nameservers"]
-+                    if dns not in found_nameservers
-+                ]
-+                found_dns_search += [
-+                    search
-+                    for search in iface["dns"]["search"]
-+                    if search not in found_dns_search
-+                ]
-+
-+        # When both global and interface specific entries are present,
-+        # use them both to generate /etc/resolv.conf eliminating duplicate
-+        # entries. Otherwise use global or interface specific entries whichever
-+        # is provided.
-+        if network_state.dns_nameservers:
-+            found_nameservers += [
-+                nameserver
-+                for nameserver in network_state.dns_nameservers
-+                if nameserver not in found_nameservers
-+            ]
-+        if network_state.dns_searchdomains:
-+            found_dns_search += [
-+                search
-+                for search in network_state.dns_searchdomains
-+                if search not in found_dns_search
-+            ]
-+
-+        # skip writing resolv.conf if no dns information is provided in conf.
-         if not any(
-             [
--                len(network_state.dns_nameservers),
--                len(network_state.dns_searchdomains),
-+                len(found_nameservers),
-+                len(found_dns_search),
-             ]
-         ):
-             return None
-         content = resolv_conf.ResolvConf("")
-         if existing_dns_path and os.path.isfile(existing_dns_path):
-             content = resolv_conf.ResolvConf(util.load_file(existing_dns_path))
--        for nameserver in network_state.dns_nameservers:
-+        for nameserver in found_nameservers:
-             content.add_nameserver(nameserver)
--        for searchdomain in network_state.dns_searchdomains:
-+        for searchdomain in found_dns_search:
-             content.add_search_domain(searchdomain)
-         header = _make_header(";")
-         content_str = str(content)
-diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
-index d7c9a414..2d716f4b 100644
---- a/tests/unittests/test_net.py
-+++ b/tests/unittests/test_net.py
-@@ -516,6 +516,8 @@ OS_SAMPLES = [
-                         }
-                     ],
-                     "ip_address": "172.19.1.34",
-+                    "dns_search": ["testweb.com"],
-+                    "dns_nameservers": ["172.19.0.13"],
-                     "id": "network0",
-                 }
-             ],
-@@ -550,7 +552,9 @@ STARTMODE=auto
-                 """
- ; Created by cloud-init automatically, do not edit.
- ;
-+nameserver 172.19.0.13
- nameserver 172.19.0.12
-+search testweb.com
- """.lstrip(),
-             ),
-             (
-@@ -582,6 +586,8 @@ AUTOCONNECT_PRIORITY=120
- BOOTPROTO=none
- DEFROUTE=yes
- DEVICE=eth0
-+DNS1=172.19.0.13
-+DOMAIN=testweb.com
- GATEWAY=172.19.3.254
- HWADDR=fa:16:3e:ed:9a:59
- IPADDR=172.19.1.34
-@@ -596,7 +602,174 @@ USERCTL=no
-                 """
- ; Created by cloud-init automatically, do not edit.
- ;
-+nameserver 172.19.0.13
- nameserver 172.19.0.12
-+search testweb.com
-+""".lstrip(),
-+            ),
-+            (
-+                "etc/NetworkManager/conf.d/99-cloud-init.conf",
-+                """
-+# Created by cloud-init automatically, do not edit.
-+#
-+[main]
-+dns = none
-+""".lstrip(),
-+            ),
-+            (
-+                "etc/udev/rules.d/70-persistent-net.rules",
-+                "".join(
-+                    [
-+                        'SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ',
-+                        'ATTR{address}=="fa:16:3e:ed:9a:59", NAME="eth0"\n',
-+                    ]
-+                ),
-+            ),
-+        ],
-+        "expected_network_manager": [
-+            (
-+                "".join(
-+                    [
-+                        "etc/NetworkManager/system-connections",
-+                        "/cloud-init-eth0.nmconnection",
-+                    ]
-+                ),
-+                """
-+# Generated by cloud-init. Changes will be lost.
-+
-+[connection]
-+id=cloud-init eth0
-+uuid=1dd9a779-d327-56e1-8454-c65e2556c12c
-+autoconnect-priority=120
-+type=ethernet
-+
-+[user]
-+org.freedesktop.NetworkManager.origin=cloud-init
-+
-+[ethernet]
-+mac-address=FA:16:3E:ED:9A:59
-+
-+[ipv4]
-+method=manual
-+may-fail=false
-+address1=172.19.1.34/22
-+route1=0.0.0.0/0,172.19.3.254
-+dns=172.19.0.13;
-+dns-search=testweb.com;
-+
-+""".lstrip(),
-+            ),
-+        ],
-+    },
-+    {
-+        "in_data": {
-+            "services": [
-+                {
-+                    "type": "dns",
-+                    "address": "172.19.0.12",
-+                    "search": ["example1.com", "example2.com"],
-+                }
-+            ],
-+            "networks": [
-+                {
-+                    "network_id": "dacd568d-5be6-4786-91fe-750c374b78b4",
-+                    "type": "ipv4",
-+                    "netmask": "255.255.252.0",
-+                    "link": "eth0",
-+                    "routes": [
-+                        {
-+                            "netmask": "0.0.0.0",
-+                            "network": "0.0.0.0",
-+                            "gateway": "172.19.3.254",
-+                        }
-+                    ],
-+                    "ip_address": "172.19.1.34",
-+                    "dns_search": ["example3.com"],
-+                    "dns_nameservers": ["172.19.0.12"],
-+                    "id": "network0",
-+                }
-+            ],
-+            "links": [
-+                {
-+                    "ethernet_mac_address": "fa:16:3e:ed:9a:59",
-+                    "mtu": None,
-+                    "type": "physical",
-+                    "id": "eth0",
-+                },
-+            ],
-+        },
-+        "in_macs": {
-+            "fa:16:3e:ed:9a:59": "eth0",
-+        },
-+        "out_sysconfig_opensuse": [
-+            (
-+                "etc/sysconfig/network/ifcfg-eth0",
-+                """
-+# Created by cloud-init automatically, do not edit.
-+#
-+BOOTPROTO=static
-+IPADDR=172.19.1.34
-+LLADDR=fa:16:3e:ed:9a:59
-+NETMASK=255.255.252.0
-+STARTMODE=auto
-+""".lstrip(),
-+            ),
-+            (
-+                "etc/resolv.conf",
-+                """
-+; Created by cloud-init automatically, do not edit.
-+;
-+nameserver 172.19.0.12
-+search example3.com example1.com example2.com
-+""".lstrip(),
-+            ),
-+            (
-+                "etc/NetworkManager/conf.d/99-cloud-init.conf",
-+                """
-+# Created by cloud-init automatically, do not edit.
-+#
-+[main]
-+dns = none
-+""".lstrip(),
-+            ),
-+            (
-+                "etc/udev/rules.d/85-persistent-net-cloud-init.rules",
-+                "".join(
-+                    [
-+                        'SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ',
-+                        'ATTR{address}=="fa:16:3e:ed:9a:59", NAME="eth0"\n',
-+                    ]
-+                ),
-+            ),
-+        ],
-+        "out_sysconfig_rhel": [
-+            (
-+                "etc/sysconfig/network-scripts/ifcfg-eth0",
-+                """
-+# Created by cloud-init automatically, do not edit.
-+#
-+AUTOCONNECT_PRIORITY=120
-+BOOTPROTO=none
-+DEFROUTE=yes
-+DEVICE=eth0
-+DNS1=172.19.0.12
-+DOMAIN=example3.com
-+GATEWAY=172.19.3.254
-+HWADDR=fa:16:3e:ed:9a:59
-+IPADDR=172.19.1.34
-+NETMASK=255.255.252.0
-+ONBOOT=yes
-+TYPE=Ethernet
-+USERCTL=no
-+""".lstrip(),
-+            ),
-+            (
-+                "etc/resolv.conf",
-+                """
-+; Created by cloud-init automatically, do not edit.
-+;
-+nameserver 172.19.0.12
-+search example3.com example1.com example2.com
- """.lstrip(),
-             ),
-             (
-@@ -647,6 +820,7 @@ may-fail=false
- address1=172.19.1.34/22
- route1=0.0.0.0/0,172.19.3.254
- dns=172.19.0.12;
-+dns-search=example3.com;
- 
- """.lstrip(),
-             ),
-@@ -654,7 +828,13 @@ dns=172.19.0.12;
-     },
-     {
-         "in_data": {
--            "services": [{"type": "dns", "address": "172.19.0.12"}],
-+            "services": [
-+                {
-+                    "type": "dns",
-+                    "address": "172.19.0.12",
-+                    "search": "example.com",
-+                }
-+            ],
-             "networks": [
-                 {
-                     "network_id": "public-ipv4",
-@@ -715,6 +895,7 @@ STARTMODE=auto
- ; Created by cloud-init automatically, do not edit.
- ;
- nameserver 172.19.0.12
-+search example.com
- """.lstrip(),
-             ),
-             (
-@@ -763,6 +944,7 @@ USERCTL=no
- ; Created by cloud-init automatically, do not edit.
- ;
- nameserver 172.19.0.12
-+search example.com
- """.lstrip(),
-             ),
-             (
--- 
-2.39.3
-
diff --git a/SOURCES/ci-fix-Add-subnet-ipv4-ipv6-to-network-schema-5191.patch b/SOURCES/ci-fix-Add-subnet-ipv4-ipv6-to-network-schema-5191.patch
deleted file mode 100644
index 4c75da5..0000000
--- a/SOURCES/ci-fix-Add-subnet-ipv4-ipv6-to-network-schema-5191.patch
+++ /dev/null
@@ -1,45 +0,0 @@
-From 6a61ce0f0cde11551bfe92835d0b33c7b1022b68 Mon Sep 17 00:00:00 2001
-From: James Falcon <james.falcon@canonical.com>
-Date: Thu, 18 Apr 2024 20:27:27 -0500
-Subject: [PATCH] fix: Add subnet ipv4/ipv6  to network schema (#5191)
-
-RH-Author: Ani Sinha <anisinha@redhat.com>
-RH-MergeRequest: 109: fix: Add subnet ipv4/ipv6  to network schema (#5191)
-RH-Jira: RHEL-54686
-RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
-RH-Acked-by: Cathy Avery <cavery@redhat.com>
-RH-Commit: [1/1] 83692fac8f9af1831970091bdf7c43d0e59f314c (anisinha/cloud-init)
-
-These are used by our openstack network_data.json parsing code and
-get used by the sysconfig renderer.
-
-Fixes GH-4911
-
-(cherry picked from commit 0b1ca174095e3ad685e6d6649bb08aafb19a95b9)
-Signed-off-by: Ani Sinha <anisinha@redhat.com>
----
- cloudinit/config/schemas/schema-network-config-v1.json | 8 ++++++++
- 1 file changed, 8 insertions(+)
-
-diff --git a/cloudinit/config/schemas/schema-network-config-v1.json b/cloudinit/config/schemas/schema-network-config-v1.json
-index 64c492a4..f485c784 100644
---- a/cloudinit/config/schemas/schema-network-config-v1.json
-+++ b/cloudinit/config/schemas/schema-network-config-v1.json
-@@ -523,6 +523,14 @@
-           "items": {
-             "$ref": "#/$defs/anyOf_type_route"
-           }
-+        },
-+        "ipv4": {
-+          "type": "boolean",
-+          "description": "Indicate if the subnet is IPv4. If not specified, it will be inferred from the subnet type or address. This exists for compatibility with OpenStack's ``network_data.json`` when rendered through sysconfig."
-+        },
-+        "ipv6": {
-+          "type": "boolean",
-+          "description": "Indicate if the subnet is IPv6. If not specified, it will be inferred from the subnet type or address. This is exists for compatibility with OpenStack's ``network_data.json`` when rendered through sysconfig."
-         }
-       }
-     },
--- 
-2.39.3
-
diff --git a/SOURCES/ci-fix-Add-types-to-network-v1-schema-4841.patch b/SOURCES/ci-fix-Add-types-to-network-v1-schema-4841.patch
deleted file mode 100644
index 48224c6..0000000
--- a/SOURCES/ci-fix-Add-types-to-network-v1-schema-4841.patch
+++ /dev/null
@@ -1,110 +0,0 @@
-From 2f7f3dc6237ea70825dcb70f71d9718f631a9d95 Mon Sep 17 00:00:00 2001
-From: James Falcon <james.falcon@canonical.com>
-Date: Tue, 6 Feb 2024 09:24:37 -0600
-Subject: [PATCH] fix: Add types to network v1 schema (#4841)
-
-RH-Author: Cathy Avery <cavery@redhat.com>
-RH-MergeRequest: 69: fix: Add types to network v1 schema (#4841)
-RH-Jira: RHEL-21324
-RH-Acked-by: Ani Sinha <None>
-RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
-RH-Commit: [1/1] 59b2b4b07dd9eed956943a22b90af487f18b4cbd (cavery/cloud-init-c-9-s)
-
-Conflicts:
-No log argument as we are not including commit e168b4a1383b6eae9c1dc81411d7684fcbbf7df9
-
-Even though it has conflicted with our documentation, we have allowed
-nameserver address to a be a string, mtu to be empty, and nameserver
-search to be missing. Since we have allowed these, expand our schema
-and documentation accordingly.
-
-Fixes GH-4710
-
-(cherry picked from commit b08193b376552ede5d162d8283310adc783d81bf)
-Signed-off-by: Cathy Avery <cavery@redhat.com>
----
- .../config/schemas/schema-network-config-v1.json    | 13 +++++++++----
- doc/rtd/reference/network-config-format-v1.rst      |  4 ++--
- tests/unittests/config/test_schema.py               | 13 +++++++++++++
- 3 files changed, 24 insertions(+), 6 deletions(-)
-
-diff --git a/cloudinit/config/schemas/schema-network-config-v1.json b/cloudinit/config/schemas/schema-network-config-v1.json
-index c77885ec..56dc27c9 100644
---- a/cloudinit/config/schemas/schema-network-config-v1.json
-+++ b/cloudinit/config/schemas/schema-network-config-v1.json
-@@ -24,7 +24,10 @@
-           "description": "The lowercase MAC address of the physical device."
-         },
-         "mtu": {
--          "type": "integer",
-+          "type": [
-+            "integer",
-+            "null"
-+          ],
-           "description": "The MTU size in bytes. The ``mtu`` key represents a device's Maximum Transmission Unit, which is the largest size packet or frame, specified in octets (eight-bit bytes), that can be sent in a packet- or frame-based network. Specifying ``mtu`` is optional. Values too small or too large for a device may be ignored by that device."
-         },
-         "subnets": {
-@@ -384,8 +387,7 @@
-       "additionalProperties": false,
-       "required": [
-         "type",
--        "address",
--        "search"
-+        "address"
-       ],
-       "properties": {
-         "type": {
-@@ -396,7 +398,10 @@
-         },
-         "address": {
-           "description": "List of IPv4 or IPv6 address of nameservers.",
--          "type": "array",
-+          "type": [
-+            "array",
-+            "string"
-+          ],
-           "items": {
-             "type": "string"
-           }
-diff --git a/doc/rtd/reference/network-config-format-v1.rst b/doc/rtd/reference/network-config-format-v1.rst
-index d267eb94..42f2dc22 100644
---- a/doc/rtd/reference/network-config-format-v1.rst
-+++ b/doc/rtd/reference/network-config-format-v1.rst
-@@ -252,8 +252,8 @@ Users can specify a ``nameserver`` type. Nameserver dictionaries include
- the following keys:
- 
- - ``address``: List of IPv4 or IPv6 address of nameservers.
--- ``search``: List of hostnames to include in the :file:`resolv.conf` search
--  path.
-+- ``search``: Optional. List of hostnames to include in the :file:`resolv.conf`
-+  search path.
- - ``interface``: Optional. Ties the nameserver definition to the specified
-   interface. The value specified here must match the ``name`` of an interface
-   defined in this config. If unspecified, this nameserver will be considered
-diff --git a/tests/unittests/config/test_schema.py b/tests/unittests/config/test_schema.py
-index 28f0b39d..52667332 100644
---- a/tests/unittests/config/test_schema.py
-+++ b/tests/unittests/config/test_schema.py
-@@ -2048,6 +2048,19 @@ class TestNetworkSchema:
-                 does_not_raise(),
-                 id="bond_with_all_known_properties",
-             ),
-+            pytest.param(
-+                {
-+                    "network": {
-+                        "version": 1,
-+                        "config": [
-+                            {"type": "physical", "name": "eth0", "mtu": None},
-+                            {"type": "nameserver", "address": "8.8.8.8"},
-+                        ],
-+                    }
-+                },
-+                does_not_raise(),
-+                id="GH-4710_mtu_none_and_str_address",
-+            ),
-         ),
-     )
-     def test_network_schema(self, src_config, expectation):
--- 
-2.39.3
-
diff --git a/SOURCES/ci-fix-Address-TIOBE-abstract-interpretation-issues-486.patch b/SOURCES/ci-fix-Address-TIOBE-abstract-interpretation-issues-486.patch
deleted file mode 100644
index 68d5884..0000000
--- a/SOURCES/ci-fix-Address-TIOBE-abstract-interpretation-issues-486.patch
+++ /dev/null
@@ -1,73 +0,0 @@
-From 8ead44cb39f7726a695aa21a34820f6d40270829 Mon Sep 17 00:00:00 2001
-From: James Falcon <james.falcon@canonical.com>
-Date: Mon, 12 Feb 2024 14:48:01 -0600
-Subject: [PATCH 5/6] fix: Address TIOBE abstract interpretation issues (#4866)
-
-RH-Author: Ani Sinha <anisinha@redhat.com>
-RH-MergeRequest: 92: Update pylint version to support python 3.12
-RH-Jira: RHEL-44598
-RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
-RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
-RH-Commit: [2/3] 3ca11206fa159ab45b2db21e78c4cfaf358b1e01 (anisinha/cloud-init)
-
-These involve operations on possibly null variables or impossible logic.
-
-(cherry picked from commit 5e7ef1032a12267a9a518358fbf89da0a88ddb99)
----
- cloudinit/config/cc_lxd.py            | 2 +-
- cloudinit/distros/parsers/ifconfig.py | 6 ++++++
- cloudinit/util.py                     | 1 +
- 3 files changed, 8 insertions(+), 1 deletion(-)
-
-diff --git a/cloudinit/config/cc_lxd.py b/cloudinit/config/cc_lxd.py
-index cb9fc4f3..9f267b4c 100644
---- a/cloudinit/config/cc_lxd.py
-+++ b/cloudinit/config/cc_lxd.py
-@@ -432,7 +432,7 @@ def bridge_to_cmd(bridge_cfg):
-             % (bridge_cfg.get("ipv6_address"), bridge_cfg.get("ipv6_netmask"))
-         )
- 
--        if bridge_cfg.get("ipv6_nat", "false") == "true":
-+        if bridge_cfg.get("ipv6_nat") == "true":
-             cmd_create.append("ipv6.nat=true")
- 
-     else:
-diff --git a/cloudinit/distros/parsers/ifconfig.py b/cloudinit/distros/parsers/ifconfig.py
-index 516b5eb5..d671df1f 100644
---- a/cloudinit/distros/parsers/ifconfig.py
-+++ b/cloudinit/distros/parsers/ifconfig.py
-@@ -102,6 +102,7 @@ class Ifconfig:
-         """
-         ifindex = 0
-         ifs_by_mac = defaultdict(list)
-+        dev = None
-         for line in text.splitlines():
-             if len(line) == 0:
-                 continue
-@@ -119,6 +120,11 @@ class Ifconfig:
-                 dev.index = ifindex
-                 self._ifs_by_name[curif] = dev
- 
-+            if not dev:
-+                # This shouldn't happen with normal ifconfig output, but
-+                # if it does, ensure we don't Traceback
-+                continue
-+
-             toks = line.lower().strip().split()
- 
-             if len(toks) > 1 and toks[1].startswith("flags="):
-diff --git a/cloudinit/util.py b/cloudinit/util.py
-index 3295735c..5f787c5c 100644
---- a/cloudinit/util.py
-+++ b/cloudinit/util.py
-@@ -1417,6 +1417,7 @@ def find_devs_with_netbsd(
-     devlist = []
-     label = None
-     _type = None
-+    mscdlabel_out = ""
-     if criteria:
-         if criteria.startswith("LABEL="):
-             label = criteria.lstrip("LABEL=")
--- 
-2.39.3
-
diff --git a/SOURCES/ci-fix-Always-use-single-datasource-if-specified-5098.patch b/SOURCES/ci-fix-Always-use-single-datasource-if-specified-5098.patch
deleted file mode 100644
index bcb65c9..0000000
--- a/SOURCES/ci-fix-Always-use-single-datasource-if-specified-5098.patch
+++ /dev/null
@@ -1,66 +0,0 @@
-From 62cec1e38e117fe6b24888862576ac57be14bbda Mon Sep 17 00:00:00 2001
-From: James Falcon <james.falcon@canonical.com>
-Date: Tue, 26 Mar 2024 15:55:50 -0500
-Subject: [PATCH] fix: Always use single datasource if specified (#5098)
-
-RH-Author: Ani Sinha <anisinha@redhat.com>
-RH-MergeRequest: 82: fix: Always use single datasource if specified (#5098)
-RH-Jira: RHEL-36255
-RH-Acked-by: Cathy Avery <cavery@redhat.com>
-RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
-RH-Commit: [1/1] 068e97fcc18dd99f1112a9109acdb30fe2880f6e (anisinha/cloud-init)
-
-This change may require a user to add `None` to the `datasource_list`
-defined in `/etc/cloud/cloud.cfg[.d]` if they have a customized
-datasource_list and want the DataSourceNone fallback behavior.
-
-ds-identify would automatically append "None" to the datasource_list
-if a single entry was provided in /etc/cloud/cloud.cfg[.d].
-This wasn't a problem in the past as the python code would detect
-a single datasource along with None as an indication to automatically
-use that datasource. Since the python code no longer does that,
-we should ensure that one specified datasource results in one specified
-datasource after ds-identify has run.
-
-Fixes GH-5091
-
-(cherry picked from commit cdbbd17ae400e432d13f674c18a6f5c873fa328b)
-Signed-off-by: Ani Sinha <anisinha@redhat.com>
----
- tests/unittests/test_ds_identify.py | 2 +-
- tools/ds-identify                   | 6 +++++-
- 2 files changed, 6 insertions(+), 2 deletions(-)
-
-diff --git a/tests/unittests/test_ds_identify.py b/tests/unittests/test_ds_identify.py
-index ba0bf779..acbf3f03 100644
---- a/tests/unittests/test_ds_identify.py
-+++ b/tests/unittests/test_ds_identify.py
-@@ -522,7 +522,7 @@ class TestDsIdentify(DsIdentifyBase):
-         mydata = copy.deepcopy(VALID_CFG["Ec2-hvm"])
-         cfgpath = "etc/cloud/cloud.cfg.d/myds.cfg"
-         mydata["files"][cfgpath] = 'datasource_list: ["NoCloud"]\n'
--        self._check_via_dict(mydata, rc=RC_FOUND, dslist=["NoCloud", DS_NONE])
-+        self._check_via_dict(mydata, rc=RC_FOUND, dslist=["NoCloud"])
- 
-     def test_configured_list_with_none(self):
-         """When datasource_list already contains None, None is not added.
-diff --git a/tools/ds-identify b/tools/ds-identify
-index ec2cc18a..6e49ded3 100755
---- a/tools/ds-identify
-+++ b/tools/ds-identify
-@@ -1865,7 +1865,11 @@ _main() {
-     # if there is only a single entry in $DI_DSLIST
-     if [ $# -eq 1 ] || [ $# -eq 2 -a "$2" = "None" ] ; then
-         debug 1 "single entry in datasource_list ($DI_DSLIST) use that."
--        found "$@"
-+        if [ $# -eq 1 ]; then
-+            write_result "datasource_list: [ $1 ]"
-+        else
-+            found "$@"
-+        fi
-         return
-     fi
- 
--- 
-2.39.3
-
diff --git a/SOURCES/ci-fix-Clean-cache-if-no-datasource-fallback-5499.patch b/SOURCES/ci-fix-Clean-cache-if-no-datasource-fallback-5499.patch
deleted file mode 100644
index fc9bd8c..0000000
--- a/SOURCES/ci-fix-Clean-cache-if-no-datasource-fallback-5499.patch
+++ /dev/null
@@ -1,246 +0,0 @@
-From 914ac26ebd889b1f5cbb13d55fc011e92fc213c6 Mon Sep 17 00:00:00 2001
-From: James Falcon <james.falcon@canonical.com>
-Date: Thu, 18 Jul 2024 09:04:54 -0400
-Subject: [PATCH 1/2] fix: Clean cache if no datasource fallback (#5499)
-
-RH-Author: Ani Sinha <anisinha@redhat.com>
-RH-MergeRequest: 103: fix: Clean cache if no datasource fallback (#5499)
-RH-Jira: RHEL-49736
-RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
-RH-Commit: [1/1] 37eacd97f5e60fae2f71d401c528d508d3db517e (anisinha/cloud-init)
-
-9929a00 added the ability to used a cached datasource when none is
-found. This was supposed to be per-datasource, but the lack of cache
-cleaning got applied universally. This commit makes it so cache will be
-cleaned as it was before if fallback isn't implemented in datasource.
-
-Fixes GH-5486
-
-(cherry picked from commit 550c685c98551f65c30832b186fe091721b48477)
-Signed-off-by: Ani Sinha <anisinha@redhat.com>
----
- cloudinit/stages.py                           |   1 +
- .../assets/DataSourceNoCacheNetworkOnly.py    |  23 ++++
- .../assets/DataSourceNoCacheWithFallback.py   |  29 +++++
- .../datasources/test_caching.py               | 115 ++++++++++++++++++
- tests/integration_tests/instances.py          |   4 +-
- 5 files changed, 171 insertions(+), 1 deletion(-)
- create mode 100644 tests/integration_tests/assets/DataSourceNoCacheNetworkOnly.py
- create mode 100644 tests/integration_tests/assets/DataSourceNoCacheWithFallback.py
- create mode 100644 tests/integration_tests/datasources/test_caching.py
-
-diff --git a/cloudinit/stages.py b/cloudinit/stages.py
-index 0b795624..ace94c9a 100644
---- a/cloudinit/stages.py
-+++ b/cloudinit/stages.py
-@@ -378,6 +378,7 @@ class Init:
-                         ds,
-                     )
-                 else:
-+                    util.del_file(self.paths.instance_link)
-                     raise e
-         self.datasource = ds
-         # Ensure we adjust our path members datasource
-diff --git a/tests/integration_tests/assets/DataSourceNoCacheNetworkOnly.py b/tests/integration_tests/assets/DataSourceNoCacheNetworkOnly.py
-new file mode 100644
-index 00000000..54a7bab3
---- /dev/null
-+++ b/tests/integration_tests/assets/DataSourceNoCacheNetworkOnly.py
-@@ -0,0 +1,23 @@
-+import logging
-+
-+from cloudinit import sources
-+
-+LOG = logging.getLogger(__name__)
-+
-+
-+class DataSourceNoCacheNetworkOnly(sources.DataSource):
-+    def _get_data(self):
-+        LOG.debug("TEST _get_data called")
-+        return True
-+
-+
-+datasources = [
-+    (
-+        DataSourceNoCacheNetworkOnly,
-+        (sources.DEP_FILESYSTEM, sources.DEP_NETWORK),
-+    ),
-+]
-+
-+
-+def get_datasource_list(depends):
-+    return sources.list_from_depends(depends, datasources)
-diff --git a/tests/integration_tests/assets/DataSourceNoCacheWithFallback.py b/tests/integration_tests/assets/DataSourceNoCacheWithFallback.py
-new file mode 100644
-index 00000000..fdfc473f
---- /dev/null
-+++ b/tests/integration_tests/assets/DataSourceNoCacheWithFallback.py
-@@ -0,0 +1,29 @@
-+import logging
-+import os
-+
-+from cloudinit import sources
-+
-+LOG = logging.getLogger(__name__)
-+
-+
-+class DataSourceNoCacheWithFallback(sources.DataSource):
-+    def _get_data(self):
-+        if os.path.exists("/ci-test-firstboot"):
-+            LOG.debug("TEST _get_data called")
-+            return True
-+        return False
-+
-+    def check_if_fallback_is_allowed(self):
-+        return True
-+
-+
-+datasources = [
-+    (
-+        DataSourceNoCacheWithFallback,
-+        (sources.DEP_FILESYSTEM,),
-+    ),
-+]
-+
-+
-+def get_datasource_list(depends):
-+    return sources.list_from_depends(depends, datasources)
-diff --git a/tests/integration_tests/datasources/test_caching.py b/tests/integration_tests/datasources/test_caching.py
-new file mode 100644
-index 00000000..33e4b671
---- /dev/null
-+++ b/tests/integration_tests/datasources/test_caching.py
-@@ -0,0 +1,115 @@
-+import pytest
-+
-+from tests.integration_tests import releases, util
-+from tests.integration_tests.instances import IntegrationInstance
-+
-+
-+def setup_custom_datasource(client: IntegrationInstance, datasource_name: str):
-+    client.write_to_file(
-+        "/etc/cloud/cloud.cfg.d/99-imds.cfg",
-+        f"datasource_list: [ {datasource_name}, None ]\n"
-+        "datasource_pkg_list: [ cisources ]",
-+    )
-+    assert client.execute(
-+        "mkdir -p /usr/lib/python3/dist-packages/cisources"
-+    )
-+    client.push_file(
-+        util.ASSETS_DIR / f"DataSource{datasource_name}.py",
-+        "/usr/lib/python3/dist-packages/cisources/"
-+        f"DataSource{datasource_name}.py",
-+    )
-+
-+
-+def verify_no_cache_boot(client: IntegrationInstance):
-+    log = client.read_from_file("/var/log/cloud-init.log")
-+    util.verify_ordered_items_in_text(
-+        [
-+            "No local datasource found",
-+            "running 'init'",
-+            "no cache found",
-+            "Detected platform",
-+            "TEST _get_data called",
-+        ],
-+        text=log,
-+    )
-+    util.verify_clean_boot(client)
-+
-+
-+@pytest.mark.skipif(
-+    not releases.IS_UBUNTU,
-+    reason="hardcoded dist-packages directory",
-+)
-+def test_no_cache_network_only(client: IntegrationInstance):
-+    """Test cache removal per boot. GH-5486
-+
-+    This tests the CloudStack password reset use case. The expectation is:
-+    - Metadata is fetched in network timeframe only
-+    - Because `check_instance_id` is not defined, no cached datasource
-+      is found in the init-local phase, but the cache is used in the
-+      remaining phases due to existance of /run/cloud-init/.instance-id
-+    - Because `check_if_fallback_is_allowed` is not defined, cloud-init
-+      does NOT fall back to the pickled datasource, and will
-+      instead delete the cache during the init-local phase
-+    - Metadata is therefore fetched every boot in the network phase
-+    """
-+    setup_custom_datasource(client, "NoCacheNetworkOnly")
-+
-+    # Run cloud-init as if first boot
-+    assert client.execute("cloud-init clean --logs")
-+    client.restart()
-+
-+    verify_no_cache_boot(client)
-+
-+    # Clear the log without clean and run cloud-init for subsequent boot
-+    assert client.execute("echo '' > /var/log/cloud-init.log")
-+    client.restart()
-+
-+    verify_no_cache_boot(client)
-+
-+
-+@pytest.mark.skipif(
-+    not releases.IS_UBUNTU,
-+    reason="hardcoded dist-packages directory",
-+)
-+def test_no_cache_with_fallback(client: IntegrationInstance):
-+    """Test we use fallback when defined and no cache available."""
-+    setup_custom_datasource(client, "NoCacheWithFallback")
-+
-+    # Run cloud-init as if first boot
-+    assert client.execute("cloud-init clean --logs")
-+    # Used by custom datasource
-+    client.execute("touch /ci-test-firstboot")
-+    client.restart()
-+
-+    log = client.read_from_file("/var/log/cloud-init.log")
-+    util.verify_ordered_items_in_text(
-+        [
-+            "no cache found",
-+            "Detected platform",
-+            "TEST _get_data called",
-+            "running 'init'",
-+            "restored from cache with run check",
-+            "running 'modules:config'",
-+        ],
-+        text=log,
-+    )
-+    util.verify_clean_boot(client)
-+
-+    # Clear the log without clean and run cloud-init for subsequent boot
-+    assert client.execute("echo '' > /var/log/cloud-init.log")
-+    client.execute("rm /ci-test-firstboot")
-+    client.restart()
-+
-+    log = client.read_from_file("/var/log/cloud-init.log")
-+    util.verify_ordered_items_in_text(
-+        [
-+            "cache invalid in datasource",
-+            "Detected platform",
-+            "Restored fallback datasource from checked cache",
-+            "running 'init'",
-+            "restored from cache with run check",
-+            "running 'modules:config'",
-+        ],
-+        text=log,
-+    )
-+    util.verify_clean_boot(client)
-diff --git a/tests/integration_tests/instances.py b/tests/integration_tests/instances.py
-index 3fc6558a..23c0dc98 100644
---- a/tests/integration_tests/instances.py
-+++ b/tests/integration_tests/instances.py
-@@ -88,7 +88,9 @@ class IntegrationInstance:
-         # First push to a temporary directory because of permissions issues
-         tmp_path = _get_tmp_path()
-         self.instance.push_file(str(local_path), tmp_path)
--        assert self.execute("mv {} {}".format(tmp_path, str(remote_path))).ok
-+        assert self.execute(
-+            "mv {} {}".format(tmp_path, str(remote_path))
-+        ), f"Failed to push {tmp_path} to {remote_path}"
- 
-     def read_from_file(self, remote_path) -> str:
-         result = self.execute("cat {}".format(remote_path))
--- 
-2.39.3
-
diff --git a/SOURCES/ci-fix-Correct-v2-NetworkManager-route-rendering-4637.patch b/SOURCES/ci-fix-Correct-v2-NetworkManager-route-rendering-4637.patch
deleted file mode 100644
index 6d13dc7..0000000
--- a/SOURCES/ci-fix-Correct-v2-NetworkManager-route-rendering-4637.patch
+++ /dev/null
@@ -1,391 +0,0 @@
-From aaf1d063f198ce09f0d539a85e1a1a2bb834520b Mon Sep 17 00:00:00 2001
-From: James Falcon <james.falcon@canonical.com>
-Date: Tue, 2 Jan 2024 11:29:17 -0600
-Subject: [PATCH 1/3] fix: Correct v2 NetworkManager route rendering (#4637)
-
-RH-Author: Cathy Avery <cavery@redhat.com>
-RH-MergeRequest: 72: Fixes for cloud-init fails to configure DNS/search domains for network-config v1
-RH-Jira: RHEL-20964
-RH-Acked-by: Ani Sinha <anisinha@redhat.com>
-RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
-RH-Commit: [1/2] fb865987dbcf506a674eb9798f9c06859539a696 (cavery/cloud-init-c-9-s)
-
-fix: Correct v2 NetworkManager route rendering
-
-Because network v2 route defintions can have mixed v4 and v6 routes, we
-need to determine the IP family per route rather than per subnet.
-
-Similar, ensure dns-search is rendered correctly.
-
-Fixes GH-4518
-
-(cherry picked from commit c2c100e8c9fd8709539b3ab2b0ee34c66ba3f2f7)
-Signed-off-by: Cathy Avery <cavery@redhat.com>
----
- cloudinit/net/__init__.py        |   2 +
- cloudinit/net/network_manager.py |  87 +++++++++-------
- tests/unittests/test_net.py      | 165 ++++++++++++++++++++++++++++++-
- 3 files changed, 219 insertions(+), 35 deletions(-)
-
-diff --git a/cloudinit/net/__init__.py b/cloudinit/net/__init__.py
-index c0888f52..65e7ff33 100644
---- a/cloudinit/net/__init__.py
-+++ b/cloudinit/net/__init__.py
-@@ -1287,6 +1287,8 @@ def subnet_is_ipv6(subnet) -> bool:
-     """Common helper for checking network_state subnets for ipv6."""
-     # 'static6', 'dhcp6', 'ipv6_dhcpv6-stateful', 'ipv6_dhcpv6-stateless' or
-     # 'ipv6_slaac'
-+    # This function is inappropriate for v2-based routes as routes defined
-+    # under v2 subnets can contain ipv4 and ipv6 simultaneously
-     if subnet["type"].endswith("6") or subnet["type"] in IPV6_DYNAMIC_TYPES:
-         # This is a request either static6 type or DHCPv6.
-         return True
-diff --git a/cloudinit/net/network_manager.py b/cloudinit/net/network_manager.py
-index 76a0ac15..bd6e6d75 100644
---- a/cloudinit/net/network_manager.py
-+++ b/cloudinit/net/network_manager.py
-@@ -12,10 +12,15 @@ import itertools
- import logging
- import os
- import uuid
--from typing import Optional
-+from typing import List, Optional
- 
- from cloudinit import subp, util
--from cloudinit.net import is_ipv6_address, renderer, subnet_is_ipv6
-+from cloudinit.net import (
-+    is_ipv6_address,
-+    is_ipv6_network,
-+    renderer,
-+    subnet_is_ipv6,
-+)
- from cloudinit.net.network_state import NetworkState
- from cloudinit.net.sysconfig import available_nm_ifcfg_rh
- 
-@@ -158,11 +163,11 @@ class NMConnection:
-         if self.config[family]["method"] == "auto" and method == "manual":
-             return
- 
--        if (
--            subnet_type == "ipv6_dhcpv6-stateful"
--            or subnet_type == "ipv6_dhcpv6-stateless"
--            or subnet_type == "ipv6_slaac"
--        ):
-+        if subnet_type in [
-+            "ipv6_dhcpv6-stateful",
-+            "ipv6_dhcpv6-stateless",
-+            "ipv6_slaac",
-+        ]:
-             # set ipv4 method to 'disabled' to align with sysconfig renderer.
-             self._set_default("ipv4", "method", "disabled")
- 
-@@ -174,7 +179,8 @@ class NMConnection:
-         Adds a numbered property, such as address<n> or route<n>, ensuring
-         the appropriate value gets used for <n>.
-         """
--
-+        if not self.config.has_section(section):
-+            self.config[section] = {}
-         for index in itertools.count(1):
-             key = f"{key_prefix}{index}"
-             if not self.config.has_option(section, key):
-@@ -189,40 +195,37 @@ class NMConnection:
-         value = subnet["address"] + "/" + str(subnet["prefix"])
-         self._add_numbered(family, "address", value)
- 
--    def _add_route(self, family, route):
--        """
--        Adds a ipv[46].route<n> property.
--        """
--
-+    def _add_route(self, route):
-+        """Adds a ipv[46].route<n> property."""
-+        # Because network v2 route definitions can have mixed v4 and v6
-+        # routes, determine the family per route based on the gateway
-+        family = "ipv6" if is_ipv6_network(route["gateway"]) else "ipv4"
-         value = route["network"] + "/" + str(route["prefix"])
-         if "gateway" in route:
-             value = value + "," + route["gateway"]
-         self._add_numbered(family, "route", value)
- 
--    def _add_nameserver(self, dns):
-+    def _add_nameserver(self, dns: str) -> None:
-         """
-         Extends the ipv[46].dns property with a name server.
-         """
--
--        # FIXME: the subnet contains IPv4 and IPv6 name server mixed
--        # together. We might be getting an IPv6 name server while
--        # we're dealing with an IPv4 subnet. Sort this out by figuring
--        # out the correct family and making sure a valid section exist.
-         family = "ipv6" if is_ipv6_address(dns) else "ipv4"
--        self._set_default(family, "method", "disabled")
--
--        self._set_default(family, "dns", "")
--        self.config[family]["dns"] = self.config[family]["dns"] + dns + ";"
-+        if self.config.has_section(family):
-+            self._set_default(family, "dns", "")
-+            self.config[family]["dns"] = self.config[family]["dns"] + dns + ";"
- 
--    def _add_dns_search(self, family, dns_search):
-+    def _add_dns_search(self, dns_search: List[str]) -> None:
-         """
-         Extends the ipv[46].dns-search property with a name server.
-         """
--
--        self._set_default(family, "dns-search", "")
--        self.config[family]["dns-search"] = (
--            self.config[family]["dns-search"] + ";".join(dns_search) + ";"
--        )
-+        for family in ["ipv4", "ipv6"]:
-+            if self.config.has_section(family):
-+                self._set_default(family, "dns-search", "")
-+                self.config[family]["dns-search"] = (
-+                    self.config[family]["dns-search"]
-+                    + ";".join(dns_search)
-+                    + ";"
-+                )
- 
-     def con_uuid(self):
-         """
-@@ -304,8 +307,11 @@ class NMConnection:
- 
-         device_mtu = iface["mtu"]
-         ipv4_mtu = None
-+        found_nameservers = []
-+        found_dns_search = []
- 
-         # Deal with Layer 3 configuration
-+        use_top_level_dns = "dns" in iface
-         for subnet in iface["subnets"]:
-             family = "ipv6" if subnet_is_ipv6(subnet) else "ipv4"
- 
-@@ -315,15 +321,28 @@ class NMConnection:
-             if "gateway" in subnet:
-                 self.config[family]["gateway"] = subnet["gateway"]
-             for route in subnet["routes"]:
--                self._add_route(family, route)
--            if "dns_nameservers" in subnet:
-+                self._add_route(route)
-+            if not use_top_level_dns and "dns_nameservers" in subnet:
-                 for nameserver in subnet["dns_nameservers"]:
--                    self._add_nameserver(nameserver)
--            if "dns_search" in subnet:
--                self._add_dns_search(family, subnet["dns_search"])
-+                    found_nameservers.append(nameserver)
-+            if not use_top_level_dns and "dns_search" in subnet:
-+                found_dns_search.append(subnet["dns_search"])
-             if family == "ipv4" and "mtu" in subnet:
-                 ipv4_mtu = subnet["mtu"]
- 
-+        # Now add our DNS search domains. We add them later because we
-+        # only want them if an IP family has already been defined
-+        if use_top_level_dns:
-+            for nameserver in iface["dns"]["nameservers"]:
-+                self._add_nameserver(nameserver)
-+            if iface["dns"]["search"]:
-+                self._add_dns_search(iface["dns"]["search"])
-+        else:
-+            for nameserver in found_nameservers:
-+                self._add_nameserver(nameserver)
-+            for dns_search in found_dns_search:
-+                self._add_dns_search(dns_search)
-+
-         # we do not want to set may-fail to false for both ipv4 and ipv6 dhcp
-         # at the at the same time. This will make the network configuration
-         # work only when both ipv4 and ipv6 dhcp succeeds. This may not be
-diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
-index d9ef493b..2a99f150 100644
---- a/tests/unittests/test_net.py
-+++ b/tests/unittests/test_net.py
-@@ -2962,9 +2962,9 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
-                 may-fail=false
-                 address1=192.168.0.2/24
-                 gateway=192.168.0.1
-+                address2=192.168.2.10/24
-                 dns=192.168.0.10;10.23.23.134;
-                 dns-search=barley.maas;sacchromyces.maas;brettanomyces.maas;
--                address2=192.168.2.10/24
- 
-                 """
-             ),
-@@ -4154,6 +4154,148 @@ iface bond0 inet6 static
-             """
-         ),
-     },
-+    "v2-mixed-routes": {
-+        "expected_network_manager": {
-+            "cloud-init-eth0.nmconnection": textwrap.dedent(
-+                """\
-+                # Generated by cloud-init. Changes will be lost.
-+
-+                [connection]
-+                id=cloud-init eth0
-+                uuid=1dd9a779-d327-56e1-8454-c65e2556c12c
-+                autoconnect-priority=120
-+                type=ethernet
-+                interface-name=eth0
-+
-+                [user]
-+                org.freedesktop.NetworkManager.origin=cloud-init
-+
-+                [ethernet]
-+
-+                [ipv4]
-+                method=auto
-+                may-fail=true
-+                route1=169.254.42.42/32,62.210.0.1
-+                route2=169.254.42.43/32,62.210.0.2
-+                address1=192.168.1.20/16
-+                dns=8.8.8.8;
-+                dns-search=lab;home;
-+
-+                [ipv6]
-+                route1=::/0,fe80::dc00:ff:fe20:186
-+                route2=fe80::dc00:ff:fe20:188/64,fe80::dc00:ff:fe20:187
-+                method=auto
-+                may-fail=true
-+                address1=2001:bc8:1210:232:dc00:ff:fe20:185/64
-+                dns=FEDC::1;
-+                dns-search=lab;home;
-+
-+            """
-+            )
-+        },
-+        "yaml": textwrap.dedent(
-+            """\
-+            version: 2
-+            ethernets:
-+              eth0:
-+                dhcp4: true
-+                dhcp6: true
-+                nameservers:
-+                  search: [lab, home]
-+                  addresses: [8.8.8.8, "FEDC::1"]
-+                routes:
-+                  - to: 169.254.42.42/32
-+                    via: 62.210.0.1
-+                  - via: fe80::dc00:ff:fe20:186
-+                    to: ::/0
-+                  - to: 169.254.42.43/32
-+                    via: 62.210.0.2
-+                  - via: fe80::dc00:ff:fe20:187
-+                    to: fe80::dc00:ff:fe20:188
-+                addresses:
-+                  - 192.168.1.20/16
-+                  - 2001:bc8:1210:232:dc00:ff:fe20:185/64
-+        """
-+        ),
-+    },
-+    "v2-dns-no-if-ips": {
-+        "expected_network_manager": {
-+            "cloud-init-eth0.nmconnection": textwrap.dedent(
-+                """\
-+                # Generated by cloud-init. Changes will be lost.
-+
-+                [connection]
-+                id=cloud-init eth0
-+                uuid=1dd9a779-d327-56e1-8454-c65e2556c12c
-+                autoconnect-priority=120
-+                type=ethernet
-+                interface-name=eth0
-+
-+                [user]
-+                org.freedesktop.NetworkManager.origin=cloud-init
-+
-+                [ethernet]
-+
-+                [ipv4]
-+                method=auto
-+                may-fail=true
-+                dns=8.8.8.8;
-+                dns-search=lab;home;
-+
-+                [ipv6]
-+                method=auto
-+                may-fail=true
-+                dns=FEDC::1;
-+                dns-search=lab;home;
-+
-+            """
-+            )
-+        },
-+        "yaml": textwrap.dedent(
-+            """\
-+            version: 2
-+            ethernets:
-+              eth0:
-+                dhcp4: true
-+                dhcp6: true
-+                nameservers:
-+                  search: [lab, home]
-+                  addresses: [8.8.8.8, "FEDC::1"]
-+        """
-+        ),
-+    },
-+    "v2-dns-no-dhcp": {
-+        "expected_network_manager": {
-+            "cloud-init-eth0.nmconnection": textwrap.dedent(
-+                """\
-+                # Generated by cloud-init. Changes will be lost.
-+
-+                [connection]
-+                id=cloud-init eth0
-+                uuid=1dd9a779-d327-56e1-8454-c65e2556c12c
-+                autoconnect-priority=120
-+                type=ethernet
-+                interface-name=eth0
-+
-+                [user]
-+                org.freedesktop.NetworkManager.origin=cloud-init
-+
-+                [ethernet]
-+
-+            """
-+            )
-+        },
-+        "yaml": textwrap.dedent(
-+            """\
-+            version: 2
-+            ethernets:
-+              eth0:
-+                nameservers:
-+                  search: [lab, home]
-+                  addresses: [8.8.8.8, "FEDC::1"]
-+        """
-+        ),
-+    },
- }
- 
- 
-@@ -6267,6 +6409,27 @@ class TestNetworkManagerRendering(CiTestCase):
-             entry[self.expected_name], self.expected_conf_d, found
-         )
- 
-+    def test_v2_mixed_routes(self):
-+        entry = NETWORK_CONFIGS["v2-mixed-routes"]
-+        found = self._render_and_read(network_config=yaml.load(entry["yaml"]))
-+        self._compare_files_to_expected(
-+            entry[self.expected_name], self.expected_conf_d, found
-+        )
-+
-+    def test_v2_dns_no_ips(self):
-+        entry = NETWORK_CONFIGS["v2-dns-no-if-ips"]
-+        found = self._render_and_read(network_config=yaml.load(entry["yaml"]))
-+        self._compare_files_to_expected(
-+            entry[self.expected_name], self.expected_conf_d, found
-+        )
-+
-+    def test_v2_dns_no_dhcp(self):
-+        entry = NETWORK_CONFIGS["v2-dns-no-dhcp"]
-+        found = self._render_and_read(network_config=yaml.load(entry["yaml"]))
-+        self._compare_files_to_expected(
-+            entry[self.expected_name], self.expected_conf_d, found
-+        )
-+
- 
- @mock.patch(
-     "cloudinit.net.is_openvswitch_internal_interface",
--- 
-2.39.3
-
diff --git a/SOURCES/ci-fix-Fall-back-to-cached-local-ds-if-no-valid-ds-foun.patch b/SOURCES/ci-fix-Fall-back-to-cached-local-ds-if-no-valid-ds-foun.patch
deleted file mode 100644
index 364a100..0000000
--- a/SOURCES/ci-fix-Fall-back-to-cached-local-ds-if-no-valid-ds-foun.patch
+++ /dev/null
@@ -1,156 +0,0 @@
-From cf35040b46abb66c7239d156bd92c7267d7c40f7 Mon Sep 17 00:00:00 2001
-From: PengpengSun <40026211+PengpengSun@users.noreply.github.com>
-Date: Fri, 29 Mar 2024 22:39:13 +0800
-Subject: [PATCH] fix: Fall back to cached local ds if no valid ds found
- (#4997)
-
-RH-Author: Ani Sinha <anisinha@redhat.com>
-RH-MergeRequest: 75: fix: Fall back to cached local ds if no valid ds found (#4997)
-RH-Jira: RHEL-32846
-RH-Acked-by: Cathy Avery <cavery@redhat.com>
-RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
-RH-Commit: [1/1] 408c41fd8009255d98c31210ef936f2e68dfde75 (anisinha/cloud-init)
-
-Rebooting an instance which has finished VMware guest
-customization with DataSourceVMware will load
-DataSourceNone due to metadata is NOT available.
-
-This is mostly a re-post of PR#229, few differences are:
-1. Let ds decide if fallback is allowed, not always fall back
-   to previous cached LOCAL ds.
-2. No comparing instance-id of cached ds with previous instance-id
-   due to I think they are always identical.
-
-Fixes GH-3402
-
-(cherry picked from commit 9929a00580d50afc60bf4e0fb9f2f39d4f797b4b)
-Signed-off-by: Ani Sinha <anisinha@redhat.com>
-
-Conflicts:
-	cloudinit/sources/__init__.py
-	Conflicts because of changes in upstream source coming from
-	30d5e9a3358f4cbaced ("refactor: Use _unpickle rather than hasattr() in sources")
----
- cloudinit/sources/DataSourceVMware.py | 14 +++++++++-
- cloudinit/sources/__init__.py         | 14 ++++++++++
- cloudinit/stages.py                   | 40 +++++++++++++++++----------
- 3 files changed, 53 insertions(+), 15 deletions(-)
-
-diff --git a/cloudinit/sources/DataSourceVMware.py b/cloudinit/sources/DataSourceVMware.py
-index 1591121d..2d5d42eb 100644
---- a/cloudinit/sources/DataSourceVMware.py
-+++ b/cloudinit/sources/DataSourceVMware.py
-@@ -197,7 +197,7 @@ class DataSourceVMware(sources.DataSource):
-                 break
- 
-         if not self.data_access_method:
--            LOG.error("failed to find a valid data access method")
-+            LOG.debug("failed to find a valid data access method")
-             return False
- 
-         LOG.info("using data access method %s", self._get_subplatform())
-@@ -291,6 +291,18 @@ class DataSourceVMware(sources.DataSource):
-             self.metadata["instance-id"] = str(id_file.read()).rstrip().lower()
-             return self.metadata["instance-id"]
- 
-+    def check_if_fallback_is_allowed(self):
-+        if (
-+            self.data_access_method
-+            and self.data_access_method == DATA_ACCESS_METHOD_IMC
-+            and is_vmware_platform()
-+        ):
-+            LOG.debug(
-+                "Cache fallback is allowed for : %s", self._get_subplatform()
-+            )
-+            return True
-+        return False
-+
-     def get_public_ssh_keys(self):
-         for key_name in (
-             "public-keys-data",
-diff --git a/cloudinit/sources/__init__.py b/cloudinit/sources/__init__.py
-index c207b5ed..453801be 100644
---- a/cloudinit/sources/__init__.py
-+++ b/cloudinit/sources/__init__.py
-@@ -312,6 +312,10 @@ class DataSource(CloudInitPickleMixin, metaclass=abc.ABCMeta):
-             self.vendordata2_raw = None
-         if not hasattr(self, "skip_hotplug_detect"):
-             self.skip_hotplug_detect = False
-+
-+        if not hasattr(self, "check_if_fallback_is_allowed"):
-+            setattr(self, "check_if_fallback_is_allowed", lambda: False)
-+
-         if hasattr(self, "userdata") and self.userdata is not None:
-             # If userdata stores MIME data, on < python3.6 it will be
-             # missing the 'policy' attribute that exists on >=python3.6.
-@@ -914,6 +918,16 @@ class DataSource(CloudInitPickleMixin, metaclass=abc.ABCMeta):
-         # quickly (local check only) if self.instance_id is still
-         return False
- 
-+    def check_if_fallback_is_allowed(self):
-+        """check_if_fallback_is_allowed()
-+        Checks if a cached ds is allowed to be restored when no valid ds is
-+        found in local mode by checking instance-id and searching valid data
-+        through ds list.
-+
-+        @return True if a ds allows fallback, False otherwise.
-+        """
-+        return False
-+
-     @staticmethod
-     def _determine_dsmode(candidates, default=None, valid=None):
-         # return the first candidate that is non None, warn if not valid
-diff --git a/cloudinit/stages.py b/cloudinit/stages.py
-index 3b6405f5..0b795624 100644
---- a/cloudinit/stages.py
-+++ b/cloudinit/stages.py
-@@ -353,20 +353,32 @@ class Init:
-             LOG.debug(myrep.description)
- 
-         if not ds:
--            util.del_file(self.paths.instance_link)
--            (cfg_list, pkg_list) = self._get_datasources()
--            # Deep copy so that user-data handlers can not modify
--            # (which will affect user-data handlers down the line...)
--            (ds, dsname) = sources.find_source(
--                self.cfg,
--                self.distro,
--                self.paths,
--                copy.deepcopy(self.ds_deps),
--                cfg_list,
--                pkg_list,
--                self.reporter,
--            )
--            LOG.info("Loaded datasource %s - %s", dsname, ds)
-+            try:
-+                cfg_list, pkg_list = self._get_datasources()
-+                # Deep copy so that user-data handlers can not modify
-+                # (which will affect user-data handlers down the line...)
-+                ds, dsname = sources.find_source(
-+                    self.cfg,
-+                    self.distro,
-+                    self.paths,
-+                    copy.deepcopy(self.ds_deps),
-+                    cfg_list,
-+                    pkg_list,
-+                    self.reporter,
-+                )
-+                util.del_file(self.paths.instance_link)
-+                LOG.info("Loaded datasource %s - %s", dsname, ds)
-+            except sources.DataSourceNotFoundException as e:
-+                if existing != "check":
-+                    raise e
-+                ds = self._restore_from_cache()
-+                if ds and ds.check_if_fallback_is_allowed():
-+                    LOG.info(
-+                        "Restored fallback datasource from checked cache: %s",
-+                        ds,
-+                    )
-+                else:
-+                    raise e
-         self.datasource = ds
-         # Ensure we adjust our path members datasource
-         # now that we have one (thus allowing ipath to be used)
--- 
-2.39.3
-
diff --git a/SOURCES/ci-fix-Undeprecate-network-in-schema-route-definition-5.patch b/SOURCES/ci-fix-Undeprecate-network-in-schema-route-definition-5.patch
deleted file mode 100644
index 2892e06..0000000
--- a/SOURCES/ci-fix-Undeprecate-network-in-schema-route-definition-5.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-From 332bb23bcfde801edf792e6c629ec350be07b952 Mon Sep 17 00:00:00 2001
-From: James Falcon <james.falcon@canonical.com>
-Date: Tue, 19 Mar 2024 14:24:11 -0500
-Subject: [PATCH 3/3] fix: Undeprecate 'network' in schema route definition
- (#5072)
-
-RH-Author: Ani Sinha <anisinha@redhat.com>
-RH-MergeRequest: 73: fix: Undeprecate 'network' in schema route definition (#5072)
-RH-Jira: RHEL-29709
-RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
-RH-Acked-by: Cathy Avery <cavery@redhat.com>
-RH-Commit: [1/1] 61c660be43fd25999bca0cfd66d7b2150fee5a14 (anisinha/cloud-init)
-
-It is passed through to our v1 schema from OpenStack network_data.json
-
-Fixes GH-5051
-
-(cherry picked from commit ff40d1af8a6de3ee27937382ec4ceea931d80a88)
-Signed-off-by: Ani Sinha <anisinha@redhat.com>
----
- cloudinit/config/schemas/schema-network-config-v1.json | 5 +----
- 1 file changed, 1 insertion(+), 4 deletions(-)
-
-diff --git a/cloudinit/config/schemas/schema-network-config-v1.json b/cloudinit/config/schemas/schema-network-config-v1.json
-index 56dc27c9..64c492a4 100644
---- a/cloudinit/config/schemas/schema-network-config-v1.json
-+++ b/cloudinit/config/schemas/schema-network-config-v1.json
-@@ -445,10 +445,7 @@
-         },
-         "network": {
-           "type": "string",
--          "description": "IPv4 network address with CIDR netmask notation or IPv6 with prefix length. Alias for ``destination`` and only read when ``destination`` key is absent.",
--          "deprecated": true,
--          "deprecated_version": "23.3",
--          "deprecated_description": "Use ``destination`` instead."
-+          "description": "IPv4 network address with CIDR netmask notation or IPv6 with prefix length. Alias for ``destination`` and only read when ``destination`` key is absent. This exists for OpenStack support. OpenStack route definitions are passed through to v1 config and OpenStack's ``network_data.json`` uses ``network`` instead of ``destination``."
-         },
-         "destination": {
-           "type": "string",
--- 
-2.39.3
-
diff --git a/SOURCES/ci-fix-add-schema-rules-for-baseurl-and-metalink-in-yum.patch b/SOURCES/ci-fix-add-schema-rules-for-baseurl-and-metalink-in-yum.patch
deleted file mode 100644
index 775f9c6..0000000
--- a/SOURCES/ci-fix-add-schema-rules-for-baseurl-and-metalink-in-yum.patch
+++ /dev/null
@@ -1,66 +0,0 @@
-From ed3c05af60c0d50a4576a63c8638e148e58ebf06 Mon Sep 17 00:00:00 2001
-From: Ani Sinha <anisinha@redhat.com>
-Date: Thu, 11 Jul 2024 00:49:58 +0530
-Subject: [PATCH] fix: add schema rules for 'baseurl' and 'metalink' in yum
- repo config (#5501)
-
-RH-Author: Ani Sinha <anisinha@redhat.com>
-RH-MergeRequest: 101: fix: add schema rules for 'baseurl' and 'metalink' in yum repo config (#5501)
-RH-Jira: RHEL-46873
-RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
-RH-Acked-by: xiachen <xiachen@redhat.com>
-RH-Commit: [1/1] df01c93fde517e66ce71a66f80ee54d3ed504906 (anisinha/cloud-init)
-
-At least one of (or both) 'baseurl' or 'metalink' should be provided for yum
-repository specification. Add schema changes to enforce it. Without this,
-with just 'metalink' property set, one would get the schema validator error
-
-\---
-Error: Cloud config schema errors: yum_repos.epel-release: 'baseurl' is a required property
-\---
-
-Signed-off-by: Ani Sinha <anisinha@redhat.com>
-(cherry picked from commit 7d35664ef8b85840f92f18cc48187f7284d227bc)
----
- .../config/schemas/schema-cloud-config-v1.json | 18 ++++++++++++++++--
- 1 file changed, 16 insertions(+), 2 deletions(-)
-
-diff --git a/cloudinit/config/schemas/schema-cloud-config-v1.json b/cloudinit/config/schemas/schema-cloud-config-v1.json
-index 03e723e2..4fb7fd93 100644
---- a/cloudinit/config/schemas/schema-cloud-config-v1.json
-+++ b/cloudinit/config/schemas/schema-cloud-config-v1.json
-@@ -3442,6 +3442,11 @@
-                   "format": "uri",
-                   "description": "URL to the directory where the yum repository's 'repodata' directory lives"
-                 },
-+                "metalink": {
-+                  "type": "string",
-+                  "format": "uri",
-+                  "description": "Specifies a URL to a metalink file for the repomd.xml"
-+                },
-                 "name": {
-                   "type": "string",
-                   "description": "Optional human-readable name of the yum repo."
-@@ -3469,8 +3474,17 @@
-                   "description": "Any supported yum repository configuration options will be written to the yum repo config file. See: man yum.conf"
-                 }
-               },
--              "required": [
--                "baseurl"
-+              "anyOf": [
-+                {
-+                  "required": [
-+                    "baseurl"
-+                  ]
-+                },
-+                {
-+                  "required": [
-+                    "metalink"
-+                  ]
-+                }
-               ]
-             }
-           }
--- 
-2.39.3
-
diff --git a/SOURCES/ci-fix-cloudstack-Use-parsed-lease-file-for-virtual-rou.patch b/SOURCES/ci-fix-cloudstack-Use-parsed-lease-file-for-virtual-rou.patch
deleted file mode 100644
index 97feacc..0000000
--- a/SOURCES/ci-fix-cloudstack-Use-parsed-lease-file-for-virtual-rou.patch
+++ /dev/null
@@ -1,58 +0,0 @@
-From fcaff2e02a07af587d8366f61df1685435e32288 Mon Sep 17 00:00:00 2001
-From: Brett Holman <brett.holman@canonical.com>
-Date: Wed, 3 Jan 2024 09:11:40 -0700
-Subject: [PATCH] fix(cloudstack): Use parsed lease file for virtual router in
- cloudstack
-
-RH-Author: Ani Sinha <anisinha@redhat.com>
-RH-MergeRequest: 85: fix(cloudstack): Use parsed lease file for virtual router in cloudstack
-RH-Jira: RHEL-40217
-RH-Acked-by: Cathy Avery <cavery@redhat.com>
-RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
-RH-Commit: [1/1] 9d1353620ee2c773170e424479bb2664116554f4 (anisinha/cloud-init)
-
-Fixes 5942f4023e2581a
-
-(cherry picked from commit cb36bf38b823f811a3e938ccffc03d7d13190095)
-Signed-off-by: Ani Sinha <anisinha@redhat.com>
----
- cloudinit/sources/DataSourceCloudStack.py | 22 +++++++++++-----------
- 1 file changed, 11 insertions(+), 11 deletions(-)
-
-diff --git a/cloudinit/sources/DataSourceCloudStack.py b/cloudinit/sources/DataSourceCloudStack.py
-index fd2482a3..f752765d 100644
---- a/cloudinit/sources/DataSourceCloudStack.py
-+++ b/cloudinit/sources/DataSourceCloudStack.py
-@@ -229,18 +229,18 @@ def get_vr_address():
-         )
-         return latest_address
- 
--    # Try dhcp lease files next...
-+    # Try dhcp lease files next
-     lease_file = dhcp.IscDhclient.get_latest_lease()
--    if not lease_file:
--        LOG.debug("No lease file found, using default gateway")
--        return get_default_gateway()
--
--    lease_file = dhcp.IscDhclient.parse_dhcp_server_from_lease_file(lease_file)
--    if not latest_address:
--        # No virtual router found, fallback on default gateway
--        LOG.debug("No DHCP found, using default gateway")
--        return get_default_gateway()
--    return latest_address
-+    if lease_file:
-+        latest_address = dhcp.IscDhclient.parse_dhcp_server_from_lease_file(
-+            lease_file
-+        )
-+        if latest_address:
-+            return latest_address
-+
-+    # No virtual router found, fallback to default gateway
-+    LOG.debug("No DHCP found, using default gateway")
-+    return get_default_gateway()
- 
- 
- # Used to match classes to dependencies
--- 
-2.39.3
-
diff --git a/SOURCES/ci-fix-dhcp-Guard-against-FileNotFoundError-and-NameErr.patch b/SOURCES/ci-fix-dhcp-Guard-against-FileNotFoundError-and-NameErr.patch
deleted file mode 100644
index b7eb978..0000000
--- a/SOURCES/ci-fix-dhcp-Guard-against-FileNotFoundError-and-NameErr.patch
+++ /dev/null
@@ -1,132 +0,0 @@
-From 2b74b0eb94edfd7caa42bc0d8affc37311ba041b Mon Sep 17 00:00:00 2001
-From: Brett Holman <brett.holman@canonical.com>
-Date: Wed, 3 Jan 2024 09:11:21 -0700
-Subject: [PATCH 4/6] fix(dhcp): Guard against FileNotFoundError and NameError
- exceptions
-
-RH-Author: Ani Sinha <anisinha@redhat.com>
-RH-MergeRequest: 92: Update pylint version to support python 3.12
-RH-Jira: RHEL-44598
-RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
-RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
-RH-Commit: [1/3] 730b8de9ceb2c380d3b15573d83691ab95a1487e (anisinha/cloud-init)
-
-(cherry picked from commit 53eb8555e091474803b724700815adc09aa84f05)
----
- cloudinit/net/dhcp.py            | 20 ++++++++++------
- tests/unittests/net/test_dhcp.py | 40 ++++++++++++++++++++++++++++++++
- 2 files changed, 53 insertions(+), 7 deletions(-)
-
-diff --git a/cloudinit/net/dhcp.py b/cloudinit/net/dhcp.py
-index 07c13390..a0aee98c 100644
---- a/cloudinit/net/dhcp.py
-+++ b/cloudinit/net/dhcp.py
-@@ -5,15 +5,15 @@
- # This file is part of cloud-init. See LICENSE file for license information.
- 
- import abc
--import contextlib
- import glob
- import logging
- import os
- import re
- import signal
- import time
-+from contextlib import suppress
- from io import StringIO
--from typing import Any, Dict, List
-+from typing import Any, Dict, List, Optional
- 
- import configobj
- 
-@@ -268,7 +268,7 @@ class IscDhclient(DhcpClient):
- 
-         # this function waits for these files to exist, clean previous runs
-         # to avoid false positive in wait_for_files
--        with contextlib.suppress(FileNotFoundError):
-+        with suppress(FileNotFoundError):
-             os.remove(pid_file)
-             os.remove(lease_file)
- 
-@@ -514,9 +514,15 @@ class IscDhclient(DhcpClient):
-         return latest_file
- 
-     @staticmethod
--    def parse_dhcp_server_from_lease_file(lease_file):
--        with open(lease_file, "r") as fd:
--            for line in fd:
-+    def parse_dhcp_server_from_lease_file(lease_file) -> Optional[str]:
-+        """Parse a lease file for the dhcp server address
-+
-+        @param lease_file: Name of a file to be parsed
-+        @return: An address if found, or None
-+        """
-+        latest_address = None
-+        with suppress(FileNotFoundError), open(lease_file, "r") as file:
-+            for line in file:
-                 if "dhcp-server-identifier" in line:
-                     words = line.strip(" ;\r\n").split(" ")
-                     if len(words) > 2:
-@@ -561,7 +567,7 @@ class Udhcpc(DhcpClient):
- 
-         tmp_dir = temp_utils.get_tmp_ancestor(needs_exe=True)
-         lease_file = os.path.join(tmp_dir, interface + ".lease.json")
--        with contextlib.suppress(FileNotFoundError):
-+        with suppress(FileNotFoundError):
-             os.remove(lease_file)
- 
-         # udhcpc needs the interface up to send initial discovery packets
-diff --git a/tests/unittests/net/test_dhcp.py b/tests/unittests/net/test_dhcp.py
-index a7b62312..8ec96eef 100644
---- a/tests/unittests/net/test_dhcp.py
-+++ b/tests/unittests/net/test_dhcp.py
-@@ -32,6 +32,46 @@ LEASE_F = "/run/dhclient.lease"
- DHCLIENT = "/sbin/dhclient"
- 
- 
-+@pytest.mark.parametrize(
-+    "server_address,lease_file_content",
-+    (
-+        pytest.param(None, None, id="no_server_addr_on_absent_lease_file"),
-+        pytest.param(None, "", id="no_server_addr_on_empty_lease_file"),
-+        pytest.param(
-+            None,
-+            "lease {\n  fixed-address: 10.1.2.3;\n}\n",
-+            id="no_server_addr_when_no_server_ident",
-+        ),
-+        pytest.param(
-+            "10.4.5.6",
-+            "lease {\n fixed-address: 10.1.2.3;\n"
-+            "  option dhcp-server-identifier 10.4.5.6;\n"
-+            "  option dhcp-renewal-time 1800;\n}\n",
-+            id="server_addr_found_when_server_ident_present",
-+        ),
-+    ),
-+)
-+class TestParseDHCPServerFromLeaseFile:
-+    def test_find_server_address_when_present(
-+        self, server_address, lease_file_content, tmp_path
-+    ):
-+        """Test that we return None in the case of no file or file contains no
-+        server address, otherwise return the address.
-+        """
-+        lease_file = tmp_path / "dhcp.leases"
-+        if server_address:
-+            if lease_file_content:
-+                lease_file.write_text(lease_file_content)
-+            assert (
-+                server_address
-+                == IscDhclient.parse_dhcp_server_from_lease_file(lease_file)
-+            )
-+        else:
-+            assert not IscDhclient.parse_dhcp_server_from_lease_file(
-+                lease_file
-+            )
-+
-+
- class TestParseDHCPLeasesFile(CiTestCase):
-     def test_parse_empty_lease_file_errors(self):
-         """parse_dhcp_lease_file errors when file content is empty."""
--- 
-2.39.3
-
diff --git a/SOURCES/ci-fix-jsonschema-Add-missing-sudo-definition-5418.patch b/SOURCES/ci-fix-jsonschema-Add-missing-sudo-definition-5418.patch
deleted file mode 100644
index 221d24f..0000000
--- a/SOURCES/ci-fix-jsonschema-Add-missing-sudo-definition-5418.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-From b7fddab36d805099639358736dab474d2924906b Mon Sep 17 00:00:00 2001
-From: Brett Holman <brett.holman@canonical.com>
-Date: Wed, 19 Jun 2024 17:07:56 -0600
-Subject: [PATCH 2/6] fix(jsonschema): Add missing sudo definition (#5418)
-
-RH-Author: Ani Sinha <anisinha@redhat.com>
-RH-MergeRequest: 90: fix(jsonschema): Add missing sudo definition (#5418)
-RH-Jira: RHEL-44337
-RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
-RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
-RH-Commit: [1/2] 9e56c7ab35744c6530c8cef2f122ffdcc0480d29 (anisinha/cloud-init)
-
-This configuration:
-
-```
-users:
-  - name: osadmin
-    lock_passwd: false
-    sudo: ["ALL=(ALL) NOPASSWD:ALL"]
-```
-
-Is valid syntax but is missing from the jsonschema definition.
-
-Fixes GH-5399
-
-(cherry picked from commit b533fa51acb850ed754e2b1925e276ff8e5f3507)
----
- cloudinit/config/schemas/schema-cloud-config-v1.json | 9 +++++++++
- 1 file changed, 9 insertions(+)
-
-diff --git a/cloudinit/config/schemas/schema-cloud-config-v1.json b/cloudinit/config/schemas/schema-cloud-config-v1.json
-index a553c52c..8b10fe70 100644
---- a/cloudinit/config/schemas/schema-cloud-config-v1.json
-+++ b/cloudinit/config/schemas/schema-cloud-config-v1.json
-@@ -299,6 +299,15 @@
-               ],
-               "description": "Sudo rule to use or false. Absence of a sudo value or ``null`` will result in no sudo rules added for this user."
-             },
-+            {
-+              "type": "array",
-+              "items": {
-+                "type": [
-+                  "string",
-+                  "null"
-+                ]
-+              }
-+            },
-             {
-               "type": "boolean",
-               "changed": true,
--- 
-2.39.3
-
diff --git a/SOURCES/ci-fix-schema-permit-deprecated-hyphenated-keys-under-u.patch b/SOURCES/ci-fix-schema-permit-deprecated-hyphenated-keys-under-u.patch
deleted file mode 100644
index 82723c2..0000000
--- a/SOURCES/ci-fix-schema-permit-deprecated-hyphenated-keys-under-u.patch
+++ /dev/null
@@ -1,412 +0,0 @@
-From ce69cd178d9c05827db1ca1654de82dc3f9f521e Mon Sep 17 00:00:00 2001
-From: Chad Smith <chad.smith@canonical.com>
-Date: Thu, 27 Jun 2024 18:12:31 -0600
-Subject: [PATCH 3/3] fix(schema): permit deprecated hyphenated keys under
- users key (#5456)
-
-RH-Author: Ani Sinha <anisinha@redhat.com>
-RH-MergeRequest: 95: Deprecate the users ssh-authorized-keys property (#5162)
-RH-Jira: RHEL-45262
-RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
-RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
-RH-Commit: [3/3] 76804599a9166796dc52bab2031a706993ad2e3c (anisinha/cloud-init)
-
-Both hyphenated and underscore delimited key names are permitted
-by cloudinit/distros/ug_util.py#L114 due to magic replacement
-of key names.
-
-Since this is still valid json schema, add the necessary hyphenated
-aliases for all users/groups keys. Because the goal in the future is
-to only support one config key for a given configuraion option, add
-deprecated keys to those schema definitions.
-
-Also drop the description key from the deprecates lock-passwd schema
-key.
-
-Any deprecated schema key which provides a suggested replacement should
-not provide duplicated key descriptions as the preferred replacement
-will provided the necessary context.
-
-Fixes GH-5454
-
-(cherry picked from commit b3618d44a37ae6345f0c3d935b77ae0ae9dd1c92)
----
- .../schemas/schema-cloud-config-v1.json       | 103 +++++++++++++-----
- tests/unittests/config/test_cc_grub_dpkg.py   |   4 +-
- .../test_cc_package_update_upgrade_install.py |  11 +-
- .../unittests/config/test_cc_users_groups.py  |  33 +++---
- tests/unittests/config/test_schema.py         |  15 ++-
- 5 files changed, 108 insertions(+), 58 deletions(-)
-
-diff --git a/cloudinit/config/schemas/schema-cloud-config-v1.json b/cloudinit/config/schemas/schema-cloud-config-v1.json
-index 97cf2b74..03e723e2 100644
---- a/cloudinit/config/schemas/schema-cloud-config-v1.json
-+++ b/cloudinit/config/schemas/schema-cloud-config-v1.json
-@@ -178,9 +178,9 @@
-               "patternProperties": {
-                 "^.+$": {
-                   "label": "<group_name>",
--                  "description": "When providing an object for users.groups the ``<group_name>`` keys are the groups to add this user to",
-                   "deprecated": true,
-                   "deprecated_version": "23.1",
-+                  "deprecated_description": "The use of ``object`` type is deprecated. Use ``string`` or ``array`` of ``string`` instead.",
-                   "type": [
-                     "null"
-                   ],
-@@ -203,9 +203,7 @@
-           "type": "string"
-         },
-         "lock-passwd": {
--          "default": true,
-           "type": "boolean",
--          "description": "Default: ``true``",
-           "deprecated": true,
-           "deprecated_version": "22.3",
-           "deprecated_description": "Use ``lock_passwd`` instead."
-@@ -215,16 +213,34 @@
-           "description": "Disable password login. Default: ``true``",
-           "type": "boolean"
-         },
-+        "no-create-home": {
-+          "type": "boolean",
-+          "deprecated": true,
-+          "deprecated_version": "24.2",
-+          "deprecated_description": "Use ``no_create_home`` instead."
-+        },
-         "no_create_home": {
-           "default": false,
-           "description": "Do not create home directory. Default: ``false``",
-           "type": "boolean"
-         },
-+        "no-log-init": {
-+          "type": "boolean",
-+          "deprecated": true,
-+          "deprecated_version": "24.2",
-+          "deprecated_description": "Use ``no_log_init`` instead."
-+        },
-         "no_log_init": {
-           "default": false,
-           "description": "Do not initialize lastlog and faillog for user. Default: ``false``",
-           "type": "boolean"
-         },
-+        "no-user-group": {
-+          "type": "boolean",
-+          "deprecated": true,
-+          "deprecated_version": "24.2",
-+          "deprecated_description": "Use ``no_user_group`` instead."
-+        },
-         "no_user_group": {
-           "default": false,
-           "description": "Do not create group named after user. Default: ``false``",
-@@ -234,24 +250,54 @@
-           "description": "Hash of user password applied when user does not exist. This will NOT be applied if the user already exists. To generate this hash, run: mkpasswd --method=SHA-512 --rounds=4096. **Note:** While hashed password is better than plain text, using ``passwd`` in user-data represents a security risk as user-data could be accessible by third-parties depending on your cloud platform.",
-           "type": "string"
-         },
-+        "hashed-passwd": {
-+          "type": "string",
-+          "deprecated": true,
-+          "deprecated_version": "24.2",
-+          "deprecated_description": "Use ``hashed_passwd`` instead."
-+        },
-         "hashed_passwd": {
-           "description": "Hash of user password to be applied. This will be applied even if the user is pre-existing. To generate this hash, run: mkpasswd --method=SHA-512 --rounds=4096. **Note:** While ``hashed_password`` is better than ``plain_text_passwd``, using ``passwd`` in user-data represents a security risk as user-data could be accessible by third-parties depending on your cloud platform.",
-           "type": "string"
-         },
-+        "plain-text-passwd": {
-+          "type": "string",
-+          "deprecated": true,
-+          "deprecated_version": "24.2",
-+          "deprecated_description": "Use ``plain_text_passwd`` instead."
-+        },
-         "plain_text_passwd": {
-           "description": "Clear text of user password to be applied. This will be applied even if the user is pre-existing. There are many more secure options than using plain text passwords, such as ``ssh_import_id`` or ``hashed_passwd``. Do not use this in production as user-data and your password can be exposed.",
-           "type": "string"
-         },
-+        "create-groups": {
-+          "type": "boolean",
-+          "deprecated": true,
-+          "deprecated_version": "24.2",
-+          "deprecated_description": "Use ``create_groups`` instead."
-+        },
-         "create_groups": {
-           "default": true,
-           "description": "Boolean set ``false`` to disable creation of specified user ``groups``. Default: ``true``.",
-           "type": "boolean"
-         },
-+        "primary-group": {
-+          "type": "string",
-+          "deprecated": true,
-+          "deprecated_version": "24.2",
-+          "deprecated_description": "Use ``primary_group`` instead."
-+        },
-         "primary_group": {
-           "default": "``<username>``",
-           "description": "Primary group for user. Default: ``<username>``",
-           "type": "string"
-         },
-+        "selinux-user": {
-+          "type": "string",
-+          "deprecated": true,
-+          "deprecated_version": "24.2",
-+          "deprecated_description": "Use ``selinux_user`` instead."
-+        },
-         "selinux_user": {
-           "description": "SELinux user for user's login. Default to default SELinux user.",
-           "type": "string"
-@@ -273,20 +319,24 @@
-           "minItems": 1
-         },
-         "ssh-authorized-keys": {
--          "allOf": [
--            {
--              "type": "array",
--              "items": {
--                "type": "string"
--              },
--              "minItems": 1
--            },
--            {
--              "deprecated": true,
--              "deprecated_version": "18.3",
--              "deprecated_description": "Use ``ssh_authorized_keys`` instead."
--            }
--          ]
-+          "type": "array",
-+          "items": {
-+            "type": "string"
-+          },
-+          "minItems": 1,
-+          "deprecated": true,
-+          "deprecated_version": "18.3",
-+          "deprecated_description": "Use ``ssh_authorized_keys`` instead."
-+        },
-+        "ssh-import-id": {
-+          "type": "array",
-+          "items": {
-+            "type": "string"
-+          },
-+          "minItems": 1,
-+          "deprecated": true,
-+          "deprecated_version": "24.2",
-+          "deprecated_description": "Use ``ssh_import_id`` instead."
-         },
-         "ssh_import_id": {
-           "description": "List of SSH IDs to import for user. Can not be combined with ``ssh_redirect_user``.",
-@@ -296,6 +346,12 @@
-           },
-           "minItems": 1
-         },
-+        "ssh-redirect-user": {
-+          "type": "boolean",
-+          "deprecated": true,
-+          "deprecated_version": "24.2",
-+          "deprecated_description": "Use ``ssh_redirect_user`` instead."
-+        },
-         "ssh_redirect_user": {
-           "type": "boolean",
-           "default": false,
-@@ -398,7 +454,6 @@
-       "properties": {
-         "remove-defaults": {
-           "type": "boolean",
--          "default": false,
-           "deprecated": true,
-           "deprecated_version": "22.3",
-           "deprecated_description": "Use ``remove_defaults`` instead."
-@@ -516,9 +571,9 @@
-         },
-         "system_info": {
-           "type": "object",
--          "description": "System and/or distro specific settings. This is not intended to be overridden by user data or vendor data.",
-           "deprecated": true,
--          "deprecated_version": "24.2"
-+          "deprecated_version": "24.2",
-+          "deprecated_description": "System and/or distro specific settings. This is not intended to be overridden by user data or vendor data."
-         }
-       }
-     },
-@@ -1483,7 +1538,6 @@
-         },
-         "grub-dpkg": {
-           "type": "object",
--          "description": "An alias for ``grub_dpkg``",
-           "deprecated": true,
-           "deprecated_version": "22.2",
-           "deprecated_description": "Use ``grub_dpkg`` instead."
-@@ -2082,24 +2136,18 @@
-         },
-         "apt_update": {
-           "type": "boolean",
--          "default": false,
--          "description": "Default: ``false``.",
-           "deprecated": true,
-           "deprecated_version": "22.2",
-           "deprecated_description": "Use ``package_update`` instead."
-         },
-         "apt_upgrade": {
-           "type": "boolean",
--          "default": false,
--          "description": "Default: ``false``.",
-           "deprecated": true,
-           "deprecated_version": "22.2",
-           "deprecated_description": "Use ``package_upgrade`` instead."
-         },
-         "apt_reboot_if_required": {
-           "type": "boolean",
--          "default": false,
--          "description": "Default: ``false``.",
-           "deprecated": true,
-           "deprecated_version": "22.2",
-           "deprecated_description": "Use ``package_reboot_if_required`` instead."
-@@ -2798,7 +2846,6 @@
-                 }
-               ],
-               "minItems": 1,
--              "description": "List of ``username:password`` pairs. Each user will have the corresponding password set. A password can be randomly generated by specifying ``RANDOM`` or ``R`` as a user's password. A hashed password, created by a tool like ``mkpasswd``, can be specified. A regex (``r'\\$(1|2a|2y|5|6)(\\$.+){2}'``) is used to determine if a password value should be treated as a hash.",
-               "deprecated": true,
-               "deprecated_version": "22.2",
-               "deprecated_description": "Use ``users`` instead."
-diff --git a/tests/unittests/config/test_cc_grub_dpkg.py b/tests/unittests/config/test_cc_grub_dpkg.py
-index b4bd48df..36ef7fd9 100644
---- a/tests/unittests/config/test_cc_grub_dpkg.py
-+++ b/tests/unittests/config/test_cc_grub_dpkg.py
-@@ -300,8 +300,8 @@ class TestGrubDpkgSchema:
-                 pytest.raises(
-                     SchemaValidationError,
-                     match=(
--                        "Cloud config schema deprecations: grub-dpkg: An alias"
--                        " for ``grub_dpkg`` Deprecated in version 22.2. Use "
-+                        "Cloud config schema deprecations: grub-dpkg:"
-+                        "  Deprecated in version 22.2. Use "
-                         "``grub_dpkg`` instead."
-                     ),
-                 ),
-diff --git a/tests/unittests/config/test_cc_package_update_upgrade_install.py b/tests/unittests/config/test_cc_package_update_upgrade_install.py
-index 9ba7f178..734dbc53 100644
---- a/tests/unittests/config/test_cc_package_update_upgrade_install.py
-+++ b/tests/unittests/config/test_cc_package_update_upgrade_install.py
-@@ -192,16 +192,16 @@ class TestPackageUpdateUpgradeSchema:
-             (
-                 {"apt_update": False},
-                 (
--                    "Cloud config schema deprecations: apt_update: "
--                    "Default: ``false``. Deprecated in version 22.2. "
-+                    "Cloud config schema deprecations: apt_update:  "
-+                    "Deprecated in version 22.2. "
-                     "Use ``package_update`` instead."
-                 ),
-             ),
-             (
-                 {"apt_upgrade": False},
-                 (
--                    "Cloud config schema deprecations: apt_upgrade: "
--                    "Default: ``false``. Deprecated in version 22.2. "
-+                    "Cloud config schema deprecations: apt_upgrade:  "
-+                    "Deprecated in version 22.2. "
-                     "Use ``package_upgrade`` instead."
-                 ),
-             ),
-@@ -209,8 +209,7 @@ class TestPackageUpdateUpgradeSchema:
-                 {"apt_reboot_if_required": False},
-                 (
-                     "Cloud config schema deprecations: "
--                    "apt_reboot_if_required: Default: ``false``. "
--                    "Deprecated in version 22.2. Use "
-+                    "apt_reboot_if_required:  Deprecated in version 22.2. Use "
-                     "``package_reboot_if_required`` instead."
-                 ),
-             ),
-diff --git a/tests/unittests/config/test_cc_users_groups.py b/tests/unittests/config/test_cc_users_groups.py
-index 53e231e1..4ca67f77 100644
---- a/tests/unittests/config/test_cc_users_groups.py
-+++ b/tests/unittests/config/test_cc_users_groups.py
-@@ -371,9 +371,20 @@ class TestUsersGroupsSchema:
-                     SchemaValidationError,
-                     match=(
-                         "Cloud config schema deprecations: "
--                        "users.0.lock-passwd: Default: ``true`` "
--                        "Deprecated in version 22.3. Use "
--                        "``lock_passwd`` instead."
-+                        "users.0.lock-passwd:  Deprecated in version 22.3."
-+                        " Use ``lock_passwd`` instead."
-+                    ),
-+                ),
-+                False,
-+            ),
-+            (
-+                {"users": [{"name": "bbsw", "no-create-home": True}]},
-+                pytest.raises(
-+                    SchemaValidationError,
-+                    match=(
-+                        "Cloud config schema deprecations: "
-+                        "users.0.no-create-home:  Deprecated in version 24.2."
-+                        " Use ``no_create_home`` instead."
-                     ),
-                 ),
-                 False,
-@@ -394,13 +405,10 @@ class TestUsersGroupsSchema:
-                     SchemaValidationError,
-                     match=(
-                         "Cloud config schema deprecations: "
--                        "users.0.groups.adm: When providing an object "
--                        "for users.groups the ``<group_name>`` keys "
--                        "are the groups to add this user to Deprecated"
--                        " in version 23.1., users.0.groups.sudo: When "
--                        "providing an object for users.groups the "
--                        "``<group_name>`` keys are the groups to add "
--                        "this user to Deprecated in version 23.1."
-+                        "users.0.groups.adm:  Deprecated in version 23.1. "
-+                        "The use of ``object`` type is deprecated. Use "
-+                        "``string`` or ``array`` of ``string`` instead., "
-+                        "users.0.groups.sudo:  Deprecated in version 23.1."
-                     ),
-                 ),
-                 False,
-@@ -456,10 +464,7 @@ class TestUsersGroupsSchema:
-                     SchemaValidationError,
-                     match=(
-                         "Cloud config schema deprecations: "
--                        "user.groups.sbuild: When providing an object "
--                        "for users.groups the ``<group_name>`` keys "
--                        "are the groups to add this user to Deprecated"
--                        " in version 23.1."
-+                        "user.groups.sbuild:  Deprecated in version 23.1."
-                     ),
-                 ),
-                 False,
-diff --git a/tests/unittests/config/test_schema.py b/tests/unittests/config/test_schema.py
-index 52667332..8208affc 100644
---- a/tests/unittests/config/test_schema.py
-+++ b/tests/unittests/config/test_schema.py
-@@ -2251,9 +2251,9 @@ class TestHandleSchemaArgs:
-                     apt_reboot_if_required: true            # D3
- 
-                     # Deprecations: -------------
--                    # D1: Default: ``false``. Deprecated in version 22.2. Use ``package_update`` instead.
--                    # D2: Default: ``false``. Deprecated in version 22.2. Use ``package_upgrade`` instead.
--                    # D3: Default: ``false``. Deprecated in version 22.2. Use ``package_reboot_if_required`` instead.
-+                    # D1: Deprecated in version 22.2. Use ``package_update`` instead.
-+                    # D2: Deprecated in version 22.2. Use ``package_upgrade`` instead.
-+                    # D3: Deprecated in version 22.2. Use ``package_reboot_if_required`` instead.
- 
-                     Valid schema {cfg_file}
-                     """  # noqa: E501
-@@ -2264,11 +2264,10 @@ class TestHandleSchemaArgs:
-                 dedent(
-                     """\
-                     Cloud config schema deprecations: \
--apt_reboot_if_required: Default: ``false``. Deprecated in version 22.2.\
-- Use ``package_reboot_if_required`` instead., apt_update: Default: \
--``false``. Deprecated in version 22.2. Use ``package_update`` instead.,\
-- apt_upgrade: Default: ``false``. Deprecated in version 22.2. Use \
--``package_upgrade`` instead.\
-+apt_reboot_if_required: Deprecated in version 22.2. Use\
-+ ``package_reboot_if_required`` instead., apt_update: Deprecated in version\
-+ 22.2. Use ``package_update`` instead., apt_upgrade: Deprecated in version\
-+ 22.2. Use ``package_upgrade`` instead.\
-                     Valid schema {cfg_file}
-                     """  # noqa: E501
-                 ),
--- 
-2.39.3
-
diff --git a/SOURCES/ci-fix-vmware-Set-IPv6-to-dhcp-when-there-is-no-IPv6-ad.patch b/SOURCES/ci-fix-vmware-Set-IPv6-to-dhcp-when-there-is-no-IPv6-ad.patch
deleted file mode 100644
index 615e767..0000000
--- a/SOURCES/ci-fix-vmware-Set-IPv6-to-dhcp-when-there-is-no-IPv6-ad.patch
+++ /dev/null
@@ -1,185 +0,0 @@
-From 9ee9fe608b906fe4e523cbf7fbe4539f0322ba2f Mon Sep 17 00:00:00 2001
-From: PengpengSun <40026211+PengpengSun@users.noreply.github.com>
-Date: Thu, 4 Jul 2024 04:06:39 +0800
-Subject: [PATCH 2/2] fix(vmware): Set IPv6 to dhcp when there is no IPv6 addr
- (#5471)
-
-RH-Author: xiachen <xiachen@redhat.com>
-RH-MergeRequest: 99: fix(vmware): Set IPv6 to dhcp when there is no IPv6 addr (#5471)
-RH-Jira: RHEL-46194
-RH-Acked-by: Ani Sinha <anisinha@redhat.com>
-RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
-RH-Commit: [1/1] fbae24c7e7f48239200eaf457d260203fb550845 (xiachen/cloud-init-centos)
-
-When there is no IPv6 addr given in the customization configuration,
-we shall set IPv6 type to dhcp6, then customized Linux network will be
-set to dhcp IPv6 explicitly.
-
-(cherry picked from commit 2b6fe6403db769de14f7c7b7e4aa65f5bea8f3e0)
----
- .../sources/helpers/vmware/imc/config_nic.py  |  2 +-
- .../sources/vmware/test_vmware_config_file.py | 68 ++++++++++++++-----
- 2 files changed, 52 insertions(+), 18 deletions(-)
-
-diff --git a/cloudinit/sources/helpers/vmware/imc/config_nic.py b/cloudinit/sources/helpers/vmware/imc/config_nic.py
-index b07214a2..254518af 100644
---- a/cloudinit/sources/helpers/vmware/imc/config_nic.py
-+++ b/cloudinit/sources/helpers/vmware/imc/config_nic.py
-@@ -207,7 +207,7 @@ class NicConfigurator:
-         """
- 
-         if not nic.staticIpv6:
--            return ([], [])
-+            return ([{"type": "dhcp6"}], [])
- 
-         subnet_list = []
-         # Static Ipv6
-diff --git a/tests/unittests/sources/vmware/test_vmware_config_file.py b/tests/unittests/sources/vmware/test_vmware_config_file.py
-index b53ea96c..25d3b093 100644
---- a/tests/unittests/sources/vmware/test_vmware_config_file.py
-+++ b/tests/unittests/sources/vmware/test_vmware_config_file.py
-@@ -240,27 +240,45 @@ class TestVmwareConfigFile(CiTestCase):
-             elif cfg.get("name") == nic2.get("name"):
-                 nic2.update(cfg)
- 
-+        # Test NIC1
-         self.assertEqual("physical", nic1.get("type"), "type of NIC1")
-         self.assertEqual("NIC1", nic1.get("name"), "name of NIC1")
-         self.assertEqual(
-             "00:50:56:a6:8c:08", nic1.get("mac_address"), "mac address of NIC1"
-         )
-         subnets = nic1.get("subnets")
--        self.assertEqual(1, len(subnets), "number of subnets for NIC1")
--        subnet = subnets[0]
--        self.assertEqual("dhcp", subnet.get("type"), "DHCP type for NIC1")
--        self.assertEqual("auto", subnet.get("control"), "NIC1 Control type")
-+        self.assertEqual(2, len(subnets), "number of subnets for NIC1")
-+        subnet_ipv4 = subnets[0]
-+        self.assertEqual(
-+            "dhcp", subnet_ipv4.get("type"), "Ipv4 DHCP type for NIC1"
-+        )
-+        self.assertEqual(
-+            "auto", subnet_ipv4.get("control"), "NIC1 Control type"
-+        )
-+        subnet_ipv6 = subnets[1]
-+        self.assertEqual(
-+            "dhcp6", subnet_ipv6.get("type"), "Ipv6 DHCP type for NIC1"
-+        )
- 
-+        # Test NIC2
-         self.assertEqual("physical", nic2.get("type"), "type of NIC2")
-         self.assertEqual("NIC2", nic2.get("name"), "name of NIC2")
-         self.assertEqual(
-             "00:50:56:a6:5a:de", nic2.get("mac_address"), "mac address of NIC2"
-         )
-         subnets = nic2.get("subnets")
--        self.assertEqual(1, len(subnets), "number of subnets for NIC2")
--        subnet = subnets[0]
--        self.assertEqual("dhcp", subnet.get("type"), "DHCP type for NIC2")
--        self.assertEqual("auto", subnet.get("control"), "NIC2 Control type")
-+        self.assertEqual(2, len(subnets), "number of subnets for NIC2")
-+        subnet_ipv4 = subnets[0]
-+        self.assertEqual(
-+            "dhcp", subnet_ipv4.get("type"), "Ipv4 DHCP type for NIC2"
-+        )
-+        self.assertEqual(
-+            "auto", subnet_ipv4.get("control"), "NIC2 Control type"
-+        )
-+        subnet_ipv6 = subnets[1]
-+        self.assertEqual(
-+            "dhcp6", subnet_ipv6.get("type"), "Ipv6 DHCP type for NIC2"
-+        )
- 
-     def test_get_nics_list_static(self):
-         """Tests if NicConfigurator properly calculates network subnets
-@@ -285,6 +303,7 @@ class TestVmwareConfigFile(CiTestCase):
-                 elif cfg.get("name") == nic2.get("name"):
-                     nic2.update(cfg)
- 
-+        # Test NIC1
-         self.assertEqual("physical", nic1.get("type"), "type of NIC1")
-         self.assertEqual("NIC1", nic1.get("name"), "name of NIC1")
-         self.assertEqual(
-@@ -344,6 +363,7 @@ class TestVmwareConfigFile(CiTestCase):
-             else:
-                 self.assertEqual(True, False, "invalid gateway %s" % (gateway))
- 
-+        # Test NIC2
-         self.assertEqual("physical", nic2.get("type"), "type of NIC2")
-         self.assertEqual("NIC2", nic2.get("name"), "name of NIC2")
-         self.assertEqual(
-@@ -351,16 +371,18 @@ class TestVmwareConfigFile(CiTestCase):
-         )
- 
-         subnets = nic2.get("subnets")
--        self.assertEqual(1, len(subnets), "Number of subnets for NIC2")
-+        self.assertEqual(2, len(subnets), "Number of subnets for NIC2")
- 
--        subnet = subnets[0]
--        self.assertEqual("static", subnet.get("type"), "Subnet type")
-+        subnet_ipv4 = subnets[0]
-+        self.assertEqual("static", subnet_ipv4.get("type"), "Subnet type")
-         self.assertEqual(
--            "192.168.6.102", subnet.get("address"), "Subnet address"
-+            "192.168.6.102", subnet_ipv4.get("address"), "Subnet address"
-         )
-         self.assertEqual(
--            "255.255.0.0", subnet.get("netmask"), "Subnet netmask"
-+            "255.255.0.0", subnet_ipv4.get("netmask"), "Subnet netmask"
-         )
-+        subnet_ipv6 = subnets[1]
-+        self.assertEqual("dhcp6", subnet_ipv6.get("type"), "Subnet type")
- 
-     def test_custom_script(self):
-         cf = ConfigFile("tests/data/vmware/cust-dhcp-2nic.cfg")
-@@ -447,7 +469,10 @@ class TestVmwareNetConfig(CiTestCase):
-                             "type": "static",
-                             "address": "10.20.87.154",
-                             "netmask": "255.255.252.0",
--                        }
-+                        },
-+                        {
-+                            "type": "dhcp6",
-+                        },
-                     ],
-                 }
-             ],
-@@ -498,7 +523,10 @@ class TestVmwareNetConfig(CiTestCase):
-                                     "metric": 10000,
-                                 }
-                             ],
--                        }
-+                        },
-+                        {
-+                            "type": "dhcp6",
-+                        },
-                     ],
-                 }
-             ],
-@@ -558,7 +586,10 @@ class TestVmwareNetConfig(CiTestCase):
-                                     "metric": 10000,
-                                 }
-                             ],
--                        }
-+                        },
-+                        {
-+                            "type": "dhcp6",
-+                        },
-                     ],
-                 }
-             ],
-@@ -603,7 +634,10 @@ class TestVmwareNetConfig(CiTestCase):
-                             "address": "10.20.87.154",
-                             "netmask": "255.255.252.0",
-                             "gateway": "10.20.87.253",
--                        }
-+                        },
-+                        {
-+                            "type": "dhcp6",
-+                        },
-                     ],
-                 }
-             ],
--- 
-2.39.3
-
diff --git a/SOURCES/ci-net-sysconfig-do-not-remove-all-existing-settings-of.patch b/SOURCES/ci-net-sysconfig-do-not-remove-all-existing-settings-of.patch
new file mode 100644
index 0000000..b12b343
--- /dev/null
+++ b/SOURCES/ci-net-sysconfig-do-not-remove-all-existing-settings-of.patch
@@ -0,0 +1,144 @@
+From fe6b81e710c8e45652a1abe853b3537a61d44229 Mon Sep 17 00:00:00 2001
+From: Ani Sinha <anisinha@redhat.com>
+Date: Sat, 15 Feb 2025 01:54:31 +0530
+Subject: [PATCH] net/sysconfig: do not remove all existing settings of
+ /etc/sysconfig/network (#5991)
+
+RH-Author: Ani Sinha <anisinha@redhat.com>
+RH-MergeRequest: 124: net/sysconfig: do not remove all existing settings of /etc/sysconfig/network (#5991)
+RH-Jira: RHEL-76361
+RH-Acked-by: xiachen <xiachen@redhat.com>
+RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
+RH-Commit: [1/1] 9c9d5a23d693103f93a4683512dfb9654aa39d77 (anisinha/cloud-init)
+
+In some distros, /etc/sysconfig/network may have important configurations that
+are necessary for the instance to come up. For example, centos based distros
+write NOZEROCONF=yes in /etc/sysconfig/network for some instances that require
+zeroconf to be disabled. Removing these customizations would prevent the
+instance to come up. So leave the customizations in /etc/sysconfig/network
+intact except those that we are interested in.
+
+Fixes GH-5990
+Signed-off-by: Ani Sinha <anisinha@redhat.com>
+(cherry picked from commit fa331315d22f4bbe33320485e89a02bb2f695fbf)
+---
+ cloudinit/net/sysconfig.py                | 18 +++++++
+ tests/unittests/distros/test_netconfig.py | 62 ++++++++++++++++++++++-
+ 2 files changed, 78 insertions(+), 2 deletions(-)
+
+diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
+index 2151db3ab..bce307286 100644
+--- a/cloudinit/net/sysconfig.py
++++ b/cloudinit/net/sysconfig.py
+@@ -1119,6 +1119,24 @@ class Renderer(renderer.Renderer):
+             if network_state.use_ipv6:
+                 netcfg.append("NETWORKING_IPV6=yes")
+                 netcfg.append("IPV6_AUTOCONF=no")
++
++            # if sysconfig file exists and is not empty, append rest of the
++            # file content, do not remove the exsisting customizations.
++            if os.path.exists(sysconfig_path):
++                for line in util.load_text_file(sysconfig_path).splitlines():
++                    if (
++                        not any(
++                            setting in line
++                            for setting in [
++                                "NETWORKING",
++                                "NETWORKING_IPV6",
++                                "IPV6_AUTOCONF",
++                            ]
++                        )
++                        and line not in _make_header().splitlines()
++                    ):
++                        netcfg.append(line)
++
+             util.write_file(
+                 sysconfig_path, "\n".join(netcfg) + "\n", file_mode
+             )
+diff --git a/tests/unittests/distros/test_netconfig.py b/tests/unittests/distros/test_netconfig.py
+index 3768623f2..72887252d 100644
+--- a/tests/unittests/distros/test_netconfig.py
++++ b/tests/unittests/distros/test_netconfig.py
+@@ -691,12 +691,16 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
+         return "/etc/sysconfig/network"
+ 
+     def _apply_and_verify(
+-        self, apply_fn, config, expected_cfgs=None, bringup=False
++        self,
++        apply_fn,
++        config,
++        expected_cfgs=None,
++        bringup=False,
++        tmpd=None,
+     ):
+         if not expected_cfgs:
+             raise ValueError("expected_cfg must not be None")
+ 
+-        tmpd = None
+         with mock.patch("cloudinit.net.sysconfig.available") as m_avail:
+             m_avail.return_value = True
+             with self.reRooted(tmpd) as tmpd:
+@@ -789,6 +793,60 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
+             expected_cfgs=expected_cfgs.copy(),
+         )
+ 
++    def test_sysconfig_network_no_overwite_ipv6_rh(self):
++        expected_cfgs = {
++            self.ifcfg_path("eth0"): dedent(
++                """\
++                AUTOCONNECT_PRIORITY=120
++                BOOTPROTO=none
++                DEFROUTE=yes
++                DEVICE=eth0
++                IPV6ADDR=2607:f0d0:1002:0011::2/64
++                IPV6INIT=yes
++                IPV6_AUTOCONF=no
++                IPV6_DEFAULTGW=2607:f0d0:1002:0011::1
++                IPV6_FORCE_ACCEPT_RA=no
++                ONBOOT=yes
++                TYPE=Ethernet
++                USERCTL=no
++                """
++            ),
++            self.ifcfg_path("eth1"): dedent(
++                """\
++                AUTOCONNECT_PRIORITY=120
++                BOOTPROTO=dhcp
++                DEVICE=eth1
++                ONBOOT=yes
++                TYPE=Ethernet
++                USERCTL=no
++                """
++            ),
++            self.control_path(): dedent(
++                """\
++                NETWORKING=yes
++                NETWORKING_IPV6=yes
++                IPV6_AUTOCONF=no
++                NOZEROCONF=yes
++                """
++            ),
++        }
++        tmpdir = self.tmp_dir()
++        file_mode = 0o644
++        # pre-existing config in /etc/sysconfig/network should not be removed
++        with self.reRooted(tmpdir) as tmpdir:
++            util.write_file(
++                self.control_path(),
++                "".join("NOZEROCONF=yes") + "\n",
++                file_mode,
++            )
++
++        self._apply_and_verify(
++            self.distro.apply_network_config,
++            V1_NET_CFG_IPV6,
++            expected_cfgs=expected_cfgs.copy(),
++            tmpd=tmpdir,
++        )
++
+     def test_vlan_render_unsupported(self):
+         """Render officially unsupported vlan names."""
+         cfg = {
+-- 
+2.48.1
+
diff --git a/SPECS/cloud-init.spec b/SPECS/cloud-init.spec
index f41b97b..b895649 100644
--- a/SPECS/cloud-init.spec
+++ b/SPECS/cloud-init.spec
@@ -1,6 +1,6 @@
 Name:           cloud-init
-Version:        23.4
-Release:        19%{?dist}.alma.1
+Version:        24.4
+Release:        4%{?dist}.alma.1
 Summary:        Cloud instance init scripts
 License:        ASL 2.0 or GPLv3
 URL:            http://launchpad.net/cloud-init
@@ -8,67 +8,21 @@ Source0:        https://github.com/canonical/cloud-init/archive/refs/tags/%{vers
 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
-# For RHEL-22255 - [Azure][RHEL-9] cloud-init-23.4 cannot read "- Azure" datasource_list format
-Patch9: ci-Revert-Use-grep-for-faster-parsing-of-cloud-config-i.patch
-Patch10: ci-Pin-pythes-8.0.0.patch
-# For RHEL-21324 - [rhel-9] The schema WARNING info for network-config.json is not suitable in cloud-init-23.4
-Patch11: ci-fix-Add-types-to-network-v1-schema-4841.patch
-# For RHEL-28549 - [RHEL 9.4] cloud-init 23.4 returns 2 on recoverable errors instead of 0
-Patch12: ci-Retain-exit-code-in-cloud-init-status-for-recoverabl.patch
-# For RHEL-20964 - [rhel-9]cloud-init fails to configure DNS/search domains for network-config v1
-Patch13: ci-fix-Correct-v2-NetworkManager-route-rendering-4637.patch
-# For RHEL-20964 - [rhel-9]cloud-init fails to configure DNS/search domains for network-config v1
-Patch14: ci-feat-apply-global-DNS-to-interfaces-in-network-manag.patch
-# For RHEL-29709 - Suggest to backport patch ff40d1a to undeprecate 'network' in schema route definition
-Patch15: ci-fix-Undeprecate-network-in-schema-route-definition-5.patch
-# For RHEL-32846 - [cloud-init][ESXi]VMware datasource resets on every boot causing it to lose network configuration [rhel-9]
-Patch16: ci-fix-Fall-back-to-cached-local-ds-if-no-valid-ds-foun.patch
-# For RHEL-36255 - [rhel-9.5] DataSourceNoCloudNet not configurable via config files
-Patch17: ci-fix-Always-use-single-datasource-if-specified-5098.patch
-# For RHEL-40217 - [Cloud-init] CloudstackDataSource cannot work with NetworkManager
-Patch18: ci-fix-cloudstack-Use-parsed-lease-file-for-virtual-rou.patch
-# For RHEL-17961 - [RHEL-9] cloud-init fails to configure DNS search domains
-Patch19: ci-feat-sysconfig-Add-DNS-from-interface-config-to-reso.patch
-# For RHEL-44337 - [rhel-9] fix `SUDO` configuration schema for users and groups
-Patch20: ci-fix-jsonschema-Add-missing-sudo-definition-5418.patch
-# For RHEL-44337 - [rhel-9] fix `SUDO` configuration schema for users and groups
-Patch21: ci-doc-update-examples-to-reflect-alternative-ways-to-p.patch
-# For RHEL-44598 - fix pylint error and support python 3.12
-Patch22: ci-fix-dhcp-Guard-against-FileNotFoundError-and-NameErr.patch
-# For RHEL-44598 - fix pylint error and support python 3.12
-Patch23: ci-fix-Address-TIOBE-abstract-interpretation-issues-486.patch
-# For RHEL-44598 - fix pylint error and support python 3.12
-Patch24: ci-Update-pylint-version-to-support-python-3.12-5338.patch
-# For RHEL-45262 - Deprecate the users ssh-authorized-keys property and permit deprecated hyphenated keys under users key
-Patch25: ci-Deprecate-the-users-ssh-authorized-keys-property-516.patch
-# For RHEL-45262 - Deprecate the users ssh-authorized-keys property and permit deprecated hyphenated keys under users key
-Patch26: ci-docs-Add-deprecated-system_info-to-schema-5168.patch
-# For RHEL-45262 - Deprecate the users ssh-authorized-keys property and permit deprecated hyphenated keys under users key
-Patch27: ci-fix-schema-permit-deprecated-hyphenated-keys-under-u.patch
-# For RHEL-44916 - [RFE] Support metalink in yum repository config
-Patch28: ci-Support-metalink-in-yum-repository-config-5444.patch
-# For RHEL-46194 - [RHEL-9] It leaves the ipv6 networking config as blank in NM keyfile when config dhcp ipv6 with customization spec
-Patch29: ci-fix-vmware-Set-IPv6-to-dhcp-when-there-is-no-IPv6-ad.patch
-# For RHEL-46873 - Suggest to update schema to support metalink
-Patch30: ci-fix-add-schema-rules-for-baseurl-and-metalink-in-yum.patch
-# For RHEL-49736 - [Cloud-init] [RHEL-9] Password reset feature broken with CloudstackDataSource
-Patch31: ci-fix-Clean-cache-if-no-datasource-fallback-5499.patch
-# For RHEL-49674 - Support setting mirrorlist in yum repository config
-Patch32: ci-Support-setting-mirrorlist-in-yum-repository-config-.patch
-# For RHEL-54373 - [RHEL9]Revert "fix(vmware): Set IPv6 to dhcp when there is no IPv6 addr (#5471)"
-Patch33: ci-Revert-fix-vmware-Set-IPv6-to-dhcp-when-there-is-no-.patch
-# For RHEL-54686 - [RHEL-9.5] cloud-init schema validation fails.
-Patch34: ci-fix-Add-subnet-ipv4-ipv6-to-network-schema-5191.patch
+Patch1: 0001-downstream-Add-initial-redhat-changes.patch
+Patch2: 0002-downstream-Setting-autoconnect-priority-setting-for-.patch
+Patch3: 0004-downstream-Revert-chore-eliminate-redundant-ordering.patch
+Patch4: 0005-downstream-remove-single-process-optimization.patch
+Patch5: 0006-fix-don-t-deadlock-when-starting-network-service-wit.patch
+# For RHEL-74334 - [rhel-9.6] Suggest to continue using sysconfig as the default network renderer in rhel-9.6
+Patch6: ci-downstream-Revert-feat-Use-NetworkManager-renderer-b.patch
+# For RHEL-71122 - Suggest to change some log messages from warning to info after rebase cloud-init-24.4 [RHEL-9.6] 
+Patch7: ci-Use-log_with_downgradable_level-for-user-password-wa.patch
+# For RHEL-71122 - Suggest to change some log messages from warning to info after rebase cloud-init-24.4 [RHEL-9.6] 
+Patch8: ci-downstream-set-deprecation-boundary-version.patch
+# For RHEL-76361 - [c9s] cloud-init remove 'NOZEROCONF=yes' from /etc/sysconfig/network
+Patch9: ci-net-sysconfig-do-not-remove-all-existing-settings-of.patch
 
-# AlmaLinux OS patches
+# AlmaLinux Patch
 Patch3100: 0031-Improvements-for-AlmaLinux-OS-and-CloudLinux-OS.patch
 
 BuildArch:      noarch
@@ -278,19 +232,58 @@ fi
 %{_datadir}/bash-completion/completions/cloud-init
 %{_bindir}/cloud-id
 %{_systemdgeneratordir}/cloud-init-generator
-%{_sysconfdir}/systemd/system/sshd-keygen@.service.d/disable-sshd-keygen-if-cloud-init-active.conf
+%{_unitdir}/sshd-keygen@.service.d/disable-sshd-keygen-if-cloud-init-active.conf
 
 %dir %{_sysconfdir}/rsyslog.d
 %config(noreplace) %{_sysconfdir}/rsyslog.d/21-cloudinit.conf
 
 %changelog
-* Mon Sep 30 2024 Elkhan Mammadli <elkhan@almalinux.org> - 23.4-19.alma.1
+* Tue Mar 11 2025 Elkhan Mammadli <elkhan@almalinux.org> - 24.4-4.alma.1
 - 0031-Improvements-for-AlmaLinux-OS-and-CloudLinux-OS.patch
 
+* Mon Feb 17 2025 Jon Maloy <jmaloy@redhat.com> - 24.4-4
+- ci-net-sysconfig-do-not-remove-all-existing-settings-of.patch [RHEL-76361]
+- Resolves: RHEL-76361
+  ([c9s] cloud-init remove 'NOZEROCONF=yes' from /etc/sysconfig/network)
+
+* Mon Feb 10 2025 Jon Maloy <jmaloy@redhat.com> - 24.4-3
+- ci-Use-log_with_downgradable_level-for-user-password-wa.patch [RHEL-71122]
+- ci-downstream-set-deprecation-boundary-version.patch [RHEL-71122]
+- Resolves: RHEL-71122
+  (Suggest to change some log messages from warning to info after rebase cloud-init-24.4 [RHEL-9.6] )
+
+* Mon Jan 20 2025 Miroslav Rezanina <mrezanin@redhat.com> - 24.4-2
+- ci-downstream-Revert-feat-Use-NetworkManager-renderer-b.patch [RHEL-74334]
+- Resolves: RHEL-74334
+  ([rhel-9.6] Suggest to continue using sysconfig as the default network renderer in rhel-9.6)
+
+* Mon Jan 06 2025 Miroslav Rezanina <mrezanin@redhat.com> - 24.4-1
+- Rebase to 24.4 [RHEL-66251]
+- Resolves: RHEL-66251
+  ([RHEL-9] Rebase cloud-init to 24.4 version)
+
+* Mon Nov 18 2024 Miroslav Rezanina <mrezanin@redhat.com> - 23.4-22
+- ci-Prevent-NM-from-handling-DNS-when-network-interfaces.patch [RHEL-65768]
+- Resolves: RHEL-65768
+  ([RHEL-9] Prevent NM from handling DNS when network interfaces have DNS config)
+
+* Wed Nov 06 2024 Miroslav Rezanina <mrezanin@redhat.com> - 23.4-21
+- ci-fix-Render-bridges-correctly-for-v2-on-sysconfig-wit.patch [RHEL-38927]
+- ci-fix-Render-v2-bridges-correctly-on-network-manager-w.patch [RHEL-38927]
+- Resolves: RHEL-38927
+  (NoCloud - network_config bridges incorrectly configured)
+
+* Wed Oct 30 2024 Miroslav Rezanina <mrezanin@redhat.com> - 23.4-20
+- ci-Fix-metric-setting-for-ifcfg-network-connections-for.patch [RHEL-61224]
+- ci-fix-python3.13-Fix-import-error-for-passlib-on-Pytho.patch [RHEL-61224]
+- Resolves: RHEL-61224
+  (Configuring metric for default gateway is not working)
+
 * 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