From 11a4b7006e279842b6813f07c56231d40f9666db Mon Sep 17 00:00:00 2001 From: Colin Date: Tue, 18 Jul 2023 09:54:06 +0000 Subject: [PATCH] upnp-forwards: fix timer to actually run every hour --- modules/ports.nix | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/modules/ports.nix b/modules/ports.nix index 90af5247..0bd9d829 100644 --- a/modules/ports.nix +++ b/modules/ports.nix @@ -78,9 +78,13 @@ in type = types.bool; }; upnpRenewInterval = mkOption { - default = "1hr"; + default = "hourly"; type = types.str; - description = "how frequently to renew UPnP leases"; + description = '' + how frequently to renew UPnP leases. + syntax is what systemd uses for Calendar Events: + - + ''; }; upnpLeaseDuration = mkOption { default = 86400; @@ -101,17 +105,33 @@ in }) (lib.mkIf cfg.openUpnp { systemd.services = lib.mkMerge (lib.mapAttrsToList upnpServiceForPort cfg.ports); + # in order to run all upnp-forward-xyz services on a regular schedule: + # - upnp-forwards.timer + # -> activates upnp-forwards.target + # -> activates all upnp-forward-xyz.service's + # + # crucially, the timer only activates the target if upnp-forwards.target is in the "stopped" (or, "inactive") state. + # this isn't the case by default. but adding `StopWhenUnneeded` to the target causes it to be considered "stopped" + # immediately after it schedules the services. + # + # additionally, one could add `Upholds = upnp-forwards.target` to all the services if we only want the target to + # be stopped after all forwards are complete. + # source: systemd.timers.upnp-forwards = { wantedBy = [ "network.target" ]; timerConfig = { OnStartupSec = "1min"; - OnUnitActiveSec = cfg.upnpRenewInterval; + OnCalendar = cfg.upnpRenewInterval; + RandomizeDelaySec = "2min"; Unit = "upnp-forwards.target"; }; }; systemd.targets.upnp-forwards = { description = "forward ports from upstream gateway to this host"; after = [ "network.target" ]; + unitConfig = { + StopWhenUnneeded = true; + }; }; }) ];