diff --git a/examples/router-with-l2tp.nix b/examples/router-with-l2tp.nix index 08d1ce3..5244a62 100644 --- a/examples/router-with-l2tp.nix +++ b/examples/router-with-l2tp.nix @@ -177,16 +177,6 @@ in rec { }; }; - services.restart-on-change = longrun { - name = "wlan0-restart-on-change"; - run = '' - ${pkgs.watch-outputs}/bin/watch-outputs -r wlan0.link.hostapd ${config.services.secrets} wpa_passphrase - ''; - dependencies = [ - config.services.hostap-liminix - config.services.hostap-liminix5 - ]; - }; services.bootstrap-dhcpc = svc.network.dhcp.client.build { interface = config.services.wwan; diff --git a/modules/hostapd/default.nix b/modules/hostapd/default.nix index 02703a0..b1b0a23 100644 --- a/modules/hostapd/default.nix +++ b/modules/hostapd/default.nix @@ -16,6 +16,7 @@ let inherit (lib) mkOption types; inherit (pkgs) liminix; in { + imports = [ ../secrets ]; options = { system.service.hostapd = mkOption { type = liminix.lib.types.serviceDefn; diff --git a/modules/hostapd/service.nix b/modules/hostapd/service.nix index a2752f8..9c258c9 100644 --- a/modules/hostapd/service.nix +++ b/modules/hostapd/service.nix @@ -1,5 +1,6 @@ { liminix +, svc , hostapd , output-template , writeText @@ -39,13 +40,21 @@ let (mapAttrsToList format_value attrs)) + "\n")); -in longrun { - inherit name; - dependencies = [ interface ]; - run = '' - mkdir -p /run/${name} - chmod 0700 /run/${name} - ${output-template}/bin/output-template '{{' '}}' < ${conf} > /run/${name}/hostapd.conf - exec ${hostapd}/bin/hostapd -i $(output ${interface} ifname) -P /run/${name}/hostapd.pid -S /run/${name}/hostapd.conf - ''; + service = longrun { + inherit name; + dependencies = [ interface ]; + run = '' + mkdir -p /run/${name} + chmod 0700 /run/${name} + ${output-template}/bin/output-template '{{' '}}' < ${conf} > /run/${name}/hostapd.conf + exec ${hostapd}/bin/hostapd -i $(output ${interface} ifname) -P /run/${name}/hostapd.pid -S /run/${name}/hostapd.conf + ''; + }; +in svc.secrets.subscriber.build { + watch = { + service = attrs.wpa_passphrase.service; + paths = ["wpa_passphrase"]; + }; + inherit service; + action = "restart-all"; } diff --git a/modules/secrets/default.nix b/modules/secrets/default.nix index fd830be..ab394b9 100644 --- a/modules/secrets/default.nix +++ b/modules/secrets/default.nix @@ -14,6 +14,10 @@ in { description = "fetch secrets from external vault with https"; type = liminix.lib.types.serviceDefn; }; + subscriber = mkOption { + description = "wrapper around a service that needs notifying (e.g. restarting) when secrets change"; + type = liminix.lib.types.serviceDefn; + }; }; config.system.service.secrets = { @@ -32,5 +36,31 @@ in { description = "how often to check the source, in minutes"; }; }; + subscriber = config.system.callService ./subscriber.nix { + watch = { + service = mkOption { + description = "secrets service to subscribe to"; + type = liminix.lib.types.service; + }; + paths = mkOption { + description = "list of output paths we are interested in"; + example = ["wan/l2tp" "wifi/wlan5"]; + type = types.listOf types.str; + }; + }; + service = mkOption { + description = "subscribing service that will receive notification"; + type = liminix.lib.types.service; + }; + action = mkOption { + description = "how do we notify the service to regenerate its config"; + default = "restart-all"; + type = types.enum [ + "restart" "restart-all" + "hup" "int" "quit" "kill" "term" + "winch" "usr1" "usr2" + ]; + }; + }; }; } diff --git a/modules/secrets/subscriber.nix b/modules/secrets/subscriber.nix new file mode 100644 index 0000000..398506a --- /dev/null +++ b/modules/secrets/subscriber.nix @@ -0,0 +1,23 @@ +{ + liminix, lib, lim, s6, s6-rc, watch-outputs +}: +{ watch, service, action } : +let + inherit (liminix.services) oneshot longrun; + inherit (builtins) toString; + inherit (service) name; + watcher = let name' = "check-${name}"; in longrun { + name = name'; + run = '' + dir=/run/service/${name} + echo waiting for $dir + if test -e $dir/notification-fd; then flag="-U"; else flag="-u"; fi + ${s6}/bin/s6-svwait $flag /run/service/${name} || exit + PATH=${s6-rc}/bin:${s6}/bin:$PATH + ${watch-outputs}/bin/watch-outputs -r ${name} ${watch.service} ${lib.concatStringsSep " " watch.paths} + ''; + }; +in service.overrideAttrs(o: { + buildInputs = (lim.orEmpty o.buildInputs) ++ [ watcher ]; + dependencies = (lim.orEmpty o.dependencies) ++ [ watcher ]; +}) diff --git a/pkgs/watch-outputs/watch-outputs.fnl b/pkgs/watch-outputs/watch-outputs.fnl index deb270f..6cd4865 100644 --- a/pkgs/watch-outputs/watch-outputs.fnl +++ b/pkgs/watch-outputs/watch-outputs.fnl @@ -33,12 +33,13 @@ _ path (ipairs paths)] (or changed? (not (table= (dig old-tree path) (dig new-tree path)))))) +(fn %% [fmt ...] (string.format fmt ...)) (fn do-action [action service] (case action - :restart (system "s6-svc -r /run/service/%s" service) - :restart-all (system "s6-rc -b -d %q; s6-rc-up-tree %q" service service) - [:signal n] (system "s6-svc -s %d /run/service/%s" n service))) + :restart (system (%% "s6-svc -r /run/service/%s" service)) + :restart-all (system (%% "s6-rc -b -d %q; s6-rc-up-tree %q" service service)) + [:signal n] (system (%% "s6-svc -s %d /run/service/%s" n service)))) (fn run [] (let [{