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 defaultText = literalExpression "pkgs.atop";
23 description = ''
24 Which package to use for Atop.
25 '';
26 };
27
28 netatop = {
29 enable = mkOption {
30 type = types.bool;
31 default = false;
32 description = ''
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 = ''
42 Which package to use for netatop.
43 '';
44 };
45 };
46
47 atopgpu.enable = mkOption {
48 type = types.bool;
49 default = false;
50 description = ''
51 Whether to install and enable the atopgpud daemon to get information about
52 NVIDIA gpus.
53 '';
54 };
55
56 setuidWrapper.enable = mkOption {
57 type = types.bool;
58 default = false;
59 description = ''
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 };
65
66 atopService.enable = mkOption {
67 type = types.bool;
68 default = true;
69 description = ''
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 = ''
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 = ''
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 = ''
99 Parameters to be written to <filename>/etc/atoprc</filename>.
100 '';
101 };
102 };
103 };
104
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: cond: name: restartTriggers: {
127 ${name} = lib.mkIf cond {
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 =
138 mkService cfg.atopService.enable "atop" [ atop ]
139 // mkService cfg.atopacctService.enable "atopacct" [ atop ]
140 // mkService cfg.netatop.enable "netatop" [ cfg.netatop.package ]
141 // mkService cfg.atopgpu.enable "atopgpu" [ atop ];
142 timers = mkTimer cfg.atopRotateTimer.enable "atop-rotate" [ atop ];
143 };
144
145 security.wrappers = lib.mkIf cfg.setuidWrapper.enable {
146 atop =
147 { setuid = true;
148 owner = "root";
149 group = "root";
150 source = "${atop}/bin/atop";
151 };
152 };
153 }
154 );
155}