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,
|
||||
token,
|
||||
token_stdin,
|
||||
} => github_set_token(&agent, token, token_stdin).await,
|
||||
} => github_set_token(&socket, &agent, token, token_stdin).await,
|
||||
},
|
||||
Cmd::Gateway { cmd } => match cmd {
|
||||
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
|
||||
/// hive-priv, so the agent's `gh` wrapper + git credential helper can
|
||||
/// 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) {
|
||||
(Some(t), _) => t,
|
||||
(None, true) => {
|
||||
|
|
@ -1250,12 +1258,15 @@ async fn github_set_token(agent: &str, token: Option<String>, token_stdin: bool)
|
|||
if token.is_empty() {
|
||||
bail!("refusing to write an empty GitHub token for agent '{agent}'");
|
||||
}
|
||||
hive_c0re::priv_client::write_agent_github_token(agent, &token).await?;
|
||||
println!(
|
||||
"wrote github-token for agent '{agent}' \
|
||||
(read live by the gh wrapper / git credential helper — no rebuild needed)"
|
||||
);
|
||||
Ok(())
|
||||
daemon_request(
|
||||
socket,
|
||||
hive_host_sock::HostRequest::SetAgentGithubToken {
|
||||
agent: agent.to_owned(),
|
||||
token,
|
||||
},
|
||||
"github",
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
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
|
||||
// daemon handler.
|
||||
let password = resolve_password(password, password_stdin)?;
|
||||
forge_request(
|
||||
daemon_request(
|
||||
socket,
|
||||
hive_host_sock::HostRequest::ForgeCreateUser {
|
||||
name: name.to_owned(),
|
||||
password,
|
||||
},
|
||||
"forge",
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
/// Send a forge provisioning request to the daemon and print its result
|
||||
/// lines. Mirrors [`matrix_request`] — the daemon owns the provisioning
|
||||
/// logic; hivectl just relays the outcome.
|
||||
async fn forge_request(socket: &Path, req: hive_host_sock::HostRequest) -> Result<()> {
|
||||
/// Send a provisioning request to the daemon and print its result lines.
|
||||
/// The daemon owns the provisioning logic; hivectl just relays the outcome,
|
||||
/// prefixing any error with `label` (e.g. `forge` / `github`).
|
||||
async fn daemon_request(
|
||||
socket: &Path,
|
||||
req: hive_host_sock::HostRequest,
|
||||
label: &str,
|
||||
) -> Result<()> {
|
||||
let resp = hive_c0re::client::request(socket, req)
|
||||
.await
|
||||
.with_context(|| format!("connect to daemon socket {}", socket.display()))?;
|
||||
if !resp.ok {
|
||||
bail!(
|
||||
"forge: {}",
|
||||
"{label}: {}",
|
||||
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 } => {
|
||||
handle_forge_create_user(name, password.as_deref()).await?
|
||||
}
|
||||
HostRequest::SetAgentGithubToken { agent, token } => {
|
||||
handle_set_agent_github_token(agent, token).await?
|
||||
}
|
||||
})
|
||||
}
|
||||
.await;
|
||||
|
|
@ -395,6 +398,16 @@ async fn handle_forge_create_user(name: &str, password: Option<&str>) -> Result<
|
|||
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> {
|
||||
require_matrix_present().await?;
|
||||
let register_token =
|
||||
|
|
|
|||
|
|
@ -158,6 +158,12 @@ pub enum HostRequest {
|
|||
#[serde(default)]
|
||||
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`] /
|
||||
|
|
|
|||
Loading…
Reference in a new issue