controller v0.265.0: R-634 cause fixed, held apps say so, OOM storm alarm, R-647 leftovers
gates / gates (push) Successful in 27s

R-634: a whole-box backup no longer stops/restarts a DEPLOYING app (the
measured cause of containers running under 'not deployed'); StopStack
and StartStack refuse a deploying stack for every caller.
R-625: held badge 'Stopped - restore needed', no Update button.
R-636: kernel oom_kill counter; 20+ in 30 min -> one app_oom_storm.
R-647: held error per reader, copy_holds key, two log wordings.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
2026-09-23 17:16:57 +02:00
parent 0a3026180a
commit 0054d4bd69
28 changed files with 832 additions and 48 deletions
+6 -13
View File
@@ -19,7 +19,6 @@ import (
"gitea.dooplex.hu/admin/felhom-controller/internal/backup"
cf "gitea.dooplex.hu/admin/felhom-controller/internal/cloudflare"
"gitea.dooplex.hu/admin/felhom-controller/internal/config"
"gitea.dooplex.hu/admin/felhom-controller/internal/i18n"
"gitea.dooplex.hu/admin/felhom-controller/internal/integrations"
"gitea.dooplex.hu/admin/felhom-controller/internal/metrics"
"gitea.dooplex.hu/admin/felhom-controller/internal/notify"
@@ -383,18 +382,12 @@ func (r *Router) getStack(w http.ResponseWriter, req *http.Request, name string)
// v0.264.0 (R-606): the page polls this for the Update button's label and the outcome. Rendered in
// the reader's language; a Hungarian reader gets exactly the bytes it always got. GetStack returns a
// COPY, so nothing here touches the manager's own state.
if lang := r.langFor(req); lang != i18n.Default {
stack.UpdatePhaseLabel = stacks.UpdatePhaseLabelIn(lang, stack.UpdatePhase)
stack.UpdateError = stack.UpdateErrorIn(lang)
if stack.HoldReason != "" && r.backupMgr != nil {
if held, why := r.backupMgr.RestoreHoldForLang(name, lang); held && why != "" {
stack.HoldReason = why
if stack.UpdateErrorKey == "" && stack.UpdatePhase == stacks.UpdatePhaseFailed {
stack.UpdateError = why // a held update's UpdateError IS the hold sentence
}
}
}
}
// v0.265.0 (R-647): EVERY reader, Hungarian included — a Hungarian reader of an English box read
// the hold in English before. On a Hungarian box a Hungarian reader still gets the same bytes.
lang := r.langFor(req)
stack.UpdatePhaseLabel = stacks.UpdatePhaseLabelIn(lang, stack.UpdatePhase)
stack.UpdateError = r.stackMgr.UpdateErrorFor(*stack, lang)
stack.HoldReason = r.stackMgr.HoldReasonFor(*stack, lang)
writeJSON(w, http.StatusOK, apiResponse{OK: true, Data: stack})
}