1# Configuration for the xfs_quota command
2
3{
4 config,
5 lib,
6 pkgs,
7 ...
8}:
9
10let
11
12 cfg = config.programs.xfs_quota;
13
14 limitOptions =
15 opts:
16 builtins.concatStringsSep " " [
17 (lib.optionalString (opts.sizeSoftLimit != null) "bsoft=${opts.sizeSoftLimit}")
18 (lib.optionalString (opts.sizeHardLimit != null) "bhard=${opts.sizeHardLimit}")
19 ];
20
21in
22
23{
24
25 ###### interface
26
27 options = {
28
29 programs.xfs_quota = {
30 projects = lib.mkOption {
31 default = { };
32 type = lib.types.attrsOf (
33 lib.types.submodule {
34 options = {
35 id = lib.mkOption {
36 type = lib.types.int;
37 description = "Project ID.";
38 };
39
40 fileSystem = lib.mkOption {
41 type = lib.types.str;
42 description = "XFS filesystem hosting the xfs_quota project.";
43 default = "/";
44 };
45
46 path = lib.mkOption {
47 type = lib.types.str;
48 description = "Project directory.";
49 };
50
51 sizeSoftLimit = lib.mkOption {
52 type = lib.types.nullOr lib.types.str;
53 default = null;
54 example = "30g";
55 description = "Soft limit of the project size";
56 };
57
58 sizeHardLimit = lib.mkOption {
59 type = lib.types.nullOr lib.types.str;
60 default = null;
61 example = "50g";
62 description = "Hard limit of the project size.";
63 };
64 };
65 }
66 );
67
68 description = "Setup of xfs_quota projects. Make sure the filesystem is mounted with the pquota option.";
69
70 example = {
71 projname = {
72 id = 50;
73 path = "/xfsprojects/projname";
74 sizeHardLimit = "50g";
75 };
76 };
77 };
78 };
79
80 };
81
82 ###### implementation
83
84 config = lib.mkIf (cfg.projects != { }) {
85
86 environment.etc.projects.source = pkgs.writeText "etc-project" (
87 builtins.concatStringsSep "\n" (
88 lib.mapAttrsToList (name: opts: "${builtins.toString opts.id}:${opts.path}") cfg.projects
89 )
90 );
91
92 environment.etc.projid.source = pkgs.writeText "etc-projid" (
93 builtins.concatStringsSep "\n" (
94 lib.mapAttrsToList (name: opts: "${name}:${builtins.toString opts.id}") cfg.projects
95 )
96 );
97
98 systemd.services = lib.mapAttrs' (
99 name: opts:
100 lib.nameValuePair "xfs_quota-${name}" {
101 description = "Setup xfs_quota for project ${name}";
102 script = ''
103 ${pkgs.xfsprogs.bin}/bin/xfs_quota -x -c 'project -s ${name}' ${opts.fileSystem}
104 ${pkgs.xfsprogs.bin}/bin/xfs_quota -x -c 'limit -p ${limitOptions opts} ${name}' ${opts.fileSystem}
105 '';
106
107 wantedBy = [ "multi-user.target" ];
108 after = [ ((builtins.replaceStrings [ "/" ] [ "-" ] opts.fileSystem) + ".mount") ];
109
110 restartTriggers = [ config.environment.etc.projects.source ];
111
112 serviceConfig = {
113 Type = "oneshot";
114 RemainAfterExit = true;
115 };
116 }
117 ) cfg.projects;
118
119 };
120
121}