74558c88fb
The initial commit accidentally left in some commented code and if you were using alerts, they simply didn't work. Smokeping also includes some JS code for the webui allowing you to zoom into graphs and it was not passed into the homedir. Additionally, generate static html pages for other webservers to serve the cache directory. Add additional options to specify sendmail path or mailhost and verify that both are not set. Add one extra config hook that allows you to bypass all of the invidual config stanzas and just hand it a string.
304 lines
9.3 KiB
Nix
304 lines
9.3 KiB
Nix
{ config, lib, pkgs, ... }:
|
|
|
|
with lib;
|
|
let
|
|
|
|
cfg = config.services.smokeping;
|
|
smokepingHome = "/var/lib/smokeping";
|
|
smokepingPidDir = "/run";
|
|
configFile =
|
|
if cfg.config == null
|
|
then
|
|
''
|
|
*** General ***
|
|
owner = ${cfg.owner}
|
|
contact = ${cfg.ownerEmail}
|
|
${lib.optionalString (cfg.mailHost != "") "mailhost = ${cfg.mailHost}"}
|
|
${lib.optionalString (cfg.sendmail != null) "sendmail = ${cfg.sendmail}"}
|
|
imgcache = ${smokepingHome}/cache
|
|
imgurl = http://${cfg.hostName}:${builtins.toString cfg.port}/cache
|
|
datadir = ${smokepingHome}/data
|
|
pagedir = ${smokepingHome}/cache
|
|
piddir = ${smokepingPidDir}
|
|
cgiurl = http://${cfg.hostName}:${builtins.toString cfg.port}/smokeping.cgi
|
|
linkstyle = ${cfg.linkStyle}
|
|
smokemail = ${cfg.smokeMailTemplate}
|
|
*** Presentation ***
|
|
template = ${cfg.presentationTemplate}
|
|
${cfg.presentationConfig}
|
|
*** Alerts ***
|
|
${cfg.alertConfig}
|
|
*** Database ***
|
|
${cfg.databaseConfig}
|
|
*** Probes ***
|
|
${cfg.probeConfig}
|
|
*** Targets ***
|
|
${cfg.targetConfig}
|
|
${cfg.extraConfig}
|
|
''
|
|
else
|
|
cfg.config;
|
|
|
|
configPath = pkgs.writeText "smokeping.conf" configFile;
|
|
cgiHome = pkgs.writeScript "smokeping.fcgi" ''
|
|
#!${pkgs.bash}/bin/bash
|
|
${cfg.package}/bin/smokeping_cgi ${configPath}
|
|
'';
|
|
in
|
|
|
|
{
|
|
options = {
|
|
services.smokeping = {
|
|
enable = mkOption {
|
|
type = types.bool;
|
|
default = false;
|
|
description = "Enable the smokeping service";
|
|
};
|
|
webService = mkOption {
|
|
type = types.bool;
|
|
default = true;
|
|
description = "Enable a smokeping web interface";
|
|
};
|
|
|
|
user = mkOption {
|
|
type = types.string;
|
|
default = "smokeping";
|
|
description = "User that runs smokeping and (optionally) thttpd";
|
|
};
|
|
mailHost = mkOption {
|
|
type = types.string;
|
|
default = "";
|
|
example = "localhost";
|
|
description = "Use this SMTP server to send alerts";
|
|
};
|
|
sendmail = mkOption {
|
|
type = types.nullOr types.path;
|
|
default = null;
|
|
example = "/var/setuid-wrappers/sendmail";
|
|
description = "Use this sendmail compatible script to deliver alerts";
|
|
};
|
|
smokeMailTemplate = mkOption {
|
|
type = types.string;
|
|
default = "${cfg.package}/etc/smokemail.dist";
|
|
description = "Specify the smokemail template for alerts.";
|
|
};
|
|
|
|
package = mkOption {
|
|
type = types.package;
|
|
default = pkgs.smokeping;
|
|
defaultText = "pkgs.smokeping";
|
|
description = "Specify a custom smokeping package";
|
|
};
|
|
owner = mkOption {
|
|
type = types.string;
|
|
default = "nobody";
|
|
example = "Joe Admin";
|
|
description = "Real name of the owner of the instance";
|
|
};
|
|
hostName = mkOption {
|
|
type = types.string;
|
|
default = config.networking.hostName;
|
|
example = "somewhere.example.com";
|
|
description = "DNS name for the urls generated in the cgi.";
|
|
};
|
|
linkStyle = mkOption {
|
|
type = types.enum ["original" "absolute" "relative"];
|
|
default = "relative";
|
|
example = "absolute";
|
|
description = "DNS name for the urls generated in the cgi.";
|
|
};
|
|
port = mkOption {
|
|
type = types.int;
|
|
default = 8081;
|
|
example = 8081;
|
|
description = "TCP port to use for the web server.";
|
|
};
|
|
ownerEmail = mkOption {
|
|
type = types.string;
|
|
default = "no-reply@${cfg.hostName}";
|
|
example = "no-reply@yourdomain.com";
|
|
description = "Email contact for owner";
|
|
};
|
|
|
|
databaseConfig = mkOption {
|
|
type = types.string;
|
|
default = ''
|
|
step = 300
|
|
pings = 20
|
|
# consfn mrhb steps total
|
|
AVERAGE 0.5 1 1008
|
|
AVERAGE 0.5 12 4320
|
|
MIN 0.5 12 4320
|
|
MAX 0.5 12 4320
|
|
AVERAGE 0.5 144 720
|
|
MAX 0.5 144 720
|
|
MIN 0.5 144 720
|
|
|
|
'';
|
|
example = literalExample ''
|
|
# near constant pings.
|
|
step = 30
|
|
pings = 20
|
|
# consfn mrhb steps total
|
|
AVERAGE 0.5 1 10080
|
|
AVERAGE 0.5 12 43200
|
|
MIN 0.5 12 43200
|
|
MAX 0.5 12 43200
|
|
AVERAGE 0.5 144 7200
|
|
MAX 0.5 144 7200
|
|
MIN 0.5 144 7200
|
|
'';
|
|
description = ''Configure the ping frequency and retention of the rrd files.
|
|
Once set, changing the interval will require deletion or migration of all
|
|
the collected data.'';
|
|
};
|
|
alertConfig = mkOption {
|
|
type = types.string;
|
|
default = ''
|
|
to = root@localhost
|
|
from = smokeping@localhost
|
|
'';
|
|
example = literalExample ''
|
|
to = alertee@address.somewhere
|
|
from = smokealert@company.xy
|
|
|
|
+someloss
|
|
type = loss
|
|
# in percent
|
|
pattern = >0%,*12*,>0%,*12*,>0%
|
|
comment = loss 3 times in a row;
|
|
'';
|
|
description = "Configuration for alerts.";
|
|
};
|
|
presentationTemplate = mkOption {
|
|
type = types.string;
|
|
default = "${pkgs.smokeping}/etc/basepage.html.dist";
|
|
description = "Default page layout for the web UI.";
|
|
};
|
|
|
|
presentationConfig = mkOption {
|
|
type = types.string;
|
|
default = ''
|
|
+ charts
|
|
menu = Charts
|
|
title = The most interesting destinations
|
|
++ stddev
|
|
sorter = StdDev(entries=>4)
|
|
title = Top Standard Deviation
|
|
menu = Std Deviation
|
|
format = Standard Deviation %f
|
|
++ max
|
|
sorter = Max(entries=>5)
|
|
title = Top Max Roundtrip Time
|
|
menu = by Max
|
|
format = Max Roundtrip Time %f seconds
|
|
++ loss
|
|
sorter = Loss(entries=>5)
|
|
title = Top Packet Loss
|
|
menu = Loss
|
|
format = Packets Lost %f
|
|
++ median
|
|
sorter = Median(entries=>5)
|
|
title = Top Median Roundtrip Time
|
|
menu = by Median
|
|
format = Median RTT %f seconds
|
|
+ overview
|
|
width = 600
|
|
height = 50
|
|
range = 10h
|
|
+ detail
|
|
width = 600
|
|
height = 200
|
|
unison_tolerance = 2
|
|
"Last 3 Hours" 3h
|
|
"Last 30 Hours" 30h
|
|
"Last 10 Days" 10d
|
|
"Last 360 Days" 360d
|
|
'';
|
|
description = "presentation graph style";
|
|
};
|
|
probeConfig = mkOption {
|
|
type = types.string;
|
|
default = ''
|
|
+ FPing
|
|
binary = ${pkgs.fping}/bin/fping
|
|
'';
|
|
description = "Probe configuration";
|
|
};
|
|
targetConfig = mkOption {
|
|
type = types.string;
|
|
default = ''
|
|
probe = FPing
|
|
menu = Top
|
|
title = Network Latency Grapher
|
|
remark = Welcome to the SmokePing website of xxx Company. \
|
|
Here you will learn all about the latency of our network.
|
|
+ Local
|
|
menu = Local
|
|
title = Local Network
|
|
++ LocalMachine
|
|
menu = Local Machine
|
|
title = This host
|
|
host = localhost
|
|
'';
|
|
description = "Target configuration";
|
|
};
|
|
extraConfig = mkOption {
|
|
type = types.string;
|
|
default = "";
|
|
description = "Any additional customization not already included.";
|
|
};
|
|
config = mkOption {
|
|
type = types.nullOr types.string;
|
|
default = null;
|
|
description = "Full smokeping config supplied by the user. Overrides " +
|
|
"and replaces any other configuration supplied.";
|
|
};
|
|
|
|
};
|
|
|
|
};
|
|
|
|
config = mkIf cfg.enable {
|
|
assertions = [
|
|
{
|
|
assertion = !(cfg.sendmail != null && cfg.mailHost != "");
|
|
message = "services.smokeping: sendmail and Mailhost cannot both be enabled.";
|
|
}
|
|
];
|
|
security.setuidPrograms = [ "fping" ];
|
|
environment.systemPackages = [ pkgs.fping ];
|
|
users.extraUsers = singleton {
|
|
name = cfg.user;
|
|
isNormalUser = false;
|
|
isSystemUser = true;
|
|
uid = config.ids.uids.smokeping;
|
|
description = "smokeping daemon user";
|
|
home = smokepingHome;
|
|
};
|
|
systemd.services.smokeping = {
|
|
wantedBy = [ "multi-user.target"];
|
|
serviceConfig.User = cfg.user;
|
|
serviceConfig.PermissionsStartOnly = true;
|
|
preStart = ''
|
|
mkdir -m 0755 -p ${smokepingHome}/cache ${smokepingHome}/data
|
|
rm -f ${smokepingHome}/cropper
|
|
ln -s ${cfg.package}/htdocs/cropper ${smokepingHome}/cropper
|
|
chown -R ${cfg.user} ${smokepingHome}
|
|
cp ${cgiHome} ${smokepingHome}/smokeping.fcgi
|
|
${cfg.package}/bin/smokeping --check --config=${configPath}
|
|
${cfg.package}/bin/smokeping --static --config=${configPath}
|
|
'';
|
|
script = ''${cfg.package}/bin/smokeping --config=${configPath} --nodaemon'';
|
|
};
|
|
systemd.services.thttpd = mkIf cfg.webService {
|
|
wantedBy = [ "multi-user.target"];
|
|
requires = [ "smokeping.service"];
|
|
partOf = [ "smokeping.service"];
|
|
path = with pkgs; [ bash rrdtool smokeping thttpd ];
|
|
script = ''thttpd -u ${cfg.user} -c "**.fcgi" -d ${smokepingHome} -p ${builtins.toString cfg.port} -D -nos'';
|
|
serviceConfig.Restart = "always";
|
|
};
|
|
};
|
|
}
|
|
|