This commit is contained in:
mjallen18
2026-03-30 19:16:09 -05:00
parent c97e96f2da
commit 9728f49e42
8 changed files with 208 additions and 124 deletions

View File

@@ -138,7 +138,7 @@
# variable assignments for simple strings (e.g. username=admin).
# shellcheck SC2209 flags this as a warning, breaking the build when
# the value matches a command name. Exclude SC2209 globally.
(final: prev: {
(_final: prev: {
writeShellApplication =
args:
prev.writeShellApplication (

View File

@@ -31,6 +31,7 @@ in
desktop.plasma = enabled;
programs = {
opencode = enabled;
thunderbird = enabled;
hyprland = {
enable = false;

View File

@@ -147,6 +147,20 @@ rec {
"Extra environment variables passed to the service";
reverseProxy = mkReverseProxyOpt name;
hostedService = {
enable = mkBoolOpt false "Expose this service in Glance dashboard";
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";
url = mkOpt types.str (
if cfg.reverseProxy.enable then
"https://${cfg.reverseProxy.subdomain}.${cfg.reverseProxy.domain}"
else
"http://127.0.0.1:${toString cfg.port}"
) "Service URL for Glance (auto-derived from reverseProxy if enabled)";
basicAuth = mkOpt types.bool false "Require basic auth for this service in Glance";
};
}
// options;
};
@@ -298,6 +312,8 @@ rec {
# ---------------------------------------------------------------------------
# Option creation helpers
# ---------------------------------------------------------------------------
# Option creation helpers
# ---------------------------------------------------------------------------
mkOpt =
type: default: description:

View File

@@ -69,10 +69,11 @@ in
mission-center
parted
vesktop
] ++ (
if isArm then
]
++ (
if isArm then
[ ]
else
else
[
proton-pass
]

View File

@@ -92,9 +92,7 @@ in
type = mkOpt types.str "wifi" "type of the network.(wifi/ethernet)";
interface =
mkOpt types.str ""
"Interface for this profile (defaults to global ipv4.interface).";
interface = mkOpt types.str "" "Interface for this profile (defaults to global ipv4.interface).";
autoconnect = mkBoolOpt true "autoconnect to this connection";

View File

@@ -4,11 +4,130 @@
namespace,
...
}:
with lib;
let
name = "glance";
cfg = config.${namespace}.services.${name};
net = lib.${namespace}.network;
hostedServiceSites =
let
servicesCfg = config.${namespace}.services;
serviceNames = builtins.attrNames servicesCfg;
in
builtins.concatMap (
serviceName:
let
serviceCfg = servicesCfg.${serviceName};
hosted = serviceCfg.hostedService or null;
in
if hosted != null && hosted.enable then
[
(
{
title = hosted.title;
url = hosted.url;
icon = hosted.icon;
}
// optionalAttrs hosted.basicAuth {
basic-auth = {
username = "\${ARR_USER}";
password = "\${ARR_PASS}";
};
}
)
]
else
[ ]
) 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}";
};
};
};
glanceConfig = lib.${namespace}.mkModule {
inherit config name;
description = "glance";
@@ -18,6 +137,58 @@ let
default = cfg.dataDir;
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)";
};
extraSites = lib.mkOption {
type = lib.types.listOf (
lib.types.submodule {
options = {
title = lib.mkOption {
type = lib.types.str;
description = "Display title";
};
url = lib.mkOption {
type = lib.types.str;
description = "Service URL";
};
icon = lib.mkOption {
type = lib.types.str;
default = "si:glance";
description = "Icon identifier (e.g. si:servicename)";
};
allow-insecure = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Allow insecure connections";
};
basic-auth = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Require basic auth (uses ARR credentials)";
};
};
}
);
default = [ ];
description = "Extra sites to display in the monitor widget";
};
};
moduleConfig = {
services.glance = {
@@ -33,7 +204,6 @@ let
{
name = "Startpage";
width = "default";
# tab = "First";
hide-desktop-navigation = true;
center-vertically = true;
columns = [
@@ -56,7 +226,7 @@ let
{
type = "local";
name = "Jallen-NAS";
cpu-temp-sensor = "/sys/devices/pci0000:00/0000:00:08.1/0000:cd:00.0/hwmon/hwmon*/temp1_input"; # Tctl
cpu-temp-sensor = "/sys/devices/pci0000:00/0000:00:08.1/0000:cd:00.0/hwmon/hwmon*/temp1_input";
mountpoints = {
"/home" = {
name = "Home";
@@ -72,7 +242,6 @@ let
}
{
size = "full";
# tab = "First";
widgets = [
{
type = "search";
@@ -90,101 +259,21 @@ let
type = "monitor";
cache = "1m";
title = "Services";
sites = [
{
title = "Actual";
url = "https://actual.mjallen.dev/";
icon = "si:actualbudget";
}
{
title = "Jellyfin";
url = "https://jellyfin.mjallen.dev/";
icon = "si:jellyfin";
}
{
title = "Gitea";
url = "https://gitea.mjallen.dev/";
icon = "si:gitea";
}
{
title = "Nextcloud";
url = "https://cloud.mjallen.dev/";
icon = "si:nextcloud";
}
{
title = "Immich";
url = "https://immich.mjallen.dev/";
icon = "si:immich";
}
{
title = "AdGuard Home";
url = "http://${net.hosts.pi5.lan}:${toString net.ports.pi5.adguard}/";
icon = "si:adguard";
allow-insecure = true;
}
{
title = "Home Assistant";
url = "https://hass.mjallen.dev/";
icon = "si:homeassistant";
}
{
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:nanokvm";
allow-insecure = true;
}
{
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}";
};
}
{
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}";
};
}
{
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}";
};
}
# {
# title = "";
# url = "";
# icon = "si:";
# }
];
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;
url = site.url;
icon = site.icon;
}
// optionalAttrs site.allow-insecure { allow-insecure = true; }
) cfg.extraSites;
}
{
type = "bookmarks";
# tab = "First";
groups = [
{
title = "General";
@@ -255,25 +344,6 @@ let
}
];
}
# {
# name = "test";
# width = "default";
# hide-desktop-navigation = true;
# center-vertically = true;
# columns = [
# {
# size = "small";
# widgets = [
# {
# type = "adguard";
# url = "http://pi4.local:3000";
# username = "mjallen";
# password = "BogieDudie1";
# }
# ];
# }
# ];
# }
];
};
};
@@ -284,7 +354,6 @@ in
imports = [
glanceConfig
# Sops env-file for arr credentials (gated behind glance.enable)
{
config = lib.mkIf cfg.enable (
lib.${namespace}.mkSopsEnvFile {

View File

@@ -8,7 +8,6 @@ with lib;
let
name = "kavita";
cfg = config.${namespace}.services.${name};
rootUrl = "https://kavita.${namespace}.dev/";
kavitaConfig = lib.${namespace}.mkModule {
inherit config name;

View File

@@ -1,5 +1,5 @@
{ ... }:
final: prev: {
_final: prev: {
home-assistant = prev.home-assistant.override {
packageOverrides = _self: super: {
psnawp = super.psnawp.overridePythonAttrs (old: {