v0.342.0 (unreleased): the upload and CPU watch — an app that sends or burns far more than its own numbers explain is one operator-only alarm; the line learnt from the off-site push; qBittorrent's default upload limit (never over the household's)
gates / gates (push) Successful in 1m17s

internal/upwatch: exact per-container counters from the Docker Engine API, per-app judging (upload >= max(5 Mbit/s,
25% of the line) for 15 min; CPU >= max(150%, 50% x cores) for 30 min), explainers qBittorrent / Transmission / Plex,
app_unexplained_upload / app_unexplained_cpu + _cleared (hub 0.169.0). The off-site push is sampled once a second
for the line (a lower bound). qBittorrent limit = 50% of the line, the household's limit always wins. 20 red-proofs.
Spike + design: felhom.eu audits/SPIKE-upload-watch-2026-10-23.md, architecture/08 section 9. Not released.
This commit is contained in:
2026-10-23 21:26:09 +02:00
parent 277e99839d
commit a9c1997fbc
35 changed files with 2438 additions and 0 deletions
+7
View File
@@ -36,9 +36,12 @@ import (
"gitea.dooplex.hu/admin/felhom-controller/internal/settings"
"gitea.dooplex.hu/admin/felhom-controller/internal/stacks"
"gitea.dooplex.hu/admin/felhom-controller/internal/system"
"gitea.dooplex.hu/admin/felhom-controller/internal/upwatch"
)
type Server struct {
// upwatchView (SetUpwatchView) feeds the two upload-watch lines; nil = not shown.
upwatchView func() upwatch.View
// R-871: the missed-backup banner's inputs (SetMissedBackupBanner); nil = no banner.
nightLedger *nightchain.Ledger
metricsRecord *metrics.MetricsStore
@@ -515,6 +518,10 @@ func (s *Server) addShellAssetData(data map[string]interface{}) {
// so a cache that already held the first build's stylesheet kept serving it — measured through
// Cloudflare (`audits/app-page-2026-10-15b/P0/VERDICT.md`). build.sh now refuses a second push of a
// version, and this makes the asset URL change even when the version does not.
// SetUpwatchView hands the pages the upload watch's state (internal/upwatch): the measured line and the qBittorrent
// limit the box set. Nil = neither line is shown.
func (s *Server) SetUpwatchView(fn func() upwatch.View) { s.upwatchView = fn }
func (s *Server) SetBuildIdentity(gitCommit, buildTime string) {
s.buildID = gitCommit + "/" + buildTime
}