hivectl: add start/stop agent verbs, rename spawn to create
This commit is contained in:
parent
e6ecd8db60
commit
3421925442
7 changed files with 127 additions and 35 deletions
|
|
@ -36,6 +36,55 @@ async fn agents_restart(socket: &Path, name: &str, no_wait: bool) -> Result<()>
|
|||
}
|
||||
}
|
||||
|
||||
/// `hivectl agent <name> start` — start an EXISTING agent container.
|
||||
/// Fails immediately (no request even sent) if `name` has no state dir
|
||||
/// at all, rather than silently resolving to an empty scope. Reuses the
|
||||
/// exact hive-wide `hivectl start` DAG (`HostRequest::Start`'s
|
||||
/// 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<()> {
|
||||
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
|
||||
);
|
||||
}
|
||||
render(
|
||||
crate::client::request(
|
||||
socket,
|
||||
HostRequest::Start {
|
||||
scope: hive_host_sock::LifecycleScope {
|
||||
agent_names: vec![name.to_owned()],
|
||||
..Default::default()
|
||||
},
|
||||
},
|
||||
)
|
||||
.await?,
|
||||
)
|
||||
}
|
||||
|
||||
/// `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
|
||||
/// path), scoped to this one name. Distinct from `AgentCmd::Kill`, which
|
||||
/// hard-stops via a separate DAG that does escalate.
|
||||
async fn agents_stop(socket: &Path, name: &str) -> Result<()> {
|
||||
render(
|
||||
crate::client::request(
|
||||
socket,
|
||||
HostRequest::Stop {
|
||||
scope: hive_host_sock::LifecycleScope {
|
||||
agent_names: vec![name.to_owned()],
|
||||
..Default::default()
|
||||
},
|
||||
graceful: true,
|
||||
},
|
||||
)
|
||||
.await?,
|
||||
)
|
||||
}
|
||||
|
||||
/// `hivectl list-agents` — fetch the per-agent status roster from the
|
||||
/// daemon (`HostRequest::AgentStatus`) and render it as a padded table,
|
||||
/// or the raw JSON rows with `--json`. Reuses the dashboard's
|
||||
|
|
@ -149,14 +198,16 @@ 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::Spawn => {
|
||||
AgentCmd::Start => agents_start(socket, name).await,
|
||||
AgentCmd::Create => {
|
||||
let name = crate::util::parse_ident(name)?;
|
||||
render(crate::client::request(socket, HostRequest::Spawn { name }).await?)
|
||||
}
|
||||
AgentCmd::RequestSpawn => {
|
||||
AgentCmd::RequestCreate => {
|
||||
let name = crate::util::parse_ident(name)?;
|
||||
render(crate::client::request(socket, HostRequest::RequestSpawn { name }).await?)
|
||||
}
|
||||
AgentCmd::Stop => agents_stop(socket, name).await,
|
||||
AgentCmd::Kill => {
|
||||
let name = crate::util::parse_ident(name)?;
|
||||
render(crate::client::request(socket, HostRequest::Kill { name }).await?)
|
||||
|
|
|
|||
|
|
@ -468,14 +468,22 @@ pub enum AgentCmd {
|
|||
Pause,
|
||||
/// Resume this paused agent — it drains whatever queued up while parked.
|
||||
Resume,
|
||||
/// Spawn this agent container directly, bypassing the approval queue.
|
||||
/// 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,
|
||||
/// Create this agent container from scratch (full first-time
|
||||
/// provisioning), bypassing the approval queue.
|
||||
///
|
||||
/// Operator-on-the-host only; use `request-spawn` for an approval-gated
|
||||
/// spawn.
|
||||
Spawn,
|
||||
/// Queue a spawn request for operator approval.
|
||||
RequestSpawn,
|
||||
/// Stop this managed container (graceful).
|
||||
/// Operator-on-the-host only; use `request-create` for an
|
||||
/// approval-gated creation.
|
||||
Create,
|
||||
/// Queue a first-creation request for operator approval.
|
||||
RequestCreate,
|
||||
/// Gracefully stop this agent container: signal → drain → reconcile.
|
||||
/// Never escalates to a hard kill — use `kill` for that.
|
||||
Stop,
|
||||
/// Hard-stop this managed container.
|
||||
Kill,
|
||||
/// Tear down this sub-agent container, keeping its state by default.
|
||||
/// No undo.
|
||||
|
|
|
|||
Loading…
Reference in a new issue