build: add systemd autostart for the receiver

Ship systemd/screencast-receiver.service, a template the install
script substitutes (binary path, run user) and enables so the
receiver starts at boot after the network and avahi-daemon, with
restart-on-failure and a raised start limit for slow-booting boards.
SIGTERM gives the graceful shutdown that withdraws the mDNS
announcement — systemctl stop never triggers the stale-record trap
that kill -9 does. Headless consoles render via KMSDRM (the script
adds the run user to video/render/input); desktop autologin sessions
uncomment two documented Environment lines.

The install script gains SC_RECEIVER_SERVICE=0 to opt out.

Validated: systemd-analyze verify on the substituted unit (only the
expected missing /usr/local/bin path on this dev machine), and a live
lifecycle test as a user unit: the service-managed receiver announced
itself (--discover found it), systemctl stop produced a clean exit
(Result=success, no restart) and the mDNS announcement was withdrawn
immediately.
This commit is contained in:
2026-09-07 12:30:26 +02:00
parent fb6a1087d5
commit 6e68300d05
5 changed files with 115 additions and 11 deletions
+40 -10
View File
@@ -15,6 +15,7 @@
# Environment overrides:
# SC_RECEIVER_INSTALL_DIR install target (default /usr/local/bin)
# SC_RECEIVER_SKIP_TESTS set to 1 to skip the test suite (faster install)
# SC_RECEIVER_SERVICE set to 0 to skip the systemd service setup
#
# Requirements:
# - Debian/Raspberry Pi OS (apt) with GCC 13 or newer (the code uses
@@ -28,6 +29,7 @@ REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
BUILD_DIR="${REPO_ROOT}/build-receiver"
INSTALL_DIR="${SC_RECEIVER_INSTALL_DIR:-/usr/local/bin}"
SKIP_TESTS="${SC_RECEIVER_SKIP_TESTS:-0}"
ENABLE_SERVICE="${SC_RECEIVER_SERVICE:-1}"
log() { printf '\n=== %s\n' "$*"; }
die() { printf 'install-receiver: error: %s\n' "$*" >&2; exit 1; }
@@ -99,22 +101,50 @@ install -m 755 "${BUILD_DIR}/src/app/screencast" "${INSTALL_DIR}/screencast"
systemctl enable --now avahi-daemon 2>/dev/null || true
# --- systemd autostart --------------------------------------------------------
if [ "${ENABLE_SERVICE}" = "1" ] && command -v systemctl >/dev/null 2>&1; then
log "installing the systemd service (autostart on boot)"
RUN_USER="${SUDO_USER:-root}"
# Headless KMSDRM rendering needs device access; skip groups that do
# not exist on this system.
if [ "${RUN_USER}" != "root" ] && id "${RUN_USER}" >/dev/null 2>&1; then
for group in video render input; do
if getent group "${group}" >/dev/null 2>&1; then
usermod -aG "${group}" "${RUN_USER}" || true
fi
done
fi
sed -e "s|__SC_RECEIVER_BIN__|${INSTALL_DIR}/screencast|g" \
-e "s|__SC_RECEIVER_USER__|${RUN_USER}|g" \
"${REPO_ROOT}/systemd/screencast-receiver.service" \
> /etc/systemd/system/screencast-receiver.service
chmod 644 /etc/systemd/system/screencast-receiver.service
systemctl daemon-reload
systemctl enable --now screencast-receiver.service
else
log "skipping the systemd service (disabled or systemd not available)"
fi
log "done."
cat <<'EOF'
The receiver is installed. On this machine run:
The receiver is installed and starts automatically at boot.
screencast --receive
and on the sending machine:
screencast --send # discovers this receiver on the LAN
systemctl status screencast-receiver # is it running?
journalctl -u screencast-receiver -f # follow its logs
sudo systemctl stop screencast-receiver # stop gracefully (Ctrl-C like)
sudo systemctl disable --now screencast-receiver # turn autostart off
Notes for small boards (e.g. Pi Zero 2 W):
- Decoding is software H.264; expect smooth playback for small streams
and a lower frame rate at high resolutions.
- Stop the receiver with Ctrl-C; never kill -9 (it would leave stale
mDNS records that break discovery for ~75 minutes).
- The receiver needs avahi-daemon (enabled) and a graphical session or
KMS console to open its window.
- Stop the receiver via systemctl (never kill -9; stale mDNS records
would break discovery for ~75 minutes).
- The service runs on the headless console via KMSDRM. On a desktop
session instead, edit /etc/systemd/system/screencast-receiver.service:
uncomment the Environment lines and point XDG_RUNTIME_DIR at the
session owner's /run/user/<uid> (see the comments in that file).
- avahi-daemon must stay enabled; it is what senders discover.
EOF