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