fix(host_agent): a node the operator keeps drained stays drained through its maintenance (#5777)
#5777 "Maintenance would make a node the operator keeps drained active after its reboot". A swarm node already set to drain or pause, such as a manager kept free of work, is no longer drained before its reboot or made active after it. Its job only updates and reboots it, and back-in-service needs it ready but not active. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -74,19 +74,21 @@ def is_due(plan, now: datetime) -> datetime | None:
|
||||
return slot
|
||||
|
||||
|
||||
def back_in_service(*, last_seen_at, node, services, job_finished_at, now: datetime) -> str | None:
|
||||
def back_in_service(*, last_seen_at, node, services, job_finished_at, now: datetime,
|
||||
expect_active: bool = True) -> str | None:
|
||||
"""None when the host is back in service, else why not yet. `node` is the
|
||||
freshest swarm-node row for the job's node (None outside a swarm, or when
|
||||
the job has no node); `services` the freshest row per swarm service. Only
|
||||
rows reported after the job finished count, so a stale "all fine" from
|
||||
before the reboot never passes."""
|
||||
before the reboot never passes. `expect_active` is False for a node the
|
||||
job didn't drain (the operator keeps it drained): it need only be ready."""
|
||||
if last_seen_at is None or now - last_seen_at > POSTING_WITHIN:
|
||||
return "its agent isn't posting yet"
|
||||
if node is None:
|
||||
return None
|
||||
if node.updated_at < job_finished_at:
|
||||
return "no swarm report since it came back"
|
||||
if node.status != "ready" or node.availability != "active":
|
||||
if node.status != "ready" or (expect_active and node.availability != "active"):
|
||||
return f"its swarm node is {node.status}/{node.availability}"
|
||||
fresh = [s for s in services if s.updated_at >= job_finished_at]
|
||||
if not fresh:
|
||||
@@ -184,7 +186,8 @@ async def _back(session, host, job, reg, now: datetime) -> str | None:
|
||||
freshest[s.service_name] = s
|
||||
services = list(freshest.values())
|
||||
return back_in_service(last_seen_at=reg.last_seen_at if reg else None, node=node,
|
||||
services=services, job_finished_at=job.finished_at or now, now=now)
|
||||
services=services, job_finished_at=job.finished_at or now, now=now,
|
||||
expect_active=bool(job.drain_host_id))
|
||||
|
||||
|
||||
async def advance(session, run, plan, now: datetime) -> str:
|
||||
|
||||
Reference in New Issue
Block a user