diff --git a/nixos/modules/misc/ids.nix b/nixos/modules/misc/ids.nix index 581cd4fb631..7f387b25a20 100644 --- a/nixos/modules/misc/ids.nix +++ b/nixos/modules/misc/ids.nix @@ -270,6 +270,7 @@ toxvpn = 247; squeezelite = 248; turnserver = 249; + smokeping = 250; # When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399! @@ -510,6 +511,7 @@ #toxvpn = 247; # unused #squeezelite = 248; #unused turnserver = 249; + smokeping = 250; # When adding a gid, make sure it doesn't match an existing # uid. Users and groups with the same name should have equal diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 22daf532db9..cd0ca6fcf35 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -396,6 +396,7 @@ ./services/networking/shairport-sync.nix ./services/networking/shout.nix ./services/networking/sniproxy.nix + ./services/networking/smokeping.nix ./services/networking/softether.nix ./services/networking/spiped.nix ./services/networking/sslh.nix diff --git a/nixos/modules/services/networking/smokeping.nix b/nixos/modules/services/networking/smokeping.nix new file mode 100644 index 00000000000..f7a5926dc64 --- /dev/null +++ b/nixos/modules/services/networking/smokeping.nix @@ -0,0 +1,261 @@ +{ config, lib, pkgs, ... }: + +with lib; +let + + cfg = config.services.smokeping; + smokepingHome = "/var/lib/smokeping"; + smokepingPidDir = "/run"; + configFile = '' + *** General *** + owner = ${cfg.owner} + contact = ${cfg.ownerEmail} + mailhost = ${cfg.mailHost} + #sendmail = /var/setuid-wrappers/sendmail + imgcache = ${smokepingHome}/cache + imgurl = http://${cfg.hostName}:${builtins.toString cfg.port}/cache + datadir = ${smokepingHome}/data + piddir = ${smokepingPidDir} + cgiurl = http://${cfg.hostName}:${builtins.toString cfg.port}/smokeping.cgi + smokemail = ${cfg.smokeMailTemplate} + *** Presentation *** + template = ${cfg.presentationTemplate} + ${cfg.presentationConfig} + #*** Alerts *** + #${cfg.alertConfig} + *** Database *** + ${cfg.databaseConfig} + *** Probes *** + ${cfg.probeConfig} + *** Targets *** + ${cfg.targetConfig} + ${cfg.extraConfig} + ''; + 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 = "127.0.0.1"; + description = "Use this SMTP server rather than localhost"; + }; + 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; + 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."; + }; + 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 = ""; + 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 = mkIf cfg.enable { + 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 + chown -R ${cfg.user} ${smokepingHome} + cp ${cgiHome} ${smokepingHome}/smokeping.fcgi + ${cfg.package}/bin/smokeping --check --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 ]; + script = ''${pkgs.thttpd}/bin/thttpd -u ${cfg.user} -c "**.fcgi" -d ${smokepingHome} -p ${builtins.toString cfg.port} -D''; + }; + }; +} + diff --git a/nixos/release.nix b/nixos/release.nix index 184e340341f..966dee1aff0 100644 --- a/nixos/release.nix +++ b/nixos/release.nix @@ -272,6 +272,7 @@ in rec { tests.sddm = callTest tests/sddm.nix {}; tests.sddm-kde5 = callTest tests/sddm-kde5.nix {}; tests.simple = callTest tests/simple.nix {}; + tests.smokeping = callTest tests/smokeping.nix {}; tests.taskserver = callTest tests/taskserver.nix {}; tests.tomcat = callTest tests/tomcat.nix {}; tests.udisks2 = callTest tests/udisks2.nix {}; diff --git a/nixos/tests/smokeping.nix b/nixos/tests/smokeping.nix new file mode 100644 index 00000000000..324f83147e0 --- /dev/null +++ b/nixos/tests/smokeping.nix @@ -0,0 +1,31 @@ +import ./make-test.nix ({ pkgs, ...} : { + name = "smokeping"; + meta = with pkgs.stdenv.lib.maintainers; { + maintainers = [ cransom ]; + }; + + nodes = { + sm = + { pkgs, config, ... }: + { + services.smokeping = { + enable = true; + port = 8081; + probeConfig = '' + + FPing + binary = ${pkgs.fping}/bin/fping + offset = 0% + ''; + }; + }; + }; + + testScript = '' + startAll; + $sm->waitForUnit("smokeping"); + $sm->waitForUnit("thttpd"); + $sm->waitForFile("/var/lib/smokeping/data/Local/LocalMachine.rrd"); + $sm->succeed("curl -s -f localhost:8081/smokeping.fcgi?target=Local"); + $sm->succeed("ls /var/lib/smokeping/cache/Local/LocalMachine_mini.png"); + ''; +}) diff --git a/pkgs/tools/networking/smokeping/default.nix b/pkgs/tools/networking/smokeping/default.nix new file mode 100644 index 00000000000..334a6feb8d5 --- /dev/null +++ b/pkgs/tools/networking/smokeping/default.nix @@ -0,0 +1,26 @@ +{ stdenv, fetchurl, fping, rrdtool, FCGI, CGI +, CGIFast, ConfigGrammar, DigestHMAC, NetTelnet +, NetOpenSSH, NetSNMP, LWP, IOTty, perl, NetDNS +, NetLDAP +}: + +stdenv.mkDerivation rec { + name = "smokeping-${version}"; + version = "2.6.11"; + src = fetchurl { + url = "http://oss.oetiker.ch/smokeping/pub/smokeping-${version}.tar.gz"; + sha256 = "1p9hpa2zs33p7hzrds80kwrm5255s0869v3s3qmsyx2sx63c7czj"; + }; + propagatedBuildInputs = [ + rrdtool FCGI CGI CGIFast ConfigGrammar DigestHMAC NetTelnet NetOpenSSH + NetSNMP LWP IOTty fping perl NetDNS NetLDAP ]; + postInstall = '' + mv $out/htdocs/smokeping.fcgi.dist $out/htdocs/smokeping.fcgi + ''; + meta = { + description = "Network latency collector"; + homepage = "http://oss.oetiker.ch/smokeping"; + license = stdenv.lib.licenses.gpl2Plus; + platforms = stdenv.lib.platforms.all; + }; +} diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 8d58b70cf7b..4c003ad41b0 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -17162,6 +17162,13 @@ in slock = callPackage ../misc/screensavers/slock { }; + smokeping = callPackage ../tools/networking/smokeping { + inherit fping rrdtool; + inherit (perlPackages) + FCGI CGI CGIFast ConfigGrammar DigestHMAC NetTelnet + NetOpenSSH NetSNMP LWP IOTty perl NetDNS NetLDAP; + }; + snapraid = callPackage ../tools/filesystems/snapraid { }; soundOfSorting = callPackage ../misc/sound-of-sorting { }; diff --git a/pkgs/top-level/perl-packages.nix b/pkgs/top-level/perl-packages.nix index d50237f06d5..387e886927e 100644 --- a/pkgs/top-level/perl-packages.nix +++ b/pkgs/top-level/perl-packages.nix @@ -2149,6 +2149,18 @@ let self = _self // overrides; _self = with self; { }; }; + ConfigGrammar = buildPerlPackage { + name = "Config-Grammar-1.11"; + src = fetchurl { + url = mirror://cpan/authors/id/D/DS/DSCHWEI/Config-Grammar-1.11.tar.gz; + sha256 = "dd819f89b19c51e9fac6965360cd9db54436e1328968c802416ac34188ca65ee"; + }; + meta = { + description = "A grammar-based, user-friendly config parser"; + license = "unknown"; + }; + }; + ConfigINI = buildPerlPackage rec { name = "Config-INI-0.025"; src = fetchurl { @@ -9537,6 +9549,18 @@ let self = _self // overrides; _self = with self; { }; }; + NetTelnet = buildPerlPackage { + name = "Net-Telnet-3.04"; + src = fetchurl { + url = mirror://cpan/authors/id/J/JR/JROGERS/Net-Telnet-3.04.tar.gz; + sha256 = "e64d567a4e16295ecba949368e7a6b8b5ae2a16b3ad682121d9b007dc5d2a37a"; + }; + meta = { + description = "Interact with TELNET port or other TCP ports"; + license = "unknown"; + }; + }; + NetTwitterLite = buildPerlPackage { name = "Net-Twitter-Lite-0.11002"; src = fetchurl { @@ -9665,6 +9689,18 @@ let self = _self // overrides; _self = with self; { propagatedBuildInputs = [ CGI NetOpenIDCommon JSON LWP ]; }; + NetOpenSSH = buildPerlPackage { + name = "Net-OpenSSH-0.70"; + src = fetchurl { + url = mirror://cpan/authors/id/S/SA/SALVA/Net-OpenSSH-0.70.tar.gz; + sha256 = "3fcb36a5a2fc296c1d0def54f3201cecffe7d81157ef5fa2bac9868875f63b95"; + }; + meta = { + description = "Perl SSH client package implemented on top of OpenSSH"; + license = "perl"; + }; + }; + PackageConstants = buildPerlPackage { name = "Package-Constants-0.04"; src = fetchurl {