diff -Nru cloud-init-23.4.3/ChangeLog cloud-init-23.4.4/ChangeLog --- cloud-init-23.4.3/ChangeLog 2024-02-02 21:21:52.000000000 +0000 +++ cloud-init-23.4.4/ChangeLog 2024-02-27 15:17:52.000000000 +0000 @@ -1,3 +1,8 @@ +23.4.4 + - fix(nocloud): smbios datasource definition + - tests: Check that smbios seed works + - fix(source): fix argument boundaries when parsing cmdline (#4825) + 23.4.3 - fix: Handle systemctl when dbus not ready (#4842) (LP: #2046483) diff -Nru cloud-init-23.4.3/cloudinit/sources/DataSourceNoCloud.py cloud-init-23.4.4/cloudinit/sources/DataSourceNoCloud.py --- cloud-init-23.4.3/cloudinit/sources/DataSourceNoCloud.py 2024-02-02 21:21:52.000000000 +0000 +++ cloud-init-23.4.4/cloudinit/sources/DataSourceNoCloud.py 2024-02-27 15:17:52.000000000 +0000 @@ -11,6 +11,7 @@ import errno import logging import os +from functools import partial from cloudinit import dmi, sources, util from cloudinit.net import eni @@ -368,12 +369,40 @@ self.supported_seed_starts = ("http://", "https://") def ds_detect(self): - """NoCloud requires "nocloud-net" as the way to specify - seeding from an http(s) address. This diverges from all other - datasources in that it does a kernel commandline match on something - other than the datasource dsname for only DEP_NETWORK. + """Check dmi and kernel commandline for dsname + + NoCloud historically used "nocloud-net" as its dsname + for network timeframe (DEP_NETWORK), which supports http(s) urls. + For backwards compatiblity, check for that dsname. """ - return "nocloud-net" == sources.parse_cmdline() + log_deprecated = partial( + util.deprecate, + deprecated="The 'nocloud-net' datasource name", + deprecated_version="24.1", + extra_message=( + "Use 'nocloud' instead, which uses the seedfrom protocol" + "scheme (http// or file://) to decide how to run." + ), + ) + + if "nocloud-net" == sources.parse_cmdline(): + log_deprecated() + return True + + serial = sources.parse_cmdline_or_dmi( + dmi.read_dmi_data("system-serial-number") or "" + ).lower() + + if serial in (self.dsname.lower(), "nocloud-net"): + LOG.debug( + "Machine is configured by dmi serial number to run on " + "single datasource %s.", + self, + ) + if serial == "nocloud-net": + log_deprecated() + return True + return False # Used to match classes to dependencies diff -Nru cloud-init-23.4.3/cloudinit/sources/__init__.py cloud-init-23.4.4/cloudinit/sources/__init__.py --- cloud-init-23.4.3/cloudinit/sources/__init__.py 2024-02-02 21:21:52.000000000 +0000 +++ cloud-init-23.4.4/cloudinit/sources/__init__.py 2024-02-27 15:17:52.000000000 +0000 @@ -1184,10 +1184,13 @@ """Check if command line argument for this datasource was passed Passing by command line overrides runtime datasource detection """ - cmdline = util.get_cmdline() - ds_parse_0 = re.search(r"ds=([^\s;]+)", cmdline) - ds_parse_1 = re.search(r"ci\.ds=([^\s;]+)", cmdline) - ds_parse_2 = re.search(r"ci\.datasource=([^\s;]+)", cmdline) + return parse_cmdline_or_dmi(util.get_cmdline()) + + +def parse_cmdline_or_dmi(input: str) -> str: + ds_parse_0 = re.search(r"(?:^|\s)ds=([^\s;]+)", input) + ds_parse_1 = re.search(r"(?:^|\s)ci\.ds=([^\s;]+)", input) + ds_parse_2 = re.search(r"(?:^|\s)ci\.datasource=([^\s;]+)", input) ds = ds_parse_0 or ds_parse_1 or ds_parse_2 deprecated = ds_parse_1 or ds_parse_2 if deprecated: diff -Nru cloud-init-23.4.3/cloudinit/version.py cloud-init-23.4.4/cloudinit/version.py --- cloud-init-23.4.3/cloudinit/version.py 2024-02-02 21:21:52.000000000 +0000 +++ cloud-init-23.4.4/cloudinit/version.py 2024-02-27 15:17:52.000000000 +0000 @@ -4,7 +4,7 @@ # # This file is part of cloud-init. See LICENSE file for license information. -__VERSION__ = "23.4.3" +__VERSION__ = "23.4.4" _PACKAGED_VERSION = "@@PACKAGED_VERSION@@" FEATURES = [ diff -Nru cloud-init-23.4.3/debian/changelog cloud-init-23.4.4/debian/changelog --- cloud-init-23.4.3/debian/changelog 2024-02-02 22:00:04.000000000 +0000 +++ cloud-init-23.4.4/debian/changelog 2024-02-27 15:17:49.000000000 +0000 @@ -1,3 +1,11 @@ +cloud-init (23.4.4-0ubuntu0~23.10.1) mantic; urgency=medium + + * Upstream snapshot based on 23.4.4. (LP: #2055081). + List of changes from upstream can be found at + https://raw.githubusercontent.com/canonical/cloud-init/23.4.4/ChangeLog + + -- Chad Smith Tue, 27 Feb 2024 08:17:49 -0700 + cloud-init (23.4.3-0ubuntu0~23.10.1) mantic; urgency=medium * Upstream snapshot based on 23.4.3. (LP: #2046483). diff -Nru cloud-init-23.4.3/tests/integration_tests/datasources/test_nocloud.py cloud-init-23.4.4/tests/integration_tests/datasources/test_nocloud.py --- cloud-init-23.4.3/tests/integration_tests/datasources/test_nocloud.py 2024-02-02 21:21:52.000000000 +0000 +++ cloud-init-23.4.4/tests/integration_tests/datasources/test_nocloud.py 2024-02-27 15:17:52.000000000 +0000 @@ -1,4 +1,6 @@ """NoCloud datasource integration tests.""" +from textwrap import dedent + import pytest from pycloudlib.lxd.instance import LXDInstance @@ -88,3 +90,102 @@ client.restart() assert client.execute("cloud-init status").ok assert "seeded_vendordata_test_file" in client.execute("ls /var/tmp") + + +SMBIOS_USERDATA = """\ +#cloud-config +runcmd: + - touch /var/tmp/smbios_test_file +""" +SMBIOS_SEED_DIR = "/smbios_seed" + + +def setup_nocloud_local_serial(instance: LXDInstance): + subp( + [ + "lxc", + "config", + "set", + instance.name, + "raw.qemu=-smbios " + f"type=1,serial=ds=nocloud;s=file://{SMBIOS_SEED_DIR};h=myhost", + ] + ) + + +def setup_nocloud_network_serial(instance: LXDInstance): + subp( + [ + "lxc", + "config", + "set", + instance.name, + "raw.qemu=-smbios " + "type=1,serial=ds=nocloud-net;s=http://0.0.0.0/;h=myhost", + ] + ) + + +@pytest.mark.lxd_use_exec +@pytest.mark.skipif( + PLATFORM != "lxd_vm", + reason="Requires NoCloud with raw QEMU serial setup", +) +class TestSmbios: + @pytest.mark.lxd_setup.with_args(setup_nocloud_local_serial) + def test_smbios_seed_local(self, client: IntegrationInstance): + """Check that smbios seeds that use local disk work""" + assert client.execute(f"mkdir -p {SMBIOS_SEED_DIR}").ok + client.write_to_file(f"{SMBIOS_SEED_DIR}/user-data", SMBIOS_USERDATA) + client.write_to_file(f"{SMBIOS_SEED_DIR}/meta-data", "") + client.write_to_file(f"{SMBIOS_SEED_DIR}/vendor-data", "") + assert client.execute("cloud-init clean --logs").ok + client.restart() + assert client.execute("test -f /var/tmp/smbios_test_file").ok + + @pytest.mark.lxd_setup.with_args(setup_nocloud_network_serial) + def test_smbios_seed_network(self, client: IntegrationInstance): + """Check that smbios seeds that use network (http/https) work""" + service_file = "/lib/systemd/system/local-server.service" + client.write_to_file( + service_file, + dedent( + """\ + [Unit] + Description=Serve a local webserver + Before=cloud-init.service + Wants=cloud-init-local.service + DefaultDependencies=no + After=systemd-networkd-wait-online.service + After=networking.service + + + [Install] + WantedBy=cloud-init.target + + [Service] + """ + f"WorkingDirectory={SMBIOS_SEED_DIR}" + """ + ExecStart=/usr/bin/env python3 -m http.server --bind 0.0.0.0 80 + """ + ), + ) + assert client.execute( + "chmod 644 /lib/systemd/system/local-server.service" + ).ok + assert client.execute("systemctl enable local-server.service").ok + client.write_to_file( + "/etc/cloud/cloud.cfg.d/91_do_not_use_lxd.cfg", + "datasource_list: [ NoCloud, None ]\n", + ) + assert client.execute(f"mkdir -p {SMBIOS_SEED_DIR}").ok + client.write_to_file(f"{SMBIOS_SEED_DIR}/user-data", SMBIOS_USERDATA) + client.write_to_file(f"{SMBIOS_SEED_DIR}/meta-data", "") + client.write_to_file(f"{SMBIOS_SEED_DIR}/vendor-data", "") + assert client.execute("cloud-init clean --logs").ok + client.restart() + assert client.execute("test -f /var/tmp/smbios_test_file").ok + assert "'nocloud-net' datasource name is deprecated" in client.execute( + "cloud-init status --format json" + ) diff -Nru cloud-init-23.4.3/tests/unittests/sources/test___init__.py cloud-init-23.4.4/tests/unittests/sources/test___init__.py --- cloud-init-23.4.3/tests/unittests/sources/test___init__.py 2024-02-02 21:21:52.000000000 +0000 +++ cloud-init-23.4.4/tests/unittests/sources/test___init__.py 2024-02-27 15:17:52.000000000 +0000 @@ -17,6 +17,7 @@ ("aosiejfoij ci.ds=OpenStack faljskebflk", openstack_ds_name), ("ci.ds=OpenStack;", openstack_ds_name), ("ci.ds=openstack;", openstack_ds_name), + ("notci.ds=somecloud ci.ds=openstack", openstack_ds_name), # test ci.datasource= ("aosiejfoij ci.datasource=OpenStack ", openstack_ds_name), ("ci.datasource=OpenStack", openstack_ds_name), @@ -24,6 +25,7 @@ ("aosiejfoij ci.datasource=OpenStack faljskebflk", openstack_ds_name), ("ci.datasource=OpenStack;", openstack_ds_name), ("ci.datasource=openstack;", openstack_ds_name), + ("notci.datasource=0 ci.datasource=nocloud", "nocloud"), # weird whitespace ("ci.datasource=OpenStack\n", openstack_ds_name), ("ci.datasource=OpenStack\t", openstack_ds_name), @@ -35,6 +37,11 @@ ("ci.ds=OpenStack\v", openstack_ds_name), ("ci.ds=nocloud-net\v", "nocloud-net"), ("ci.datasource=nocloud\v", "nocloud"), + # test ds= + ("ds=nocloud-net", "nocloud-net"), + ("foo ds=nocloud-net bar", "nocloud-net"), + ("bonding.max_bonds=0", ""), + ("foo bonding.max_bonds=0 ds=nocloud-net bar", "nocloud-net"), ), ) def test_ds_detect_kernel_commandline(m_cmdline, expected_ds): diff -Nru cloud-init-23.4.3/tools/.github-cla-signers cloud-init-23.4.4/tools/.github-cla-signers --- cloud-init-23.4.3/tools/.github-cla-signers 2024-02-02 21:21:52.000000000 +0000 +++ cloud-init-23.4.4/tools/.github-cla-signers 2024-02-27 15:17:52.000000000 +0000 @@ -57,6 +57,7 @@ GabrielNagy garzdin giggsoff +gilbsgilbs glyg hamalq holmanb