summaryrefslogtreecommitdiffstats
path: root/krebs/3modules/permown.nix
blob: 7a86013e18d88e4a48a795a4dfb6a30c09828e59 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
with import <stockholm/lib>;
{ config, pkgs, ... }: {

  options.krebs.permown = mkOption {
    default = [];
    type = types.listOf (types.submodule {
      options = {
        directory-mode = mkOption {
          default = "=rwx";
          type = types.str; # TODO
        };
        file-mode = mkOption {
          default = "=rw";
          type = types.str; # TODO
        };
        group = mkOption {
          apply = x: if x == null then "" else x;
          default = null;
          type = types.nullOr types.groupname;
        };
        owner = mkOption {
          type = types.username;
        };
        path = mkOption {
          type = types.absolute-pathname;
        };
        umask = mkOption {
          default = "0027";
          type = types.file-mode;
        };
      };
    });
  };

  config.systemd.services = genAttrs' config.krebs.permown (plan: {
    name = "permown.${replaceStrings ["/"] ["_"] plan.path}";
    value = {
      environment = {
        DIR_MODE = plan.directory-mode;
        FILE_MODE = plan.file-mode;
        OWNER_GROUP = "${plan.owner}:${plan.group}";
        ROOT_PATH = plan.path;
      };
      path = [
        pkgs.coreutils
        pkgs.findutils
        pkgs.inotifyTools
      ];
      serviceConfig = {
        ExecStart = pkgs.writeDash "permown" ''
          set -efu

          find "$ROOT_PATH" -exec chown "$OWNER_GROUP" {} +
          find "$ROOT_PATH" -type d -exec chmod "$DIR_MODE" {} +
          find "$ROOT_PATH" -type f -exec chmod "$FILE_MODE" {} +

          inotifywait -mrq -e CREATE --format %w%f "$ROOT_PATH" |
          while read -r path; do
            if test -d "$path"; then
              exec "$0" "$@"
            fi
            chown "$OWNER_GROUP" "$path"
            chmod "$FILE_MODE" "$path"
          done
        '';
        Restart = "always";
        RestartSec = 10;
        UMask = plan.umask;
      };
      wantedBy = [ "multi-user.target" ];
    };
  });

}