From a4f4d6b0bedbd8eb7287e799607b49a4e78932a4 Mon Sep 17 00:00:00 2001 From: Ani Sinha 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 Signed-off-by: Cathy Avery --- 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 98084a492..882492d96 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()