This reworks the preset, reload/restart, and cleanup handling and moves it from a (proposed [1]) abuild patch that would generate install scripts for every -systemd package to a series of commit hooks and a trigger that would exist in this package. This was made possible by using `treescan`, which quickly[2] recursively scans /usr/lib/systemd and allows the commit hook and trigger to diff units before and after an install or uninstall transaction. I chose to put the trigger and commit hook in pmos-base-systemd instead of the systemd package because: 1) It's annoying to have to rebuild systemd just to update the logic in this script. Rebuilding this package is MUCH faster (nothing to compile) 2) IF the systemd package moves elsewhere (i.e. out of pmaports), it's unclear if this preset stuff would follow it, and it's safer for us to keep it separate so know it's always being included in pmOS+systemd installs. It can always be moved later if we decide to. More info on how the three situations are handled by this patch: Presets: Pre-commit hook captures current unit file list (using treescan) before changes, then the trigger on /usr/lib/systemd/system captures (using treescan) the state after changes and diffs them. It picks out only unit files that were added, and runs systemctl preset to apply any preset config that might exist for them. Reload/restart: This relies on manual post-upgrade scripts in packages that need it. post-upgrade scripts should mark units with systemctl set-property ... Markers=+needs-reload/restart. Actual reload/restart handled by the existing systemd.trigger that queries these markers... This is going to be a bit annoying for package maintainers[3], but I don't think many packages will *need* this. As of today, there are 0 packages explicitly requesting reload/restart on upgrade. This also means there will be no automatic detection of whether a unit should be reloaded/restarted. AFAIK Fedora doesn't support this, packages have to explicitly request a reload or restart. Cleanup: The pre-commit hook uses treescan to capture systemd unit directory state before transactions and the trigger identifies removed units (using treescan + diff). It then finds broken symlinks in /etc/systemd/ that point to any newly removed unit files from the transaction, and removes only them. Benefits: - Simple abuild patch for -systemd split func - Uses existing APK mechanisms (commit hooks, triggers). Hooks can see before/after transaction state for cleanup. - Logic updates don't require rebuilding all packages. Tradeoffs: - Requires additional per-package complexity to support reload/restart functionality. - Moves unit discovery/parsing for preset and cleanup from build-time to runtime (every device does this work vs. once at build) - Package behavior varies based on installed trigger/hook versions rather than being deterministic per package version. - There's a (tiny) risk of some operations being race-y, e.g. if the user is actively enabling/disabling/adding unit files between apk running the pre-commit hook and the trigger firing... It seems unlikely this will cause issues, but 🤷♂️ 1. https://gitlab.alpinelinux.org/alpine/abuild/-/merge_requests/394 2. I used hyperfine to measure performance of treescan on my laptop, with lots of units installed, and it was ~20ms without disk caching 3. A post-upgrade that would mark a unit for reload might look like this: ``` if [ -d "/run/systemd/system" ]; then echo "Marking sshd.service for reload..." systemctl set-property sshd.service Markers=+needs-reload fi ``` Part-of: https://gitlab.postmarketos.org/postmarketOS/pmaports/-/merge_requests/6892
15 lines
274 B
Bash
15 lines
274 B
Bash
#!/bin/sh
|
|
|
|
UNIT_LIST_PATH=/var/lib/systemd-apk/installed.units
|
|
|
|
pre_commit() {
|
|
mkdir -p "$(dirname "$UNIT_LIST_PATH")"
|
|
treescan /usr/lib/systemd/system > "$UNIT_LIST_PATH"
|
|
treescan /usr/lib/systemd/user >> "$UNIT_LIST_PATH"
|
|
}
|
|
|
|
case "$1" in
|
|
pre-commit)
|
|
pre_commit;;
|
|
esac
|