diff --git a/pkgs/tools/virtualization/cloud-init/0001-add-nixos-support.patch b/pkgs/tools/virtualization/cloud-init/0001-add-nixos-support.patch index f79e3dda8497..f26690bacb70 100644 --- a/pkgs/tools/virtualization/cloud-init/0001-add-nixos-support.patch +++ b/pkgs/tools/virtualization/cloud-init/0001-add-nixos-support.patch @@ -12,10 +12,10 @@ index b82852e1..c998b21e 100644 LOG = logging.getLogger(__name__) diff --git a/cloudinit/distros/nixos.py b/cloudinit/distros/nixos.py new file mode 100644 -index 00000000..d53d2a61 +index 00000000..d53d2a62 --- /dev/null +++ b/cloudinit/distros/nixos.py -@@ -0,0 +1,103 @@ +@@ -0,0 +1,109 @@ +# vi: ts=4 expandtab +# +# Copyright (C) 2012 Canonical Ltd. @@ -47,6 +47,7 @@ index 00000000..d53d2a61 +from cloudinit import atomic_helper + +from cloudinit.distros.parsers.hostname import HostnameConf ++from cloudinit.net import dhcp + +LOG = logging.getLogger(__name__) + @@ -61,6 +62,11 @@ index 00000000..d53d2a61 + self.usr_lib_exec = os.path.join(os.path.dirname(__file__), + "../../../../../libexec") + self.osfamily = 'nixos' ++ self.dhcp_client_priority = [ ++ dhcp.Udhcpc, ++ dhcp.IscDhclient, ++ dhcp.Dhcpcd, ++ ] + + def _select_hostname(self, hostname, fqdn): + # Prefer the short hostname over the long @@ -112,10 +118,10 @@ index 00000000..d53d2a61 + raise NotImplementedError() + + def package_command(self, command, args=None, pkgs=None): -+ raise NotImplementedError() ++ pass + + def set_timezone(self, tz): -+ raise NotImplementedError() ++ pass + + def update_package_sources(self): -+ raise NotImplementedError() ++ pass diff --git a/pkgs/tools/virtualization/cloud-init/0002-Add-Udhcpc-support.patch b/pkgs/tools/virtualization/cloud-init/0002-Add-Udhcpc-support.patch index ef1694837691..0df3f27a2c40 100644 --- a/pkgs/tools/virtualization/cloud-init/0002-Add-Udhcpc-support.patch +++ b/pkgs/tools/virtualization/cloud-init/0002-Add-Udhcpc-support.patch @@ -1,15 +1,56 @@ +From 53260ce3bd70a0852d3e0d5569474214cea0ec0c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Roche?= +Date: Mon, 19 Jun 2023 15:56:46 +0200 +Subject: [PATCH] net/dhcp: add udhcpc support + +The currently used dhcp client, dhclient, is coming from the unmaintained package, isc-dhcp-client (refer https://www.isc.org/dhcp/) which ended support in 2022. + +This change introduce support for the dhcp client, udhcpc, from the busybox project. Busybox advantages are that it is available across many distributions and comes with lightweight executables. +--- + cloudinit/distros/__init__.py | 8 +- + cloudinit/net/dhcp.py | 129 ++++++++++++++++++++++- + tests/unittests/net/test_dhcp.py | 175 ++++++++++++++++++++++++++++++- + tools/.github-cla-signers | 1 + + 4 files changed, 309 insertions(+), 4 deletions(-) + +diff --git a/cloudinit/distros/__init__.py b/cloudinit/distros/__init__.py +index ec148939..0fab8945 100644 +--- a/cloudinit/distros/__init__.py ++++ b/cloudinit/distros/__init__.py +@@ -110,14 +110,18 @@ class Distro(persistence.CloudInitPickleMixin, metaclass=abc.ABCMeta): + resolve_conf_fn = "/etc/resolv.conf" + + osfamily: str +- dhcp_client_priority = [dhcp.IscDhclient, dhcp.Dhcpcd] ++ dhcp_client_priority = [dhcp.IscDhclient, dhcp.Dhcpcd, dhcp.Udhcpc] + + def __init__(self, name, cfg, paths): + self._paths = paths + self._cfg = cfg + self.name = name + self.networking: Networking = self.networking_cls() +- self.dhcp_client_priority = [dhcp.IscDhclient, dhcp.Dhcpcd] ++ self.dhcp_client_priority = [ ++ dhcp.IscDhclient, ++ dhcp.Dhcpcd, ++ dhcp.Udhcpc, ++ ] + + def _unpickle(self, ci_pkl_version: int) -> None: + """Perform deserialization fixes for Distro.""" diff --git a/cloudinit/net/dhcp.py b/cloudinit/net/dhcp.py -index a9a1c980..2d83089b 100644 +index 6c8c2f54..f5586cea 100644 --- a/cloudinit/net/dhcp.py +++ b/cloudinit/net/dhcp.py -@@ -14,12 +14,48 @@ from io import StringIO - - import configobj - --from cloudinit import subp, util -+from cloudinit import subp, util, temp_utils - from cloudinit.net import find_fallback_nic, get_devicelist - +@@ -21,6 +21,7 @@ from cloudinit import subp, temp_utils, util + from cloudinit.net import ( + find_fallback_nic, + get_devicelist, ++ get_ib_interface_hwaddr, + get_interface_mac, + is_ib_interface, + ) +@@ -28,6 +29,37 @@ from cloudinit.net import ( LOG = logging.getLogger(__name__) NETWORKD_LEASES_DIR = "/run/systemd/netif/leases" @@ -17,9 +58,7 @@ index a9a1c980..2d83089b 100644 +log() { + echo "udhcpc[$PPID]" "$interface: $2" +} -+ +[ -z "$1" ] && echo "Error: should be called from udhcpc" && exit 1 -+ +case $1 in + bound|renew) + cat < "$LEASE_FILE" @@ -32,17 +71,14 @@ index a9a1c980..2d83089b 100644 +} +JSON + ;; -+ + deconfig) + log err "Not supported" + exit 1 + ;; -+ + leasefail | nak) + log err "configuration failed: $1: $message" + exit 1 + ;; -+ + *) + echo "$0: Unknown udhcpc command: $1" >&2 + exit 1 @@ -52,134 +88,199 @@ index a9a1c980..2d83089b 100644 class NoDHCPLeaseError(Exception): -@@ -43,12 +79,14 @@ class NoDHCPLeaseMissingDhclientError(NoDHCPLeaseError): +@@ -50,6 +82,10 @@ class NoDHCPLeaseMissingDhclientError(NoDHCPLeaseError): + """Raised when unable to find dhclient.""" - def maybe_perform_dhcp_discovery(nic=None, dhcp_log_func=None, tmp_dir=None): -- """Perform dhcp discovery if nic valid and dhclient command exists. -+ """Perform dhcp discovery if nic valid and dhclient or udhcpc command -+ exists. - - If the nic is invalid or undiscoverable or dhclient command is not found, - skip dhcp_discovery and return an empty dict. - -- @param nic: Name of the network interface we want to run dhclient on. -+ @param nic: Name of the network interface we want to run the dhcp client -+ on. - @param dhcp_log_func: A callable accepting the dhclient output and error - streams. - @param tmp_dir: Tmp dir with exec permissions. -@@ -66,11 +104,16 @@ def maybe_perform_dhcp_discovery(nic=None, dhcp_log_func=None, tmp_dir=None): - "Skip dhcp_discovery: nic %s not found in get_devicelist.", nic - ) - raise NoDHCPLeaseInterfaceError() -+ udhcpc_path = subp.which("udhcpc") -+ if udhcpc_path: -+ return dhcp_udhcpc_discovery(udhcpc_path, nic, dhcp_log_func) - dhclient_path = subp.which("dhclient") -- if not dhclient_path: -- LOG.debug("Skip dhclient configuration: No dhclient command found.") -- raise NoDHCPLeaseMissingDhclientError() -- return dhcp_discovery(dhclient_path, nic, dhcp_log_func) -+ if dhclient_path: -+ return dhcp_discovery(dhclient_path, nic, dhcp_log_func) -+ LOG.debug( -+ "Skip dhclient configuration: No dhclient or udhcpc command found." -+ ) -+ raise NoDHCPLeaseMissingDhclientError() - - - def parse_dhcp_lease_file(lease_file): -@@ -107,6 +150,61 @@ def parse_dhcp_lease_file(lease_file): - return dhcp_leases - - -+def dhcp_udhcpc_discovery(udhcpc_cmd_path, interface, dhcp_log_func=None): -+ """Run udhcpc on the interface without scripts or filesystem artifacts. ++class NoDHCPLeaseMissingUdhcpcError(NoDHCPLeaseError): ++ """Raised when unable to find udhcpc client.""" + -+ @param udhcpc_cmd_path: Full path to the udhcpc used. -+ @param interface: Name of the network interface on which to dhclient. -+ @param dhcp_log_func: A callable accepting the dhclient output and error -+ streams. + -+ @return: A list of dicts of representing the dhcp leases parsed from the -+ dhclient.lease file or empty list. -+ """ -+ LOG.debug("Performing a dhcp discovery on %s", interface) + def select_dhcp_client(distro): + """distros set priority list, select based on this order which to use + +@@ -60,7 +96,10 @@ def select_dhcp_client(distro): + dhcp_client = client() + LOG.debug("DHCP client selected: %s", client.client_name) + return dhcp_client +- except NoDHCPLeaseMissingDhclientError: ++ except ( ++ NoDHCPLeaseMissingDhclientError, ++ NoDHCPLeaseMissingUdhcpcError, ++ ): + LOG.warning("DHCP client not found: %s", client.client_name) + raise NoDHCPLeaseMissingDhclientError() + +@@ -497,3 +536,91 @@ class Dhcpcd: + + def __init__(self): + raise NoDHCPLeaseMissingDhclientError("Dhcpcd not yet implemented") + -+ tmp_dir = temp_utils.get_tmp_ancestor(needs_exe=True) -+ lease_file = os.path.join(tmp_dir, interface + ".lease.json") -+ with contextlib.suppress(FileNotFoundError): -+ os.remove(lease_file) + -+ # udhcpc needs the interface up to send initial discovery packets. -+ # Generally dhclient relies on dhclient-script PREINIT action to bring the -+ # link up before attempting discovery. Since we are using -sf /bin/true, -+ # we need to do that "link up" ourselves first. -+ subp.subp(["ip", "link", "set", "dev", interface, "up"], capture=True) -+ udhcpc_script = os.path.join(tmp_dir, "udhcpc_script") -+ util.write_file(udhcpc_script, UDHCPC_SCRIPT, 0o755) -+ cmd = [ -+ udhcpc_cmd_path, -+ "-O", -+ "staticroutes", -+ "-i", ++class Udhcpc(DhcpClient): ++ client_name = "udhcpc" ++ ++ def __init__(self): ++ self.udhcpc_path = subp.which("udhcpc") ++ if not self.udhcpc_path: ++ LOG.debug("Skip udhcpc configuration: No udhcpc command found.") ++ raise NoDHCPLeaseMissingUdhcpcError() ++ ++ def dhcp_discovery( ++ self, + interface, -+ "-s", -+ udhcpc_script, -+ "-n", # Exit if lease is not obtained -+ "-q", # Exit after obtaining lease -+ "-f", # Run in foreground -+ "-v", -+ ] ++ dhcp_log_func=None, ++ distro=None, ++ ): ++ """Run udhcpc on the interface without scripts or filesystem artifacts. + -+ out, err = subp.subp( -+ cmd, update_env={"LEASE_FILE": lease_file}, capture=True -+ ) ++ @param interface: Name of the network interface on which to run udhcpc. ++ @param dhcp_log_func: A callable accepting the udhcpc output and ++ error streams. + -+ if dhcp_log_func is not None: -+ dhcp_log_func(out, err) -+ lease_json = util.load_json(util.load_file(lease_file)) -+ static_routes = lease_json["static_routes"].split() -+ if static_routes: -+ # format: dest1/mask gw1 ... destn/mask gwn -+ lease_json["static_routes"] = [ -+ i for i in zip(static_routes[::2], static_routes[1::2]) ++ @return: A list of dicts of representing the dhcp leases parsed from ++ the udhcpc lease file. ++ """ ++ LOG.debug("Performing a dhcp discovery on %s", interface) ++ ++ tmp_dir = temp_utils.get_tmp_ancestor(needs_exe=True) ++ lease_file = os.path.join(tmp_dir, interface + ".lease.json") ++ with contextlib.suppress(FileNotFoundError): ++ os.remove(lease_file) ++ ++ # udhcpc needs the interface up to send initial discovery packets ++ subp.subp(["ip", "link", "set", "dev", interface, "up"], capture=True) ++ ++ udhcpc_script = os.path.join(tmp_dir, "udhcpc_script") ++ util.write_file(udhcpc_script, UDHCPC_SCRIPT, 0o755) ++ ++ cmd = [ ++ self.udhcpc_path, ++ "-O", ++ "staticroutes", ++ "-i", ++ interface, ++ "-s", ++ udhcpc_script, ++ "-n", # Exit if lease is not obtained ++ "-q", # Exit after obtaining lease ++ "-f", # Run in foreground ++ "-v", + ] -+ return [lease_json] + ++ # For INFINIBAND port the dhcpc must be running with ++ # client id option. So here we are checking if the interface is ++ # INFINIBAND or not. If yes, we are generating the the client-id to be ++ # used with the udhcpc ++ if is_ib_interface(interface): ++ dhcp_client_identifier = get_ib_interface_hwaddr( ++ interface, ethernet_format=True ++ ) ++ cmd.extend( ++ ["-x", "0x3d:%s" % dhcp_client_identifier.replace(":", "")] ++ ) ++ try: ++ out, err = subp.subp( ++ cmd, update_env={"LEASE_FILE": lease_file}, capture=True ++ ) ++ except subp.ProcessExecutionError as error: ++ LOG.debug( ++ "udhcpc exited with code: %s stderr: %r stdout: %r", ++ error.exit_code, ++ error.stderr, ++ error.stdout, ++ ) ++ raise NoDHCPLeaseError from error + - def dhcp_discovery(dhclient_cmd_path, interface, dhcp_log_func=None): - """Run dhclient on the interface without scripts or filesystem artifacts. - ++ if dhcp_log_func is not None: ++ dhcp_log_func(out, err) ++ ++ lease_json = util.load_json(util.load_file(lease_file)) ++ static_routes = lease_json["static_routes"].split() ++ if static_routes: ++ # format: dest1/mask gw1 ... destn/mask gwn ++ lease_json["static_routes"] = [ ++ i for i in zip(static_routes[::2], static_routes[1::2]) ++ ] ++ return [lease_json] diff --git a/tests/unittests/net/test_dhcp.py b/tests/unittests/net/test_dhcp.py -index 40340553..8913cf65 100644 +index 55d4c6e9..9123cd15 100644 --- a/tests/unittests/net/test_dhcp.py +++ b/tests/unittests/net/test_dhcp.py -@@ -12,6 +12,7 @@ from cloudinit.net.dhcp import ( +@@ -13,6 +13,8 @@ from cloudinit.net.dhcp import ( NoDHCPLeaseError, NoDHCPLeaseInterfaceError, NoDHCPLeaseMissingDhclientError, -+ dhcp_udhcpc_discovery, - dhcp_discovery, ++ NoDHCPLeaseMissingUdhcpcError, ++ Udhcpc, maybe_perform_dhcp_discovery, networkd_load_leases, -@@ -334,6 +335,43 @@ class TestDHCPParseStaticRoutes(CiTestCase): + ) +@@ -388,11 +390,13 @@ class TestDHCPDiscoveryClean(CiTestCase): + self.logs.getvalue(), ) ++ @mock.patch("cloudinit.temp_utils.get_tmp_ancestor", return_value="/tmp") + @mock.patch("cloudinit.net.dhcp.find_fallback_nic", return_value="eth9") + @mock.patch("cloudinit.net.dhcp.os.remove") + @mock.patch("cloudinit.net.dhcp.subp.subp") + @mock.patch("cloudinit.net.dhcp.subp.which") +- def test_dhcp_client_failover(self, m_which, m_subp, m_remove, m_fallback): ++ def test_dhcp_client_failover(self, m_which, m_subp, m_remove, m_fallback, ++ m_get_tmp_ancestor): + """Log and do nothing when nic is absent and no fallback is found.""" + m_subp.side_effect = [ + ("", ""), +@@ -928,3 +932,172 @@ class TestEphemeralDhcpLeaseErrors: + pass + assert len(m_dhcp.mock_calls) == 1 ++ ++ +class TestUDHCPCDiscoveryClean(CiTestCase): ++ with_logs = True + maxDiff = None + ++ @mock.patch("cloudinit.temp_utils.get_tmp_ancestor", return_value="/tmp") ++ @mock.patch("cloudinit.net.dhcp.subp.which") ++ @mock.patch("cloudinit.net.dhcp.find_fallback_nic") ++ def test_absent_udhcpc_command(self, m_fallback, m_which, ++ m_get_tmp_ancestor): ++ """When dhclient doesn't exist in the OS, log the issue and no-op.""" ++ m_fallback.return_value = "eth9" ++ m_which.return_value = None # udhcpc isn't found ++ ++ distro = MockDistro() ++ distro.dhcp_client_priority = [Udhcpc] ++ ++ with pytest.raises(NoDHCPLeaseMissingDhclientError): ++ maybe_perform_dhcp_discovery(distro) ++ ++ self.assertIn( ++ "Skip udhcpc configuration: No udhcpc command found.", ++ self.logs.getvalue(), ++ ) ++ ++ @mock.patch("cloudinit.temp_utils.get_tmp_ancestor", return_value="/tmp") ++ @mock.patch("cloudinit.net.dhcp.is_ib_interface", return_value=False) ++ @mock.patch("cloudinit.net.dhcp.subp.which", return_value="/sbin/udhcpc") + @mock.patch("cloudinit.net.dhcp.os.remove") + @mock.patch("cloudinit.net.dhcp.subp.subp") + @mock.patch("cloudinit.util.load_json") + @mock.patch("cloudinit.util.load_file") + @mock.patch("cloudinit.util.write_file") + def test_udhcpc_discovery( -+ self, m_write_file, m_load_file, m_loadjson, m_subp, m_remove ++ self, ++ m_write_file, ++ m_load_file, ++ m_loadjson, ++ m_subp, ++ m_remove, ++ m_which, ++ mocked_is_ib_interface, ++ m_get_tmp_ancestor, + ): -+ """dhcp_discovery waits for the presence of pidfile and dhcp.leases.""" ++ """dhcp_discovery runs udcpc and parse the dhcp leases.""" + m_subp.return_value = ("", "") + m_loadjson.return_value = { + "interface": "eth9", @@ -201,22 +302,120 @@ index 40340553..8913cf65 100644 + "subnet-mask": "255.255.255.0", + } + ], -+ dhcp_udhcpc_discovery("/sbin/udhcpc", "eth9"), ++ Udhcpc().dhcp_discovery("eth9", distro=MockDistro()), ++ ) ++ # Interface was brought up before dhclient called ++ m_subp.assert_has_calls( ++ [ ++ mock.call( ++ ["ip", "link", "set", "dev", "eth9", "up"], ++ capture=True, ++ ), ++ mock.call( ++ [ ++ "/sbin/udhcpc", ++ "-O", ++ "staticroutes", ++ "-i", ++ "eth9", ++ "-s", ++ "/tmp/udhcpc_script", ++ "-n", ++ "-q", ++ "-f", ++ "-v", ++ ], ++ update_env={"LEASE_FILE": "/tmp/eth9.lease.json"}, ++ capture=True, ++ ), ++ ] + ) + -+ - class TestDHCPDiscoveryClean(CiTestCase): - with_logs = True - -@@ -372,7 +410,7 @@ class TestDHCPDiscoveryClean(CiTestCase): - maybe_perform_dhcp_discovery() - - self.assertIn( -- "Skip dhclient configuration: No dhclient command found.", -+ "Skip dhclient configuration: No dhclient or udhcpc command found.", - self.logs.getvalue(), - ) - ++ @mock.patch("cloudinit.temp_utils.get_tmp_ancestor", return_value="/tmp") ++ @mock.patch("cloudinit.net.dhcp.is_ib_interface", return_value=True) ++ @mock.patch("cloudinit.net.dhcp.get_ib_interface_hwaddr") ++ @mock.patch("cloudinit.net.dhcp.subp.which", return_value="/sbin/udhcpc") ++ @mock.patch("cloudinit.net.dhcp.os.remove") ++ @mock.patch("cloudinit.net.dhcp.subp.subp") ++ @mock.patch("cloudinit.util.load_json") ++ @mock.patch("cloudinit.util.load_file") ++ @mock.patch("cloudinit.util.write_file") ++ def test_udhcpc_discovery_ib( ++ self, ++ m_write_file, ++ m_load_file, ++ m_loadjson, ++ m_subp, ++ m_remove, ++ m_which, ++ m_get_ib_interface_hwaddr, ++ m_is_ib_interface, ++ m_get_tmp_ancestor, ++ ): ++ """dhcp_discovery runs udcpc and parse the dhcp leases.""" ++ m_subp.return_value = ("", "") ++ m_loadjson.return_value = { ++ "interface": "ib0", ++ "fixed-address": "192.168.2.74", ++ "subnet-mask": "255.255.255.0", ++ "routers": "192.168.2.1", ++ "static_routes": "10.240.0.1/32 0.0.0.0 0.0.0.0/0 10.240.0.1", ++ } ++ m_get_ib_interface_hwaddr.return_value = "00:21:28:00:01:cf:4b:01" ++ self.assertEqual( ++ [ ++ { ++ "fixed-address": "192.168.2.74", ++ "interface": "ib0", ++ "routers": "192.168.2.1", ++ "static_routes": [ ++ ("10.240.0.1/32", "0.0.0.0"), ++ ("0.0.0.0/0", "10.240.0.1"), ++ ], ++ "subnet-mask": "255.255.255.0", ++ } ++ ], ++ Udhcpc().dhcp_discovery("ib0", distro=MockDistro()), ++ ) ++ # Interface was brought up before dhclient called ++ m_subp.assert_has_calls( ++ [ ++ mock.call( ++ ["ip", "link", "set", "dev", "ib0", "up"], capture=True ++ ), ++ mock.call( ++ [ ++ "/sbin/udhcpc", ++ "-O", ++ "staticroutes", ++ "-i", ++ "ib0", ++ "-s", ++ "/tmp/udhcpc_script", ++ "-n", ++ "-q", ++ "-f", ++ "-v", ++ "-x", ++ "0x3d:0021280001cf4b01", ++ ], ++ update_env={"LEASE_FILE": "/tmp/ib0.lease.json"}, ++ capture=True, ++ ), ++ ] ++ ) +diff --git a/tools/.github-cla-signers b/tools/.github-cla-signers +index b4a9326e..4d82a055 100644 +--- a/tools/.github-cla-signers ++++ b/tools/.github-cla-signers +@@ -65,6 +65,7 @@ jacobsalmela + jamesottinger + Jehops + jf ++jfroche + Jille + JohnKepplers + johnsonshi -- -2.38.4 +2.40.1 diff --git a/pkgs/tools/virtualization/cloud-init/0003-vultr-remove-check_route-check.patch b/pkgs/tools/virtualization/cloud-init/0003-vultr-remove-check_route-check.patch deleted file mode 100644 index d0d635b939f2..000000000000 --- a/pkgs/tools/virtualization/cloud-init/0003-vultr-remove-check_route-check.patch +++ /dev/null @@ -1,110 +0,0 @@ -From 6df2a198013ebed9aeff119ee0d15cb2d616474c Mon Sep 17 00:00:00 2001 -From: zimbatm -Date: Sun, 30 Apr 2023 12:13:54 +0200 -Subject: [PATCH] vultr: remove check_route check - -The heuristic is assuming that the URL will contain an IP, and that the -route explicitly lists that IP (eg: 0.0.0.0/0 should match but doesn't). -In order for the heuristic to be 100% reliable, it would have to -replicate exactly what the system is doing both in terms of DNS and -route resolution. - -Because the HTTP request below is already exercising the python nd -system resolution, it is simpler to just remove this check and lean on -the HTTP request to provide the answer if the network is up or not. ---- - cloudinit/sources/helpers/vultr.py | 22 ---------------------- - tests/unittests/sources/test_vultr.py | 12 ------------ - 2 files changed, 34 deletions(-) - -diff --git a/cloudinit/sources/helpers/vultr.py b/cloudinit/sources/helpers/vultr.py -index 71676bb1..aac2a610 100644 ---- a/cloudinit/sources/helpers/vultr.py -+++ b/cloudinit/sources/helpers/vultr.py -@@ -32,10 +32,6 @@ def get_metadata( - iface=iface, - connectivity_url_data={"url": url}, - ): -- # Check for the metadata route, skip if not there -- if not check_route(url): -- continue -- - # Fetch the metadata - v1 = read_metadata(url, timeout, retries, sec_between, agent) - -@@ -75,24 +71,6 @@ def get_interface_list(): - return ifaces - - --# Check for /32 route that our dhcp servers inject --# in order to determine if this a customer-run dhcp server --def check_route(url): -- # Get routes, confirm entry exists -- routes = netinfo.route_info() -- -- # If no tools exist and empty dict is returned -- if "ipv4" not in routes: -- return False -- -- # Parse each route into a more searchable format -- for route in routes["ipv4"]: -- if route.get("destination", None) in url: -- return True -- -- return False -- -- - # Read the system information from SMBIOS - def get_sysinfo(): - return { -diff --git a/tests/unittests/sources/test_vultr.py b/tests/unittests/sources/test_vultr.py -index ba21ae24..7fa02b1c 100644 ---- a/tests/unittests/sources/test_vultr.py -+++ b/tests/unittests/sources/test_vultr.py -@@ -274,14 +274,6 @@ INTERFACE_MAP = { - FINAL_INTERFACE_USED = "" - - --# Static override, pylint doesnt like this in --# classes without self --def check_route(url): -- if FINAL_INTERFACE_USED == "eth0": -- return True -- return False -- -- - class TestDataSourceVultr(CiTestCase): - def setUp(self): - global VULTR_V1_3 -@@ -431,7 +423,6 @@ class TestDataSourceVultr(CiTestCase): - @mock.patch( - "cloudinit.net.ephemeral.EphemeralDHCPv4.__exit__", override_exit - ) -- @mock.patch("cloudinit.sources.helpers.vultr.check_route") - @mock.patch("cloudinit.sources.helpers.vultr.is_vultr") - @mock.patch("cloudinit.sources.helpers.vultr.read_metadata") - @mock.patch("cloudinit.sources.helpers.vultr.get_interface_list") -@@ -440,12 +431,10 @@ class TestDataSourceVultr(CiTestCase): - mock_interface_list, - mock_read_metadata, - mock_isvultr, -- mock_check_route, - ): - mock_read_metadata.return_value = {} - mock_isvultr.return_value = True - mock_interface_list.return_value = FILTERED_INTERFACES -- mock_check_route.return_value = True - - distro = mock.MagicMock() - distro.get_tmp_exec_path = self.tmp_dir -@@ -461,7 +450,6 @@ class TestDataSourceVultr(CiTestCase): - self.assertEqual(FINAL_INTERFACE_USED, INTERFACES[3]) - - # Test route checking sucessful DHCPs -- @mock.patch("cloudinit.sources.helpers.vultr.check_route", check_route) - @mock.patch( - "cloudinit.net.ephemeral.EphemeralDHCPv4.__init__", - ephemeral_init_always, --- -2.40.0 - diff --git a/pkgs/tools/virtualization/cloud-init/default.nix b/pkgs/tools/virtualization/cloud-init/default.nix index fa9b21defc75..bb3197d53537 100644 --- a/pkgs/tools/virtualization/cloud-init/default.nix +++ b/pkgs/tools/virtualization/cloud-init/default.nix @@ -16,22 +16,20 @@ python3.pkgs.buildPythonApplication rec { pname = "cloud-init"; - version = "23.1.2"; + version = "23.2"; namePrefix = ""; src = fetchFromGitHub { owner = "canonical"; repo = "cloud-init"; rev = "refs/tags/${version}"; - hash = "sha256-tn4flcrf04hVWhqkmK4qDenXcnV93pP+C+8J63b6FXQ="; + hash = "sha256-/bhezXS5GunlgID7e/QaTC4UsQ2hDvS5HnG8Wphk64k="; }; patches = [ ./0001-add-nixos-support.patch - # upstream: https://github.com/canonical/cloud-init/pull/2125 + # upstream: https://github.com/canonical/cloud-init/pull/4190 ./0002-Add-Udhcpc-support.patch - # upstream: https://github.com/canonical/cloud-init/pull/2151 - ./0003-vultr-remove-check_route-check.patch ]; prePatch = ''