1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6
7 cfg = config.services.networkd-dispatcher;
8
9in {
10
11 options = {
12 services.networkd-dispatcher = {
13
14 enable = mkEnableOption (mdDoc ''
15 Networkd-dispatcher service for systemd-networkd connection status
16 change. See [https://gitlab.com/craftyguy/networkd-dispatcher](upstream instructions)
17 for usage.
18 '');
19
20 rules = mkOption {
21 default = {};
22 example = lib.literalExpression ''
23 { "restart-tor" = {
24 onState = ["routable" "off"];
25 script = '''
26 #!''${pkgs.runtimeShell}
27 if [[ $IFACE == "wlan0" && $AdministrativeState == "configured" ]]; then
28 echo "Restarting Tor ..."
29 systemctl restart tor
30 fi
31 exit 0
32 ''';
33 };
34 };
35 '';
36 description = lib.mdDoc ''
37 Declarative configuration of networkd-dispatcher rules. See
38 [https://gitlab.com/craftyguy/networkd-dispatcher](upstream instructions)
39 for an introduction and example scripts.
40 '';
41 type = types.attrsOf (types.submodule {
42 options = {
43 onState = mkOption {
44 type = types.listOf (types.enum [
45 "routable" "dormant" "no-carrier" "off" "carrier" "degraded"
46 "configuring" "configured"
47 ]);
48 default = null;
49 description = lib.mdDoc ''
50 List of names of the systemd-networkd operational states which
51 should trigger the script. See <https://www.freedesktop.org/software/systemd/man/networkctl.html>
52 for a description of the specific state type.
53 '';
54 };
55 script = mkOption {
56 type = types.lines;
57 description = lib.mdDoc ''
58 Shell commands executed on specified operational states.
59 '';
60 };
61 };
62 });
63 };
64
65 };
66 };
67
68 config = mkIf cfg.enable {
69
70 systemd = {
71 packages = [ pkgs.networkd-dispatcher ];
72 services.networkd-dispatcher = {
73 wantedBy = [ "multi-user.target" ];
74 # Override existing ExecStart definition
75 serviceConfig.ExecStart = let
76 scriptDir = pkgs.symlinkJoin {
77 name = "networkd-dispatcher-script-dir";
78 paths = lib.mapAttrsToList (name: cfg:
79 (map(state:
80 pkgs.writeTextFile {
81 inherit name;
82 text = cfg.script;
83 destination = "/${state}.d/${name}";
84 executable = true;
85 }
86 ) cfg.onState)
87 ) cfg.rules;
88 };
89 in [
90 ""
91 "${pkgs.networkd-dispatcher}/bin/networkd-dispatcher -v --script-dir ${scriptDir} $networkd_dispatcher_args"
92 ];
93 };
94 };
95
96 };
97}
98