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