agent permissions: drop hive-c0re's swarm-agent-permissions.json fallback, fail closed before the first read
Removes the HiveCopy hand-off: hive-c0re no longer writes each agent's entry from swarm-agent-permissions.json into its runtime dir as swarm-permissions.json, and the harness and subagent daemon no longer read it. hive-c0re keeps the file as its own last read of the swarm for the manage_root_agent mounts. Also removes permissions_import::pending(), its only caller being the hand-off. No nix provisioned the copy, so no nix option is removed and no tombstone is needed. Rule after this change: until an agent's first successful read of its key it holds no permissions (no execution, so no bash), and a subagent it starts holds the same. After a read a set key wins, [] holds none and an unset key is the default. A failed read keeps the last value, so an unreachable queue at start keeps the agent closed until a read succeeds. The harness logs once at warn that it starts closed. Fixes #5315
This commit is contained in:
parent
6e7b5f84e9
commit
2f00f9041f
2 changed files with 121 additions and 283 deletions
|
|
@ -120,13 +120,6 @@ fn meta_dir() -> PathBuf {
|
|||
crate::paths::meta_root()
|
||||
}
|
||||
|
||||
/// Whether a meta repo file is still waiting to be imported.
|
||||
#[must_use]
|
||||
pub fn pending() -> bool {
|
||||
let meta = meta_dir();
|
||||
META_FILES.iter().any(|f| meta.join(f).exists())
|
||||
}
|
||||
|
||||
/// Store the files' grants as the last-read swarm permissions, when a file
|
||||
/// is still there and nothing has been stored yet.
|
||||
pub fn seed_local() {
|
||||
|
|
|
|||
|
|
@ -6,9 +6,7 @@
|
|||
//! [`crate::permissions`], where the container's bind mounts are worked out.
|
||||
//! Those are fixed when the container starts, so an agent whose
|
||||
//! `manage_root_agent` changed is restarted, after its current turn. The
|
||||
//! agent applies the rest of its permissions itself; after every pass each
|
||||
//! agent's copy of its stored entry is refreshed
|
||||
//! ([`crate::permissions::hand_at`]), which it holds until it reads its key.
|
||||
//! agent applies the rest of its permissions itself.
|
||||
//!
|
||||
//! A failed read, or a bucket that does not answer, leaves the stored
|
||||
//! permissions as they are and restarts nothing.
|
||||
|
|
@ -71,7 +69,6 @@ pub async fn follow(
|
|||
});
|
||||
}
|
||||
}
|
||||
hand_all().await;
|
||||
tokio::select! {
|
||||
() = tokio::time::sleep(READ_INTERVAL) => {}
|
||||
_ = shutdown.changed() => {
|
||||
|
|
@ -136,24 +133,6 @@ where
|
|||
.collect())
|
||||
}
|
||||
|
||||
/// Refresh the copy of its stored permissions each agent with a runtime dir
|
||||
/// holds, so it follows this pass's reads and the import's progress.
|
||||
async fn hand_all() {
|
||||
let agents = match crate::lifecycle::agents_for_meta_listing().await {
|
||||
Ok(agents) => agents,
|
||||
Err(e) => {
|
||||
tracing::warn!(error = ?e, "swarm permissions: enumerating agents to hand their copies failed");
|
||||
return;
|
||||
}
|
||||
};
|
||||
for spec in agents {
|
||||
let dir = crate::paths::agent_runtime_dir(&spec.name);
|
||||
if dir.is_dir() {
|
||||
crate::lifecycle::hand_permissions(&spec.name, &dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether `agent` holds the one permission hive-c0re enforces under `stored`.
|
||||
fn manages(agent: &str, stored: &Stored) -> bool {
|
||||
permissions::effective(stored.get(agent)).contains(&Permission::ManageRootAgent)
|
||||
|
|
|
|||
Loading…
Reference in a new issue