Add Last Update widget to Homepage via record-update script

record-update parses nvd diff after switch and writes latest.json;
Homepage polls a local-only nginx listener and renders date/changes/
closure/kernel via a customapi widget.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
ediblerope 2026-04-16 20:58:19 +01:00
parent 916c1d1c2d
commit f57c6e99ec
5 changed files with 76 additions and 1 deletions

View file

@ -74,7 +74,7 @@
# Shell aliases (work in both bash and fish) # Shell aliases (work in both bash and fish)
environment.shellAliases = { environment.shellAliases = {
update = "bash -c 'OLD_SYSTEM=$(readlink /run/current-system) && sudo nixos-rebuild build $@ --flake github:ediblerope/nixos-config && sudo nixos-rebuild switch $@ --flake github:ediblerope/nixos-config && nvd diff $OLD_SYSTEM /run/current-system && command -v matugen &>/dev/null && matugen image ~/.local/share/backgrounds/wallpaper.png --source-color-index 0 -m dark || true' --"; update = "bash -c 'OLD_SYSTEM=$(readlink /run/current-system) && sudo nixos-rebuild build $@ --flake github:ediblerope/nixos-config && sudo nixos-rebuild switch $@ --flake github:ediblerope/nixos-config && nvd diff $OLD_SYSTEM /run/current-system && (command -v record-update &>/dev/null && record-update $OLD_SYSTEM /run/current-system || true) && command -v matugen &>/dev/null && matugen image ~/.local/share/backgrounds/wallpaper.png --source-color-index 0 -m dark || true' --";
clean = "sudo nix-collect-garbage -d"; clean = "sudo nix-collect-garbage -d";
ll = "ls -alh"; ll = "ls -alh";
clear = "command clear"; clear = "command clear";

View file

@ -22,6 +22,10 @@
export PATH="${pkgs.jellyfin-ffmpeg}/bin:${pkgs.coreutils}/bin:${pkgs.findutils}/bin:${pkgs.gnugrep}/bin:${pkgs.gawk}/bin:${pkgs.bc}/bin:${pkgs.curl}/bin:$PATH" export PATH="${pkgs.jellyfin-ffmpeg}/bin:${pkgs.coreutils}/bin:${pkgs.findutils}/bin:${pkgs.gnugrep}/bin:${pkgs.gawk}/bin:${pkgs.bc}/bin:${pkgs.curl}/bin:$PATH"
exec ${pkgs.bash}/bin/bash ${../scripts/transcode-hevc.sh} "$@" exec ${pkgs.bash}/bin/bash ${../scripts/transcode-hevc.sh} "$@"
'') '')
(pkgs.writeShellScriptBin "record-update" ''
export PATH="${pkgs.nvd}/bin:${pkgs.coreutils}/bin:${pkgs.gnugrep}/bin:${pkgs.gnused}/bin:$PATH"
exec ${pkgs.bash}/bin/bash ${../scripts/record-update.sh} "$@"
'')
]; ];
# Basic networking # Basic networking

41
scripts/record-update.sh Normal file
View file

@ -0,0 +1,41 @@
#!/usr/bin/env bash
# Parse `nvd diff <old> <new>` output and write a JSON summary
# consumed by the Homepage dashboard's customapi widget.
set -euo pipefail
OLD="${1:-}"
NEW="${2:-/run/current-system}"
OUT_DIR="/var/lib/homepage-updates"
OUT_FILE="$OUT_DIR/latest.json"
if [ -z "$OLD" ]; then
echo "usage: record-update <old-system> [new-system]" >&2
exit 1
fi
mkdir -p "$OUT_DIR"
DIFF=$(nvd diff "$OLD" "$NEW" 2>&1 || true)
CHANGES=$(printf '%s\n' "$DIFF" | grep -cE '^\[[UAR][.*]\]' || true)
CLOSURE=$(printf '%s\n' "$DIFF" | grep -oE 'disk usage [+-][0-9.]+[A-Za-z]*B?' | head -1 | sed 's/disk usage //')
CLOSURE="${CLOSURE:-+0B}"
KERNEL=$(uname -r)
DATE=$(date '+%Y-%m-%d %H:%M')
if [ "$CHANGES" = "0" ]; then
LABEL="No changes"
else
LABEL="$CHANGES package changes"
fi
cat > "$OUT_FILE.tmp" <<EOF
{
"date": "$DATE",
"changes": "$LABEL",
"closure": "$CLOSURE",
"kernel": "$KERNEL"
}
EOF
mv "$OUT_FILE.tmp" "$OUT_FILE"

View file

@ -65,6 +65,7 @@ in
systemd.tmpfiles.rules = [ systemd.tmpfiles.rules = [
"d /var/lib/homepage-custom-css 0755 fred users -" "d /var/lib/homepage-custom-css 0755 fred users -"
"f /var/lib/homepage-custom-css/custom.css 0644 fred users -" "f /var/lib/homepage-custom-css/custom.css 0644 fred users -"
"d /var/lib/homepage-updates 0755 fred users -"
]; ];
systemd.services.homepage-dashboard.serviceConfig.BindPaths = [ systemd.services.homepage-dashboard.serviceConfig.BindPaths = [
@ -257,6 +258,25 @@ in
icon = "go2rtc.png"; icon = "go2rtc.png";
}; };
} }
{
"Last Update" = {
description = "Most recent nixos-rebuild switch";
icon = "mdi-history";
widget = {
type = "customapi";
url = "http://127.0.0.1:8083/latest.json";
refreshInterval = 60000;
method = "GET";
display = "list";
mappings = [
{ field = "date"; label = "Date"; }
{ field = "changes"; label = "Changes"; }
{ field = "closure"; label = "Closure"; }
{ field = "kernel"; label = "Kernel"; }
];
};
};
}
]; ];
} }
]; ];

View file

@ -107,6 +107,16 @@ in
# --- Protected by Authelia --- # --- Protected by Authelia ---
"camera.nordhammer.it" = protectedProxy 1984; "camera.nordhammer.it" = protectedProxy 1984;
"homepage.nordhammer.it" = protectedProxy 8082; "homepage.nordhammer.it" = protectedProxy 8082;
# --- Local-only: serves update history JSON to Homepage's customapi widget ---
"homepage-updates.local" = {
listen = [ { addr = "127.0.0.1"; port = 8083; } ];
locations."/".root = "/var/lib/homepage-updates";
extraConfig = ''
default_type application/json;
add_header Access-Control-Allow-Origin *;
'';
};
}; };
}; };