diff mbox series

[meta-oe,v1,3/3] classes: add a systemd-sysext image class

Message ID 20250531110022.3843938-4-johannes.schneider@leica-geosystems.com
State Under Review
Headers show
Series add support for building "system extension images" | expand

Commit Message

SCHNEIDER Johannes May 31, 2025, 11 a.m. UTC
systemd-sysext can load a raw-image containing usr/ and opt/ folders
to mount them as RO overlay over the rootfs, to "extend" the systems.

This class provides the necessary changes/additions to the enclosed
filesystem so that systemd-sysext accepts the extension for "merge"
into the rootfs.

With such a created image, placed into the correct folder (see [1]),
`systemd-sysext list` should be able to list the "extension" and
`systemd-sysext merge` should enable the overlay. On both commands a
preceding "SYSTEMD_LOG_LEVEL=debug" can aide in figuring out what is
amiss.

Link: https://www.freedesktop.org/software/systemd/man/latest/systemd-sysext.html
Link: https://0pointer.net/blog/testing-my-system-code-in-usr-without-modifying-usr.html
Signed-off-by: Johannes Schneider <johannes.schneider@leica-geosystems.com>
---
 meta-oe/classes/sysext-image.bbclass | 76 ++++++++++++++++++++++++++++
 1 file changed, 76 insertions(+)
 create mode 100644 meta-oe/classes/sysext-image.bbclass
diff mbox series

Patch

diff --git a/meta-oe/classes/sysext-image.bbclass b/meta-oe/classes/sysext-image.bbclass
new file mode 100644
index 0000000000..4d97b59ce3
--- /dev/null
+++ b/meta-oe/classes/sysext-image.bbclass
@@ -0,0 +1,76 @@ 
+#
+# Copyright OpenEmbedded Contributors
+#
+# SPDX-License-Identifier: MIT
+#
+
+# System extension images may – dynamically at runtime — extend the
+# /usr/ and /opt/ directory hierarchies with additional files. This is
+# particularly useful on immutable system images where a /usr/ and/or
+# /opt/ hierarchy residing on a read-only file system shall be
+# extended temporarily at runtime without making any persistent
+# modifications.
+
+# Example usage:
+## place a symlink into the systemd-sysext image search path:
+# $> mkdir /run/extensions
+# $> ln -s /tmp/extension-example.sysext.ddi /run/extensions/example.raw
+## list all available extensions:
+# $> systemd-sysext list
+## and enable the found extensions:
+# $> SYSTEMD_LOG_LEVEL=debug systemd-sysext merge
+
+# Note: PACKAGECONFIG:pn-systemd needs to include 'sysext'
+
+# systemd-sysext [1] has a simple mechanism for version compatibility:
+# the extension to be loaded has to contain a file named
+# /usr/lib/extension-release.d/extension-release.NAME
+# with "NAME" part *exactly* matching the filename of the extensions
+# raw-device filename/
+#
+# From the extension-release file the "ID" and "VERSION_ID" fields are
+# matched against same fields present in `os-release` and the extension
+# is "merged" only if values in both fields from both files are an
+# exact match.
+#
+# Link: https://www.freedesktop.org/software/systemd/man/latest/systemd-sysext.html
+
+inherit image
+
+# Include '.sysext' in the deployed image filename and symlink
+IMAGE_NAME = "${IMAGE_BASENAME}${IMAGE_MACHINE_SUFFIX}${IMAGE_VERSION_SUFFIX}.sysext"
+IMAGE_LINK_NAME = "${IMAGE_BASENAME}${IMAGE_MACHINE_SUFFIX}.sysext"
+EXTENSION_NAME = "${IMAGE_LINK_NAME}.${IMAGE_FSTYPES}"
+
+# Base extension identification fields
+EXTENSION_ID_FIELD ?= "${DISTRO}"
+EXTENSION_VERSION_FIELD ?= "${DISTRO_VERSION}"
+
+sysext_image_add_version_identifier_file() {
+    # Use matching based on Distro name and version
+    echo 'ID=${EXTENSION_ID_FIELD}' > ${WORKDIR}/extension-release.base
+    # os-release.bb does "sanitise_value(ver)", which needs to be done here too
+    echo 'VERSION_ID=${EXTENSION_VERSION_FIELD}' \
+        | sed 's,+,-,g;s, ,_,g' \
+        >> ${WORKDIR}/extension-release.base
+
+    # Instruct `systemd-sysext` to perform re-load once extension image is verified
+    echo 'EXTENSION_RELOAD_MANAGER=1' >> ${WORKDIR}/extension-release.base
+
+    install -d ${IMAGE_ROOTFS}${nonarch_libdir}/extension-release.d
+    install -m 0644 ${WORKDIR}/extension-release.base \
+        ${IMAGE_ROOTFS}${nonarch_libdir}/extension-release.d/extension-release.${EXTENSION_NAME}
+
+    # systemd-sysext expects an extension-release file of the exact same name as the image;
+    # by setting a xattr we allow renaming of the extension image file.
+    # (Kernel: this requires xattr support in the used filesystem)
+    setfattr -n user.extension-release.strict -v false \
+        ${IMAGE_ROOTFS}${nonarch_libdir}/extension-release.d/extension-release.${EXTENSION_NAME}
+}
+
+ROOTFS_POSTPROCESS_COMMAND += "sysext_image_add_version_identifier_file"
+
+# remove 'os-release' from the packages to be installed into the image.
+# systemd-sysext otherwise raises the error:
+# Extension contains '/usr/lib/os-release', which is not allowed, refusing.
+PACKAGE_EXCLUDE += "os-release"