diff --git a/hosts/servo/services/trust-dns.nix b/hosts/servo/services/trust-dns.nix index 825b8d1a..0c7792aa 100644 --- a/hosts/servo/services/trust-dns.nix +++ b/hosts/servo/services/trust-dns.nix @@ -49,62 +49,21 @@ "/var/lib/trust-dns/native.uninsane.org.zone" ]; - systemd.services.ddns-trust-dns = { - description = "update dynamic DNS entries for self-hosted trust-dns"; - after = [ "network.target" ]; - wantedBy = [ "trust-dns.service" ]; - restartTriggers = [( - builtins.toJSON config.sane.services.trust-dns - )]; - serviceConfig.Type = "oneshot"; - script = let - check-ip = "${pkgs.sane-scripts}/bin/sane-ip-check-router-wan"; - sed = "${pkgs.gnused}/bin/sed"; - zone-dir = "/var/lib/trust-dns"; - zone-out = "${zone-dir}/native.uninsane.org.zone"; - diff = "${pkgs.diffutils}/bin/diff"; - systemctl = "${pkgs.systemd}/bin/systemctl"; - zone-template = pkgs.writeText "native.uninsane.org.zone.in" '' - @ A %NATIVE% - ns1 A %NATIVE% - native A %NATIVE% - ''; - in '' - set -ex - mkdir -p ${zone-dir} - ip=$(${check-ip}) - - ${sed} s/%NATIVE%/$ip/ ${zone-template} > ${zone-out}.new - - # see if anything changed - # TODO: instead of diffing, we could `dig` against the actual deployment. - # - that could be more resilient to races. - touch ${zone-out} # in case it didn't exist yet - cp ${zone-out} ${zone-out}.old - mv ${zone-out}.new ${zone-out} - # if so, restart trust-dns - if [ ${diff} -u ${zone-out}.old ${zone-out} ] - then - echo "zone unchanged. ip: $ip" - else - echo "zone changed." - status=$(${systemctl} is-active trust-dns.service || true) - echo $status - if [ "$status" = "active" ] - then - echo "restarting trust-dns." - ${systemctl} restart trust-dns.service - fi - fi + systemd.services.trust-dns.preStart = let + sed = "${pkgs.gnused}/bin/sed"; + zone-dir = "/var/lib/trust-dns"; + zone-out = "${zone-dir}/native.uninsane.org.zone"; + zone-template = pkgs.writeText "native.uninsane.org.zone.in" '' + @ A %NATIVE% + ns1 A %NATIVE% + native A %NATIVE% ''; - }; + in '' + # make WAN records available to trust-dns + mkdir -p ${zone-dir} + ip=$(cat '${config.sane.services.dyn-dns.ipPath}') + ${sed} s/%NATIVE%/$ip/ ${zone-template} > ${zone-out} + ''; - systemd.timers.ddns-trust-dns = { - # wantedBy = [ "multi-user.target" ]; - wantedBy = [ "trust-dns.service" ]; - timerConfig = { - OnStartupSec = "10min"; - OnUnitActiveSec = "10min"; - }; - }; + sane.services.dyn-dns.restartOnChange = [ "trust-dns.service" ]; } diff --git a/modules/services/dyn-dns.nix b/modules/services/dyn-dns.nix index d0ff1045..814b8113 100644 --- a/modules/services/dyn-dns.nix +++ b/modules/services/dyn-dns.nix @@ -41,32 +41,39 @@ in config = mkIf cfg.enable { systemd.services.dyn-dns = { description = "update this host's record of its WAN IP"; - after = [ "network.target" ]; - restartTriggers = [(builtins.toJSON cfg)]; serviceConfig.Type = "oneshot"; + restartTriggers = [(builtins.toJSON cfg)]; + + after = [ "network.target" ]; + wantedBy = cfg.restartOnChange; + before = cfg.restartOnChange; + script = '' - mkdir -p $(dirname '${cfg.ipPath}') + mkdir -p "$(dirname '${cfg.ipPath}')" newIp=$(${cfg.ipCmd}) + oldIp=$(cat '${cfg.ipPath}' || true) # systemd path units are triggered on any file write action, # regardless of content change. so only update the file if our IP *actually* changed - if [ "$newIp" != "$(cat '${cfg.ipPath}')" ] + if [ "$newIp" != "$oldIp" ] then echo "$newIp" > '${cfg.ipPath}' + echo "WAN ip changed $oldIp -> $newIp" fi + exit $(test -f '${cfg.ipPath}') ''; }; systemd.timers.dyn-dns = { - wantedBy = [ "multi-user.target" ]; + # if anything wants dyn-dns.service, they surely want the timer too. + wantedBy = [ "dyn-dns.service" ]; timerConfig = { - OnStartupSec = cfg.interval; OnUnitActiveSec = cfg.interval; }; }; systemd.paths.dyn-dns-watcher = { - before = [ "dyn-dns.service" ]; - wantedBy = [ "dyn-dns.service" ]; + before = [ "dyn-dns.timer" ]; + wantedBy = [ "dyn-dns.timer" ]; pathConfig = { Unit = "dyn-dns-reactor.service"; PathChanged = [ cfg.ipPath ]; diff --git a/modules/services/trust-dns.nix b/modules/services/trust-dns.nix index aca83634..447f347d 100644 --- a/modules/services/trust-dns.nix +++ b/modules/services/trust-dns.nix @@ -137,8 +137,6 @@ in RestartSec = "10s"; # TODO: hardening (like, don't run as root!) }; - wants = [ "ddns-trust-dns.service" "ddns-trust-dns.timer" ]; - # XXX: can't be after ddns-trust-dns.service, because the latter `restarts` this one -- *before* it's done activating. after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; };