at 24.11-pre 12 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4let 5 6 cfg = config.services.smokeping; 7 smokepingHome = "/var/lib/smokeping"; 8 smokepingPidDir = "/run"; 9 configFile = 10 if cfg.config == null 11 then 12 '' 13 *** General *** 14 cgiurl = ${cfg.cgiUrl} 15 contact = ${cfg.ownerEmail} 16 datadir = ${smokepingHome}/data 17 imgcache = ${smokepingHome}/cache 18 imgurl = ${cfg.imgUrl} 19 linkstyle = ${cfg.linkStyle} 20 ${lib.optionalString (cfg.mailHost != "") "mailhost = ${cfg.mailHost}"} 21 owner = ${cfg.owner} 22 pagedir = ${smokepingHome}/cache 23 piddir = ${smokepingPidDir} 24 ${lib.optionalString (cfg.sendmail != null) "sendmail = ${cfg.sendmail}"} 25 smokemail = ${cfg.smokeMailTemplate} 26 *** Presentation *** 27 template = ${cfg.presentationTemplate} 28 ${cfg.presentationConfig} 29 *** Alerts *** 30 ${cfg.alertConfig} 31 *** Database *** 32 ${cfg.databaseConfig} 33 *** Probes *** 34 ${cfg.probeConfig} 35 *** Targets *** 36 ${cfg.targetConfig} 37 ${cfg.extraConfig} 38 '' 39 else 40 cfg.config; 41 42 configPath = pkgs.writeText "smokeping.conf" configFile; 43 cgiHome = pkgs.writeScript "smokeping.fcgi" '' 44 #!${pkgs.bash}/bin/bash 45 ${cfg.package}/bin/smokeping_cgi /etc/smokeping.conf 46 ''; 47in 48 49{ 50 imports = [ 51 (mkRemovedOptionModule [ "services" "smokeping" "port" ] '' 52 The smokeping web service is now served by nginx. 53 In order to change the port, you need to change the nginx configuration under `services.nginx.virtualHosts.smokeping.listen.*.port`. 54 '') 55 ]; 56 57 options = { 58 services.smokeping = { 59 enable = mkEnableOption "smokeping service"; 60 61 alertConfig = mkOption { 62 type = types.lines; 63 default = '' 64 to = root@localhost 65 from = smokeping@localhost 66 ''; 67 example = '' 68 to = alertee@address.somewhere 69 from = smokealert@company.xy 70 71 +someloss 72 type = loss 73 # in percent 74 pattern = >0%,*12*,>0%,*12*,>0% 75 comment = loss 3 times in a row; 76 ''; 77 description = "Configuration for alerts."; 78 }; 79 cgiUrl = mkOption { 80 type = types.str; 81 default = "http://${cfg.hostName}/smokeping.cgi"; 82 defaultText = literalExpression ''"http://''${hostName}/smokeping.cgi"''; 83 example = "https://somewhere.example.com/smokeping.cgi"; 84 description = "URL to the smokeping cgi."; 85 }; 86 config = mkOption { 87 type = types.nullOr types.lines; 88 default = null; 89 description = '' 90 Full smokeping config supplied by the user. Overrides 91 and replaces any other configuration supplied. 92 ''; 93 }; 94 databaseConfig = mkOption { 95 type = types.lines; 96 default = '' 97 step = 300 98 pings = 20 99 # consfn mrhb steps total 100 AVERAGE 0.5 1 1008 101 AVERAGE 0.5 12 4320 102 MIN 0.5 12 4320 103 MAX 0.5 12 4320 104 AVERAGE 0.5 144 720 105 MAX 0.5 144 720 106 MIN 0.5 144 720 107 108 ''; 109 example = '' 110 # near constant pings. 111 step = 30 112 pings = 20 113 # consfn mrhb steps total 114 AVERAGE 0.5 1 10080 115 AVERAGE 0.5 12 43200 116 MIN 0.5 12 43200 117 MAX 0.5 12 43200 118 AVERAGE 0.5 144 7200 119 MAX 0.5 144 7200 120 MIN 0.5 144 7200 121 ''; 122 description = ''Configure the ping frequency and retention of the rrd files. 123 Once set, changing the interval will require deletion or migration of all 124 the collected data.''; 125 }; 126 extraConfig = mkOption { 127 type = types.lines; 128 default = ""; 129 description = "Any additional customization not already included."; 130 }; 131 hostName = mkOption { 132 type = types.str; 133 default = config.networking.fqdn; 134 defaultText = literalExpression "config.networking.fqdn"; 135 example = "somewhere.example.com"; 136 description = "DNS name for the urls generated in the cgi."; 137 }; 138 imgUrl = mkOption { 139 type = types.str; 140 default = "cache"; 141 defaultText = literalExpression ''"cache"''; 142 example = "https://somewhere.example.com/cache"; 143 description = '' 144 Base url for images generated in the cgi. 145 146 The default is a relative URL to ensure it works also when e.g. forwarding 147 the GUI port via SSH. 148 ''; 149 }; 150 linkStyle = mkOption { 151 type = types.enum [ "original" "absolute" "relative" ]; 152 default = "relative"; 153 example = "absolute"; 154 description = "DNS name for the urls generated in the cgi."; 155 }; 156 mailHost = mkOption { 157 type = types.str; 158 default = ""; 159 example = "localhost"; 160 description = "Use this SMTP server to send alerts"; 161 }; 162 owner = mkOption { 163 type = types.str; 164 default = "nobody"; 165 example = "Bob Foobawr"; 166 description = "Real name of the owner of the instance"; 167 }; 168 ownerEmail = mkOption { 169 type = types.str; 170 default = "no-reply@${cfg.hostName}"; 171 defaultText = literalExpression ''"no-reply@''${hostName}"''; 172 example = "no-reply@yourdomain.com"; 173 description = "Email contact for owner"; 174 }; 175 package = mkPackageOption pkgs "smokeping" { }; 176 host = mkOption { 177 type = types.nullOr types.str; 178 default = "localhost"; 179 example = "192.0.2.1"; # rfc5737 example IP for documentation 180 description = '' 181 Host/IP to bind to for the web server. 182 183 Setting it to `null` skips passing the -h option to thttpd, 184 which makes it bind to all interfaces. 185 ''; 186 }; 187 presentationConfig = mkOption { 188 type = types.lines; 189 default = '' 190 + charts 191 menu = Charts 192 title = The most interesting destinations 193 ++ stddev 194 sorter = StdDev(entries=>4) 195 title = Top Standard Deviation 196 menu = Std Deviation 197 format = Standard Deviation %f 198 ++ max 199 sorter = Max(entries=>5) 200 title = Top Max Roundtrip Time 201 menu = by Max 202 format = Max Roundtrip Time %f seconds 203 ++ loss 204 sorter = Loss(entries=>5) 205 title = Top Packet Loss 206 menu = Loss 207 format = Packets Lost %f 208 ++ median 209 sorter = Median(entries=>5) 210 title = Top Median Roundtrip Time 211 menu = by Median 212 format = Median RTT %f seconds 213 + overview 214 width = 600 215 height = 50 216 range = 10h 217 + detail 218 width = 600 219 height = 200 220 unison_tolerance = 2 221 "Last 3 Hours" 3h 222 "Last 30 Hours" 30h 223 "Last 10 Days" 10d 224 "Last 360 Days" 360d 225 ''; 226 description = "presentation graph style"; 227 }; 228 presentationTemplate = mkOption { 229 type = types.str; 230 default = "${pkgs.smokeping}/etc/basepage.html.dist"; 231 defaultText = literalExpression ''"''${pkgs.smokeping}/etc/basepage.html.dist"''; 232 description = "Default page layout for the web UI."; 233 }; 234 probeConfig = mkOption { 235 type = types.lines; 236 default = '' 237 + FPing 238 binary = ${config.security.wrapperDir}/fping 239 ''; 240 defaultText = literalExpression '' 241 ''' 242 + FPing 243 binary = ''${config.security.wrapperDir}/fping 244 ''' 245 ''; 246 description = "Probe configuration"; 247 }; 248 sendmail = mkOption { 249 type = types.nullOr types.path; 250 default = null; 251 example = "/run/wrappers/bin/sendmail"; 252 description = "Use this sendmail compatible script to deliver alerts"; 253 }; 254 smokeMailTemplate = mkOption { 255 type = types.str; 256 default = "${cfg.package}/etc/smokemail.dist"; 257 defaultText = literalExpression ''"''${package}/etc/smokemail.dist"''; 258 description = "Specify the smokemail template for alerts."; 259 }; 260 targetConfig = mkOption { 261 type = types.lines; 262 default = '' 263 probe = FPing 264 menu = Top 265 title = Network Latency Grapher 266 remark = Welcome to the SmokePing website of xxx Company. \ 267 Here you will learn all about the latency of our network. 268 + Local 269 menu = Local 270 title = Local Network 271 ++ LocalMachine 272 menu = Local Machine 273 title = This host 274 host = localhost 275 ''; 276 description = "Target configuration"; 277 }; 278 user = mkOption { 279 type = types.str; 280 default = "smokeping"; 281 description = "User that runs smokeping and (optionally) thttpd. A group of the same name will be created as well."; 282 }; 283 webService = mkOption { 284 type = types.bool; 285 default = true; 286 description = "Enable a smokeping web interface"; 287 }; 288 }; 289 290 }; 291 292 config = mkIf cfg.enable { 293 assertions = [ 294 { 295 assertion = !(cfg.sendmail != null && cfg.mailHost != ""); 296 message = "services.smokeping: sendmail and Mailhost cannot both be enabled."; 297 } 298 ]; 299 security.wrappers = { 300 fping = 301 { 302 setuid = true; 303 owner = "root"; 304 group = "root"; 305 source = "${pkgs.fping}/bin/fping"; 306 }; 307 }; 308 environment.etc."smokeping.conf".source = configPath; 309 environment.systemPackages = [ pkgs.fping ]; 310 users.users.${cfg.user} = { 311 isNormalUser = false; 312 isSystemUser = true; 313 group = cfg.user; 314 description = "smokeping daemon user"; 315 home = smokepingHome; 316 createHome = true; 317 # When `cfg.webService` is enabled, `nginx` requires read permissions on the home directory. 318 homeMode = "711"; 319 }; 320 users.groups.${cfg.user} = { }; 321 systemd.services.smokeping = { 322 reloadTriggers = [ configPath ]; 323 requiredBy = [ "multi-user.target" ]; 324 serviceConfig = { 325 User = cfg.user; 326 Restart = "on-failure"; 327 ExecStart = "${cfg.package}/bin/smokeping --config=/etc/smokeping.conf --nodaemon"; 328 }; 329 preStart = '' 330 mkdir -m 0755 -p ${smokepingHome}/cache ${smokepingHome}/data 331 ln -snf ${cfg.package}/htdocs/css ${smokepingHome}/css 332 ln -snf ${cfg.package}/htdocs/js ${smokepingHome}/js 333 ln -snf ${cgiHome} ${smokepingHome}/smokeping.fcgi 334 ${cfg.package}/bin/smokeping --check --config=${configPath} 335 ${cfg.package}/bin/smokeping --static --config=${configPath} 336 ''; 337 }; 338 339 # use nginx to serve the smokeping web service 340 services.fcgiwrap.enable = mkIf cfg.webService true; 341 services.nginx = mkIf cfg.webService { 342 enable = true; 343 virtualHosts."smokeping" = { 344 serverName = mkDefault cfg.host; 345 locations."/" = { 346 root = smokepingHome; 347 index = "smokeping.fcgi"; 348 }; 349 locations."/smokeping.fcgi" = { 350 extraConfig = '' 351 include ${config.services.nginx.package}/conf/fastcgi_params; 352 fastcgi_pass unix:${config.services.fcgiwrap.socketAddress}; 353 fastcgi_param SCRIPT_FILENAME ${smokepingHome}/smokeping.fcgi; 354 fastcgi_param DOCUMENT_ROOT ${smokepingHome}; 355 ''; 356 }; 357 }; 358 }; 359 }; 360 361 meta.maintainers = with lib.maintainers; [ 362 erictapen 363 nh2 364 ]; 365} 366