typioca: 2.7.0 -> 2.8.0
[NixPkgs.git] / nixos / modules / programs / atop.nix
bloba5f4d990bdbe1fe61b9444e0db8fbe0c635dd259
1 # Global configuration for atop.
3 { config, lib, pkgs, ... }:
5 with lib;
7 let cfg = config.programs.atop;
9 in
11   ###### interface
13   options = {
15     programs.atop = rec {
17       enable = mkEnableOption (lib.mdDoc "Atop");
19       package = mkOption {
20         type = types.package;
21         default = pkgs.atop;
22         defaultText = literalExpression "pkgs.atop";
23         description = lib.mdDoc ''
24           Which package to use for Atop.
25         '';
26       };
28       netatop = {
29         enable = mkOption {
30           type = types.bool;
31           default = false;
32           description = lib.mdDoc ''
33             Whether to install and enable the netatop kernel module.
34             Note: this sets the kernel taint flag "O" for loading out-of-tree modules.
35           '';
36         };
37         package = mkOption {
38           type = types.package;
39           default = config.boot.kernelPackages.netatop;
40           defaultText = literalExpression "config.boot.kernelPackages.netatop";
41           description = lib.mdDoc ''
42             Which package to use for netatop.
43           '';
44         };
45       };
47       atopgpu.enable = mkOption {
48         type = types.bool;
49         default = false;
50         description = lib.mdDoc ''
51           Whether to install and enable the atopgpud daemon to get information about
52           NVIDIA gpus.
53         '';
54       };
56       setuidWrapper.enable = mkOption {
57         type = types.bool;
58         default = false;
59         description = lib.mdDoc ''
60           Whether to install a setuid wrapper for Atop. This is required to use some of
61           the features as non-root user (e.g.: ipc information, netatop, atopgpu).
62           Atop tries to drop the root privileges shortly after starting.
63         '';
64       };
66       atopService.enable = mkOption {
67         type = types.bool;
68         default = true;
69         description = lib.mdDoc ''
70           Whether to enable the atop service responsible for storing statistics for
71           long-term analysis.
72         '';
73       };
74       atopRotateTimer.enable = mkOption {
75         type = types.bool;
76         default = true;
77         description = lib.mdDoc ''
78           Whether to enable the atop-rotate timer, which restarts the atop service
79           daily to make sure the data files are rotate.
80         '';
81       };
82       atopacctService.enable = mkOption {
83         type = types.bool;
84         default = true;
85         description = lib.mdDoc ''
86           Whether to enable the atopacct service which manages process accounting.
87           This allows Atop to gather data about processes that disappeared in between
88           two refresh intervals.
89         '';
90       };
91       settings = mkOption {
92         type = types.attrs;
93         default = { };
94         example = {
95           flags = "a1f";
96           interval = 5;
97         };
98         description = lib.mdDoc ''
99           Parameters to be written to {file}`/etc/atoprc`.
100         '';
101       };
102     };
103   };
105   config = mkIf cfg.enable (
106     let
107       atop =
108         if cfg.atopgpu.enable then
109           (cfg.package.override { withAtopgpu = true; })
110         else
111           cfg.package;
112     in
113     {
114       environment.etc = mkIf (cfg.settings != { }) {
115         atoprc.text = concatStrings
116           (mapAttrsToList
117             (n: v: ''
118               ${n} ${toString v}
119             '')
120             cfg.settings);
121       };
122       environment.systemPackages = [ atop (lib.mkIf cfg.netatop.enable cfg.netatop.package) ];
123       boot.extraModulePackages = [ (lib.mkIf cfg.netatop.enable cfg.netatop.package) ];
124       systemd =
125         let
126           mkSystemd = type: name: restartTriggers: {
127             ${name} = {
128               inherit restartTriggers;
129               wantedBy = [ (if type == "services" then "multi-user.target" else if type == "timers" then "timers.target" else null) ];
130             };
131           };
132           mkService = mkSystemd "services";
133           mkTimer = mkSystemd "timers";
134         in
135         {
136           packages = [ atop (lib.mkIf cfg.netatop.enable cfg.netatop.package) ];
137           services = lib.mkMerge [
138             (lib.mkIf cfg.atopService.enable (lib.recursiveUpdate
139               (mkService "atop" [ atop ])
140               {
141                 # always convert logs to newer version first
142                 # XXX might trigger TimeoutStart but restarting atop.service will
143                 # convert remainings logs and start eventually
144                 atop.preStart = ''
145                   set -e -u
146                   shopt -s nullglob
147                   for logfile in "$LOGPATH"/atop_*
148                   do
149                     ${atop}/bin/atopconvert "$logfile" "$logfile".new
150                     # only replace old file if version was upgraded to avoid
151                     # false positives for atop-rotate.service
152                     if ! ${pkgs.diffutils}/bin/cmp -s "$logfile" "$logfile".new
153                     then
154                       ${pkgs.coreutils}/bin/mv -v -f "$logfile".new "$logfile"
155                     else
156                       ${pkgs.coreutils}/bin/rm -f "$logfile".new
157                     fi
158                   done
159                 '';
160               }))
161             (lib.mkIf cfg.atopacctService.enable (mkService "atopacct" [ atop ]))
162             (lib.mkIf cfg.netatop.enable (mkService "netatop" [ cfg.netatop.package ]))
163             (lib.mkIf cfg.atopgpu.enable (mkService "atopgpu" [ atop ]))
164           ];
165           timers = lib.mkIf cfg.atopRotateTimer.enable (mkTimer "atop-rotate" [ atop ]);
166         };
168       security.wrappers = lib.mkIf cfg.setuidWrapper.enable {
169         atop = {
170           setuid = true;
171           owner = "root";
172           group = "root";
173           source = "${atop}/bin/atop";
174         };
175       };
176     }
177   );