From af96549515e07ef2208bf0d93f0b511e6be3c3d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Fri, 4 Oct 2024 14:11:49 +0200 Subject: [PATCH] tools/toolbox: Add toolbox-sysext-install.sh script The new command will take an extension directory set up with `meson-build --sysext` inside a toolbox, and turn it into a merged system extension on the host. Namely it will 1. copy the extension directory from the container to the host 2. set up the extension-release file expected by systemd-sysext 3. compile gsettings schemas if necessary (using the merged schemas directory) 4. install the extension to either runtime or system 5. merge the extension Part-of: --- tools/toolbox/toolbox-sysext-install.sh | 143 ++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100755 tools/toolbox/toolbox-sysext-install.sh diff --git a/tools/toolbox/toolbox-sysext-install.sh b/tools/toolbox/toolbox-sysext-install.sh new file mode 100755 index 000000000..0ff3b659a --- /dev/null +++ b/tools/toolbox/toolbox-sysext-install.sh @@ -0,0 +1,143 @@ +#!/usr/bin/bash + +set -eu + +DEFAULT_TOOLBOX=gnome-shell-devel +CONFIG_FILE=${XDG_CONFIG_HOME:-$HOME/.config}/gnome-shell-toolbox-tools.conf + +usage() { + cat <<-EOF + Usage: $(basename $0) [OPTION…] + + Extract and install a systemd-sysext extension from a toolbox + + Options: + -t, --toolbox=TOOLBOX Use TOOLBOX instead of the default "$DEFAULT_TOOLBOX" + + --persistent Install extension under /var/lib/extensions/ to persist after reboots + + -h, --help Display this help + + EOF +} + +die() { + echo "$@" >&2 + exit 1 +} + +init_sysext() { + rm -rf $HOME_SYSEXT_DIR + mkdir -p $HOME_SYSEXT_DIR + podman cp $TOOLBOX:/var/lib/extensions/$TOOLBOX/. $HOME_SYSEXT_DIR + + local ext_dir=$HOME_SYSEXT_DIR/usr/lib/extension-release.d + mkdir -p $ext_dir + podman cp $TOOLBOX:/etc/os-release $ext_dir/extension-release.$TOOLBOX +} + +runtime_install_command() { + local dest=$(dirname $RUN_SYSEXT_DIR) + + echo -n "mkdir -p $dest && " + echo -n "ln -sf $HOME_SYSEXT_DIR $dest && " + echo -n "rm -fr $VAR_SYSEXT_DIR" +} + +system_install_command() { + local dest=$(dirname $VAR_SYSEXT_DIR) + local attr=mode + + selinuxenabled 2>/dev/null && attr="$attr,context" + + echo -n "mkdir -p $dest && " + echo -n "cp -r --preserve=$attr $HOME_SYSEXT_DIR $dest && " + echo -n "rm -fr $RUN_SYSEXT_DIR" +} + +install_command() { + if [[ ${PERSISTENT:-0} ]]; then + system_install_command + else + runtime_install_command + fi +} + +sysext_merge_command() { + echo -n systemd-sysext refresh +} + +compile_schemas_command() { + local schemadir=usr/share/glib-2.0/schemas + if [ -d $HOME_SYSEXT_DIR/$schemadir ] + then + echo -n "$(runtime_install_command) && " + echo -n "$(sysext_merge_command) && " + echo -n "glib-compile-schemas --targetdir $HOME_SYSEXT_DIR/$schemadir /$schemadir 2>/dev/null && " + echo -n "chown $(id -un):$(id -gn) $HOME_SYSEXT_DIR/$schemadir/gschemas.compiled" + else + echo -n : + fi +} + +relabel_command() { + local setfiles=$(which setfiles 2>/dev/null) + if [ -x "$setfiles" ] + then + local spec=/etc/selinux/targeted/contexts/files/file_contexts + echo -n "$setfiles -F -r $HOME_SYSEXT_DIR $spec $HOME_SYSEXT_DIR/usr" + else + echo -n : + fi +} + +# load defaults +. $CONFIG_FILE +TOOLBOX=$DEFAULT_TOOLBOX + +TEMP=$(getopt \ + --name $(basename $0) \ + --options 't:h' \ + --longoptions 'toolbox:' \ + --longoptions 'persistent' \ + --longoptions 'help' \ + -- "$@") || die "Run $(basename $0) --help to see available options" + +eval set -- "$TEMP" +unset TEMP + +while true; do + case $1 in + -t|--toolbox) + TOOLBOX=$2 + shift 2 + ;; + + --persistent) + PERSISTENT=1 + shift + ;; + + -h|--help) + usage + exit 0 + ;; + + --) + shift + break + ;; + esac +done + +HOME_SYSEXT_DIR=$HOME/.local/lib/toolbox-extensions/$TOOLBOX +RUN_SYSEXT_DIR=/run/extensions/$TOOLBOX +VAR_SYSEXT_DIR=/var/lib/extensions/$TOOLBOX + +init_sysext + +sudo sh -c " + $(compile_schemas_command) && + $(relabel_command) && + $(install_command) && + $(sysext_merge_command)"