1# Global configuration for atop.
2
3{ config, lib, pkgs, ... }:
4
5with lib;
6
7let cfg = config.programs.atop;
8
9in
10{
11 ###### interface
12
13 options = {
14
15 programs.atop = rec {
16
17 enable = mkEnableOption "Atop";
18
19 package = mkOption {
20 type = types.package;
21 default = pkgs.atop;
22 description = ''
23 Which package to use for Atop.
24 '';
25 };
26
27 netatop = {
28 enable = mkOption {
29 type = types.bool;
30 default = false;
31 description = ''
32 Whether to install and enable the netatop kernel module.
33 Note: this sets the kernel taint flag "O" for loading out-of-tree modules.
34 '';
35 };
36 package = mkOption {
37 type = types.package;
38 default = config.boot.kernelPackages.netatop;
39 description = ''
40 Which package to use for netatop.
41 '';
42 };
43 };
44
45 atopgpu.enable = mkOption {
46 type = types.bool;
47 default = false;
48 description = ''
49 Whether to install and enable the atopgpud daemon to get information about
50 NVIDIA gpus.
51 '';
52 };
53
54 setuidWrapper.enable = mkOption {
55 type = types.bool;
56 default = false;
57 description = ''
58 Whether to install a setuid wrapper for Atop. This is required to use some of
59 the features as non-root user (e.g.: ipc information, netatop, atopgpu).
60 Atop tries to drop the root privileges shortly after starting.
61 '';
62 };
63
64 atopService.enable = mkOption {
65 type = types.bool;
66 default = true;
67 description = ''
68 Whether to enable the atop service responsible for storing statistics for
69 long-term analysis.
70 '';
71 };
72 atopRotateTimer.enable = mkOption {
73 type = types.bool;
74 default = true;
75 description = ''
76 Whether to enable the atop-rotate timer, which restarts the atop service
77 daily to make sure the data files are rotate.
78 '';
79 };
80 atopacctService.enable = mkOption {
81 type = types.bool;
82 default = true;
83 description = ''
84 Whether to enable the atopacct service which manages process accounting.
85 This allows Atop to gather data about processes that disappeared in between
86 two refresh intervals.
87 '';
88 };
89 settings = mkOption {
90 type = types.attrs;
91 default = { };
92 example = {
93 flags = "a1f";
94 interval = 5;
95 };
96 description = ''
97 Parameters to be written to <filename>/etc/atoprc</filename>.
98 '';
99 };
100 };
101 };
102
103 config = mkIf cfg.enable (
104 let
105 atop =
106 if cfg.atopgpu.enable then
107 (cfg.package.override { withAtopgpu = true; })
108 else
109 cfg.package;
110 in
111 {
112 environment.etc = mkIf (cfg.settings != { }) {
113 atoprc.text = concatStrings
114 (mapAttrsToList
115 (n: v: ''
116 ${n} ${toString v}
117 '')
118 cfg.settings);
119 };
120 environment.systemPackages = [ atop (lib.mkIf cfg.netatop.enable cfg.netatop.package) ];
121 boot.extraModulePackages = [ (lib.mkIf cfg.netatop.enable cfg.netatop.package) ];
122 systemd =
123 let
124 mkSystemd = type: cond: name: restartTriggers: {
125 ${name} = lib.mkIf cond {
126 inherit restartTriggers;
127 wantedBy = [ (if type == "services" then "multi-user.target" else if type == "timers" then "timers.target" else null) ];
128 };
129 };
130 mkService = mkSystemd "services";
131 mkTimer = mkSystemd "timers";
132 in
133 {
134 packages = [ atop (lib.mkIf cfg.netatop.enable cfg.netatop.package) ];
135 services =
136 mkService cfg.atopService.enable "atop" [ atop ]
137 // mkService cfg.atopacctService.enable "atopacct" [ atop ]
138 // mkService cfg.netatop.enable "netatop" [ cfg.netatop.package ]
139 // mkService cfg.atopgpu.enable "atopgpu" [ atop ];
140 timers = mkTimer cfg.atopRotateTimer.enable "atop-rotate" [ atop ];
141 };
142 security.wrappers =
143 lib.mkIf cfg.setuidWrapper.enable { atop = { source = "${atop}/bin/atop"; }; };
144 }
145 );
146}