hivectl/dashboard: add --paused / ?paused=1 to agent start
This commit is contained in:
parent
c0f59089d4
commit
af3976a76a
4 changed files with 118 additions and 16 deletions
|
|
@ -43,13 +43,29 @@ async fn agents_restart(socket: &Path, name: &str, no_wait: bool) -> Result<()>
|
|||
/// scope-based path), just scoped to this one name — a separate
|
||||
/// per-agent wire request would have duplicated logic this scope-based
|
||||
/// one already covers.
|
||||
async fn agents_start(socket: &Path, name: &str) -> Result<()> {
|
||||
///
|
||||
/// `paused`: if the agent is already running, sets the pause marker in
|
||||
/// place and returns without submitting a start DAG at all (nothing to
|
||||
/// start). Otherwise sets the marker *before* the start request, so the
|
||||
/// container comes up paused rather than racing the harness's own
|
||||
/// pause-gate poll against a start that's already in flight — the same
|
||||
/// "pausing a stopped agent makes it come up paused" guarantee `pause`
|
||||
/// already provides on its own.
|
||||
async fn agents_start(socket: &Path, name: &str, paused: bool) -> Result<()> {
|
||||
if !crate::util::agent_exists(socket, name).await? {
|
||||
bail!(
|
||||
"no such agent: '{name}' (no state dir under {}/) — use 'hivectl agent {name} create' to provision a brand-new agent",
|
||||
hive_host_sock::AGENTS_ROOT
|
||||
);
|
||||
}
|
||||
if paused {
|
||||
let already_running = agent_running(socket, name).await?;
|
||||
set_paused(socket, name, true).await?;
|
||||
if already_running {
|
||||
eprintln!("'{name}' is already running — paused in place, not (re)started");
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
render(
|
||||
crate::client::request(
|
||||
socket,
|
||||
|
|
@ -64,6 +80,27 @@ async fn agents_start(socket: &Path, name: &str) -> Result<()> {
|
|||
)
|
||||
}
|
||||
|
||||
/// Whether `name`'s container is currently running, per the same
|
||||
/// `AgentStatus` roster `hivectl list-agents` renders. No per-agent wire
|
||||
/// request exists for this (nor should one, for a single boolean a rarely
|
||||
/// called CLI flag needs) — filter the hive-wide roster down to one row.
|
||||
async fn agent_running(socket: &Path, name: &str) -> Result<bool> {
|
||||
let resp = crate::client::request(socket, HostRequest::AgentStatus)
|
||||
.await
|
||||
.with_context(|| format!("connect to daemon socket {}", socket.display()))?;
|
||||
if !resp.ok {
|
||||
bail!(
|
||||
"agent status: {}",
|
||||
resp.error.as_deref().unwrap_or("unknown error")
|
||||
);
|
||||
}
|
||||
Ok(resp
|
||||
.agent_statuses
|
||||
.unwrap_or_default()
|
||||
.iter()
|
||||
.any(|r| r.name == name && r.running))
|
||||
}
|
||||
|
||||
/// `hivectl agent <name> stop` — graceful-only stop (signal → drain →
|
||||
/// reconcile), never escalating to a hard kill. Reuses the hive-wide
|
||||
/// `hivectl stop --graceful` DAG (`HostRequest::Stop`'s scope-based
|
||||
|
|
@ -198,7 +235,7 @@ pub(crate) async fn run_agent(socket: &Path, name: &str, cmd: AgentCmd) -> Resul
|
|||
AgentCmd::Restart { no_wait } => agents_restart(socket, name, no_wait).await,
|
||||
AgentCmd::Pause => set_paused(socket, name, true).await,
|
||||
AgentCmd::Resume => set_paused(socket, name, false).await,
|
||||
AgentCmd::Start => agents_start(socket, name).await,
|
||||
AgentCmd::Start { paused } => agents_start(socket, name, paused).await,
|
||||
AgentCmd::Create => {
|
||||
let name = crate::util::parse_ident(name)?;
|
||||
render(crate::client::request(socket, HostRequest::Spawn { name }).await?)
|
||||
|
|
|
|||
|
|
@ -471,7 +471,15 @@ pub enum AgentCmd {
|
|||
/// Start this EXISTING agent container. Fails immediately if `name`
|
||||
/// has no config/topology entry at all — it never attempts
|
||||
/// first-time creation. Use `create` for that.
|
||||
Start,
|
||||
Start {
|
||||
/// Start (or leave) the agent paused: if it's currently down, the
|
||||
/// pause marker is written before the container boots, so it comes
|
||||
/// up paused instead of driving turns immediately. If it's already
|
||||
/// running, this pauses it in place and does not attempt a
|
||||
/// (re)start.
|
||||
#[arg(long)]
|
||||
paused: bool,
|
||||
},
|
||||
/// Create this agent container from scratch (full first-time
|
||||
/// provisioning), bypassing the approval queue.
|
||||
///
|
||||
|
|
|
|||
Loading…
Reference in a new issue