diff options
| author | Akshay Nair <phenax5@gmail.com> | 2025-06-10 13:06:48 +0530 |
|---|---|---|
| committer | Akshay Nair <phenax5@gmail.com> | 2025-06-10 18:58:25 +0530 |
| commit | 2a73a5899124fa15c3962b9bd385ebd415a0ccf9 (patch) | |
| tree | 3b0c29a29cf9ef4c844afc90aafcd61ef8122d21 | |
| parent | 279241632b566fd26011409672277ca02ed697d1 (diff) | |
| download | homeserver-nixos-config-2a73a5899124fa15c3962b9bd385ebd415a0ccf9.tar.gz homeserver-nixos-config-2a73a5899124fa15c3962b9bd385ebd415a0ccf9.zip | |
Add dashboard for linking services
| -rw-r--r-- | .gitignore | 3 | ||||
| -rwxr-xr-x | build.sh | 18 | ||||
| -rw-r--r-- | configuration.nix | 7 | ||||
| -rw-r--r-- | modules/dashboard/bacchus-dashboard.service.nix | 46 | ||||
| -rw-r--r-- | modules/dashboard/dashboard-template.nix | 114 | ||||
| -rw-r--r-- | modules/dashboard/default.nix | 40 | ||||
| -rw-r--r-- | notes.org | 5 | ||||
| -rw-r--r-- | scripts/init.sh | 8 |
8 files changed, 222 insertions, 19 deletions
@@ -1 +1,2 @@ -*.private.nix +*.private.* +*.ignore.* @@ -5,16 +5,16 @@ getconfig() { nix eval --impure --expr "(import ./settings.nix { lib = (import <nixpkgs> {}).lib; })$@" | jq -r } -SSH_HOST="$(getconfig .network.host)" +HOME_HOST="$(getconfig .network.host)" SSH_PORT="$(getconfig .network.ports.ssh)" -SSH_TARGET="bacchus@$SSH_HOST" +SSH_TARGET="bacchus@$HOME_HOST" SCRIPT_PATH="$(readlink -f "$0")" run_ssh() { ssh -t "$SSH_TARGET" -p "$SSH_PORT" "$@"; } copy() { rsync -ravh --delete --exclude '.git' -e "ssh -p $SSH_PORT" "$@"; } waittostart() { echo "Waiting..."; - until timeout 2 nc -z "$SSH_HOST" "$SSH_PORT" 2> /dev/null; do + until timeout 2 nc -z "$HOME_HOST" "$SSH_PORT" 2> /dev/null; do echo -n '.'; sleep 1 done; @@ -39,6 +39,13 @@ chaincmds() { done } +gen_test_dash() { + nix eval --impure \ + --expr 'import ./modules/dashboard/dashboard-template.nix { title = "Dashboard"; links = [{ title = "Google"; url = "https://google.com"; key = "g"; } { title = "DuckDuckGo"; url = "https://duckduckgo.com"; key = "d"; color = "#4c82cf"; }]; }' \ + | jq -r > index.ignore.html +} +open_test_dash() { brave "file://$PWD/index.ignore.html"; } + cmd="$1"; shift; case "$cmd" in sync) config_sync ;; @@ -49,7 +56,10 @@ case "$cmd" in clean) run_ssh sudo nix-collect-garbage -d ;; top) run_ssh btm ;; fs) run_ssh lf ;; + test-dash) gen_test_dash ;; + open-test-dash) open_test_dash ;; + dash) brave "http://$HOME_HOST" ;; _) chaincmds "$@" ;; - *) echo "Invalid cmd: $1" && exit 1 ;; + *) echo "Invalid cmd: $cmd" && exit 1 ;; esac diff --git a/configuration.nix b/configuration.nix index 9d1b067..45b34ab 100644 --- a/configuration.nix +++ b/configuration.nix @@ -2,14 +2,15 @@ # your system. Help is available in the configuration.nix(5) man page # and in the NixOS manual (accessible by running ‘nixos-help’). -{ config, pkgs, ... }: +{ pkgs, ... }: { imports = [ ./modules/hardware.nix ./modules/users.nix - ./modules/network/default.nix - ./modules/media/default.nix + ./modules/network + ./modules/media + ./modules/dashboard ]; nixpkgs.config.allowUnfree = true; diff --git a/modules/dashboard/bacchus-dashboard.service.nix b/modules/dashboard/bacchus-dashboard.service.nix new file mode 100644 index 0000000..c14111b --- /dev/null +++ b/modules/dashboard/bacchus-dashboard.service.nix @@ -0,0 +1,46 @@ +{ config, lib, pkgs, ... }: +with lib; +let + cfg = config.services.bacchus-dashboard; + + rootHTML = import ./dashboard-template.nix cfg; + indexHTMLFile = pkgs.writeText "index.html" rootHTML; + + pageDir = pkgs.stdenv.mkDerivation { + pname = "dashboard-page"; + version = "0.0.0"; + unpackPhase = "true"; # no source + installPhase = '' + mkdir -p $out; + cp ${indexHTMLFile} $out/index.html; + ''; + }; +in +{ + options.services.bacchus-dashboard = { + enable = mkEnableOption "Enable dashboard"; + title = mkOption { type = types.str; default = "Dashboard"; }; + links = mkOption { + type = types.listOf (types.attrs); + default = []; + }; + openFirewall = mkEnableOption "Open firewall ports"; + host = mkOption { type = types.str; default = "_"; }; + port = mkOption { type = types.int; default = 80; }; + }; + + config = { + services.nginx = mkIf cfg.enable { + enable = true; + virtualHosts."${cfg.host}" = { + listen = [ { addr = toString cfg.port; } ]; + locations."/" = { + root = pageDir; + tryFiles = "$uri /index.html"; + }; + }; + }; + + networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall [ 80 ]; + }; +} diff --git a/modules/dashboard/dashboard-template.nix b/modules/dashboard/dashboard-template.nix new file mode 100644 index 0000000..a1df813 --- /dev/null +++ b/modules/dashboard/dashboard-template.nix @@ -0,0 +1,114 @@ +{ title, links, ... }: +with builtins; +let + withLinkAttr = link: attr: def: value: + if hasAttr attr link then value else def; + + linkHTML = link: '' + <div> + <a href="${link.url}" class="card" style="${withLinkAttr link "color" "" "--color-card-accent: ${link.color}"}"> + ${link.title} ${if hasAttr "key" link then "(${link.key})" else ""} + <div class="card-link">${link.url}</div> + </a> + </div> + ''; + + script = '' + window.addEventListener('keydown', (event) => { + const noMod = !event.ctrlKey && !event.altKey; + ${concatStringsSep "\n" (map (link: + withLinkAttr link "key" "" '' + if (event.key.toLowerCase() == ${toJSON link.key} && noMod) { + event.preventDefault(); + if (event.shiftKey) + window.open(${toJSON link.url}); + else + window.location.href = ${toJSON link.url}; + return; + } + '' + ) links)} + }); + ''; + + styles = '' + :root { + font-size: 16px; + color: #dbe0f9; + font-family: JetBrains Mono, monospace; + } + html, body { + background-color: #0f0c19; + padding: 0; + margin: 0; + } + body * { box-sizing: border-box; } + header { + padding: 1rem 2rem; + background-color: #000; + } + .links-container { + display: grid; + gap: 1rem; + grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); + padding: 0 1rem; + width: 100%; + margin: 1rem auto; + max-width: 1200px + } + .card { + --color-card-accent: #8e7ae3; + display: block; + padding: 1rem 1.5rem; + font-size: 1.2rem; + color: var(--color-card-accent); + text-decoration: none; + border: 2px solid #1a1824; + position: relative; + } + .card::before { + content: " "; + position: absolute; + left: 0; top: 0; + width: 4px; height: 100%; + background-color: var(--color-card-accent); + } + .card:hover { + border-color: var(--color-card-accent); + background-color: rgba(255,255,255,0.05); + } + .card:focus { + border-color: var(--color-card-accent); + outline: none; + } + .card-link { + font-size: 0.5em; + padding-top: 1em; + color: gray; + } + ''; + + headerHTML = '' + <header> + ${title} + </header> + ''; +in +'' +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <title>${title}</title> + <style>${styles}</style> + </head> + <body> + ${headerHTML} + <section class="links-container"> + ${concatStringsSep "" (map linkHTML links)} + </section> + <script>${script}</script> + </body> +</html> +'' diff --git a/modules/dashboard/default.nix b/modules/dashboard/default.nix new file mode 100644 index 0000000..54db0d9 --- /dev/null +++ b/modules/dashboard/default.nix @@ -0,0 +1,40 @@ +{ lib, ... }: +let + settings = import ../../settings.nix { inherit lib; }; + ports = settings.network.ports; +in +{ + imports = [ ./bacchus-dashboard.service.nix ]; + + services.bacchus-dashboard = { + enable = true; + openFirewall = true; + title = "Dashboard"; + links = [ + { + title = "Jellyfin"; + key = "j"; + url = "http://${settings.network.host}:${toString ports.jellyfin}"; + color = "#AA5CC3"; + } + { + title = "Sonarr"; + key = "s"; + url = "http://${settings.network.host}:${toString ports.sonarr}"; + color = "#4c82cf"; + } + { + title = "Radarr"; + key = "r"; + url = "http://${settings.network.host}:${toString ports.radarr}"; + color = "#fcbd00"; + } + { + title = "Prowlarr"; + key = "p"; + url = "http://${settings.network.host}:${toString ports.prowlarr}"; + color = "#ff9a7e"; + } + ]; + }; +} @@ -1,14 +1,13 @@ ** Current -- [ ] Home dashboard ([[https://github.com/tariqbuilds/linux-dash]]) -- [ ] Make autoconnect via networkmanager work consistently (higher frequency) - [ ] DNS server (dnsmasq, bind, octodns, nsd, [[https://github.com/nix-community/dns.nix]]) +- [ ] Syncthing ** Later -- [ ] Syncthing - [ ] Jellyfin library for photos (shared/private) - [ ] NAS - [ ] [[https://ntfy.sh]] - [ ] Think of where to place the server +- [ ] Make autoconnect via networkmanager work consistently (higher frequency) ** Maybe - [ ] Git bare repos (pass/notes) diff --git a/scripts/init.sh b/scripts/init.sh deleted file mode 100644 index a0e1eab..0000000 --- a/scripts/init.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env sh -set -euo pipefail - -sudo chown -R bacchus:multimedia /media -sudo chown -R sonarr:multimedia /media/tv -sudo chown -R radarr:multimedia /media/movies -sudo chown -R transmission:multimedia /media/_downloads - |
