refactor(#1474): extract dispatch arm logic in manager_server + hive-priv

This commit is contained in:
damocles 2026-06-09 11:43:31 +02:00 committed by mara
commit 02dcf4d028
2 changed files with 336 additions and 261 deletions

View file

@ -157,8 +157,10 @@ async fn write_line_event(writer: &mut OwnedWriteHalf, stream: PrivStream, data:
/// the returned strings are empty.
#[allow(
clippy::too_many_lines,
reason = "flat dispatch table: one match arm per privileged request variant; \
splitting it would scatter the routing logic"
reason = "flat routing table over the privileged request variants — the \
logic-bearing arms (resource-limits / daemon-reload / \
restart-matrix / create+update) are extracted to helpers; the \
rest are one-line validate-then-delegate dispatches kept inline"
)]
async fn exec(req: PrivRequest, writer: &mut OwnedWriteHalf) -> Result<(String, String)> {
match req {
@ -178,35 +180,11 @@ async fn exec(req: PrivRequest, writer: &mut OwnedWriteHalf) -> Result<(String,
}
PrivRequest::UpdateContainer { ref name, stream } => {
validate_container_name(name)?;
let flake_ref = agent_flake_ref(name);
let args = [
"update",
&container_system_name(name),
"--flake",
&flake_ref,
];
if stream {
container_run_streaming(&args, writer).await
} else {
container_run(&args).await
}
container_flake_action("update", name, stream, writer).await
}
PrivRequest::CreateContainer { ref name, stream } => {
validate_container_name(name)?;
let flake_ref = agent_flake_ref(name);
let args = [
"create",
&container_system_name(name),
"--flake",
&flake_ref,
];
if stream {
container_run_streaming(&args, writer).await
} else {
container_run(&args).await
}
container_flake_action("create", name, stream, writer).await
}
PrivRequest::DestroyContainer { ref name } => {
@ -242,15 +220,7 @@ async fn exec(req: PrivRequest, writer: &mut OwnedWriteHalf) -> Result<(String,
ref container,
ref memory_max,
ref cpu_quota,
} => {
validate_container_system_name(container)?;
let dir = format!("/run/systemd/system/container@{container}.service.d");
std::fs::create_dir_all(&dir).with_context(|| format!("create {dir}"))?;
let path = format!("{dir}/hyperhive-limits.conf");
let content = format!("[Service]\nMemoryMax={memory_max}\nCPUQuota={cpu_quota}\n");
std::fs::write(&path, content).with_context(|| format!("write {path}"))?;
Ok((String::new(), String::new()))
}
} => write_resource_limits(container, memory_max, cpu_quota),
PrivRequest::RemoveServiceDropin { ref container } => {
validate_container_system_name(container)?;
@ -261,21 +231,7 @@ async fn exec(req: PrivRequest, writer: &mut OwnedWriteHalf) -> Result<(String,
Ok((String::new(), String::new()))
}
PrivRequest::DaemonReload => {
let out = Command::new("systemctl")
.arg("daemon-reload")
.output()
.await
.context("invoke systemctl daemon-reload")?;
if !out.status.success() {
bail!(
"systemctl daemon-reload failed ({}): {}",
out.status,
String::from_utf8_lossy(&out.stderr).trim()
);
}
Ok((String::new(), String::new()))
}
PrivRequest::DaemonReload => daemon_reload().await,
PrivRequest::ReloadGatewayNginx => sync_gateway_nginx().await,
@ -327,29 +283,87 @@ async fn exec(req: PrivRequest, writer: &mut OwnedWriteHalf) -> Result<(String,
}
PrivRequest::RestartMatrixDaemon { ref agent_name } => {
validate_agent_name(agent_name)?;
let machine = format!("--machine=h-{agent_name}");
let unit = "hive-matrix-daemon.service";
let out = Command::new("systemctl")
.args([&machine, "restart", unit])
.output()
.await
.with_context(|| format!("systemctl restart {unit} in container h-{agent_name}"))?;
if !out.status.success() {
bail!(
"systemctl restart {unit} in h-{agent_name} exited {}: {}",
out.status,
String::from_utf8_lossy(&out.stderr).trim()
);
}
Ok((
String::from_utf8_lossy(&out.stdout).into_owned(),
String::from_utf8_lossy(&out.stderr).into_owned(),
))
restart_matrix_daemon(agent_name).await
}
}
}
/// Shared body for `CreateContainer` / `UpdateContainer`: validate the
/// name, build the `nixos-container <verb> … --flake <ref>` argv, and
/// run it (streaming line events to `writer` when `stream` is set).
async fn container_flake_action(
verb: &str,
name: &str,
stream: bool,
writer: &mut OwnedWriteHalf,
) -> Result<(String, String)> {
validate_container_name(name)?;
let flake_ref = agent_flake_ref(name);
let args = [verb, &container_system_name(name), "--flake", &flake_ref];
if stream {
container_run_streaming(&args, writer).await
} else {
container_run(&args).await
}
}
/// `WriteResourceLimits` — drop a systemd `MemoryMax`/`CPUQuota`
/// override into the container service's drop-in dir.
fn write_resource_limits(
container: &str,
memory_max: &str,
cpu_quota: &str,
) -> Result<(String, String)> {
validate_container_system_name(container)?;
let dir = format!("/run/systemd/system/container@{container}.service.d");
std::fs::create_dir_all(&dir).with_context(|| format!("create {dir}"))?;
let path = format!("{dir}/hyperhive-limits.conf");
let content = format!("[Service]\nMemoryMax={memory_max}\nCPUQuota={cpu_quota}\n");
std::fs::write(&path, content).with_context(|| format!("write {path}"))?;
Ok((String::new(), String::new()))
}
/// `DaemonReload` — `systemctl daemon-reload` on the host.
async fn daemon_reload() -> Result<(String, String)> {
let out = Command::new("systemctl")
.arg("daemon-reload")
.output()
.await
.context("invoke systemctl daemon-reload")?;
if !out.status.success() {
bail!(
"systemctl daemon-reload failed ({}): {}",
out.status,
String::from_utf8_lossy(&out.stderr).trim()
);
}
Ok((String::new(), String::new()))
}
/// `RestartMatrixDaemon` — restart the matrix daemon unit inside the
/// agent's container.
async fn restart_matrix_daemon(agent_name: &str) -> Result<(String, String)> {
validate_agent_name(agent_name)?;
let machine = format!("--machine=h-{agent_name}");
let unit = "hive-matrix-daemon.service";
let out = Command::new("systemctl")
.args([&machine, "restart", unit])
.output()
.await
.with_context(|| format!("systemctl restart {unit} in container h-{agent_name}"))?;
if !out.status.success() {
bail!(
"systemctl restart {unit} in h-{agent_name} exited {}: {}",
out.status,
String::from_utf8_lossy(&out.stderr).trim()
);
}
Ok((
String::from_utf8_lossy(&out.stdout).into_owned(),
String::from_utf8_lossy(&out.stderr).into_owned(),
))
}
/// Shared helper for `WriteAgentForgeToken` and `WriteAgentMatrixToken`.
/// Writes `content` to `AGENT_STATE_ROOT/<agent_name>/state/<filename>`,
/// chowns to the agent user (derived from the state dir's existing owner),