refactor(#2352): route hivectl github set-token through a daemon wire command
This commit is contained in:
parent
756e850681
commit
6c654921a0
3 changed files with 49 additions and 14 deletions
|
|
@ -696,7 +696,7 @@ async fn main() -> Result<()> {
|
||||||
agent,
|
agent,
|
||||||
token,
|
token,
|
||||||
token_stdin,
|
token_stdin,
|
||||||
} => github_set_token(&agent, token, token_stdin).await,
|
} => github_set_token(&socket, &agent, token, token_stdin).await,
|
||||||
},
|
},
|
||||||
Cmd::Gateway { cmd } => match cmd {
|
Cmd::Gateway { cmd } => match cmd {
|
||||||
GatewayCmd::CreateUser {
|
GatewayCmd::CreateUser {
|
||||||
|
|
@ -1234,7 +1234,15 @@ fn choom(name: &str, resume_session: Option<&str>) -> Result<()> {
|
||||||
/// into the agent's `github-token` state file (0600, agent-owned) via
|
/// into the agent's `github-token` state file (0600, agent-owned) via
|
||||||
/// hive-priv, so the agent's `gh` wrapper + git credential helper can
|
/// hive-priv, so the agent's `gh` wrapper + git credential helper can
|
||||||
/// authenticate. Read live at invocation, so no rebuild/restart is needed.
|
/// authenticate. Read live at invocation, so no rebuild/restart is needed.
|
||||||
async fn github_set_token(agent: &str, token: Option<String>, token_stdin: bool) -> Result<()> {
|
async fn github_set_token(
|
||||||
|
socket: &Path,
|
||||||
|
agent: &str,
|
||||||
|
token: Option<String>,
|
||||||
|
token_stdin: bool,
|
||||||
|
) -> Result<()> {
|
||||||
|
// Resolve + validate the token client-side (inline flag or stdin read);
|
||||||
|
// the daemon never touches this process's stdin. Persistence happens
|
||||||
|
// daemon-side via the privileged helper.
|
||||||
let token = match (token, token_stdin) {
|
let token = match (token, token_stdin) {
|
||||||
(Some(t), _) => t,
|
(Some(t), _) => t,
|
||||||
(None, true) => {
|
(None, true) => {
|
||||||
|
|
@ -1250,12 +1258,15 @@ async fn github_set_token(agent: &str, token: Option<String>, token_stdin: bool)
|
||||||
if token.is_empty() {
|
if token.is_empty() {
|
||||||
bail!("refusing to write an empty GitHub token for agent '{agent}'");
|
bail!("refusing to write an empty GitHub token for agent '{agent}'");
|
||||||
}
|
}
|
||||||
hive_c0re::priv_client::write_agent_github_token(agent, &token).await?;
|
daemon_request(
|
||||||
println!(
|
socket,
|
||||||
"wrote github-token for agent '{agent}' \
|
hive_host_sock::HostRequest::SetAgentGithubToken {
|
||||||
(read live by the gh wrapper / git credential helper — no rebuild needed)"
|
agent: agent.to_owned(),
|
||||||
);
|
token,
|
||||||
Ok(())
|
},
|
||||||
|
"github",
|
||||||
|
)
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn forge_create_user(
|
async fn forge_create_user(
|
||||||
|
|
@ -1269,26 +1280,31 @@ async fn forge_create_user(
|
||||||
// agent-vs-operator branch, and token persistence now live in the
|
// agent-vs-operator branch, and token persistence now live in the
|
||||||
// daemon handler.
|
// daemon handler.
|
||||||
let password = resolve_password(password, password_stdin)?;
|
let password = resolve_password(password, password_stdin)?;
|
||||||
forge_request(
|
daemon_request(
|
||||||
socket,
|
socket,
|
||||||
hive_host_sock::HostRequest::ForgeCreateUser {
|
hive_host_sock::HostRequest::ForgeCreateUser {
|
||||||
name: name.to_owned(),
|
name: name.to_owned(),
|
||||||
password,
|
password,
|
||||||
},
|
},
|
||||||
|
"forge",
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Send a forge provisioning request to the daemon and print its result
|
/// Send a provisioning request to the daemon and print its result lines.
|
||||||
/// lines. Mirrors [`matrix_request`] — the daemon owns the provisioning
|
/// The daemon owns the provisioning logic; hivectl just relays the outcome,
|
||||||
/// logic; hivectl just relays the outcome.
|
/// prefixing any error with `label` (e.g. `forge` / `github`).
|
||||||
async fn forge_request(socket: &Path, req: hive_host_sock::HostRequest) -> Result<()> {
|
async fn daemon_request(
|
||||||
|
socket: &Path,
|
||||||
|
req: hive_host_sock::HostRequest,
|
||||||
|
label: &str,
|
||||||
|
) -> Result<()> {
|
||||||
let resp = hive_c0re::client::request(socket, req)
|
let resp = hive_c0re::client::request(socket, req)
|
||||||
.await
|
.await
|
||||||
.with_context(|| format!("connect to daemon socket {}", socket.display()))?;
|
.with_context(|| format!("connect to daemon socket {}", socket.display()))?;
|
||||||
if !resp.ok {
|
if !resp.ok {
|
||||||
bail!(
|
bail!(
|
||||||
"forge: {}",
|
"{label}: {}",
|
||||||
resp.error.as_deref().unwrap_or("unknown error")
|
resp.error.as_deref().unwrap_or("unknown error")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -196,6 +196,9 @@ async fn dispatch(req: &HostRequest, coord: Arc<Coordinator>) -> HostResponse {
|
||||||
HostRequest::ForgeCreateUser { name, password } => {
|
HostRequest::ForgeCreateUser { name, password } => {
|
||||||
handle_forge_create_user(name, password.as_deref()).await?
|
handle_forge_create_user(name, password.as_deref()).await?
|
||||||
}
|
}
|
||||||
|
HostRequest::SetAgentGithubToken { agent, token } => {
|
||||||
|
handle_set_agent_github_token(agent, token).await?
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
.await;
|
.await;
|
||||||
|
|
@ -395,6 +398,16 @@ async fn handle_forge_create_user(name: &str, password: Option<&str>) -> Result<
|
||||||
Ok(HostResponse::messages(out))
|
Ok(HostResponse::messages(out))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn handle_set_agent_github_token(agent: &str, token: &str) -> Result<HostResponse> {
|
||||||
|
crate::priv_client::write_agent_github_token(agent, token)
|
||||||
|
.await
|
||||||
|
.with_context(|| format!("write github-token for agent {agent}"))?;
|
||||||
|
Ok(HostResponse::messages(vec![format!(
|
||||||
|
"wrote github-token for agent '{agent}' \
|
||||||
|
(read live by the gh wrapper / git credential helper — no rebuild needed)"
|
||||||
|
)]))
|
||||||
|
}
|
||||||
|
|
||||||
async fn handle_matrix_sync_admin() -> Result<HostResponse> {
|
async fn handle_matrix_sync_admin() -> Result<HostResponse> {
|
||||||
require_matrix_present().await?;
|
require_matrix_present().await?;
|
||||||
let register_token =
|
let register_token =
|
||||||
|
|
|
||||||
|
|
@ -158,6 +158,12 @@ pub enum HostRequest {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
password: Option<String>,
|
password: Option<String>,
|
||||||
},
|
},
|
||||||
|
/// Write (or overwrite) an agent's GitHub PAT under its state dir, via
|
||||||
|
/// the privileged helper. Daemon-side equivalent of `hivectl github
|
||||||
|
/// set-token`. `token` is resolved + non-empty-validated client-side
|
||||||
|
/// (inline flag or stdin); the daemon just persists it. Read live by
|
||||||
|
/// the agent's `gh` wrapper / git credential helper — no rebuild needed.
|
||||||
|
SetAgentGithubToken { agent: String, token: String },
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Selects which container classes a hive-wide [`HostRequest::Stop`] /
|
/// Selects which container classes a hive-wide [`HostRequest::Stop`] /
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue