1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6 ecfg = config.services.earlyoom;
7in
8{
9 options = {
10 services.earlyoom = {
11
12 enable = mkOption {
13 type = types.bool;
14 default = false;
15 description = ''
16 Enable early out of memory killing.
17 '';
18 };
19
20 freeMemThreshold = mkOption {
21 type = types.int;
22 default = 10;
23 description = ''
24 Minimum of availabe memory (in percent).
25 If the free memory falls below this threshold and the analog is true for
26 <option>services.earlyoom.freeSwapThreshold</option>
27 the killing begins.
28 '';
29 };
30
31 freeSwapThreshold = mkOption {
32 type = types.int;
33 default = 10;
34 description = ''
35 Minimum of availabe swap space (in percent).
36 If the available swap space falls below this threshold and the analog
37 is true for <option>services.earlyoom.freeMemThreshold</option>
38 the killing begins.
39 '';
40 };
41
42 useKernelOOMKiller= mkOption {
43 type = types.bool;
44 default = false;
45 description = ''
46 Use kernel OOM killer instead of own user-space implementation.
47 '';
48 };
49
50 ignoreOOMScoreAdjust = mkOption {
51 type = types.bool;
52 default = false;
53 description = ''
54 Ignore oom_score_adjust values of processes.
55 User-space implementation only.
56 '';
57 };
58
59 enableDebugInfo = mkOption {
60 type = types.bool;
61 default = false;
62 description = ''
63 Enable debugging messages.
64 '';
65 };
66
67 notificationsCommand = mkOption {
68 type = types.nullOr types.str;
69 default = null;
70 description = ''
71 This option is deprecated and ignored by earlyoom since 1.6.
72 Use <option>services.earlyoom.enableNotifications</option> instead.
73 '';
74 };
75
76 enableNotifications = mkOption {
77 type = types.bool;
78 default = false;
79 description = ''
80 Send notifications about killed processes via the system d-bus.
81 To actually see the notifications in your GUI session, you need to have
82 <literal>systembus-notify</literal> running as your user.
83
84 See <link xlink:href="https://github.com/rfjakob/earlyoom#notifications">README</link> for details.
85 '';
86 };
87 };
88 };
89
90 config = mkIf ecfg.enable {
91 assertions = [
92 { assertion = ecfg.freeMemThreshold > 0 && ecfg.freeMemThreshold <= 100;
93 message = "Needs to be a positive percentage"; }
94 { assertion = ecfg.freeSwapThreshold > 0 && ecfg.freeSwapThreshold <= 100;
95 message = "Needs to be a positive percentage"; }
96 { assertion = !ecfg.useKernelOOMKiller || !ecfg.ignoreOOMScoreAdjust;
97 message = "Both options in conjunction do not make sense"; }
98 ];
99
100 warnings = optional (ecfg.notificationsCommand != null)
101 "`services.earlyoom.notificationsCommand` is deprecated and ignored by earlyoom since 1.6.";
102
103 systemd.services.earlyoom = {
104 description = "Early OOM Daemon for Linux";
105 wantedBy = [ "multi-user.target" ];
106 path = optional ecfg.enableNotifications pkgs.dbus;
107 serviceConfig = {
108 StandardOutput = "null";
109 ExecStart = ''
110 ${pkgs.earlyoom}/bin/earlyoom \
111 -m ${toString ecfg.freeMemThreshold} \
112 -s ${toString ecfg.freeSwapThreshold} \
113 ${optionalString ecfg.useKernelOOMKiller "-k"} \
114 ${optionalString ecfg.ignoreOOMScoreAdjust "-i"} \
115 ${optionalString ecfg.enableDebugInfo "-d"} \
116 ${optionalString ecfg.enableNotifications "-n"}
117 '';
118 };
119 };
120
121 environment.systemPackages = optional ecfg.enableNotifications pkgs.systembus-notify;
122 };
123}