fix(maintenance): a late return, once back, stays back, and every reader agrees (#6175)
18032a4 re-checked a "not back in service" job every minute with no end,
so any later swarm wobble on the host (radarr's failed task during the
downloads move, say) flipped maintenance_failed back to 1: five false
firings and ten emails for Docker02 overnight on 10-19. And the overview's
finding never learned the rule at all, so it still said Docker02's
maintenance failed three days on.
The job now keeps came_back_at, set the first time its host is found back.
maintenance.still_failed(job) is the one answer: the figure, the overview,
the cadence page's run rows and the host panel all ask it. A failed update
or a timed-out job still flags its host until a job succeeds.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -37,6 +37,10 @@ from datetime import datetime, timedelta, timezone
|
||||
ACTIVE = ("queued", "checking", "draining", "settling", "updating", "rebooting",
|
||||
"undraining", "recovering")
|
||||
FINISHED = ("done", "failed", "timed_out")
|
||||
# How a job failed for not coming back into service begins (cadence.py): its
|
||||
# update (and reboot) went through, so once the host is back nothing is left
|
||||
# failed.
|
||||
NOT_BACK = "not back in service within"
|
||||
# The helper action each handed state asks for.
|
||||
STEP_ACTION = {"checking": "check", "updating": "update", "draining": "drain",
|
||||
"rebooting": "reboot", "undraining": "undrain"}
|
||||
@@ -537,10 +541,26 @@ LABELS = {
|
||||
}
|
||||
|
||||
|
||||
def came_back_late(job) -> bool:
|
||||
"""A job failed only for not coming back into service in time, whose
|
||||
host has since been found back (#6175)."""
|
||||
return (job.state == "failed" and job.came_back_at is not None
|
||||
and (job.detail or "").startswith(NOT_BACK))
|
||||
|
||||
|
||||
def still_failed(job) -> bool:
|
||||
"""Whether a finished job still flags its host: it failed or timed out,
|
||||
and isn't a late return whose host has since come back (#6175). The
|
||||
maintenance_failed figure, the overview and the pages all ask this."""
|
||||
return job.state in ("failed", "timed_out") and not came_back_late(job)
|
||||
|
||||
|
||||
def summary(job) -> str:
|
||||
"""One line on what the job did, for the panel."""
|
||||
if job.state not in FINISHED:
|
||||
return LABELS[job.state]
|
||||
if came_back_late(job):
|
||||
return f"Back in service late, {job.came_back_at:%Y-%m-%d %H:%M}Z"
|
||||
parts = []
|
||||
if job.docker_update:
|
||||
parts.append("Docker upgraded")
|
||||
|
||||
Reference in New Issue
Block a user