Unverified Commit 9f10a2e8 authored by Jonas Heinrich's avatar Jonas Heinrich Committed by GitHub
Browse files

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

nixos/networkd-dispatcher: add rules option
parents ebcb6a07 22fd05ad
Loading
Loading
Loading
Loading
+61 −26
Original line number Diff line number Diff line
@@ -3,8 +3,11 @@
with lib;

let

  cfg = config.services.networkd-dispatcher;

in {

  options = {
    services.networkd-dispatcher = {

@@ -14,15 +17,50 @@ in {
        for usage.
      '');

      scriptDir = mkOption {
        type = types.path;
        default = "/var/lib/networkd-dispatcher";
        description = mdDoc ''
          This directory is used for keeping various scripts read and run by
          networkd-dispatcher. See [https://gitlab.com/craftyguy/networkd-dispatcher](upstream instructions)
          for directory structure and script usage.
      rules = mkOption {
        default = {};
        example = lib.literalExpression ''
          { "restart-tor" = {
              onState = ["routable" "off"];
              script = '''
                #!''${pkgs.runtimeShell}
                if [[ $IFACE == "wlan0" && $AdministrativeState == "configured" ]]; then
                  echo "Restarting Tor ..."
                  systemctl restart tor
                fi
                exit 0
              ''';
            };
          };
        '';
        description = lib.mdDoc ''
          Declarative configuration of networkd-dispatcher rules. See
          [https://gitlab.com/craftyguy/networkd-dispatcher](upstream instructions)
          for an introduction and example scripts.
        '';
        type = types.attrsOf (types.submodule {
          options = {
            onState = mkOption {
              type = types.listOf (types.enum [
                "routable" "dormant" "no-carrier" "off" "carrier" "degraded"
                "configuring" "configured"
              ]);
              default = null;
              description = lib.mdDoc ''
                List of names of the systemd-networkd operational states which
                should trigger the script. See <https://www.freedesktop.org/software/systemd/man/networkctl.html>
                for a description of the specific state type.
              '';
            };
            script = mkOption {
              type = types.lines;
              description = lib.mdDoc ''
                Shell commands executed on specified operational states.
              '';
            };
          };
        });
      };

    };
  };
@@ -30,34 +68,31 @@ in {
  config = mkIf cfg.enable {

    systemd = {

      packages = [ pkgs.networkd-dispatcher ];
      services.networkd-dispatcher = {
        wantedBy = [ "multi-user.target" ];
        # Override existing ExecStart definition
        serviceConfig.ExecStart = [
        serviceConfig.ExecStart = let
          scriptDir = pkgs.symlinkJoin {
            name = "networkd-dispatcher-script-dir";
            paths = lib.mapAttrsToList (name: cfg:
              (map(state:
                pkgs.writeTextFile {
                  inherit name;
                  text = cfg.script;
                  destination = "/${state}.d/${name}";
                  executable = true;
                }
              ) cfg.onState)
            ) cfg.rules;
          };
        in [
          ""
          "${pkgs.networkd-dispatcher}/bin/networkd-dispatcher -v --script-dir ${cfg.scriptDir} $networkd_dispatcher_args"
          "${pkgs.networkd-dispatcher}/bin/networkd-dispatcher -v --script-dir ${scriptDir} $networkd_dispatcher_args"
        ];
      };

      # Directory structure required according to upstream instructions
      # https://gitlab.com/craftyguy/networkd-dispatcher
      tmpfiles.rules = [
        "d '${cfg.scriptDir}'               0750 root root - -"
        "d '${cfg.scriptDir}/routable.d'    0750 root root - -"
        "d '${cfg.scriptDir}/dormant.d'     0750 root root - -"
        "d '${cfg.scriptDir}/no-carrier.d'  0750 root root - -"
        "d '${cfg.scriptDir}/off.d'         0750 root root - -"
        "d '${cfg.scriptDir}/carrier.d'     0750 root root - -"
        "d '${cfg.scriptDir}/degraded.d'    0750 root root - -"
        "d '${cfg.scriptDir}/configuring.d' 0750 root root - -"
        "d '${cfg.scriptDir}/configured.d'  0750 root root - -"
      ];

    };


  };
}
+6 −0
Original line number Diff line number Diff line
@@ -19,6 +19,12 @@ stdenv.mkDerivation rec {
    hash = "sha256-yO9/HlUkaQmW/n9N3vboHw//YMzBjxIHA2zAxgZNEv0=";
  };

  patches = [
    # Support rule files in NixOS store paths. Required for the networkd-dispatcher
    # module to work
    ./support_nix_store_path.patch
  ];

  postPatch = ''
    # Fix paths in systemd unit file
    substituteInPlace networkd-dispatcher.service \
+13 −0
Original line number Diff line number Diff line
diff --git a/networkd-dispatcher b/networkd-dispatcher
index ef877ce..8c341f2 100755
--- a/networkd-dispatcher
+++ b/networkd-dispatcher
@@ -171,6 +171,8 @@ def check_perms(path, mode=0o755, uid=0, gid=0):
 
     if not os.path.exists(path):
         raise FileNotFoundError
+    if re.search('^/nix/store/.*', str(path)):
+        return True
     st = os.stat(path, follow_symlinks=False)
     st_mode = st.st_mode & 0x00FFF
     if st.st_uid == uid and st.st_gid == gid and st_mode == mode: