refactor(#1474): extract dispatch arm logic in manager_server + hive-priv
This commit is contained in:
parent
c6d9f59c4d
commit
02dcf4d028
2 changed files with 336 additions and 261 deletions
|
|
@ -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),
|
||||
|
|
|
|||
Loading…
Reference in a new issue