From 0aa9a0f994401a42610fa8bd112a69f839868ebb Mon Sep 17 00:00:00 2001 From: mjallen18 Date: Mon, 30 Mar 2026 19:34:40 -0500 Subject: [PATCH] fmt --- lib/module/default.nix | 3 +- modules/nixos/services/glance/default.nix | 479 +++++++++++++--------- systems/x86_64-linux/jallen-nas/apps.nix | 199 +++++++++ 3 files changed, 476 insertions(+), 205 deletions(-) diff --git a/lib/module/default.nix b/lib/module/default.nix index c7572dc..e3475dc 100644 --- a/lib/module/default.nix +++ b/lib/module/default.nix @@ -149,7 +149,8 @@ rec { reverseProxy = mkReverseProxyOpt name; hostedService = { - enable = mkBoolOpt false "Expose this service in Glance dashboard"; + enable = mkOpt types.bool (cfg.reverseProxy.enable + ) "Expose this service in Glance dashboard (auto-enabled when reverseProxy is on)"; title = mkOpt types.str name "Display title in Glance"; icon = mkOpt types.str "si:glance" "Icon identifier for Glance (e.g. si:actualbudget)"; group = mkOpt types.str "Services" "Glance group/category for this service"; diff --git a/modules/nixos/services/glance/default.nix b/modules/nixos/services/glance/default.nix index a1cae88..b21503c 100644 --- a/modules/nixos/services/glance/default.nix +++ b/modules/nixos/services/glance/default.nix @@ -8,7 +8,6 @@ with lib; let name = "glance"; cfg = config.${namespace}.services.${name}; - net = lib.${namespace}.network; hostedServiceSites = let @@ -41,91 +40,25 @@ let [ ] ) serviceNames; - coreSites = { - actual = { - title = "Actual"; - url = "https://actual.mjallen.dev/"; - icon = "si:actualbudget"; - }; - jellyfin = { - title = "Jellyfin"; - url = "https://jellyfin.mjallen.dev/"; - icon = "si:jellyfin"; - }; - gitea = { - title = "Gitea"; - url = "https://gitea.mjallen.dev/"; - icon = "si:gitea"; - }; - nextcloud = { - title = "Nextcloud"; - url = "https://cloud.mjallen.dev/"; - icon = "si:nextcloud"; - }; - immich = { - title = "Immich"; - url = "https://immich.mjallen.dev/"; - icon = "si:immich"; - }; - homeassistant = { - title = "Home Assistant"; - url = "https://hass.mjallen.dev/"; - icon = "si:homeassistant"; - }; - adguard = { - title = "AdGuard Home"; - url = "http://${net.hosts.pi5.lan}:${toString net.ports.pi5.adguard}/"; - icon = "si:adguard"; - allow-insecure = true; - }; - manyfold = { - title = "Manyfold"; - url = "http://${net.hosts.nas.lan}:${toString net.ports.nas.manyfold}/collections"; - icon = "sh:manyfold"; - allow-insecure = true; - }; - code-server = { - title = "Code Server"; - url = "http://${net.hosts.nas.lan}:${toString net.ports.nas.codeServer}/"; - icon = "si:vscodium"; - allow-insecure = true; - }; - nas-kvm = { - title = "NAS KVM"; - url = "http://nas-kvm.local/"; - icon = "si:nanokvm"; - allow-insecure = true; - }; - sonarr = { - title = "Sonarr"; - url = "http://${net.hosts.nas.lan}:${toString net.ports.nas.sonarr}/"; - icon = "si:sonarr"; - allow-insecure = true; - basic-auth = { - username = "\${ARR_USER}"; - password = "\${ARR_PASS}"; - }; - }; - radarr = { - title = "Radarr"; - url = "http://${net.hosts.nas.lan}:${toString net.ports.nas.radarr}/"; - icon = "si:radarr"; - allow-insecure = true; - basic-auth = { - username = "\${ARR_USER}"; - password = "\${ARR_PASS}"; - }; - }; - sabnzbd = { - title = "Sabnzbd"; - url = "http://${net.hosts.nas.lan}:${toString net.ports.nas.sabnzbd}/"; - icon = "si:sabnzbd"; - allow-insecure = true; - basic-auth = { - username = "\${ARR_USER}"; - password = "\${ARR_PASS}"; - }; - }; + hostedServicesByGroup = builtins.groupBy (svc: svc.hostedService.group) ( + builtins.filter (svc: svc.hostedService.enable) ( + builtins.map ( + serviceName: + let + serviceCfg = config.${namespace}.services.${serviceName}; + in + { + inherit (serviceCfg) hostedService; + } + ) (builtins.attrNames config.${namespace}.services) + ) + ); + + makeMonitorWidget = title: sites: { + type = "monitor"; + cache = "1m"; + inherit title; + inherit sites; }; glanceConfig = lib.${namespace}.mkModule { @@ -138,22 +71,16 @@ let description = "Path to the NAS pool mount to display in server-stats."; }; - enableCoreSites = lib.mkOption { - type = lib.types.bool; - default = true; - description = "Enable the default core service sites in the monitor widget"; - }; - enableHostedServices = lib.mkOption { type = lib.types.bool; default = true; description = "Auto-discover services with hostedService.enable and add them to the monitor widget"; }; - coreServices = lib.mkOption { - type = lib.types.listOf lib.types.str; - default = builtins.attrNames coreSites; - description = "List of core service keys to include (filtered by enableCoreSites)"; + hostedServiceGroups = lib.mkOption { + type = lib.types.bool; + default = false; + description = "Create separate monitor widgets for each hostedService group instead of one combined widget"; }; extraSites = lib.mkOption { @@ -189,6 +116,213 @@ let default = [ ]; description = "Extra sites to display in the monitor widget"; }; + + weather = lib.mkOption { + type = lib.types.submodule { + options = { + enable = lib.mkOption { + type = lib.types.bool; + default = true; + description = "Enable weather widget"; + }; + location = lib.mkOption { + type = lib.types.str; + default = "Saint Paul, Minnesota, United States"; + description = "Weather location"; + }; + units = lib.mkOption { + type = lib.types.enum [ + "imperial" + "metric" + ]; + default = "imperial"; + description = "Temperature units"; + }; + hour-format = lib.mkOption { + type = lib.types.enum [ + "12h" + "24h" + ]; + default = "12h"; + description = "Hour format"; + }; + }; + }; + default = { }; + description = "Weather widget settings"; + }; + + bookmarks = lib.mkOption { + type = lib.types.listOf ( + lib.types.submodule { + options = { + title = lib.mkOption { + type = lib.types.str; + description = "Group title"; + }; + links = lib.mkOption { + type = lib.types.listOf ( + lib.types.submodule { + options = { + title = lib.mkOption { + type = lib.types.str; + description = "Link title"; + }; + url = lib.mkOption { + type = lib.types.str; + description = "Link URL"; + }; + }; + } + ); + description = "List of links"; + }; + }; + } + ); + default = [ + { + title = "General"; + links = [ + { + title = "Gmail"; + url = "https://mail.google.com/mail/u/0/"; + } + { + title = "Proton Mail"; + url = "https://mail.proton.me/u/0/inbox"; + } + { + title = "MyNixOS"; + url = "https://www.mynixos.com/"; + } + { + title = "Github"; + url = "https://github.com/"; + } + ]; + } + { + title = "Entertainment"; + links = [ + { + title = "YouTube"; + url = "https://www.youtube.com/"; + } + { + title = "Prime Video"; + url = "https://www.primevideo.com/"; + } + { + title = "Disney+"; + url = "https://www.disneyplus.com/"; + } + ]; + } + { + title = "Social"; + links = [ + { + title = "Reddit"; + url = "https://www.reddit.com/"; + } + { + title = "Twitter"; + url = "https://twitter.com/"; + } + { + title = "Instagram"; + url = "https://www.instagram.com/"; + } + ]; + } + ]; + description = "Bookmark groups"; + }; + + reddit = lib.mkOption { + type = lib.types.listOf lib.types.str; + default = [ + "hockey" + "formula1" + ]; + description = "Subreddits to show in Reddit widgets"; + }; + + search = lib.mkOption { + type = lib.types.listOf ( + lib.types.submodule { + options = { + title = lib.mkOption { + type = lib.types.str; + description = "Search engine title"; + }; + shortcut = lib.mkOption { + type = lib.types.str; + description = "Bang shortcut (e.g. !yt)"; + }; + url = lib.mkOption { + type = lib.types.str; + description = "Search URL with {QUERY} placeholder"; + }; + }; + } + ); + default = [ + { + title = "YouTube"; + shortcut = "!yt"; + url = "https://www.youtube.com/results?search_query={QUERY}"; + } + ]; + description = "Custom search engine bangs"; + }; + + servers = lib.mkOption { + type = lib.types.listOf ( + lib.types.submodule { + options = { + name = lib.mkOption { + type = lib.types.str; + description = "Server name"; + }; + cpu-temp-sensor = lib.mkOption { + type = lib.types.str; + default = ""; + description = "CPU temp sensor path"; + }; + mountpoints = lib.mkOption { + type = lib.types.attrsOf ( + lib.types.submodule { + options = { + name = lib.mkOption { + type = lib.types.str; + description = "Display name for mountpoint"; + }; + }; + } + ); + description = "Mountpoints to display"; + }; + }; + } + ); + default = [ + { + name = "Jallen-NAS"; + cpu-temp-sensor = "/sys/devices/pci0000:00/0000:00:08.1/0000:cd:00.0/hwmon/hwmon*/temp1_input"; + mountpoints = { + "/home" = { + name = "Home"; + }; + "${cfg.nasPoolPath}" = { + name = "nas_pool"; + }; + }; + } + ]; + description = "Servers for server-stats widget"; + }; }; moduleConfig = { services.glance = { @@ -214,31 +348,17 @@ let type = "calendar"; first-day-of-week = "sunday"; } - { - type = "weather"; - units = "imperial"; - hour-format = "12h"; - location = "Saint Paul, Minnesota, United States"; - } - { - type = "server-stats"; - servers = [ - { - type = "local"; - name = "Jallen-NAS"; - cpu-temp-sensor = "/sys/devices/pci0000:00/0000:00:08.1/0000:cd:00.0/hwmon/hwmon*/temp1_input"; - mountpoints = { - "/home" = { - name = "Home"; - }; - "${cfg.nasPoolPath}" = { - name = "nas_pool"; - }; - }; - } - ]; - } - ]; + ] + ++ (lib.mkIf cfg.weather.enable { + type = "weather"; + units = cfg.weather.units; + hour-format = cfg.weather.hour-format; + location = cfg.weather.location; + }) + ++ (lib.mkIf (cfg.servers != [ ]) { + type = "server-stats"; + servers = cfg.servers; + }); } { size = "full"; @@ -247,100 +367,51 @@ let type = "search"; autofocus = true; search-engine = "google"; - bangs = [ - { - title = "YouTube"; - shortcut = "!yt"; - url = "https://www.youtube.com/results?search_query={QUERY}"; - } - ]; + bangs = cfg.search; } - { + ] + ++ (lib.mkIf cfg.hostedServiceGroups ( + builtins.map ( + groupName: + makeMonitorWidget groupName ( + builtins.map (svc: { + title = svc.hostedService.title; + url = svc.hostedService.url; + icon = svc.hostedService.icon; + }) (hostedServicesByGroup.${groupName} or [ ]) + ) + ) (builtins.attrNames hostedServicesByGroup) + )) + ++ (lib.mkIf (!cfg.hostedServiceGroups && cfg.enableHostedServices) [ + (makeMonitorWidget "Services" hostedServiceSites) + ]) + ++ (lib.mkIf (cfg.extraSites != [ ]) ( + builtins.map (site: { type = "monitor"; cache = "1m"; - title = "Services"; - sites = - (if cfg.enableCoreSites then builtins.map (key: coreSites.${key}) cfg.coreServices else [ ]) - ++ (if cfg.enableHostedServices then hostedServiceSites else [ ]) - ++ builtins.map ( - site: + title = site.title; + sites = [ + ( { title = site.title; url = site.url; icon = site.icon; } // optionalAttrs site.allow-insecure { allow-insecure = true; } - ) cfg.extraSites; - } - { - type = "bookmarks"; - groups = [ - { - title = "General"; - links = [ - { - title = "Gmail"; - url = "https://mail.google.com/mail/u/0/"; - } - { - title = "Proton Mail"; - url = "https://mail.proton.me/u/0/inbox"; - } - { - title = "MyNixOS"; - url = "https://www.mynixos.com/"; - } - { - title = "Github"; - url = "https://github.com/"; - } - ]; - } - { - title = "Entertainment"; - links = [ - { - title = "YouTube"; - url = "https://www.youtube.com/"; - } - { - title = "Prime Video"; - url = "https://www.primevideo.com/"; - } - { - title = "Disney+"; - url = "https://www.disneyplus.com/"; - } - ]; - } - { - title = "Social"; - links = [ - { - title = "Reddit"; - url = "https://www.reddit.com/"; - } - { - title = "Twitter"; - url = "https://twitter.com/"; - } - { - title = "Instagram"; - url = "https://www.instagram.com/"; - } - ]; - } + ) ]; - } - { + }) cfg.extraSites + )) + ++ (lib.mkIf (cfg.bookmarks != [ ]) { + type = "bookmarks"; + groups = cfg.bookmarks; + }) + ++ (lib.mkIf (cfg.reddit != [ ]) ( + builtins.map (subreddit: { type = "reddit"; - subreddit = "hockey"; - } - { - type = "reddit"; - subreddit = "formula1"; - } - ]; + inherit subreddit; + }) cfg.reddit + )); } ]; } diff --git a/systems/x86_64-linux/jallen-nas/apps.nix b/systems/x86_64-linux/jallen-nas/apps.nix index 18779f4..7ae92af 100755 --- a/systems/x86_64-linux/jallen-nas/apps.nix +++ b/systems/x86_64-linux/jallen-nas/apps.nix @@ -6,6 +6,7 @@ }: let inherit (lib.${namespace}) enabled disabled; + net = lib.${namespace}.network; in { ${namespace} = { @@ -15,6 +16,10 @@ in port = 3333; createUser = true; reverseProxy = enabled; + hostedService = { + group = "Finance"; + icon = "si:actualbudget"; + }; }; ai = { enable = true; @@ -29,6 +34,9 @@ in enable = true; subdomain = "cache"; }; + hostedService = { + group = "Dev"; + }; }; authentik = { enable = true; @@ -36,6 +44,9 @@ in port = 9000; reverseProxy = enabled; environmentFile = "/run/secrets/jallen-nas/authentik-env"; + hostedService = { + group = "Infrastructure"; + }; redis = { enable = true; port = 6379; @@ -104,6 +115,10 @@ in enable = true; port = 3000; reverseProxy = enabled; + hostedService = { + group = "Dev"; + icon = "si:gitea"; + }; }; guacd = { enable = true; @@ -112,6 +127,165 @@ in glance = { enable = true; port = 5555; + hostedServiceGroups = true; + weather = { + enable = true; + location = "Saint Paul, Minnesota, United States"; + units = "imperial"; + hour-format = "12h"; + }; + servers = [ + { + name = "NAS"; + mountpoints."/media/nas/main" = { + name = "Main Pool"; + }; + } + { + name = "Pi5"; + mountpoints."/" = { + name = "Root"; + }; + } + ]; + bookmarks = [ + { + title = "General"; + links = [ + { + title = "Gmail"; + url = "https://mail.google.com/mail/u/0/"; + } + { + title = "Proton Mail"; + url = "https://mail.proton.me/u/0/inbox"; + } + { + title = "MyNixOS"; + url = "https://www.mynixos.com/"; + } + { + title = "Github"; + url = "https://github.com/"; + } + ]; + } + { + title = "Entertainment"; + links = [ + { + title = "YouTube"; + url = "https://www.youtube.com/"; + } + { + title = "Prime Video"; + url = "https://www.primevideo.com/"; + } + { + title = "Disney+"; + url = "https://www.disneyplus.com/"; + } + ]; + } + { + title = "Social"; + links = [ + { + title = "Reddit"; + url = "https://www.reddit.com/"; + } + { + title = "Twitter"; + url = "https://twitter.com/"; + } + { + title = "Instagram"; + url = "https://www.instagram.com/"; + } + ]; + } + ]; + reddit = [ + "hockey" + "formula1" + ]; + search = [ + { + title = "YouTube"; + shortcut = "!yt"; + url = "https://www.youtube.com/results?search_query={QUERY}"; + } + { + title = "Wikipedia"; + shortcut = "!w"; + url = "https://en.wikipedia.org/wiki/{QUERY}"; + } + ]; + extraSites = [ + { + title = "Home Assistant"; + url = "http://${net.hosts.nuc.lan}:${toString net.ports.nuc.homeAssistant}/"; + icon = "si:vscodium"; + allow-insecure = true; + } + { + title = "ESPHome"; + url = "http://${net.hosts.nuc.lan}:${toString net.ports.nuc.esphome}/"; + icon = "si:vscodium"; + allow-insecure = true; + } + { + title = "Sonarr"; + url = "http://${net.hosts.nas.lan}:${toString net.ports.nas.sonarr}/"; + icon = "si:sonarr"; + allow-insecure = true; + basic-auth = true; + } + { + title = "Radarr"; + url = "http://${net.hosts.nas.lan}:${toString net.ports.nas.radarr}/"; + icon = "si:radarr"; + allow-insecure = true; + basic-auth = true; + } + { + title = "Sabnzbd"; + url = "http://${net.hosts.nas.lan}:${toString net.ports.nas.sabnzbd}/"; + icon = "si:sabnzbd"; + allow-insecure = true; + basic-auth = true; + } + { + title = "AdGuard"; + url = "http://${net.hosts.pi5.lan}:${toString net.ports.pi5.adguard}/"; + icon = "si:adguard"; + allow-insecure = true; + } + { + title = "Manyfold"; + url = "http://${net.hosts.nas.lan}:${toString net.ports.nas.manyfold}/collections"; + icon = "sh:manyfold"; + allow-insecure = true; + } + { + title = "Code Server"; + url = "http://${net.hosts.nas.lan}:${toString net.ports.nas.codeServer}/"; + icon = "si:vscodium"; + allow-insecure = true; + } + { + title = "NAS KVM"; + url = "http://nas-kvm.local/"; + icon = "si:iterm2"; + allow-insecure = true; + } + { + title = "NUC KVM"; + url = "http://pikvm.local/"; + icon = "si:raspberrypi"; + allow-insecure = true; + } + ]; }; glances = { enable = true; @@ -131,17 +305,28 @@ in enable = true; port = 2283; reverseProxy = enabled; + hostedService = { + group = "Media"; + icon = "si:immich"; + }; }; jellyfin = { enable = true; port = 8096; reverseProxy = enabled; + hostedService = { + group = "Media"; + icon = "si:jellyfin"; + }; }; jellyseerr = { enable = true; port = 5055; createUser = true; reverseProxy = enabled; + hostedService = { + group = "Media"; + }; }; kavita = { enable = true; @@ -158,6 +343,9 @@ in enable = true; port = 6754; reverseProxy = enabled; + hostedService = { + group = "Finance"; + }; }; manyfold = { enable = true; @@ -167,6 +355,10 @@ in enable = true; port = 8448; reverseProxy = enabled; + hostedService = { + group = "Infrastructure"; + icon = "si:element"; + }; }; minecraft = disabled; mongodb = disabled; @@ -192,12 +384,19 @@ in enable = true; subdomain = "cloud"; }; + hostedService = { + group = "Infrastructure"; + icon = "si:nextcloud"; + }; }; ntfy = { enable = true; port = 2586; createUser = true; reverseProxy = enabled; + hostedService = { + group = "Infrastructure"; + }; }; ocis = disabled; onlyoffice = {