refactor(#2302): type socket wire fields as ident, validated by serde on deserialize
This commit is contained in:
parent
bf644cc126
commit
84b750fba5
33 changed files with 333 additions and 263 deletions
|
|
@ -83,11 +83,11 @@ async fn handle(stream: UnixStream, coord: Arc<Coordinator>) -> Result<()> {
|
|||
async fn dispatch(req: &HostRequest, coord: Arc<Coordinator>) -> HostResponse {
|
||||
let result: anyhow::Result<HostResponse> = async {
|
||||
Ok(match req {
|
||||
HostRequest::Spawn { name } => handle_spawn(&coord, name).await?,
|
||||
HostRequest::Spawn { name } => handle_spawn(&coord, name.as_str()).await?,
|
||||
HostRequest::RequestSpawn { name } => {
|
||||
tracing::info!(%name, "request_spawn");
|
||||
let id = coord.approvals.submit_kind(
|
||||
name,
|
||||
name.as_str(),
|
||||
hive_sh4re::ApprovalKind::Spawn,
|
||||
"",
|
||||
None,
|
||||
|
|
@ -97,8 +97,10 @@ async fn dispatch(req: &HostRequest, coord: Arc<Coordinator>) -> HostResponse {
|
|||
tracing::info!(%id, %name, "spawn approval queued");
|
||||
HostResponse::success()
|
||||
}
|
||||
HostRequest::Kill { name } => submit_single(&coord, name, Verb::Kill).await,
|
||||
HostRequest::Restart { name } => submit_single(&coord, name, Verb::Restart).await,
|
||||
HostRequest::Kill { name } => submit_single(&coord, name.as_str(), Verb::Kill).await,
|
||||
HostRequest::Restart { name } => {
|
||||
submit_single(&coord, name.as_str(), Verb::Restart).await
|
||||
}
|
||||
HostRequest::RestartAll => handle_restart_all(&coord).await?,
|
||||
HostRequest::RestartScoped { scope, graceful } => {
|
||||
handle_restart_scoped(&coord, scope, *graceful).await?
|
||||
|
|
@ -140,10 +142,12 @@ async fn dispatch(req: &HostRequest, coord: Arc<Coordinator>) -> HostResponse {
|
|||
handle_start(&coord, &agents, &infra).await?
|
||||
}
|
||||
HostRequest::Destroy { name, purge } => {
|
||||
actions::destroy(&coord, name, *purge).await?;
|
||||
actions::destroy(&coord, name.as_str(), *purge).await?;
|
||||
HostResponse::success()
|
||||
}
|
||||
HostRequest::Rebuild { name } => submit_single(&coord, name, Verb::Rebuild).await,
|
||||
HostRequest::Rebuild { name } => {
|
||||
submit_single(&coord, name.as_str(), Verb::Rebuild).await
|
||||
}
|
||||
HostRequest::QueueDag { id } => {
|
||||
// A multi-step op is one DAG now (no fan-out children to gather).
|
||||
let dags = coord
|
||||
|
|
@ -179,7 +183,10 @@ async fn dispatch(req: &HostRequest, coord: Arc<Coordinator>) -> HostResponse {
|
|||
// skip both the messages and the disk write per the
|
||||
// topology fast-path.
|
||||
coord
|
||||
.reparent_with_notify(child, new_parent.as_deref())
|
||||
.reparent_with_notify(
|
||||
child.as_str(),
|
||||
new_parent.as_ref().map(hive_types::Ident::as_str),
|
||||
)
|
||||
.await
|
||||
.map_err(anyhow::Error::msg)?;
|
||||
HostResponse::success()
|
||||
|
|
@ -188,8 +195,12 @@ async fn dispatch(req: &HostRequest, coord: Arc<Coordinator>) -> HostResponse {
|
|||
handle_matrix_create_user(name, password.as_deref()).await?
|
||||
}
|
||||
HostRequest::MatrixSyncAdmin => handle_matrix_sync_admin().await?,
|
||||
HostRequest::MatrixPromoteUser { name } => handle_matrix_promote_user(name).await?,
|
||||
HostRequest::MatrixResetPassword { name } => handle_matrix_reset_password(name).await?,
|
||||
HostRequest::MatrixPromoteUser { name } => {
|
||||
handle_matrix_promote_user(name.as_str()).await?
|
||||
}
|
||||
HostRequest::MatrixResetPassword { name } => {
|
||||
handle_matrix_reset_password(name.as_str()).await?
|
||||
}
|
||||
HostRequest::MatrixInvite { user, room } => {
|
||||
handle_matrix_invite(user, room.as_deref()).await?
|
||||
}
|
||||
|
|
@ -197,10 +208,10 @@ async fn dispatch(req: &HostRequest, coord: Arc<Coordinator>) -> HostResponse {
|
|||
handle_forge_create_user(name, password.as_deref()).await?
|
||||
}
|
||||
HostRequest::ReconcileConfigStatus { agent, verbose } => {
|
||||
crate::forge::reconcile_config_status(agent, *verbose).await?
|
||||
crate::forge::reconcile_config_status(agent.as_str(), *verbose).await?
|
||||
}
|
||||
HostRequest::ReconcileConfigApply { agent, direction } => {
|
||||
crate::forge::reconcile_config_apply(agent, *direction).await?
|
||||
crate::forge::reconcile_config_apply(agent.as_str(), *direction).await?
|
||||
}
|
||||
HostRequest::GatewayCreateUser { username, password } => {
|
||||
HostResponse::messages(vec![crate::gateway_nginx::create_user(username, password)?])
|
||||
|
|
@ -212,24 +223,30 @@ async fn dispatch(req: &HostRequest, coord: Arc<Coordinator>) -> HostResponse {
|
|||
HostResponse::messages(crate::gateway_nginx::list_users()?)
|
||||
}
|
||||
HostRequest::SetAgentGithubToken { agent, token } => {
|
||||
handle_set_agent_github_token(agent, token).await?
|
||||
handle_set_agent_github_token(agent.as_str(), token).await?
|
||||
}
|
||||
HostRequest::QuotaEnable => handle_quota_enable().await?,
|
||||
HostRequest::QuotaLimit { name, limit } => handle_quota_limit(name, *limit).await?,
|
||||
HostRequest::QuotaShow { name } => handle_quota_show(name.as_deref()).await?,
|
||||
HostRequest::UpgradeSubvolume { name } => handle_upgrade_subvolume(name).await?,
|
||||
HostRequest::QuotaLimit { name, limit } => {
|
||||
handle_quota_limit(name.as_str(), *limit).await?
|
||||
}
|
||||
HostRequest::QuotaShow { name } => {
|
||||
handle_quota_show(name.as_ref().map(hive_types::Ident::as_str)).await?
|
||||
}
|
||||
HostRequest::UpgradeSubvolume { name } => {
|
||||
handle_upgrade_subvolume(name.as_str()).await?
|
||||
}
|
||||
HostRequest::SnapshotSubvolume { name, label } => {
|
||||
handle_snapshot_subvolume(name, label).await?
|
||||
handle_snapshot_subvolume(name.as_str(), label).await?
|
||||
}
|
||||
HostRequest::DeleteSnapshot { name, label } => {
|
||||
handle_delete_snapshot(name, label).await?
|
||||
handle_delete_snapshot(name.as_str(), label).await?
|
||||
}
|
||||
HostRequest::SendSnapshot {
|
||||
name,
|
||||
label,
|
||||
parent,
|
||||
dest,
|
||||
} => handle_send_snapshot(name, label, parent.as_deref(), dest).await?,
|
||||
} => handle_send_snapshot(name.as_str(), label, parent.as_deref(), dest).await?,
|
||||
})
|
||||
}
|
||||
.await;
|
||||
|
|
@ -320,10 +337,8 @@ fn matrix_http_client() -> Result<reqwest::Client> {
|
|||
|
||||
/// True when `name` has a state dir under the agents root, i.e. it's a
|
||||
/// managed agent rather than a bare (operator/human) matrix account.
|
||||
fn agent_exists(name: &str) -> Result<bool> {
|
||||
let name = hive_host_sock::Ident::parse(name)
|
||||
.map_err(|e| anyhow::anyhow!("invalid agent name {name:?}: {e}"))?;
|
||||
crate::paths::agent_state_dir(&name)
|
||||
fn agent_exists(name: &hive_types::Ident) -> Result<bool> {
|
||||
crate::paths::agent_state_dir(name)
|
||||
.try_exists()
|
||||
.with_context(|| format!("check agent state dir for {name}"))
|
||||
}
|
||||
|
|
@ -338,7 +353,10 @@ async fn require_matrix_present() -> Result<()> {
|
|||
)
|
||||
}
|
||||
|
||||
async fn handle_matrix_create_user(name: &str, password: Option<&str>) -> Result<HostResponse> {
|
||||
async fn handle_matrix_create_user(
|
||||
name: &hive_types::Ident,
|
||||
password: Option<&str>,
|
||||
) -> Result<HostResponse> {
|
||||
require_matrix_present().await?;
|
||||
let register_token =
|
||||
crate::matrix::ensure_register_token().context("read matrix register token")?;
|
||||
|
|
@ -353,12 +371,10 @@ async fn handle_matrix_create_user(name: &str, password: Option<&str>) -> Result
|
|||
"matrix create-user: a password is for non-agent (operator) accounts only; '{name}' is an agent which authenticates via access_token"
|
||||
);
|
||||
}
|
||||
crate::matrix::ensure_user_for(&client, name, ®ister_token)
|
||||
crate::matrix::ensure_user_for(&client, name.as_str(), ®ister_token)
|
||||
.await
|
||||
.with_context(|| format!("matrix create-user {name}"))?;
|
||||
let agent = hive_host_sock::Ident::parse(name)
|
||||
.map_err(|e| anyhow::anyhow!("invalid agent name {name:?}: {e}"))?;
|
||||
let path = Coordinator::agent_notes_dir(&agent).join("matrix-token");
|
||||
let path = Coordinator::agent_notes_dir(name).join("matrix-token");
|
||||
out.push(format!("matrix: provisioned agent user '{name}'"));
|
||||
out.push(format!("token persisted at: {}", path.display()));
|
||||
} else {
|
||||
|
|
@ -368,7 +384,7 @@ async fn handle_matrix_create_user(name: &str, password: Option<&str>) -> Result
|
|||
};
|
||||
let token = crate::matrix::provision_user_token(
|
||||
&client,
|
||||
name,
|
||||
name.as_str(),
|
||||
®ister_token,
|
||||
&effective_password,
|
||||
)
|
||||
|
|
@ -391,7 +407,10 @@ async fn handle_matrix_create_user(name: &str, password: Option<&str>) -> Result
|
|||
Ok(HostResponse::messages(out))
|
||||
}
|
||||
|
||||
async fn handle_forge_create_user(name: &str, password: Option<&str>) -> Result<HostResponse> {
|
||||
async fn handle_forge_create_user(
|
||||
name: &hive_types::Ident,
|
||||
password: Option<&str>,
|
||||
) -> Result<HostResponse> {
|
||||
if !crate::forge::is_present().await {
|
||||
anyhow::bail!(
|
||||
"hive-forge container not running — wait for hive-c0re to start it before provisioning forge users"
|
||||
|
|
@ -406,16 +425,14 @@ async fn handle_forge_create_user(name: &str, password: Option<&str>) -> Result<
|
|||
"forge create-user: a password is for non-agent (operator) accounts only; '{name}' is an agent which authenticates via API token"
|
||||
);
|
||||
}
|
||||
crate::forge::ensure_user_for(name)
|
||||
crate::forge::ensure_user_for(name.as_str())
|
||||
.await
|
||||
.with_context(|| format!("forge create-user {name}"))?;
|
||||
let agent = hive_host_sock::Ident::parse(name)
|
||||
.map_err(|e| anyhow::anyhow!("invalid agent name {name:?}: {e}"))?;
|
||||
let path = Coordinator::agent_notes_dir(&agent).join("forge-token");
|
||||
let path = Coordinator::agent_notes_dir(name).join("forge-token");
|
||||
out.push(format!("forge: provisioned agent user '{name}'"));
|
||||
out.push(format!("token persisted at: {}", path.display()));
|
||||
} else {
|
||||
let token = crate::forge::provision_user_token(name, password)
|
||||
let token = crate::forge::provision_user_token(name.as_str(), password)
|
||||
.await
|
||||
.with_context(|| format!("forge create-user {name}"))?;
|
||||
out.push(format!(
|
||||
|
|
@ -467,7 +484,7 @@ async fn handle_quota_show(name: Option<&str>) -> Result<HostResponse> {
|
|||
Some(n) => vec![n.to_owned()],
|
||||
None => Coordinator::kept_state_names()
|
||||
.into_iter()
|
||||
.map(hive_host_sock::Ident::into_string)
|
||||
.map(hive_types::Ident::into_string)
|
||||
.collect(),
|
||||
};
|
||||
let mut rows = Vec::with_capacity(agents.len());
|
||||
|
|
|
|||
Loading…
Reference in a new issue