bind a namespaced agent's socket dir off /run so its owner maps to the agent user
This commit is contained in:
parent
23f4f1823b
commit
6847ed865a
1 changed files with 53 additions and 7 deletions
|
|
@ -465,11 +465,7 @@ async fn set_nspawn_flags(
|
|||
// to the agent user. Don't chown or chmod it here.
|
||||
let socket_dir = crate::agent_sockets::agent_dir_for(agent_name);
|
||||
crate::priv_client::ensure_agent_socket_dir(agent_name, private_users).await?;
|
||||
binds.push(BindMount {
|
||||
host_path: socket_dir.to_string_lossy().into_owned(),
|
||||
container_path: socket_dir.to_string_lossy().into_owned(),
|
||||
read_only: false,
|
||||
});
|
||||
binds.push(socket_bind(agent_name, &socket_dir, private_users));
|
||||
|
||||
// Every container runs in a private network namespace with a veth
|
||||
// pair attached to the host bridge — including the manager (all
|
||||
|
|
@ -495,6 +491,29 @@ async fn set_nspawn_flags(
|
|||
.await
|
||||
}
|
||||
|
||||
/// The bind of the agent's socket dir.
|
||||
///
|
||||
/// A namespaced agent's binds are mounted `owneridmap`, which maps the owner of
|
||||
/// the mount point inside the container to the host owner. nspawn mounts a
|
||||
/// fresh tmpfs on `/run` before the binds, so a mount point under `/run` is
|
||||
/// created by nspawn owned by root, and the agent user would have no mapping
|
||||
/// (EOVERFLOW). A namespaced agent gets the dir at `/agents/<name>/sockets`,
|
||||
/// whose mount point hive-priv owns to the agent; the agent module links
|
||||
/// `/run/hive-agent/<name>` to it.
|
||||
fn socket_bind(agent_name: &str, socket_dir: &Path, private_users: Option<bool>) -> BindMount {
|
||||
let host_path = socket_dir.to_string_lossy().into_owned();
|
||||
let container_path = if private_users == Some(true) {
|
||||
format!("/agents/{agent_name}/sockets")
|
||||
} else {
|
||||
host_path.clone()
|
||||
};
|
||||
BindMount {
|
||||
host_path,
|
||||
container_path,
|
||||
read_only: false,
|
||||
}
|
||||
}
|
||||
|
||||
/// What hive-priv is told about the agent's user namespace: the record's flag,
|
||||
/// or `None` (leave the agent as it is) when there is no record or it cannot be
|
||||
/// read, so a swarm outage never turns a namespaced agent off or on.
|
||||
|
|
@ -555,6 +574,21 @@ mod tests {
|
|||
/// The flag in the record is what hive-priv is told, both ways. No record
|
||||
/// and an unreadable one say nothing, so a swarm outage changes no agent's
|
||||
/// namespace; a record from before the field reads false.
|
||||
/// Only a namespaced agent's socket dir moves off `/run`.
|
||||
#[test]
|
||||
fn the_socket_dir_leaves_run_only_for_a_namespaced_agent() {
|
||||
let dir = std::path::Path::new("/run/hive-agent/iris");
|
||||
for private_users in [None, Some(false)] {
|
||||
let b = super::socket_bind("iris", dir, private_users);
|
||||
assert_eq!(b.container_path, "/run/hive-agent/iris");
|
||||
assert_eq!(b.host_path, "/run/hive-agent/iris");
|
||||
}
|
||||
let b = super::socket_bind("iris", dir, Some(true));
|
||||
assert_eq!(b.container_path, "/agents/iris/sockets");
|
||||
assert_eq!(b.host_path, "/run/hive-agent/iris");
|
||||
assert!(!b.read_only);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_records_flag_is_what_the_start_path_passes() {
|
||||
assert_eq!(
|
||||
|
|
|
|||
Loading…
Reference in a new issue