vuls: init at 0.27.0
[NixPkgs.git] / nixos / modules / services / system / earlyoom.nix
blob7e012dee02cbfcaa0c28045d09c047580217497d
1 { config, lib, pkgs, ... }:
3 let
4   cfg = config.services.earlyoom;
6   inherit (lib)
7     concatStringsSep
8     escapeShellArg
9     literalExpression
10     mkDefault
11     mkEnableOption
12     mkIf
13     mkOption
14     mkPackageOption
15     mkRemovedOptionModule
16     optionalString
17     optionals
18     types;
21   meta = {
22     maintainers = with lib.maintainers; [ AndersonTorres ];
23   };
25   options.services.earlyoom = {
26     enable = mkEnableOption "early out of memory killing";
28     package = mkPackageOption pkgs "earlyoom" { };
30     freeMemThreshold = mkOption {
31       type = types.ints.between 1 100;
32       default = 10;
33       description = ''
34         Minimum available memory (in percent).
36         If the available memory falls below this threshold (and the analog is true for
37         {option}`freeSwapThreshold`) the killing begins.
38         SIGTERM is sent first to the process that uses the most memory; then, if the available
39         memory falls below {option}`freeMemKillThreshold` (and the analog is true for
40         {option}`freeSwapKillThreshold`), SIGKILL is sent.
42         See [README](https://github.com/rfjakob/earlyoom#command-line-options) for details.
43       '';
44     };
46     freeMemKillThreshold = mkOption {
47       type = types.nullOr (types.ints.between 1 100);
48       default = null;
49       description = ''
50         Minimum available memory (in percent) before sending SIGKILL.
51         If unset, this defaults to half of {option}`freeMemThreshold`.
53         See the description of [](#opt-services.earlyoom.freeMemThreshold).
54       '';
55     };
57     freeSwapThreshold = mkOption {
58       type = types.ints.between 1 100;
59       default = 10;
60       description = ''
61         Minimum free swap space (in percent) before sending SIGTERM.
63         See the description of [](#opt-services.earlyoom.freeMemThreshold).
64       '';
65     };
67     freeSwapKillThreshold = mkOption {
68       type = types.nullOr (types.ints.between 1 100);
69       default = null;
70       description = ''
71         Minimum free swap space (in percent) before sending SIGKILL.
72         If unset, this defaults to half of {option}`freeSwapThreshold`.
74         See the description of [](#opt-services.earlyoom.freeMemThreshold).
75       '';
76     };
78     enableDebugInfo = mkOption {
79       type = types.bool;
80       default = false;
81       description = ''
82         Enable debugging messages.
83       '';
84     };
86     enableNotifications = mkOption {
87       type = types.bool;
88       default = false;
89       description = ''
90         Send notifications about killed processes via the system d-bus.
92         WARNING: enabling this option (while convenient) should *not* be done on a
93         machine where you do not trust the other users as it allows any other
94         local user to DoS your session by spamming notifications.
96         To actually see the notifications in your GUI session, you need to have
97         `systembus-notify` running as your user, which this
98         option handles by enabling {option}`services.systembus-notify`.
100         See [README](https://github.com/rfjakob/earlyoom#notifications) for details.
101       '';
102     };
104     killHook = mkOption {
105       type = types.nullOr types.path;
106       default = null;
107       example = literalExpression ''
108         pkgs.writeShellScript "earlyoom-kill-hook" '''
109           echo "Process $EARLYOOM_NAME ($EARLYOOM_PID) was killed" >> /path/to/log
110         '''
111       '';
112       description = ''
113         An absolute path to an executable to be run for each process killed.
114         Some environment variables are available, see
115         [README](https://github.com/rfjakob/earlyoom#notifications) and
116         [the man page](https://github.com/rfjakob/earlyoom/blob/master/MANPAGE.md#-n-pathtoscript)
117         for details.
118       '';
119     };
121     reportInterval = mkOption {
122       type = types.int;
123       default = 3600;
124       example = 0;
125       description = "Interval (in seconds) at which a memory report is printed (set to 0 to disable).";
126     };
128     extraArgs = mkOption {
129       type = types.listOf types.str;
130       default = [];
131       example = [ "-g" "--prefer '(^|/)(java|chromium)$'" ];
132       description = "Extra command-line arguments to be passed to earlyoom.";
133     };
134   };
136   imports = [
137     (mkRemovedOptionModule [ "services" "earlyoom" "useKernelOOMKiller" ] ''
138       This option is deprecated and ignored by earlyoom since 1.2.
139     '')
140     (mkRemovedOptionModule [ "services" "earlyoom" "notificationsCommand" ] ''
141       This option was removed in earlyoom 1.6, but was reimplemented in 1.7
142       and is available as the new option `services.earlyoom.killHook`.
143     '')
144     (mkRemovedOptionModule [ "services" "earlyoom" "ignoreOOMScoreAdjust" ] ''
145       This option is deprecated and ignored by earlyoom since 1.7.
146     '')
147   ];
149   config = mkIf cfg.enable {
150     services.systembus-notify.enable = mkDefault cfg.enableNotifications;
152     systemd.services.earlyoom = {
153       description = "Early OOM Daemon for Linux";
154       wantedBy = [ "multi-user.target" ];
155       path = optionals cfg.enableNotifications [ pkgs.dbus ];
156       serviceConfig = {
157         StandardError = "journal";
158         ExecStart = concatStringsSep " " ([
159           "${lib.getExe cfg.package}"
160           ("-m ${toString cfg.freeMemThreshold}"
161            + optionalString (cfg.freeMemKillThreshold != null) ",${toString cfg.freeMemKillThreshold}")
162           ("-s ${toString cfg.freeSwapThreshold}"
163            + optionalString (cfg.freeSwapKillThreshold != null) ",${toString cfg.freeSwapKillThreshold}")
164           "-r ${toString cfg.reportInterval}"
165         ]
166         ++ optionals cfg.enableDebugInfo [ "-d" ]
167         ++ optionals cfg.enableNotifications [ "-n" ]
168         ++ optionals (cfg.killHook != null) [ "-N ${escapeShellArg cfg.killHook}" ]
169         ++ cfg.extraArgs);
170       };
171     };
172   };