feat(docker): Docker's own status reaches Steward — an empty answer clears a host, a lost one greys it, a demoted manager's swarm rows go (#5152)
The agent (1.9.0) said nothing when Docker could not be asked and nothing when Docker had no containers, so Steward could tell neither apart from the other, and kept a host's last containers on screen as running either way. - Agent: collect_docker returns (status, detail, containers). "ok" sends docker: [] when there are none; "unavailable" (no socket, nothing listening) and "error" (permission, timeout, bad answer) say why. collect_swarm says whether /info answered, and a node that is not a manager sends swarm_manager: false. A failed /info says nothing. - Ingest: an empty docker list is a snapshot; the newest sample's status goes to the Docker plugin with the rest. - docker_host_status (docker_011): per host, status, detail, since and last report. A host that never had Docker gets no row. - An "ok" empty snapshot reaps the host's containers; an error keeps them. swarm_manager: false drops the host's swarm services and nodes. - Docker page: a "Docker not answering" card names each such host, why, and since when; its containers read as stale. Duplicate header comment in rows.html removed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -33,6 +33,9 @@ def test_stale_is_older_than_the_agents_window():
|
||||
assert not _is_stale(_c("a"), NOW, 180)
|
||||
assert _is_stale(_c("a", scraped_at=NOW - timedelta(minutes=10)), NOW, 180)
|
||||
assert _is_stale(_c("a", scraped_at=None), NOW, 180)
|
||||
# A fresh row on a host whose Docker stopped answering is stale too (#5152).
|
||||
assert _is_stale(_c("a"), NOW, 180, {"h1": object()})
|
||||
assert not _is_stale(_c("a"), NOW, 180, {"h2": object()})
|
||||
assert svc.stale_after_seconds({"PLUGINS": {"host_agent": {"stale_after_seconds": 60}}}) == 60
|
||||
assert svc.stale_after_seconds({}) == 180
|
||||
|
||||
@@ -74,3 +77,29 @@ async def test_a_healthy_board_has_no_attention_card(app):
|
||||
app, "docker", "docker/rows.html", attention=[], says=svc.PROBLEM_SAYS, severity=svc.PROBLEM_SEVERITY,
|
||||
unhealthy=0, restarting=0, stale=0, host_groups=[], swarm_services=[], running=0, stopped=0, total=0)
|
||||
assert "Needs attention</h2>" not in page and "No containers reported yet" in page
|
||||
|
||||
|
||||
async def test_a_host_whose_docker_stopped_answering_says_so(app):
|
||||
down = [{"host_id": "h1", "host_name": "nas", "status": "unavailable",
|
||||
"detail": "no Docker socket at /var/run/docker.sock", "since": NOW - timedelta(minutes=5)},
|
||||
{"host_id": "h2", "host_name": "web-1", "status": "error",
|
||||
"detail": "permission denied on /var/run/docker.sock", "since": NOW - timedelta(minutes=1)}]
|
||||
async with app.test_request_context("/plugins/docker/rows"):
|
||||
page = await render_plugin_template(
|
||||
app, "docker", "docker/rows.html", docker_down=down, attention=[], says=svc.PROBLEM_SAYS,
|
||||
severity=svc.PROBLEM_SEVERITY, unhealthy=0, restarting=0, stale=0, host_groups=[],
|
||||
swarm_services=[], running=0, stopped=0, total=0)
|
||||
page = re.sub(r">\s+<", "><", " ".join(page.split()))
|
||||
card = page[page.index("Docker not answering"):page.index("</section>")]
|
||||
assert '<span class="badge badge-warn">No Docker</span><a href="/hosts/h1">nas</a>' in card
|
||||
assert "no Docker socket at /var/run/docker.sock · since <time" in card and ">5m ago</time>" in card
|
||||
assert '<span class="badge badge-crit">Error</span><a href="/hosts/h2">web-1</a>' in card
|
||||
|
||||
|
||||
async def test_no_card_while_every_docker_answers(app):
|
||||
async with app.test_request_context("/plugins/docker/rows"):
|
||||
page = await render_plugin_template(
|
||||
app, "docker", "docker/rows.html", docker_down=[], attention=[], says=svc.PROBLEM_SAYS,
|
||||
severity=svc.PROBLEM_SEVERITY, unhealthy=0, restarting=0, stale=0, host_groups=[],
|
||||
swarm_services=[], running=0, stopped=0, total=0)
|
||||
assert "Docker not answering" not in page
|
||||
|
||||
Reference in New Issue
Block a user