feat(uptimekuma): normalize names off Homepage, publish the status page, restore the widget

NAMES. Homepage already answers "what is this service called", so the monitor
name is now that name verbatim -- a second naming authority is how drift starts,
and an alert reading "[Uptime Kuma] Beszel hub is DOWN" sends you hunting for a
card that does not exist. Only two rows moved (Beszel hub -> Beszel, Dozzle hub
-> Dozzle); the " hub" suffixes were mine, not the services'.

The remaining mixed case is deliberate and is now documented as such. talk, vor
and task-board are lowercase on Homepage and in their own repos; title-casing
them here would make this board disagree with both. What actually looked messy
was scripts/kuma's own ASCII-ordinal sort, which buried every lowercase name
below every capitalised one. Fixed to case-insensitive.

⚠ RENAME SAFETY, which this pass needed and did not have. The seed keys on NAME,
so editing a name would have read as a brand-new monitor: added fresh, with the
old row orphaned, still checking, still alerting, and holding all the history.
`rename_from:` names the old row for one run. Verified: both renamed monitors
kept their IDs and all 67 heartbeats.

Added with it, an orphan warning for any row on the board the spec no longer
names -- because a forgotten monitor keeps paging. Its first cut diffed against
the PRE-EDIT snapshot and so cried wolf on its own successful renames; it
re-reads the board now. A warning that fires on its own correct work is worse
than no warning.

STATUS PAGE + WIDGET. The Homepage uptimekuma widget reads a PUBLISHED status
page (/api/status-page/<slug>), not the admin API -- which is why the widget
labels were deliberately absent from the rebuild: a dashboard widget pointed at
a 404 is the suspected mechanism behind both of Homepage's unkillable D-state
wedges, so shipping one on purpose would have been daft.

The page now exists at slug `nethealth` (the pre-rebuild slug, so old references
still resolve) and is DECLARED IN monitors.yaml, applied by `kuma seed`. Same
principle as the notification channel: a from-scratch rebuild restores the page,
the channel and the monitors together, and nothing the widget depends on lives
only in Kuma's database. Verified in a browser: "13 SITES UP / 0 SITES DOWN /
100% UPTIME" on the dashboard.

⚠ saveStatusPage calls imgDataUrl.startsWith() unconditionally, so passing null
throws and leaves the page CREATED BUT EMPTY -- which reads as success from
/api/status-page (200, correct title) while the group list is silently blank.
Pass "" instead. Commented at the call site.
This commit is contained in:
vh
2026-09-22 00:55:29 -07:00
parent 95ab344990
commit 94899d6fa3
3 changed files with 136 additions and 16 deletions
+14 -7
View File
@@ -66,13 +66,20 @@ services:
- homepage.description=Service monitoring (fleet)
- homepage.href=http://10.250.50.70:3001
- homepage.siteMonitor=http://10.250.50.70:3001
# ⚠️ NO `homepage.widget.*` LABELS YET, deliberately. The widget needs a
# published status-page slug; on a from-scratch install none exists, so
# the widget would poll a 404 forever. That matters more than usual
# here: homepage widgets pointed at dead targets are the suspected
# mechanism behind BOTH of this dashboard's unkillable D-state wedges
# (see incident_esh_docker_nfs_boot_race, 2026-06-03). Re-add the widget
# labels only once the status page actually exists.
# The widget reads a PUBLISHED status page, not the admin API:
# /api/status-page/<slug> and /api/status-page/heartbeat/<slug>. These
# labels were deliberately absent from the 2026-09-21 rebuild until that
# page existed, because a dashboard widget pointed at a 404 is the
# suspected mechanism behind BOTH of Homepage's unkillable D-state wedges
# (incident_esh_docker_nfs_boot_race, 2026-06-03) -- shipping one on
# purpose would have been daft.
#
# The page is defined in monitors.yaml (`status_page:`) and applied by
# `scripts/kuma seed`, so a from-scratch rebuild restores the slug this
# points at. Slug `nethealth` is the one the pre-rebuild instance used.
- homepage.widget.type=uptimekuma
- homepage.widget.url=http://10.250.50.70:3001
- homepage.widget.slug=nethealth
networks:
- tnet
+24 -2
View File
@@ -13,6 +13,16 @@
# (Beszel's lane: 18 hosts x Status/CPU/Memory/Disk/Temp), and Uptime
# Kuma itself (it cannot report its own death — that is Beszel's job).
#
# NAMES COME FROM HOMEPAGE, VERBATIM. Homepage already answers "what is this
# service called", and a second naming authority is how drift starts: an alert
# reading "[Uptime Kuma] Beszel hub is DOWN" sends you looking for a card called
# "Beszel hub" that does not exist. So the monitor name IS the dashboard name --
# which is why this normalisation pass only moved two rows. The remaining mixed
# case (talk, vor, task-board against Gitea, Backrest) is NOT an inconsistency to
# fix: those are the products' own names, lowercase on Homepage and lowercase in
# their own repos. Title-casing them here would make this board disagree with
# both. `rename_from` exists for exactly this operation -- see scripts/kuma.
#
# Every URL below was probed before being written here: all returned 200 on
# 2026-09-21. A seed that ships red on day one teaches everyone to ignore the
# board, which is how you end up with a monitor nobody reads.
@@ -30,6 +40,18 @@
# Route: Kuma -> althing-alert-bridge (/kuma) -> postbox -> infra-ops inbox.
# Same path Beszel uses, different route, so the subject says which tool spoke:
# "[Uptime Kuma] Homepage is DOWN" rather than a Beszel-labelled lie.
# ---- the published status page -----------------------------------------------
# Exists so Homepage's `uptimekuma` widget has something to read: it calls
# /api/status-page/<slug> and /api/status-page/heartbeat/<slug>, and without a
# published page at that slug it polls a 404 forever. The widget labels on
# stacks/uptimekuma/compose.yaml were deliberately held back until this existed.
# Slug kept as `nethealth` -- the same one the pre-rebuild instance used, so any
# bookmark or older reference still resolves.
status_page:
slug: nethealth
title: PFI fleet services
group: Services
notifications:
- name: althing (infra-ops)
webhookURL: http://10.100.10.50:8096/kuma
@@ -78,7 +100,7 @@ monitors:
description: fleet voice bench
# ---- monitoring + backup: a blind monitor is worse than none ----
- name: Beszel hub
- name: Beszel
url: http://10.250.50.70:8090
description: the host layer; if this is down we are blind to 18 hosts
@@ -86,5 +108,5 @@ monitors:
url: http://10.250.50.70:9898
description: restic orchestration — a silent backup failure is the expensive kind
- name: Dozzle hub
- name: Dozzle
url: http://10.250.50.70:8088