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