zaphyra's git: nixfiles

zaphyra and void's nixfiles

commit 4d9f9e580eed171d32a94abb5a58a88fa4171884
parent d89873976a8e64db0a03fe7443d45195e70a12a0
Author: Katja (zaphyra) <git@ctu.cx>
Date: Thu, 22 May 2025 08:11:17 +0200

config/nixos/services: add `vnstat`
2 files changed, 160 insertions(+), 0 deletions(-)
M
config/nixos/modules/presets/katja/enable.nix
|
2
++
A
config/nixos/modules/services/vnstat.nix
|
158
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
diff --git a/config/nixos/modules/presets/katja/enable.nix b/config/nixos/modules/presets/katja/enable.nix
@@ -51,6 +51,8 @@ in
           enableRSASupport = lib.mkDefault true;
         };
         prometheus-exporters.enable = lib.mkDefault true;
+        vnstat.enable = true;
+        vnstat.vnstati.enable = true;
       };
     };
 
diff --git a/config/nixos/modules/services/vnstat.nix b/config/nixos/modules/services/vnstat.nix
@@ -0,0 +1,158 @@
+{
+  inputs,
+  povSelf,
+  config,
+  lib,
+  pkgs,
+  ...
+}:
+let
+  inherit (lib) types;
+  cfg = lib.getAttrFromPath povSelf config;
+
+in
+{
+
+  options = {
+    enable = {
+      type = types.bool;
+      default = false;
+    };
+    vnstati.enable = {
+      type = types.bool;
+      default = false;
+    };
+  };
+
+  config = lib.mkIf cfg.enable {
+    services.vnstat.enable = true;
+
+    services.nginx.virtualHosts."${config.networking.fqdn}" = lib.mkIf cfg.vnstati.enable {
+      locations."/vnstat/" = {
+        alias = "/var/run/vnstati/";
+        index = "index.html";
+      };
+    };
+
+    systemd.services.vnstati = lib.mkIf cfg.vnstati.enable {
+      wantedBy = [ "multi-user.target" ];
+      after = [ "vnstat.service" ];
+      startAt = "*-*-* *:0/10:00";
+
+      serviceConfig = {
+        User = "vnstatd";
+        Group = "nginx";
+        RuntimeDirectoryPreserve = true;
+        RuntimeDirectory = "vnstati";
+        RuntimeDirectoryMode = 775;
+        PrivateTmp = true;
+        ProtectHome = true;
+        ProtectSystem = "strict";
+      };
+
+      path = with pkgs; [
+        vnstat
+        jq
+        nix
+      ];
+      script = ''
+        set -x
+        ifaces=$(vnstat --json | jq -r .interfaces[].name | grep -v "^lo$")
+        echo $ifaces
+
+        cat > /var/run/vnstati/index.html << EOF
+        <!DOCTYPE html>
+        <html lang="en">
+          <head>
+            <title>${config.networking.hostName} - stats</title>
+            <meta charset="utf-8">
+            <meta name="robots" content="none">
+            <link rel="icon" href="static/favicon.ico" type="image/x-icon">
+            <style>
+        body {
+            padding: 0;
+            margin: 0;
+            background: #eee;
+            font-family: monospace;
+            min-height: 100vh;
+        }
+        img:not(:last-child) {
+            margin-bottom: 15px;
+        }
+        img {
+            flex-shrink: 0;
+        }
+        .ui.segment {
+            margin: 0 1em 10px 1em;
+            padding: 1em;
+            background-color: white;
+            box-shadow: 0 1px 2px 0 rgba(34,36,38,.15);
+            border-radius: .286rem;
+            border: 1px solid rgba(34,36,38,.15);
+            display: flex;
+            flex-direction: column;
+            align-items: center;
+            justify-content: center;
+
+        }
+        div.heading {
+            min-width: 100vw;
+            height: 70px;
+            display: flex;
+            flex-direction: column;
+            align-items: center;
+            justify-content: center;
+        }
+        div.table.vertical {
+            overflow-y: auto;
+            min-width: 100vw;
+            height: calc(100vh - 70px);
+            display: flex;
+            flex-direction: row;
+        }
+        div.iface {
+            display: flex;
+            flex-direction: column;
+            align-items: center;
+            flex-grow: 1;
+        }
+            </style>
+          </head>
+          <body>
+            <div class="heading">
+              <h1>${config.networking.hostName}</h1>
+            </div>
+            <div class="table vertical">            
+        EOF
+
+        for iface in $ifaces
+        do
+        cat >> /var/run/vnstati/index.html << EOF
+          <div class="iface">
+            <h3>''${iface}</h3>
+              <div class="ui segment"><img src="''${iface}-summary.png" alt="Summary"></div>
+              <div class="ui segment"><img src="''${iface}-hourly.png" alt="Hourly"></div>
+              <div class="ui segment"><img src="''${iface}-daily.png" alt="Daily"></div>
+              <div class="ui segment"><img src="''${iface}-monthly.png" alt="Monthly"></div>
+              <div class="ui segment"><img src="''${iface}-top10.png" alt="Top 10"></div>
+          </div>
+        EOF
+
+          vnstati -s -nh -i $iface -o /var/run/vnstati/$iface-summary.png
+          vnstati -h -nh -i $iface -o /var/run/vnstati/$iface-hourly.png
+          vnstati -d -nh -i $iface -o /var/run/vnstati/$iface-daily.png
+          vnstati -m -nh -i $iface -o /var/run/vnstati/$iface-monthly.png
+          vnstati -t -nh -i $iface -o /var/run/vnstati/$iface-top10.png
+        done
+
+        cat >> /var/run/vnstati/index.html << EOF
+            </div>
+          </body>
+        </html>
+        EOF
+
+      '';
+    };
+  };
+
+}