fix(maintenance): check first, drain before a Docker upgrade, wait 5 min after a drain, see containers back (#6098)
On 2026-10-18 an update on VDNT-Docker02 restarted the Docker daemon six seconds in, before the drain that came only with the reboot, and every container on the node stopped. Docker's own packages restart the daemon from their install scripts; needrestart's list-only mode doesn't stop that. - The helper gains a `check` action (agent 1.24.0): a dry run of the update for each package manager, whether Docker is among it, and the running containers outside the swarm with their restart policies. - A swarm node is drained before an update that upgrades Docker, else only before a reboot, and at most once a job. - After a drain the job settles 5 minutes before the update or reboot. - Once the work is over, the containers that ran outside the swarm must be seen running again within 10 minutes, or the job fails naming them. - An older agent gets no check and its job runs as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -22,7 +22,7 @@ from collections import deque
|
||||
from concurrent.futures import ThreadPoolExecutor, wait as wait_futures
|
||||
from datetime import datetime, timezone
|
||||
|
||||
AGENT_VERSION = "1.23.0"
|
||||
AGENT_VERSION = "1.24.0"
|
||||
|
||||
# Default path to the local Docker Engine socket. Overridable via the
|
||||
# `docker_socket` config key; collection is silently skipped if it's absent or
|
||||
@@ -1663,13 +1663,13 @@ def collect_reboot(path: str = REBOOT_REQUIRED, modules: str = KERNEL_MODULES):
|
||||
# The agent can't update or reboot its host: it runs unprivileged under
|
||||
# NoNewPrivileges. It leaves a request in MAINT_REQUESTS, the one directory its
|
||||
# unit lets it write; steward-maint.path starts the root helper (maint.py),
|
||||
# which does only update / reboot / drain / undrain and writes each outcome to
|
||||
# MAINT_RESULTS. The agent reads those back and reports each new state once.
|
||||
# which does only check / update / reboot / drain / undrain and writes each
|
||||
# outcome to MAINT_RESULTS. The agent reads those back and reports each new state once.
|
||||
|
||||
MAINT_REQUESTS = "/var/lib/steward-agent/requests"
|
||||
MAINT_RESULTS = "/var/lib/steward-maint/results"
|
||||
MAINT_PATH_UNIT = "/etc/systemd/system/steward-maint.path"
|
||||
MAINT_ACTIONS = ("update", "reboot", "drain", "undrain", "drives")
|
||||
MAINT_ACTIONS = ("check", "update", "reboot", "drain", "undrain", "drives")
|
||||
MAINT_RESULT_MAX_BYTES = 8192
|
||||
# The helper keeps results a week; only this recent a one is reported, so a
|
||||
# job a reboot interrupted still reaches Steward from the agent's next start
|
||||
@@ -1677,7 +1677,9 @@ MAINT_RESULT_MAX_BYTES = 8192
|
||||
MAINT_REPORT_WINDOW_SECONDS = 86400
|
||||
_MAINT_ID = re.compile(r"^[A-Za-z0-9-]{1,64}$")
|
||||
_MAINT_FIELDS = ("action", "state", "ok", "packages", "reboot_required", "node",
|
||||
"detail", "started_at", "finished_at")
|
||||
"detail", "started_at", "finished_at",
|
||||
# a check's answer (#6098)
|
||||
"pending", "docker_update", "docker_packages", "containers")
|
||||
|
||||
|
||||
def maint_helper_installed(unit: str = MAINT_PATH_UNIT,
|
||||
|
||||
Reference in New Issue
Block a user