feat(queue): link rebuild queue entries to build log rows for live streaming
This commit is contained in:
parent
d31a723daf
commit
7118c5efdd
6 changed files with 101 additions and 9 deletions
|
|
@ -377,6 +377,7 @@ pub async fn rebuild(
|
|||
hive: &HiveEnv,
|
||||
paths: &AgentPaths,
|
||||
on_step: &(dyn Fn(&str) + Send + Sync),
|
||||
on_build_log_id: &(dyn Fn(i64) + Send + Sync),
|
||||
) -> Result<()> {
|
||||
// Sync the meta flake (idempotent — no-op when the rendered
|
||||
// flake matches disk) so a manual rebuild from the dashboard
|
||||
|
|
@ -389,7 +390,7 @@ pub async fn rebuild(
|
|||
// `applied/<n>/main` currently points at (deployed/<latest>).
|
||||
// Commits the lock if it changed.
|
||||
crate::meta::lock_update_for_rebuild(name).await?;
|
||||
rebuild_no_meta(name, hive, paths, on_step).await
|
||||
rebuild_no_meta(name, hive, paths, on_step, on_build_log_id).await
|
||||
}
|
||||
|
||||
/// Container-level rebuild without touching the meta repo. Callers
|
||||
|
|
@ -402,11 +403,17 @@ pub async fn rebuild(
|
|||
/// label so callers can surface progress (e.g. update the rebuild-queue
|
||||
/// step shown in the dashboard). Pass `&|_| ()` when progress reporting
|
||||
/// is not needed.
|
||||
///
|
||||
/// `on_build_log_id` is called with the build-log row id immediately after
|
||||
/// the `nixos-container update` log row opens, before the actual update
|
||||
/// command starts. Callers can use this to link the queue entry to the log
|
||||
/// for live streaming. Pass `&|_| ()` when not needed.
|
||||
pub async fn rebuild_no_meta(
|
||||
name: &str,
|
||||
hive: &HiveEnv,
|
||||
paths: &AgentPaths,
|
||||
on_step: &(dyn Fn(&str) + Send + Sync),
|
||||
on_build_log_id: &(dyn Fn(i64) + Send + Sync),
|
||||
) -> Result<()> {
|
||||
validate(name)?;
|
||||
if let Some(other) = port_collision(name).await {
|
||||
|
|
@ -440,7 +447,7 @@ pub async fn rebuild_no_meta(
|
|||
priv_run("stop", name).await?;
|
||||
}
|
||||
on_step("nixos-container update");
|
||||
let update_result = priv_run("update", name).await;
|
||||
let update_result = priv_run_inner("update", name, Some(on_build_log_id)).await;
|
||||
if let Err(ref update_err) = update_result {
|
||||
// The update failed (e.g. nix build error). If the agent was
|
||||
// running before we stopped it, try to bring it back up on the
|
||||
|
|
@ -1322,6 +1329,24 @@ fn make_log_callback(
|
|||
/// is appended to the build-log row as it arrives, so the dashboard
|
||||
/// shows live progress during long `nixos-container create` / `update` runs.
|
||||
async fn priv_run(kind: &str, name: &str) -> Result<()> {
|
||||
priv_run_inner(kind, name, None).await
|
||||
}
|
||||
|
||||
/// Like `priv_run` but calls `on_log_id(log_id)` immediately after the
|
||||
/// build-log row is opened — before the actual container op starts.
|
||||
/// This lets callers surface the row id for live streaming (e.g. the
|
||||
/// rebuild-queue worker sets `build_log_id` on the queue entry so the
|
||||
/// dashboard can link to `/api/build-logs/id/{id}/stream`).
|
||||
///
|
||||
/// The callback fires only when a build-log row is successfully opened
|
||||
/// (i.e. the global `BuildLogs` handle is installed AND `h.start()`
|
||||
/// succeeds). No-op when `on_log_id` is `None` — that's the path for
|
||||
/// all callers that don't need the id.
|
||||
async fn priv_run_inner(
|
||||
kind: &str,
|
||||
name: &str,
|
||||
on_log_id: Option<&(dyn Fn(i64) + Send + Sync)>,
|
||||
) -> Result<()> {
|
||||
let container = container_name(name);
|
||||
let cmdline = format!("nixos-container {kind} {container}");
|
||||
|
||||
|
|
@ -1333,6 +1358,11 @@ async fn priv_run(kind: &str, name: &str) -> Result<()> {
|
|||
})
|
||||
.ok()
|
||||
});
|
||||
// Notify the caller as soon as the log row exists so it can surface
|
||||
// the id for live streaming before the container op even starts.
|
||||
if let (Some(id), Some(cb)) = (log_id, on_log_id) {
|
||||
cb(id);
|
||||
}
|
||||
|
||||
// For long-running ops use the streaming protocol so build_logs
|
||||
// receives lines in real time rather than as a batch at completion.
|
||||
|
|
|
|||
Loading…
Reference in a new issue