feat(#2398): dagify hivectl restart (RestartScoped)
hivectl restart --agent NAME previously composed stop() then start() as
two separate client-side daemon calls glued by CLI-process control flow
— not one DAG, and a dropped hivectl connection mid-restart (ssh drop,
Ctrl-C) left the agent stopped with no automatic follow-up. mara flagged
this as the first target for the 'dagify hivectl commands' issue.
New HostRequest::RestartScoped{scope, graceful} handles it server-side:
each targeted agent now rides exactly one atomic Restart-template DAG
(same one hivectl agents restart / restart-all already use) in the
common non-graceful case. --graceful has no single-DAG template yet, so
it submits the graceful-stop DAGs, awaits them server-side, then submits
the start DAGs — still one daemon call end to end, just not yet a single
DAG (noted as a follow-up). Infra containers restart synchronously as
before (no lease/DAG concept for them).
CLI-side restart() now just makes the one call + waits, same output
shape as before via render_lifecycle.
This commit is contained in:
parent
5853ce2c8d
commit
4cfa040154
3 changed files with 118 additions and 10 deletions
|
|
@ -1642,22 +1642,31 @@ async fn start(socket: &Path, scope: hive_host_sock::LifecycleScope, no_wait: bo
|
|||
rendered
|
||||
}
|
||||
|
||||
/// Restart = `stop` then `start` over the same scope, composed client-side
|
||||
/// from the two daemon ops (no dedicated wire op). The stop phase honours
|
||||
/// `--graceful`; if it reports a failure (`stop` returns `Err`) the `?`
|
||||
/// short-circuits before the start phase, so a half-stopped hive isn't
|
||||
/// blindly started over — the operator sees the stop errors and can recover.
|
||||
/// Restart — one `RestartScoped` daemon call, server-side DAG-based (see
|
||||
/// issue tracker "dagify hivectl commands"). Each targeted agent rides one
|
||||
/// atomic `Restart` DAG (or, with `--graceful`, a server-awaited
|
||||
/// graceful-stop DAG followed by a start DAG); infra containers restart
|
||||
/// synchronously. Unlike the old client-side stop-then-start compose, a
|
||||
/// dropped `hivectl` connection mid-restart no longer leaves an agent
|
||||
/// stopped with no automatic follow-up — the daemon owns the whole
|
||||
/// sequence once this call is made.
|
||||
///
|
||||
/// No `--no-wait` here on purpose: the stop DAGs must complete before
|
||||
/// the start submits, otherwise the start's `wanted = Up` write would
|
||||
/// land before the queued stops execute and turn them into noops.
|
||||
/// No `--no-wait` here on purpose, same as before: the operator wants to
|
||||
/// see the restart actually land, not just get queued.
|
||||
async fn restart(
|
||||
socket: &Path,
|
||||
scope: hive_host_sock::LifecycleScope,
|
||||
graceful: bool,
|
||||
) -> Result<()> {
|
||||
stop(socket, scope.clone(), graceful, false).await?;
|
||||
start(socket, scope, false).await
|
||||
let resp = hive_c0re::client::request(
|
||||
socket,
|
||||
hive_host_sock::HostRequest::RestartScoped { scope, graceful },
|
||||
)
|
||||
.await
|
||||
.with_context(|| format!("connect to daemon socket {}", socket.display()))?;
|
||||
let rendered = render_lifecycle(&resp, "restart queued");
|
||||
wait_for_dags(socket, resp.queued_dags.unwrap_or_default(), false).await?;
|
||||
rendered
|
||||
}
|
||||
|
||||
/// A [`LifecycleScope`](hive_host_sock::LifecycleScope) targeting exactly one
|
||||
|
|
|
|||
Loading…
Reference in a new issue