fix(#962): top_level_agents_in delegates to children_of(MANAGER_NAME)
The previous parent=None heuristic was wrong — the manager is not required to be the structural topology root (it can have a parent). Delegate to children_of_in(MANAGER_NAME) directly; topology.rs is the right place for this knowledge. Update comment in lifecycle.rs to say "direct child of the manager" instead of "direct child of root".
This commit is contained in:
parent
828be8e2c8
commit
a4e0628ba1
2 changed files with 11 additions and 20 deletions
|
|
@ -1149,9 +1149,10 @@ fn set_nspawn_flags(
|
||||||
}
|
}
|
||||||
|
|
||||||
// `can_manage_top_level_agents` role: additionally mount every
|
// `can_manage_top_level_agents` role: additionally mount every
|
||||||
// top-level agent (direct child of root) as a virtual child. Enables
|
// top-level agent (direct child of the manager) as a virtual child.
|
||||||
// recovery — a role holder can update a top-level agent's config even
|
// Enables recovery — a role holder can update a top-level agent's
|
||||||
// when that agent is down. Also grants RO access to /applied and /meta.
|
// config even when that agent is down. Also grants RO access to
|
||||||
|
// /applied and /meta.
|
||||||
if crate::topology::has_role(
|
if crate::topology::has_role(
|
||||||
agent_name,
|
agent_name,
|
||||||
crate::topology::ROLE_CAN_MANAGE_TOP_LEVEL_AGENTS,
|
crate::topology::ROLE_CAN_MANAGE_TOP_LEVEL_AGENTS,
|
||||||
|
|
|
||||||
|
|
@ -74,14 +74,13 @@ pub fn children_of_in(
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the agents that are direct children of the topology root
|
/// Return the direct children of the manager agent — the "top-level"
|
||||||
/// (the unique agent whose own parent is `None`). These are the
|
/// agents that role holders with `can_manage_top_level_agents` are
|
||||||
/// "top-level" agents — one layer below the auto-managed manager.
|
/// granted access to.
|
||||||
///
|
///
|
||||||
/// Callers should use this instead of `children_of(MANAGER_NAME)` so
|
/// Callers outside `topology` should use this instead of
|
||||||
/// the manager's logical name is not hardcoded outside lifecycle.rs.
|
/// `children_of(MANAGER_NAME)` so the manager's logical name stays
|
||||||
/// If the topology has no root agent (e.g. empty file on cold boot),
|
/// confined to the topology module.
|
||||||
/// returns an empty vec.
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn top_level_agents() -> Vec<String> {
|
pub fn top_level_agents() -> Vec<String> {
|
||||||
top_level_agents_in(&read())
|
top_level_agents_in(&read())
|
||||||
|
|
@ -90,16 +89,7 @@ pub fn top_level_agents() -> Vec<String> {
|
||||||
/// Pure form of [`top_level_agents`] for unit tests.
|
/// Pure form of [`top_level_agents`] for unit tests.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn top_level_agents_in(topo: &BTreeMap<String, Option<String>>) -> Vec<String> {
|
pub fn top_level_agents_in(topo: &BTreeMap<String, Option<String>>) -> Vec<String> {
|
||||||
// Find the unique root (parent = None). If none or multiple exist,
|
children_of_in(topo, crate::lifecycle::MANAGER_NAME)
|
||||||
// fall back to empty — the topology is malformed or uninitialised.
|
|
||||||
let roots: Vec<&str> = topo
|
|
||||||
.iter()
|
|
||||||
.filter_map(|(name, parent)| if parent.is_none() { Some(name.as_str()) } else { None })
|
|
||||||
.collect();
|
|
||||||
match roots.as_slice() {
|
|
||||||
[root] => children_of_in(topo, root),
|
|
||||||
_ => vec![],
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Resolve a magic recipient sentinel (currently just
|
/// Resolve a magic recipient sentinel (currently just
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue