nixos/earlyoom: bring the module up to date (#163663)

* nixos/earlyoom: bring the module up to date

Removes deprecated option `ignoreOOMScoreAdjust`, introduces `killHook`
as a replacement for `notificationsCommand`, and adds an `extraArgs`
option for things not covered by the module.

* nixos/earlyoom: add nixos test

* nixos/earlyoom: add reportInterval

Allows setting the interval for logging a memory report. Defaults to
3600 following upstream
(https://github.com/rfjakob/earlyoom/blob/master/earlyoom.default#L5)
to avoid flooding logs.

* nixos/earlyoom: add free{Mem,Swap}KillThreshold

Fixes https://github.com/NixOS/nixpkgs/issues/83504

authored by Naïm Favier and committed by GitHub a8296e75 5f779941

+99 -22
+77 -21
nixos/modules/services/system/earlyoom.nix
··· 5 6 inherit (lib) 7 mkDefault mkEnableOption mkIf mkOption types 8 - mkRemovedOptionModule 9 - concatStringsSep optional; 10 11 in 12 { ··· 17 type = types.ints.between 1 100; 18 default = 10; 19 description = '' 20 - Minimum of availabe memory (in percent). 21 - If the free memory falls below this threshold and the analog is true for 22 - <option>services.earlyoom.freeSwapThreshold</option> 23 - the killing begins. 24 ''; 25 }; 26 ··· 28 type = types.ints.between 1 100; 29 default = 10; 30 description = '' 31 - Minimum of availabe swap space (in percent). 32 - If the available swap space falls below this threshold and the analog 33 - is true for <option>services.earlyoom.freeMemThreshold</option> 34 - the killing begins. 35 ''; 36 }; 37 38 - # TODO: remove or warn after 1.7 (https://github.com/rfjakob/earlyoom/commit/7ebc4554) 39 - ignoreOOMScoreAdjust = mkOption { 40 - type = types.bool; 41 - default = false; 42 description = '' 43 - Ignore oom_score_adjust values of processes. 44 ''; 45 }; 46 ··· 63 local user to DoS your session by spamming notifications. 64 65 To actually see the notifications in your GUI session, you need to have 66 - <literal>systembus-notify</literal> running as your user which this 67 - option handles. 68 69 See <link xlink:href="https://github.com/rfjakob/earlyoom#notifications">README</link> for details. 70 ''; 71 }; 72 }; 73 74 imports = [ ··· 76 This option is deprecated and ignored by earlyoom since 1.2. 77 '') 78 (mkRemovedOptionModule [ "services" "earlyoom" "notificationsCommand" ] '' 79 - This option is deprecated and ignored by earlyoom since 1.6. 80 '') 81 ]; 82 ··· 91 StandardError = "journal"; 92 ExecStart = concatStringsSep " " ([ 93 "${pkgs.earlyoom}/bin/earlyoom" 94 - "-m ${toString cfg.freeMemThreshold}" 95 - "-s ${toString cfg.freeSwapThreshold}" 96 ] 97 - ++ optional cfg.ignoreOOMScoreAdjust "-i" 98 ++ optional cfg.enableDebugInfo "-d" 99 ++ optional cfg.enableNotifications "-n" 100 ); 101 }; 102 };
··· 5 6 inherit (lib) 7 mkDefault mkEnableOption mkIf mkOption types 8 + mkRemovedOptionModule literalExpression 9 + escapeShellArg concatStringsSep optional optionalString; 10 11 in 12 { ··· 17 type = types.ints.between 1 100; 18 default = 10; 19 description = '' 20 + Minimum available memory (in percent). 21 + 22 + If the available memory falls below this threshold (and the analog is true for 23 + <option>freeSwapThreshold</option>) the killing begins. 24 + SIGTERM is sent first to the process that uses the most memory; then, if the available 25 + memory falls below <option>freeMemKillThreshold</option> (and the analog is true for 26 + <option>freeSwapKillThreshold</option>), SIGKILL is sent. 27 + 28 + See <link xlink:href="https://github.com/rfjakob/earlyoom#command-line-options">README</link> for details. 29 + ''; 30 + }; 31 + 32 + freeMemKillThreshold = mkOption { 33 + type = types.nullOr (types.ints.between 1 100); 34 + default = null; 35 + description = '' 36 + Minimum available memory (in percent) before sending SIGKILL. 37 + If unset, this defaults to half of <option>freeMemThreshold</option>. 38 + 39 + See the description of <xref linkend="opt-services.earlyoom.freeMemThreshold"/>. 40 ''; 41 }; 42 ··· 44 type = types.ints.between 1 100; 45 default = 10; 46 description = '' 47 + Minimum free swap space (in percent) before sending SIGTERM. 48 + 49 + See the description of <xref linkend="opt-services.earlyoom.freeMemThreshold"/>. 50 ''; 51 }; 52 53 + freeSwapKillThreshold = mkOption { 54 + type = types.nullOr (types.ints.between 1 100); 55 + default = null; 56 description = '' 57 + Minimum free swap space (in percent) before sending SIGKILL. 58 + If unset, this defaults to half of <option>freeSwapThreshold</option>. 59 + 60 + See the description of <xref linkend="opt-services.earlyoom.freeMemThreshold"/>. 61 ''; 62 }; 63 ··· 80 local user to DoS your session by spamming notifications. 81 82 To actually see the notifications in your GUI session, you need to have 83 + <literal>systembus-notify</literal> running as your user, which this 84 + option handles by enabling <option>services.systembus-notify</option>. 85 86 See <link xlink:href="https://github.com/rfjakob/earlyoom#notifications">README</link> for details. 87 ''; 88 }; 89 + 90 + killHook = mkOption { 91 + type = types.nullOr types.path; 92 + default = null; 93 + example = literalExpression '' 94 + pkgs.writeShellScript "earlyoom-kill-hook" ''' 95 + echo "Process $EARLYOOM_NAME ($EARLYOOM_PID) was killed" >> /path/to/log 96 + ''' 97 + ''; 98 + description = '' 99 + An absolute path to an executable to be run for each process killed. 100 + Some environment variables are available, see 101 + <link xlink:href="https://github.com/rfjakob/earlyoom#notifications">README</link> and 102 + <link xlink:href="https://github.com/rfjakob/earlyoom/blob/master/MANPAGE.md#-n-pathtoscript">the man page</link> 103 + for details. 104 + ''; 105 + }; 106 + 107 + reportInterval = mkOption { 108 + type = types.int; 109 + default = 3600; 110 + example = 0; 111 + description = "Interval (in seconds) at which a memory report is printed (set to 0 to disable)."; 112 + }; 113 + 114 + extraArgs = mkOption { 115 + type = types.listOf types.str; 116 + default = []; 117 + example = [ "-g" "--prefer '(^|/)(java|chromium)$'" ]; 118 + description = "Extra command-line arguments to be passed to earlyoom."; 119 + }; 120 }; 121 122 imports = [ ··· 124 This option is deprecated and ignored by earlyoom since 1.2. 125 '') 126 (mkRemovedOptionModule [ "services" "earlyoom" "notificationsCommand" ] '' 127 + This option was removed in earlyoom 1.6, but was reimplemented in 1.7 128 + and is available as the new option `services.earlyoom.killHook`. 129 + '') 130 + (mkRemovedOptionModule [ "services" "earlyoom" "ignoreOOMScoreAdjust" ] '' 131 + This option is deprecated and ignored by earlyoom since 1.7. 132 '') 133 ]; 134 ··· 143 StandardError = "journal"; 144 ExecStart = concatStringsSep " " ([ 145 "${pkgs.earlyoom}/bin/earlyoom" 146 + ("-m ${toString cfg.freeMemThreshold}" 147 + + optionalString (cfg.freeMemKillThreshold != null) ",${toString cfg.freeMemKillThreshold}") 148 + ("-s ${toString cfg.freeSwapThreshold}" 149 + + optionalString (cfg.freeSwapKillThreshold != null) ",${toString cfg.freeSwapKillThreshold}") 150 + "-r ${toString cfg.reportInterval}" 151 ] 152 ++ optional cfg.enableDebugInfo "-d" 153 ++ optional cfg.enableNotifications "-n" 154 + ++ optional (cfg.killHook != null) "-N ${escapeShellArg cfg.killHook}" 155 + ++ cfg.extraArgs 156 ); 157 }; 158 };
+1
nixos/tests/all-tests.nix
··· 132 domination = handleTest ./domination.nix {}; 133 dovecot = handleTest ./dovecot.nix {}; 134 drbd = handleTest ./drbd.nix {}; 135 ec2-config = (handleTestOn ["x86_64-linux"] ./ec2.nix {}).boot-ec2-config or {}; 136 ec2-nixops = (handleTestOn ["x86_64-linux"] ./ec2.nix {}).boot-ec2-nixops or {}; 137 ecryptfs = handleTest ./ecryptfs.nix {};
··· 132 domination = handleTest ./domination.nix {}; 133 dovecot = handleTest ./dovecot.nix {}; 134 drbd = handleTest ./drbd.nix {}; 135 + earlyoom = handleTestOn ["x86_64-linux"] ./earlyoom.nix {}; 136 ec2-config = (handleTestOn ["x86_64-linux"] ./ec2.nix {}).boot-ec2-config or {}; 137 ec2-nixops = (handleTestOn ["x86_64-linux"] ./ec2.nix {}).boot-ec2-nixops or {}; 138 ecryptfs = handleTest ./ecryptfs.nix {};
+16
nixos/tests/earlyoom.nix
···
··· 1 + import ./make-test-python.nix ({ lib, ... }: { 2 + name = "earlyoom"; 3 + meta = { 4 + maintainers = with lib.maintainers; [ ncfavier ]; 5 + }; 6 + 7 + machine = { 8 + services.earlyoom = { 9 + enable = true; 10 + }; 11 + }; 12 + 13 + testScript = '' 14 + machine.wait_for_unit("earlyoom.service") 15 + ''; 16 + })
+5 -1
pkgs/os-specific/linux/earlyoom/default.nix
··· 1 - { lib, stdenv, fetchFromGitHub, pandoc, installShellFiles, withManpage ? false }: 2 3 stdenv.mkDerivation rec { 4 pname = "earlyoom"; ··· 22 '' + lib.optionalString withManpage '' 23 installManPage earlyoom.1 24 ''; 25 26 meta = with lib; { 27 description = "Early OOM Daemon for Linux";
··· 1 + { lib, stdenv, fetchFromGitHub, pandoc, installShellFiles, withManpage ? false, nixosTests }: 2 3 stdenv.mkDerivation rec { 4 pname = "earlyoom"; ··· 22 '' + lib.optionalString withManpage '' 23 installManPage earlyoom.1 24 ''; 25 + 26 + passthru.tests = { 27 + inherit (nixosTests) earlyoom; 28 + }; 29 30 meta = with lib; { 31 description = "Early OOM Daemon for Linux";