hive-c0re: route dashboard start/stop through the rebuild queue

This commit is contained in:
damocles 2026-06-21 13:05:36 +02:00 committed by mara
commit 2966f682ce
2 changed files with 72 additions and 65 deletions

View file

@ -46,6 +46,15 @@ pub enum QueueKind {
/// stop-checkpoint turn (flush durable `/state`), wait for it to drain,
/// then `nixos-container stop`. Falls back to a hard stop on timeout.
GracefulStop,
/// Start a stopped container (`lifecycle::start`). Routed through the
/// queue so the dashboard shows a visible queued→running transient — a
/// direct sub-second start only flashes the badge — and bulk starts
/// serialise legibly on the queue. Fast op.
Start,
/// Hard-stop a container (`lifecycle::kill`), no quiesce. Routed through
/// the queue for the same visible-progress reason as `Start`; the
/// quiescing variant is `GracefulStop`. Fast op.
Stop,
}
impl QueueKind {
@ -59,6 +68,8 @@ impl QueueKind {
QueueKind::Restart => "restart",
QueueKind::PermChange => "perm_change",
QueueKind::GracefulStop => "graceful_stop",
QueueKind::Start => "start",
QueueKind::Stop => "stop",
}
}
}
@ -845,9 +856,47 @@ async fn dispatch(
crate::auto_update::rebuild_agent(coord, name, &current_rev, Some(entry.id)).await
}
(QueueKind::GracefulStop, _) => run_graceful_stop(coord, entry).await,
(QueueKind::Start, _) => run_start(coord, entry).await,
(QueueKind::Stop, _) => run_stop(coord, entry).await,
}
}
/// Start a stopped container off the queue (`QueueKind::Start`), with a
/// `Starting` transient so the dashboard shows a visible queued→running
/// progression rather than the sub-second flash of a direct start.
async fn run_start(
coord: &std::sync::Arc<crate::coordinator::Coordinator>,
entry: &QueueEntry,
) -> anyhow::Result<()> {
let name = &entry.agent;
let _guard = coord.transient_guard(name, crate::coordinator::TransientKind::Starting);
coord.set_queue_step(Some(entry.id), "nixos-container start");
crate::lifecycle::start(name).await?;
coord.kick_agent(name, "container started");
coord.rescan_containers_and_emit().await;
Ok(())
}
/// Hard-stop a container off the queue (`QueueKind::Stop`) — same teardown as
/// a direct kill (unregister + `Killed` event), but with a `Stopping`
/// transient for visible queue progress. The quiescing variant is
/// `run_graceful_stop`.
async fn run_stop(
coord: &std::sync::Arc<crate::coordinator::Coordinator>,
entry: &QueueEntry,
) -> anyhow::Result<()> {
let name = &entry.agent;
let _guard = coord.transient_guard(name, crate::coordinator::TransientKind::Stopping);
coord.set_queue_step(Some(entry.id), "nixos-container stop");
crate::lifecycle::kill(name).await?;
coord.unregister_agent(name);
coord.notify_manager(&hive_sh4re::HelperEvent::Killed {
agent: name.clone(),
});
coord.rescan_containers_and_emit().await;
Ok(())
}
/// Run one `GracefulStop` entry: signal the harness to quiesce (it returns
/// `GracefulStop` on its next `Recv`, runs one stop-checkpoint turn to flush
/// durable `/state`, then exits), wait for it to drain — bounded by