Better graphical start
This commit is contained in:
@@ -8,5 +8,5 @@
|
||||
|
||||
eww-bar = pkgs.callPackage ./eww-bar { };
|
||||
|
||||
jellyfin-mpv-shim-watchdog = pkgs.callPackage ./jellyfin-mpv-shim-watchdog { };
|
||||
network-watchdog = pkgs.callPackage ./network-watchdog { };
|
||||
}
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
{ writeShellScriptBin
|
||||
, coreutils
|
||||
, findutils
|
||||
, gnugrep
|
||||
, iproute2
|
||||
, systemd
|
||||
}:
|
||||
|
||||
# jellyfin-mpv-shim keeps a persistent socket to the Jellyfin server. When the
|
||||
# machine drops off the network that socket dies, but the process stays alive
|
||||
# and the unit stays "active" — running yet deaf to cast requests, the "up but
|
||||
# not working, restart it by hand" case. systemd can't see this: nothing
|
||||
# crashes and the shim speaks no health protocol, so we probe the real thing —
|
||||
# is its MainPID still holding a live (established, non-loopback) connection?
|
||||
#
|
||||
# check (default) one tick, run by a 60s timer: restart if online but
|
||||
# not connected, rate-limited to one restart per 5 min
|
||||
# wait-online block until a real address exists; used as ExecStartPre so the
|
||||
# unit only starts once online
|
||||
|
||||
writeShellScriptBin "jellyfin-mpv-shim-watchdog" ''
|
||||
set -u
|
||||
service="jellyfin-mpv-shim.service"
|
||||
stamp="''${XDG_RUNTIME_DIR:-/run/user/$(${coreutils}/bin/id -u)}/jellyfin-mpv-shim-watchdog.stamp"
|
||||
|
||||
# A global-scope address on a non-loopback interface — true for a LAN IP too,
|
||||
# so this needs no server URL and works whether Jellyfin is local or remote.
|
||||
network_up() { ${iproute2}/bin/ip -o addr show scope global up 2>/dev/null | ${gnugrep}/bin/grep -q .; }
|
||||
|
||||
if [ "''${1:-check}" = wait-online ]; then
|
||||
while ! network_up; do ${coreutils}/bin/sleep 5; done
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Healthy: MainPID owns an established socket to something other than loopback.
|
||||
pid="$(${systemd}/bin/systemctl --user show -p MainPID --value "$service" 2>/dev/null)"
|
||||
if [ "''${pid:-0}" != 0 ] && ${iproute2}/bin/ss -tnpH state established 2>/dev/null \
|
||||
| ${gnugrep}/bin/grep "pid=$pid," \
|
||||
| ${gnugrep}/bin/grep -qv -e '127\.0\.0\.1' -e '\[::1\]'; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Not connected: only worth restarting once the network is actually back...
|
||||
network_up || exit 0
|
||||
# ...and not if we already restarted within the last 5 minutes.
|
||||
[ -e "$stamp" ] && [ -n "$(${findutils}/bin/find "$stamp" -mmin -5 2>/dev/null)" ] && exit 0
|
||||
|
||||
: > "$stamp"
|
||||
echo "jellyfin-mpv-shim-watchdog: online but no live connection -> restarting $service"
|
||||
${systemd}/bin/systemctl --user restart "$service"
|
||||
''
|
||||
@@ -0,0 +1,69 @@
|
||||
{ writeShellScriptBin
|
||||
, coreutils
|
||||
, findutils
|
||||
, gnugrep
|
||||
, iproute2
|
||||
, systemd
|
||||
}:
|
||||
|
||||
# For user services that only make sense while online (jellyfin-mpv-shim,
|
||||
# nextcloud-client, ...). They keep a persistent socket to their server; when
|
||||
# the machine drops off the network that socket dies, but the process stays
|
||||
# alive and the unit stays "active" — running yet deaf, the "up but not
|
||||
# working, restart it by hand" case. systemd can't see this: nothing crashes
|
||||
# and the programs speak no health protocol, so we probe the real thing — is
|
||||
# the MainPID still holding a live (established, non-loopback) connection?
|
||||
#
|
||||
# wait-online UNIT block until a real address exists; used as ExecStartPre
|
||||
# so UNIT only starts once online. Also stamps the start
|
||||
# time so `check` leaves a freshly (re)started UNIT alone.
|
||||
# check UNIT... one tick, run by a 60s timer: restart every UNIT that is
|
||||
# active but not connected, at most once per 5 minutes.
|
||||
#
|
||||
# Wired up by the services.network-watchdog home-manager module.
|
||||
|
||||
writeShellScriptBin "network-watchdog" ''
|
||||
set -u
|
||||
stampdir="''${XDG_RUNTIME_DIR:-/run/user/$(${coreutils}/bin/id -u)}/network-watchdog"
|
||||
${coreutils}/bin/mkdir -p "$stampdir"
|
||||
|
||||
usage() { echo "usage: network-watchdog wait-online UNIT | check UNIT..." >&2; exit 64; }
|
||||
|
||||
# A global-scope address on a non-loopback interface — true for a LAN IP too,
|
||||
# so this needs no server URL and works whether the server is local or remote.
|
||||
network_up() { ${iproute2}/bin/ip -o addr show scope global up 2>/dev/null | ${gnugrep}/bin/grep -q .; }
|
||||
|
||||
# Healthy: MainPID owns an established socket to something other than loopback.
|
||||
connected() {
|
||||
pid="$(${systemd}/bin/systemctl --user show -p MainPID --value "$1" 2>/dev/null)"
|
||||
[ "''${pid:-0}" != 0 ] && ${iproute2}/bin/ss -tnpH state established 2>/dev/null \
|
||||
| ${gnugrep}/bin/grep "pid=$pid," \
|
||||
| ${gnugrep}/bin/grep -qv -e '127\.0\.0\.1' -e '\[::1\]'
|
||||
}
|
||||
|
||||
# Stamped within the last 5 minutes: still connecting, or already restarted.
|
||||
recently_started() { [ -n "$(${findutils}/bin/find "$stampdir/$1" -mmin -5 2>/dev/null)" ]; }
|
||||
|
||||
[ $# -ge 1 ] || usage
|
||||
cmd="$1"; shift
|
||||
case "$cmd" in
|
||||
wait-online)
|
||||
[ $# -eq 1 ] || usage
|
||||
while ! network_up; do ${coreutils}/bin/sleep 5; done
|
||||
: > "$stampdir/$1"
|
||||
;;
|
||||
check)
|
||||
# Nothing can be connected while offline, and restarting wouldn't help.
|
||||
network_up || exit 0
|
||||
for unit; do
|
||||
# Not "active" (inactive, failed, or still in wait-online): systemd's job, not ours.
|
||||
${systemd}/bin/systemctl --user is-active --quiet "$unit" || continue
|
||||
recently_started "$unit" && continue
|
||||
connected "$unit" && continue
|
||||
echo "network-watchdog: $unit is online but has no live connection -> restarting"
|
||||
${systemd}/bin/systemctl --user restart "$unit" # its wait-online refreshes the stamp
|
||||
done
|
||||
;;
|
||||
*) usage ;;
|
||||
esac
|
||||
''
|
||||
Reference in New Issue
Block a user