#!/usr/bin/env bash # Enable Sunshine as a systemd --user service and turn on lingering so it # runs at boot without a graphical login. ensure_sunshine_unit_present() { # Case 1: a sunshine.service unit already exists in any path systemd-user # scans. sunshine-bin ships /usr/lib/systemd/user/sunshine.service directly. for p in \ /usr/lib/systemd/user/sunshine.service \ /etc/systemd/user/sunshine.service \ "$HOME/.config/systemd/user/sunshine.service" \ "$HOME/.local/share/systemd/user/sunshine.service" do [[ -e "$p" ]] && return 0 done # Case 2: the AUR source 'sunshine' package ships the unit under a # Flatpak-style reverse-DNS name. Symlink it as sunshine.service so the rest # of our tooling can keep using the short name. local fqdn_unit="" for p in \ /usr/lib/systemd/user/app-dev.lizardbyte.app.Sunshine.service \ /etc/systemd/user/app-dev.lizardbyte.app.Sunshine.service do [[ -f "$p" ]] && { fqdn_unit="$p"; break; } done if [[ -n "$fqdn_unit" ]]; then info "Found packaged unit at $fqdn_unit" info "Aliasing it as sunshine.service in $HOME/.config/systemd/user/" mkdir -p "$HOME/.config/systemd/user" ln -sf "$fqdn_unit" "$HOME/.config/systemd/user/sunshine.service" return 0 fi # Case 3: no unit shipped at all — drop our own. local fallback="$SCRIPT_DIR/files/sunshine.service" if [[ ! -f "$fallback" ]]; then err "No sunshine.service shipped by the package, and no fallback found at $fallback" return 1 fi info "No packaged sunshine.service found; installing repo fallback unit" mkdir -p "$HOME/.config/systemd/user" install -m 0644 "$fallback" "$HOME/.config/systemd/user/sunshine.service" ok "Installed $HOME/.config/systemd/user/sunshine.service" } enable_sunshine_service() { # The AUR 'sunshine' (source) package doesn't always ship a systemd user unit # at the standard /usr/lib/systemd/user/sunshine.service path. If systemd # can't find one, drop our own copy into ~/.config/systemd/user/. ensure_sunshine_unit_present systemctl --user daemon-reload # In headless mode, install a drop-in that pre-creates HEADLESS-1 before # Sunshine starts. Done here because the drop-in target name depends on # which unit ensure_sunshine_unit_present resolved. if [[ "${STREAM_MODE:-}" == "headless" ]] && declare -F install_headless_prestart_dropin >/dev/null; then install_headless_prestart_dropin fi if ! systemctl --user list-unit-files sunshine.service >/dev/null 2>&1; then err "sunshine.service still not found after fallback. Inspect: find /usr ~/.config -name sunshine.service" return 1 fi if ! loginctl show-user "$USER" -p Linger --value 2>/dev/null | grep -qx yes; then info "Enabling user lingering (loginctl enable-linger $USER)" as_root loginctl enable-linger "$USER" else ok "User lingering already enabled" fi info "Enabling sunshine.service (user)" systemctl --user enable sunshine.service >/dev/null # Clear any prior start-limit state from a failed run so this attempt isn't # immediately rejected with "Start request repeated too quickly." systemctl --user reset-failed sunshine.service 2>/dev/null || true info "Starting sunshine.service (user)" # Restart so a re-run picks up new config / new caps. Tolerate first-launch races. systemctl --user restart sunshine.service || systemctl --user start sunshine.service || { err "Failed to start sunshine.service. Check: journalctl --user -u sunshine" return 1 } sleep 1 if systemctl --user is-active --quiet sunshine.service; then ok "sunshine.service is active" else warn "sunshine.service did not stay active. Inspect: journalctl --user -u sunshine -n 50" fi }