53 lines
1.9 KiB
Nix
53 lines
1.9 KiB
Nix
{ lib, config, pkgs, ... }:
|
|
let
|
|
cfg = config.services.network-watchdog;
|
|
watchdog = "${pkgs.custom.network-watchdog}/bin/network-watchdog";
|
|
units = map (name: "${name}.service") cfg.units;
|
|
in {
|
|
# User services that only make sense while online: GUI clients that hold a
|
|
# socket to a server (jellyfin-mpv-shim, nextcloud-client). Their upstream
|
|
# units have no network ordering (network-online.target is a system target,
|
|
# out of reach for user units), so they happily start while offline —
|
|
# silently dead — and nothing notices a connection dropped by a network
|
|
# blip. Gate each start on the network being up, restart on failure, and let
|
|
# a watchdog catch the "up but not connected" state that systemd can't see.
|
|
# See pkgs.custom.network-watchdog.
|
|
options.services.network-watchdog.units = lib.mkOption {
|
|
type = lib.types.listOf lib.types.str;
|
|
default = [ ];
|
|
example = [ "jellyfin-mpv-shim" ];
|
|
description = "User services (no .service suffix) to gate on the network and keep connected.";
|
|
};
|
|
|
|
config = lib.mkIf (cfg.units != [ ]) {
|
|
systemd.user.services = lib.genAttrs cfg.units (name: {
|
|
Service = {
|
|
ExecStartPre = "${watchdog} wait-online ${name}.service";
|
|
TimeoutStartSec = "infinity"; # stay in start-pre until the network is back
|
|
Restart = lib.mkDefault "on-failure";
|
|
RestartSec = lib.mkDefault 5;
|
|
};
|
|
}) // {
|
|
network-watchdog = {
|
|
Unit = {
|
|
Description = "Restart network services that are up but not connected";
|
|
After = units;
|
|
};
|
|
Service = {
|
|
Type = "oneshot";
|
|
ExecStart = "${watchdog} check ${lib.concatStringsSep " " units}";
|
|
};
|
|
};
|
|
};
|
|
|
|
systemd.user.timers.network-watchdog = {
|
|
Unit.Description = "Periodic health check for network services";
|
|
Timer = {
|
|
OnActiveSec = "60s";
|
|
OnUnitActiveSec = "60s";
|
|
};
|
|
Install.WantedBy = [ "timers.target" ];
|
|
};
|
|
};
|
|
}
|