feat(#3139): tell a container that gave up from one stopped on purpose

is_running collapsed every non-active state into false, so a container that
exhausted its bounded restarts read as plain "down" -- indistinguishable
from one an operator stopped deliberately. Bounding the restarts made that
gap sharper: a slow-failing agent used to grind on visibly, now it can stop
quietly.

Adds UnitState + unit_state() beside is_running rather than widening it.
is_running has ~8 call sites and nearly all are reconcile/power logic asking
"is it up? if not, start it" -- a question with two answers. Only the view
builder needs more, and it gets both facts from one systemctl call, since
is-active prints the state when not passed --quiet.

Surfaces as a flat failed flag on ContainerView and AgentStatusRow, matching
the shape those types already document: independent, orthogonally-observed
facts rather than a state machine. serde(default) keeps it order-independent
with the frontend half.

No behaviour change: nothing acts on the flag, per the ruling.
This commit is contained in:
atlas 2026-08-10 23:18:43 +02:00 committed by mara
commit cae2cf8df6
6 changed files with 128 additions and 2 deletions

View file

@ -35,6 +35,13 @@ pub struct AgentStatusRow {
pub name: String,
/// Whether the container is currently running.
pub running: bool,
/// The container's unit is in systemd's `failed` state — it exhausted
/// its bounded restarts and gave up, as opposed to being stopped
/// deliberately. Orthogonal to `running`, like every other flag here:
/// a failed unit is not running, but a not-running unit is usually
/// just off.
#[serde(default)]
pub failed: bool,
/// Config commit is pending — the locked rev differs from the
/// agent's proposed/applied config (a rebuild would change it).
pub needs_update: bool,