agent UDS: chmod per-agent socket dir 0777 + log web_ui::serve errors

The harness runs as the non-root agent user; the per-agent
/run/hive-agent/<name>/ dir lands at 0755 root:root after
create_dir_all, so bind(2) of web.sock failed with EACCES. The error
was invisible because the web_ui::serve future was tokio::spawn'd with
its JoinHandle dropped — no log, no socket, agent looks unreachable
through the gateway.
This commit is contained in:
müde 2026-05-31 21:38:28 +02:00
commit 8b238bbfaf
2 changed files with 29 additions and 3 deletions

View file

@ -1219,6 +1219,18 @@ fn set_nspawn_flags(
let socket_dir = crate::agent_sockets::agent_dir_for(agent_name);
std::fs::create_dir_all(&socket_dir)
.with_context(|| format!("create {}", socket_dir.display()))?;
// 0777 so the in-container agent user (`sock`, `iris`, …) can
// `bind(2)` the `web.sock` file here. `create_dir_all` lands
// the dir at 0755 root:root; the harness runs as the non-root
// agent user inside the container and otherwise fails the
// bind with EACCES — silently, since web_ui::serve's spawn
// drops its JoinHandle (the gateway then sees an empty
// agent-sockets.json and the agent appears unreachable).
// Per-agent dir + per-agent bind-mount means no other
// container ever sees this path, so the wide mode is contained.
use std::os::unix::fs::PermissionsExt;
std::fs::set_permissions(&socket_dir, std::fs::Permissions::from_mode(0o777))
.with_context(|| format!("chmod 0777 {}", socket_dir.display()))?;
let _ = write!(
binds,
" --bind={socket_dir}:{socket_dir}",