Watch
0
0
Fork
You've already forked hyperhive
0
hyperhive/hivectl/src/matrix.rs
atlas ddb7d7196d matrix: swarm-controller is the only minter
Every hive is in a swarm and every swarm runs matrix, so every swarm has a
swarm-controller, and since #4810 its hive_sender pass mints each hive's
@hive-<hive>: sender token into the store every five minutes. The two
other minters of that token go:

- swarm-matrix-ctl mint: the systemd.services.swarm-matrix-ctl unit in the
  hive-matrix container, Command::Mint and src/mint.rs. The binary, its
  appservice render/publish verbs, ctlPackage, ctlActive and the ctl cert
  role stay. bao-matrix-reader's checks on the deleted unit are removed;
  the leaf-identity and no-token-in-env checks now look at
  swarm-matrix-appservice-publish, which runs under the same identity.
- the hive-side mint ladder in hive-c0re's ensure_hive_user
  (register/appservice-login/password-login with the local as_token), with
  read_appservice_token, paths::matrix_appservice_token and the helpers
  only it used. ensure_hive_user now takes the store's token, keeps the
  file when the store has none or can't be reached, and fails otherwise.
- hivectl matrix sync-admin: the verb, HostRequest::MatrixSyncAdmin and
  handle_matrix_sync_admin. The periodic MatrixSweep (ensure_all) is
  unchanged apart from no longer reading the local as_token.

This removes the double-mint race #4810's review flagged: two minters
logging in on one pinned device could leave a dead token in the store
until the next pass.

Closes #4813
Closes #4814
2026-09-30 00:46:46 +02:00

48 lines
1.6 KiB
Rust

//! `hivectl matrix` — matrix provisioning verbs. hivectl forwards
//! each request to the daemon (which owns the sender token) and renders the
//! reply; it no longer links the matrix machinery itself.
use std::path::Path;
use anyhow::{Context as _, Result, bail};
use crate::cli::MatrixCmd;
/// Route a `matrix` subcommand to its handler. Extracted from `main`'s
/// dispatch match so the top-level router stays small.
pub(crate) async fn run_matrix_cmd(socket: &Path, cmd: MatrixCmd) -> Result<()> {
match cmd {
MatrixCmd::Invite { user, room } => matrix_invite(socket, &user, room.as_deref()).await,
}
}
/// Send a matrix provisioning request to the daemon and print the
/// operator-facing result lines it returns. The daemon owns the sender token,
/// so hivectl no longer links the matrix machinery — it just forwards the
/// request and renders the reply.
async fn matrix_request(socket: &Path, req: hive_host_sock::HostRequest) -> Result<()> {
let resp = crate::client::request(socket, req)
.await
.with_context(|| format!("connect to daemon socket {}", socket.display()))?;
if !resp.ok {
bail!(
"matrix: {}",
resp.error.as_deref().unwrap_or("unknown error")
);
}
for line in &resp.messages {
println!("{line}");
}
Ok(())
}
async fn matrix_invite(socket: &Path, user: &str, room: Option<&str>) -> Result<()> {
matrix_request(
socket,
hive_host_sock::HostRequest::MatrixInvite {
user: user.to_owned(),
room: room.map(str::to_owned),
},
)
.await
}