1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6 cfg = config.services.ananicy;
7 configFile = pkgs.writeText "ananicy.conf" (generators.toKeyValue { } cfg.settings);
8 extraRules = pkgs.writeText "extraRules" (concatMapStringsSep "\n" (l: builtins.toJSON l) cfg.extraRules);
9 extraTypes = pkgs.writeText "extraTypes" (concatMapStringsSep "\n" (l: builtins.toJSON l) cfg.extraTypes);
10 extraCgroups = pkgs.writeText "extraCgroups" (concatMapStringsSep "\n" (l: builtins.toJSON l) cfg.extraCgroups);
11 servicename = if ((lib.getName cfg.package) == (lib.getName pkgs.ananicy-cpp)) then "ananicy-cpp" else "ananicy";
12in
13{
14 options = {
15 services.ananicy = {
16 enable = mkEnableOption (lib.mdDoc "Ananicy, an auto nice daemon");
17
18 package = mkOption {
19 type = types.package;
20 default = pkgs.ananicy;
21 defaultText = literalExpression "pkgs.ananicy";
22 example = literalExpression "pkgs.ananicy-cpp";
23 description = lib.mdDoc ''
24 Which ananicy package to use.
25 '';
26 };
27
28 rulesProvider = mkOption {
29 type = types.package;
30 default = pkgs.ananicy;
31 defaultText = literalExpression "pkgs.ananicy";
32 example = literalExpression "pkgs.ananicy-cpp";
33 description = lib.mdDoc ''
34 Which package to copy default rules,types,cgroups from.
35 '';
36 };
37
38 settings = mkOption {
39 type = with types; attrsOf (oneOf [ int bool str ]);
40 default = { };
41 example = {
42 apply_nice = false;
43 };
44 description = lib.mdDoc ''
45 See <https://github.com/Nefelim4ag/Ananicy/blob/master/ananicy.d/ananicy.conf>
46 '';
47 };
48
49 extraRules = mkOption {
50 type = with types; listOf attrs;
51 default = [ ];
52 description = lib.mdDoc ''
53 Rules to write in 'nixRules.rules'. See:
54 <https://github.com/Nefelim4ag/Ananicy#configuration>
55 <https://gitlab.com/ananicy-cpp/ananicy-cpp/#global-configuration>
56 '';
57 example = [
58 { name = "eog"; type = "Image-Viewer"; }
59 { name = "fdupes"; type = "BG_CPUIO"; }
60 ];
61 };
62 extraTypes = mkOption {
63 type = with types; listOf attrs;
64 default = [ ];
65 description = lib.mdDoc ''
66 Types to write in 'nixTypes.types'. See:
67 <https://gitlab.com/ananicy-cpp/ananicy-cpp/#types>
68 '';
69 example = [
70 { type = "my_type"; nice = 19; other_parameter = "value"; }
71 { type = "compiler"; nice = 19; sched = "batch"; ioclass = "idle"; }
72 ];
73 };
74 extraCgroups = mkOption {
75 type = with types; listOf attrs;
76 default = [ ];
77 description = lib.mdDoc ''
78 Cgroups to write in 'nixCgroups.cgroups'. See:
79 <https://gitlab.com/ananicy-cpp/ananicy-cpp/#cgroups>
80 '';
81 example = [
82 { cgroup = "cpu80"; CPUQuota = 80; }
83 ];
84 };
85 };
86 };
87
88 config = mkIf cfg.enable {
89 environment = {
90 systemPackages = [ cfg.package ];
91 etc."ananicy.d".source = pkgs.runCommandLocal "ananicyfiles" { } ''
92 mkdir -p $out
93 # ananicy-cpp does not include rules or settings on purpose
94 if [[ -d "${cfg.rulesProvider}/etc/ananicy.d/00-default" ]]; then
95 cp -r ${cfg.rulesProvider}/etc/ananicy.d/* $out
96 else
97 cp -r ${cfg.rulesProvider}/* $out
98 fi
99
100 # configured through .setings
101 rm -f $out/ananicy.conf
102 cp ${configFile} $out/ananicy.conf
103 ${optionalString (cfg.extraRules != [ ]) "cp ${extraRules} $out/nixRules.rules"}
104 ${optionalString (cfg.extraTypes != [ ]) "cp ${extraTypes} $out/nixTypes.types"}
105 ${optionalString (cfg.extraCgroups != [ ]) "cp ${extraCgroups} $out/nixCgroups.cgroups"}
106 '';
107 };
108
109 # ananicy and ananicy-cpp have different default settings
110 services.ananicy.settings =
111 let
112 mkOD = mkOptionDefault;
113 in
114 {
115 cgroup_load = mkOD true;
116 type_load = mkOD true;
117 rule_load = mkOD true;
118 apply_nice = mkOD true;
119 apply_ioclass = mkOD true;
120 apply_ionice = mkOD true;
121 apply_sched = mkOD true;
122 apply_oom_score_adj = mkOD true;
123 apply_cgroup = mkOD true;
124 } // (if ((lib.getName cfg.package) == (lib.getName pkgs.ananicy-cpp)) then {
125 # https://gitlab.com/ananicy-cpp/ananicy-cpp/-/blob/master/src/config.cpp#L12
126 loglevel = mkOD "warn"; # default is info but its spammy
127 cgroup_realtime_workaround = mkOD config.systemd.enableUnifiedCgroupHierarchy;
128 log_applied_rule = mkOD false;
129 } else {
130 # https://github.com/Nefelim4ag/Ananicy/blob/master/ananicy.d/ananicy.conf
131 check_disks_schedulers = mkOD true;
132 check_freq = mkOD 5;
133 });
134
135 systemd = {
136 # https://gitlab.com/ananicy-cpp/ananicy-cpp/#cgroups applies to both ananicy and -cpp
137 enableUnifiedCgroupHierarchy = mkDefault false;
138 packages = [ cfg.package ];
139 services."${servicename}" = {
140 wantedBy = [ "default.target" ];
141 };
142 };
143 };
144
145 meta = {
146 maintainers = with maintainers; [ artturin ];
147 };
148}