Merge pull request #218633 from onny/networkd-dispatcher-rules

nixos/networkd-dispatcher: add rules option

authored by Jonas Heinrich and committed by GitHub 9f10a2e8 ebcb6a07

+80 -26
+61 -26
nixos/modules/services/networking/networkd-dispatcher.nix
··· 3 3 with lib; 4 4 5 5 let 6 + 6 7 cfg = config.services.networkd-dispatcher; 8 + 7 9 in { 10 + 8 11 options = { 9 12 services.networkd-dispatcher = { 10 13 ··· 14 17 for usage. 15 18 ''); 16 19 17 - scriptDir = mkOption { 18 - type = types.path; 19 - default = "/var/lib/networkd-dispatcher"; 20 - description = mdDoc '' 21 - This directory is used for keeping various scripts read and run by 22 - networkd-dispatcher. See [https://gitlab.com/craftyguy/networkd-dispatcher](upstream instructions) 23 - for directory structure and script usage. 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 + }; 24 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 + }); 25 63 }; 26 64 27 65 }; ··· 30 68 config = mkIf cfg.enable { 31 69 32 70 systemd = { 33 - 34 71 packages = [ pkgs.networkd-dispatcher ]; 35 72 services.networkd-dispatcher = { 36 73 wantedBy = [ "multi-user.target" ]; 37 74 # Override existing ExecStart definition 38 - serviceConfig.ExecStart = [ 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 [ 39 90 "" 40 - "${pkgs.networkd-dispatcher}/bin/networkd-dispatcher -v --script-dir ${cfg.scriptDir} $networkd_dispatcher_args" 91 + "${pkgs.networkd-dispatcher}/bin/networkd-dispatcher -v --script-dir ${scriptDir} $networkd_dispatcher_args" 41 92 ]; 42 93 }; 43 - 44 - # Directory structure required according to upstream instructions 45 - # https://gitlab.com/craftyguy/networkd-dispatcher 46 - tmpfiles.rules = [ 47 - "d '${cfg.scriptDir}' 0750 root root - -" 48 - "d '${cfg.scriptDir}/routable.d' 0750 root root - -" 49 - "d '${cfg.scriptDir}/dormant.d' 0750 root root - -" 50 - "d '${cfg.scriptDir}/no-carrier.d' 0750 root root - -" 51 - "d '${cfg.scriptDir}/off.d' 0750 root root - -" 52 - "d '${cfg.scriptDir}/carrier.d' 0750 root root - -" 53 - "d '${cfg.scriptDir}/degraded.d' 0750 root root - -" 54 - "d '${cfg.scriptDir}/configuring.d' 0750 root root - -" 55 - "d '${cfg.scriptDir}/configured.d' 0750 root root - -" 56 - ]; 57 - 58 94 }; 59 - 60 95 61 96 }; 62 97 }
+6
pkgs/tools/networking/networkd-dispatcher/default.nix
··· 19 19 hash = "sha256-yO9/HlUkaQmW/n9N3vboHw//YMzBjxIHA2zAxgZNEv0="; 20 20 }; 21 21 22 + patches = [ 23 + # Support rule files in NixOS store paths. Required for the networkd-dispatcher 24 + # module to work 25 + ./support_nix_store_path.patch 26 + ]; 27 + 22 28 postPatch = '' 23 29 # Fix paths in systemd unit file 24 30 substituteInPlace networkd-dispatcher.service \
+13
pkgs/tools/networking/networkd-dispatcher/support_nix_store_path.patch
··· 1 + diff --git a/networkd-dispatcher b/networkd-dispatcher 2 + index ef877ce..8c341f2 100755 3 + --- a/networkd-dispatcher 4 + +++ b/networkd-dispatcher 5 + @@ -171,6 +171,8 @@ def check_perms(path, mode=0o755, uid=0, gid=0): 6 + 7 + if not os.path.exists(path): 8 + raise FileNotFoundError 9 + + if re.search('^/nix/store/.*', str(path)): 10 + + return True 11 + st = os.stat(path, follow_symlinks=False) 12 + st_mode = st.st_mode & 0x00FFF 13 + if st.st_uid == uid and st.st_gid == gid and st_mode == mode: