diff --git a/README.md b/README.md index 43bb900..3cde494 100644 --- a/README.md +++ b/README.md @@ -8,19 +8,16 @@ The current focus is on Docker and containerd, contributions are welcome for oth ## Systemd-sysext The `NAME.raw` sysext images (or `NAME` sysext directories) can be placed under `/etc/extensions/` or `/var/lib/extensions` to be activated on boot by `systemd-sysext.service`. -While systemd-sysext images are not really meant to also include the systemd service, Flatcar ships `ensure-sysext.service` as workaround to automatically load the image's services. -This helper service is bound to `systemd-sysext.service` which activates the sysext images on boot. -Currently it reloads the unit files from disk and reevaluates `multi-user.target`, `sockets.target`, and `timers.target`, making sure your enabled systemd units run. -In the future `systemd-sysext` will only reload the unit files when this is upstream behavior (the current upstream behavior is to do nothing and leave it to the user). -That means you need to use `Upholds=` drop-ins for the target units to start your units. -At runtime executing `systemctl restart systemd-sysext ensure-sysext` will reload the sysext images and start the services. -A manual `systemd-sysext refresh` is not recommended. +Images can specify to require systemd to do a daemon reload (needs systemd 255, Flatcar ships `ensure-sysext.service` as workaround to automatically load the image's services). + +A current limitation of `systemd-sysext` is that you need to use `TARGET.upholds` symlinks (supported from systemd 254, similar to `.wants`) or `Upholds=` drop-ins for the target units to start your units. +For current versions of Flatcar (systemd 252) you need to use `systemctl restart systemd-sysext ensure-sysext` to reload the sysext images and start the services and a manual `systemd-sysext refresh` is not recommended. The compatibility mechanism of sysext images requires a metadata file in the image under `usr/lib/extension-release.d/extension-release.NAME`. -It needs to contain a matching OS `ID`, and either a matching `VERSION_ID` or `SYSEXT_LEVEL`. +It needs to contain a matching OS `ID`, and either a matching `VERSION_ID` or `SYSEXT_LEVEL`. Here you can also set `EXTENSION_RELOAD_MANAGER=1` for a systemd daemon reload. Since the rapid release cycle and automatic updates of Flatcar Container Linux make it hard to rely on particular OS libraries by specifying a dependency of the sysext image to the OS version, it is not recommended to match by `VERSION_ID`. Instead, Flatcar defined the `SYSEXT_LEVEL` value `1.0` to match for. -With systemd 252 you can also use `ID=_any` and then neither `SYSEXT_LEVEL` nor `VERSION_ID` are needed. +You can also use `ID=_any` and then neither `SYSEXT_LEVEL` nor `VERSION_ID` are needed. The sysext image should only include static binaries. Inside the image, binaries should be placed under `usr/bin/` and systemd units under `usr/lib/systemd/system/`. @@ -61,19 +58,17 @@ storage: ## Systemd-sysext on other distributions -The tools here will by default build for Flatcar and create the metadata file `usr/lib/extension-release.d/extension-release.NAME` as follows: +The tools here will by default build for any OS and create the metadata file `usr/lib/extension-release.d/extension-release.NAME` as follows: ``` -ID=flatcar -SYSEXT_LEVEL=1.0 +ID=_any +# Depending on the image, e.g., for Docker systemd units, there is also: +# EXTENSION_RELOAD_MANAGER=1 ``` -This means other distributions will reject to load the sysext image by default. Use the configuration parameters in the tools to build for your distribution (pass `OS=` to be the OS ID from `/etc/os-release`) or to build for any distribution (pass `OS=_any`). You can also set the architecture to be arm64 to fetch the right binaries and encode this information in the sysext image metadata. -To add the automatic systemd unit loading to your distribution, store [`ensure-sysext.service`](https://raw.githubusercontent.com/flatcar/init/ccade77b6d568094fb4e4d4cf71b867819551798/systemd/system/ensure-sysext.service) in your systemd folder (e.g., `/etc/systemd/system/`) and enable the units: `systemctl enable --now ensure-sysext.service systemd-sysext.service`. - ## Recipes in this repository The tools normally generate squashfs images not only because of the compression benefits but also because it doesn't need root permissions and loop device mounts. diff --git a/bake.sh b/bake.sh index 5885324..754d457 100755 --- a/bake.sh +++ b/bake.sh @@ -1,9 +1,10 @@ #!/usr/bin/env bash set -euo pipefail -OS="${OS-flatcar}" +OS="${OS-_any}" FORMAT="${FORMAT:-squashfs}" ARCH="${ARCH-}" +RELOAD="${RELOAD-}" SOURCE_DATE_EPOCH="${SOURCE_DATE_EPOCH-0}" export SOURCE_DATE_EPOCH @@ -14,8 +15,9 @@ if [ $# -lt 1 ]; then exit 1 elif [ "$1" = "-h" ] || [ "$1" = "--help" ]; then echo "If ARCH is specified as environment variable the sysext image will be required to run on the given architecture." - echo "To build for another OS than Flatcar, pass 'OS=myosid' as environment variable (current value is '${OS}'), e.g., 'fedora' as found in 'ID' under '/etc/os-release', or pass 'OS=_any' for any OS." + echo "To build for a specific OS, pass 'OS=myosid' as environment variable (current value is '${OS}'), e.g., 'fedora' as found in 'ID' under '/etc/os-release', or pass 'OS=_any' for any OS." echo "The '/etc/os-release' file of your OS has to include 'SYSEXT_LEVEL=1.0' as done in Flatcar (not needed for 'OS=_any')." + echo "To specify that systemd should do a daemon reload for the system when the extension is loaded/unloaded, set RELOAD=1 (current value is '${RELOAD}')." echo "If the mksquashfs tool is missing you can pass FORMAT=btrfs, FORMAT=ext4, or FORMAT=ext2 as environment variable (current value is '${FORMAT}') but the script won't change the ownership of the files in the SYSEXTNAME directory, so make sure that they are owned by root before creating the sysext image to avoid any problems." echo "To make builds reproducible the SOURCE_DATE_EPOCH environment variable will be set to 0 if not defined." echo @@ -45,6 +47,9 @@ mkdir -p "${SYSEXTNAME}/usr/lib/extension-release.d" if [ "${ARCH}" != "" ]; then echo "ARCHITECTURE=${ARCH}" fi + if [ "${RELOAD}" = 1 ]; then + echo "EXTENSION_RELOAD_MANAGER=1" + fi } > "${SYSEXTNAME}/usr/lib/extension-release.d/extension-release.${SYSEXTNAME}" rm -f "${SYSEXTNAME}".raw if [ "${FORMAT}" = "btrfs" ]; then diff --git a/convert_torcx_image.sh b/convert_torcx_image.sh index 3625a16..6ea3273 100755 --- a/convert_torcx_image.sh +++ b/convert_torcx_image.sh @@ -42,5 +42,5 @@ for ENTRY in "${SYSEXTNAME}/usr/lib/systemd/system/"*.wants/*; do { echo "[Unit]"; echo "Upholds=${UNIT}"; } > "${SYSEXTNAME}/usr/lib/systemd/system/${TARGET}.d/10-${UNIT/./-}.conf" done -"${SCRIPTFOLDER}"/bake.sh "${SYSEXTNAME}" +RELOAD=1 "${SCRIPTFOLDER}"/bake.sh "${SYSEXTNAME}" rm -rf "${SYSEXTNAME}" diff --git a/create_docker_sysext.sh b/create_docker_sysext.sh index f937cd9..d41581f 100755 --- a/create_docker_sysext.sh +++ b/create_docker_sysext.sh @@ -140,5 +140,5 @@ EOF sed 's/SystemdCgroup = true/SystemdCgroup = false/g' "${SYSEXTNAME}/usr/share/containerd/config.toml" > "${SYSEXTNAME}/usr/share/containerd/config-cgroupfs.toml" fi -"${SCRIPTFOLDER}"/bake.sh "${SYSEXTNAME}" +RELOAD=1 "${SCRIPTFOLDER}"/bake.sh "${SYSEXTNAME}" rm -rf "${SYSEXTNAME}" diff --git a/create_kubernetes_sysext.sh b/create_kubernetes_sysext.sh index 517b934..84a2207 100755 --- a/create_kubernetes_sysext.sh +++ b/create_kubernetes_sysext.sh @@ -99,5 +99,5 @@ curl -o cni.tgz -fsSL "https://github.com/containernetworking/plugins/releases/d mkdir -p "${SYSEXTNAME}/usr/local/bin/cni" tar --force-local -xf "cni.tgz" -C "${SYSEXTNAME}/usr/local/bin/cni" -"${SCRIPTFOLDER}"/bake.sh "${SYSEXTNAME}" +RELOAD=1 "${SCRIPTFOLDER}"/bake.sh "${SYSEXTNAME}" rm -rf "${SYSEXTNAME}"