feat(docker): Busiest Containers shows each figure with its scale; readable names (#5253)

The widget names the busiest container in a verdict ("Busiest: tdarr on
VDNT-Docker03, 1.6 of 8 cores."), then a fixed-layout table (container,
host, CPU in cores, memory in bytes) with each figure's share drawn as
shading behind it: of the host's cores, and of the memory limit or the
host's memory.

The numbers were already rendered, but each row grew as wide as its longest
name. A grid item won't shrink below its content, so Gitea CI container
names pushed the figures out of view and the cell scrolled sideways. Names
now come from display_name(): a swarm task by its service (no slot number),
an Actions job container as "CI: <workflow> · <job>". They cut off with …
and show whole on hover.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-07 13:18:44 -04:00
co-authored by Claude Opus 5.5
parent 213a28c23f
commit d72a1991a7
5 changed files with 87 additions and 37 deletions
+1 -4
View File
@@ -284,7 +284,6 @@ async def widget_resources():
.where(DockerMetric.scraped_at >= since)
.group_by(DockerMetric.host_id, DockerMetric.container_name)
)).all()}
nodes = list((await db.execute(select(DockerSwarmNode))).scalars())
hosts = await docker_svc.host_map(db, {c.host_id for c in running})
capacity = await docker_svc.host_capacity(db, {c.host_id for c in running})
@@ -293,10 +292,9 @@ async def widget_resources():
return c.cpu_pct if v is None else float(v)
busiest = sorted(running, key=lambda c: (-(cpu_of(c) or 0), c.name))[:limit]
node_hostname = {n.node_id: n.hostname for n in nodes if n.hostname}
rows_data = [{
"c": c,
"label": docker_svc.task_label(c, node_hostname),
"label": docker_svc.display_name(c),
"host_name": hosts[c.host_id].name if c.host_id in hosts else c.host_id,
"usage": docker_svc.usage(c, *capacity.get(c.host_id, (None, None)), cpu_pct=cpu_of(c)),
} for c in busiest]
@@ -304,7 +302,6 @@ async def widget_resources():
"docker/widget_resources.html",
rows=rows_data,
minutes=CPU_AVERAGE_MINUTES,
multi_host=len({c.host_id for c in busiest}) > 1,
widget_id=widget_id,
)