fix: route gateway nginx control through hive-priv
systemctl --machine=hive-gateway requires root (machine-bus transport enters the container namespace). hive-c0re is unprivileged, so every call to nginx_active_state() and gateway_systemctl() silently failed with exit 1, causing a continuous 30s retry loop without ever syncing nginx. Fix: - Move state-aware nginx logic into hive-priv ReloadGatewayNginx: check ActiveState, then reload/reset-start/start accordingly. hive-priv already runs as root and has machine-bus rights. - Remove nginx_active_state() and gateway_systemctl() from gateway_nginx.rs (they were always running unprivileged, always failing silently). - Make write(), reload_if_pending(), reload_gateway_nginx() async so they can call the async priv_client without a blocking bridge. - Update callers in agent_sockets::spawn_poll and meta::sync_agents to await the now-async functions. The priv_client::reload_gateway_nginx() call and PrivRequest::ReloadGatewayNginx wire type already existed — the gateway_nginx module was just not using them.
This commit is contained in:
parent
7cf7f043ad
commit
1d062d1e3e
4 changed files with 103 additions and 139 deletions
|
|
@ -289,24 +289,72 @@ async fn exec(req: PrivRequest, writer: &mut OwnedWriteHalf) -> Result<(String,
|
|||
}
|
||||
|
||||
PrivRequest::ReloadGatewayNginx => {
|
||||
let out = Command::new("systemd-run")
|
||||
// Query the nginx unit's ActiveState inside the gateway container.
|
||||
// Requires root: --machine= transport enters the container namespace
|
||||
// via the machine bus, which is forbidden for unprivileged users.
|
||||
let state_out = Command::new("systemctl")
|
||||
.args([
|
||||
"--machine=hive-gateway",
|
||||
"--quiet",
|
||||
"--",
|
||||
"show",
|
||||
"--property=ActiveState",
|
||||
"--value",
|
||||
"nginx",
|
||||
"-s",
|
||||
"reload",
|
||||
])
|
||||
.output()
|
||||
.await
|
||||
.context("invoke systemd-run for gateway nginx reload")?;
|
||||
if !out.status.success() {
|
||||
bail!(
|
||||
"gateway nginx reload failed ({}): {}",
|
||||
out.status,
|
||||
String::from_utf8_lossy(&out.stderr).trim()
|
||||
);
|
||||
.context("query nginx ActiveState in hive-gateway")?;
|
||||
let state = String::from_utf8_lossy(&state_out.stdout).trim().to_owned();
|
||||
// State-aware action: reload when running; reset+start after
|
||||
// start-limit failure; plain start when inactive or unknown.
|
||||
match state.as_str() {
|
||||
"active" => {
|
||||
let out = Command::new("systemctl")
|
||||
.args(["--machine=hive-gateway", "reload", "nginx"])
|
||||
.output()
|
||||
.await
|
||||
.context("reload nginx in hive-gateway")?;
|
||||
if !out.status.success() {
|
||||
bail!(
|
||||
"gateway nginx reload failed ({}): {}",
|
||||
out.status,
|
||||
String::from_utf8_lossy(&out.stderr).trim()
|
||||
);
|
||||
}
|
||||
}
|
||||
"failed" => {
|
||||
// Clear start-limit hit so the next start can proceed.
|
||||
let _ = Command::new("systemctl")
|
||||
.args(["--machine=hive-gateway", "reset-failed", "nginx"])
|
||||
.status()
|
||||
.await;
|
||||
let out = Command::new("systemctl")
|
||||
.args(["--machine=hive-gateway", "start", "nginx"])
|
||||
.output()
|
||||
.await
|
||||
.context("start nginx after reset-failed in hive-gateway")?;
|
||||
if !out.status.success() {
|
||||
bail!(
|
||||
"gateway nginx start (after reset-failed) failed ({}): {}",
|
||||
out.status,
|
||||
String::from_utf8_lossy(&out.stderr).trim()
|
||||
);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
// inactive, activating, deactivating, unknown — just start.
|
||||
let out = Command::new("systemctl")
|
||||
.args(["--machine=hive-gateway", "start", "nginx"])
|
||||
.output()
|
||||
.await
|
||||
.context("start nginx in hive-gateway")?;
|
||||
if !out.status.success() {
|
||||
bail!(
|
||||
"gateway nginx start failed (state={state}) ({}): {}",
|
||||
out.status,
|
||||
String::from_utf8_lossy(&out.stderr).trim()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok((String::new(), String::new()))
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue