{ lib, pkgs, config, ... }: let inherit (builtins) toJSON; inherit (lib) mkOption mkMerge mkIf mkDefault; inherit (lib.my) mkOpt' mkBoolOpt'; cfg = config.my.librespeed; serversConf = map (s: s // { dlURL = "backend/garbage"; ulURL = "backend/empty"; pingURL = "backend/empty"; getIpURL = "backend/getIP"; }) cfg.frontend.servers; frontendTree = pkgs.runCommand "librespeed-frontend" { speedtestServers = toJSON serversConf; } '' mkdir "$out" cp "${pkgs.librespeed-go}"/assets/* "$out"/ substitute ${./index.html} "$out"/index.html --subst-var speedtestServers ''; backendConf = pkgs.writers.writeTOML "librespeed.toml" cfg.backend.settings; generateBackendSettings = base: dst: if (cfg.backend.extraSettingsFile != null) then '' oldUmask="$(umask)" umask 006 cat "${base}" "${cfg.backend.extraSettingsFile}" > "${dst}" umask "$oldUmask" '' else '' cp "${base}" "${dst}" ''; in { options.my.librespeed = with lib.types; { frontend = { servers = mkOpt' (listOf (attrsOf unspecified)) { } "Server configs."; webroot = mkOption { description = "Frontend webroot."; type = package; readOnly = true; }; }; backend = { enable = mkBoolOpt' false "Whether to enable librespeed backend."; settings = mkOpt' (attrsOf unspecified) { } "Backend settings."; extraSettingsFile = mkOpt' (nullOr str) null "Extra settings file."; }; }; config = mkMerge [ (mkIf (cfg.frontend.servers != { }) { my.librespeed.frontend.webroot = frontendTree; }) (mkIf cfg.backend.enable { my.librespeed.backend.settings = { assets_path = frontendTree; database_type = mkDefault "bolt"; database_file = mkDefault "/var/lib/librespeed-go/speedtest.db"; }; systemd.services.librespeed = { description = "LibreSpeed Go backend"; wants = [ "network-online.target" ]; after = [ "network-online.target" ]; preStart = generateBackendSettings backendConf "/run/librespeed-go/settings.toml"; serviceConfig = { ExecStart = "${pkgs.librespeed-go}/bin/speedtest -c /run/librespeed-go/settings.toml"; RuntimeDirectory = "librespeed-go"; StateDirectory = "librespeed-go"; }; wantedBy = [ "multi-user.target" ]; }; }) ]; }