feat(hosts): a host's page stays short — Docker folds past the busiest, monitors add on their own form, agent actions under Manage (#5276, #5277, #5278)
Docker panel (#5276): problems first, then the 8 busiest running containers by CPU; the other running and the stopped fold behind one "+N more running · M stopped" line. Containers that are not swarm tasks read the way the Docker page reads them: CI jobs as "CI: workflow · job", buildx builders as "BuildKit builder · name". Monitors card (#5277): the edit/delete icon buttons and the inline add form are gone. Each row links to its monitor's page; "Add monitor" opens the add form filed under this host, starting from its address, with the host in its breadcrumbs and Cancel back to it. Agent card (#5278): Full metrics stays in view; Update, Rotate token, Unregister agent (was "Remove") and Re-provision sit under "Manage agent". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -267,3 +267,47 @@ def test_bar_slots_end_at_the_bucket_now_falls_in():
|
||||
assert width == 900 and len(slots) == 24
|
||||
assert slots[-1] == datetime(2026, 10, 7, 12, 0, tzinfo=timezone.utc)
|
||||
assert slots[0] == datetime(2026, 10, 7, 6, 15, tzinfo=timezone.utc)
|
||||
|
||||
|
||||
def test_builders_and_ci_jobs_read_by_what_they_are_on_a_hosts_page():
|
||||
assert svc.display_name(_c("buildx_buildkit_steward-builder0")) == "BuildKit builder · steward-builder"
|
||||
ci = "FORGEJO-ACTIONS-TASK-8597-WORKFLOW-CI-JOB-unit"
|
||||
assert svc.task_label(_c(ci)) == "CI: CI · unit" # not a swarm task: display_name
|
||||
assert svc.task_label(_c("codex_db.1.37ma", service_name="codex_db")) == "codex_db · 1"
|
||||
|
||||
|
||||
def _panel_row(name, cpu, status="running", problems=()):
|
||||
c = _c(name, cpu_pct=cpu, status=status)
|
||||
return {"c": c, "label": name, "problems": list(problems), "since": None,
|
||||
"usage": svc.usage(c, 4, 8 << 30), "uptime": "2h" if status == "running" else None}
|
||||
|
||||
|
||||
def _panel_rows():
|
||||
return ([_panel_row(f"busy{n:02d}", float(n)) for n in range(1, 11)]
|
||||
+ [_panel_row("old", None, status="exited"),
|
||||
_panel_row("dead", None, status="exited", problems=["exited_nonzero"])])
|
||||
|
||||
|
||||
def test_a_hosts_docker_panel_shows_problems_then_the_busiest_and_folds_the_rest():
|
||||
"""#5276: 33 containers made the card run off the page."""
|
||||
from plugins.docker.routes import HOST_PANEL_BUSIEST, host_panel_rows
|
||||
shown, folded = host_panel_rows(_panel_rows())
|
||||
assert [r["label"] for r in shown] == ["dead"] + [f"busy{n:02d}" for n in range(10, 2, -1)]
|
||||
assert len(shown) == 1 + HOST_PANEL_BUSIEST
|
||||
assert [r["label"] for r in folded] == ["busy02", "busy01", "old"]
|
||||
|
||||
|
||||
async def test_the_folded_containers_sit_behind_one_line(app):
|
||||
from plugins.docker.routes import host_panel_rows
|
||||
shown, folded = host_panel_rows(_panel_rows())
|
||||
async with app.test_request_context("/plugins/docker/host/h1"):
|
||||
page = await render_plugin_template(
|
||||
app, "docker", "docker/host_panel.html", rows=shown, folded=folded,
|
||||
says=svc.PROBLEM_SAYS, severity=svc.PROBLEM_SEVERITY,
|
||||
running=10, stopped=2, problems=1, replaced=0, busiest=8)
|
||||
fold = page.index("<details")
|
||||
assert "+2 more running · 1 stopped" in page
|
||||
assert page.index(">busy10<") < fold < page.index(">busy01<")
|
||||
assert page.index(">dead<") < page.index(">busy10<")
|
||||
assert len(re.findall(r"<th[ >]", page)) == 6 # one header row per table
|
||||
assert not hex_colours(page), hex_colours(page)
|
||||
|
||||
Reference in New Issue
Block a user