hub(D53): held apps reach the operator — mirror, Held apps list (host + Hosts page), reminder after the grace
gates / gates (push) Successful in 1m58s
gates / gates (push) Successful in 1m58s
app_held / app_hold_cleared allow-listed and operator-only; handleEvent mirrors them in held_apps; HeldAppsChecker sends ONE app_held_reminder (warning, operator-only, per-app cooldown) after the grace per reason (6 h / 1 d / 3 d), then weekly; recorded before sending; stale rows not reminded; the hub never clears a hold. Test-only alerting.held_app_grace_override. TestD53_* in api/monitor/notify/web, red-proved by six mutations. Commit only.
This commit is contained in:
1 parent
ecd82abab8
commit
7e57e824a2
27 files changed
+935
-2
No files matched your search
@@ -72,6 +72,9 @@ type Config struct {
|
||||
// the host-root thresholds above so a single storage's policy can be tuned separately.
|
||||
StorageFillWarnPercent float64 `yaml:"storage_fill_warn_percent"`
|
||||
StorageFillCritPercent float64 `yaml:"storage_fill_crit_percent"`
|
||||
// HeldAppGraceOverride (D53) replaces every reason's reminder grace when set (a Go duration, e.g. "3m"). A TEST
|
||||
// configuration only — the live proof shortens the wait; production leaves it empty (`08` §10's per-reason grace).
|
||||
HeldAppGraceOverride string `yaml:"held_app_grace_override"`
|
||||
// Offsite POOL-BOX aggregate thresholds (v0.64.0, R-5). Fill = box used vs capacity (percent);
|
||||
// oversub = Σ(shared soft quotas)/capacity (ratio). Empty/0/invalid → defaults 80/90/2.0 (the
|
||||
// checker normalizes). Threshold VALUES are Claude's encoding of the starter suggestion — Viktor's
|
||||
@@ -899,6 +902,16 @@ func main() {
|
||||
// durable (events table), so a hub restart neither floods nor silently re-heals.
|
||||
// R-523: the agent's in-guest controller supervisor → controller_restarted_by_agent / controller_crashloop.
|
||||
controllerSupervisorChecker := monitor.NewControllerSupervisorChecker(dataStore, dispatcher.ProcessEvent, logger)
|
||||
// D53 (`08` §10): a held app reaches the OPERATOR — one reminder after the grace per reason, then weekly.
|
||||
var heldGrace time.Duration
|
||||
if v := cfg.Alerting.HeldAppGraceOverride; v != "" {
|
||||
if d, err := time.ParseDuration(v); err == nil && d > 0 {
|
||||
heldGrace = d
|
||||
} else {
|
||||
logger.Printf("[WARN] alerting.held_app_grace_override %q is not a positive duration — ignored", v)
|
||||
}
|
||||
}
|
||||
heldAppsChecker := monitor.NewHeldAppsChecker(dataStore, heldGrace, dispatcher.ProcessEvent, logger)
|
||||
offsiteDeliveryChecker := monitor.NewOffsiteDeliveryChecker(dataStore, offsiteHealReissuer, dispatcher.ProcessEvent, logger)
|
||||
// R-242 second half (S4, decision 199): published golden vs vouched golden. Needs the registry creds
|
||||
// (the same Gitea client as the Day-0 dropdowns); without them the check is off and says so.
|
||||
@@ -931,6 +944,7 @@ func main() {
|
||||
restoreTestChecker.Check() // R-85: restore-test failure + per-tier staleness
|
||||
offsiteDeliveryChecker.Check()
|
||||
controllerSupervisorChecker.Check()
|
||||
heldAppsChecker.Check() // D53: throttled to one pass per 15 min
|
||||
if goldenVouchChecker != nil {
|
||||
goldenVouchChecker.Check() // R-242: throttled to one Gitea listing per 15 min
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user