//! The hive's `meta/` directory: plain state beside the hive's other files //! (`topology.json`, the swarm limits) that the manager container sees //! read-only. Agents are built from the swarm's `internal/meta` //! ([`crate::meta_rev`]), not from anything here. use anyhow::{Context, Result}; /// Where the manager sees this directory inside its container (RO bind). pub const CONTAINER_MANAGER_META_MOUNT: &str = "/meta"; /// Delete the permission seed files a hive that predates the swarm's /// permissions left in the meta directory. Their grants live in the swarm's /// `agent-permissions` bucket once `workers::permissions_import` has sent /// them. A file already gone is fine. /// /// # Errors /// /// Removing a file fails. pub fn remove_permission_files() -> Result<()> { remove_in( &crate::paths::meta_root(), crate::workers::permissions_import::META_FILES, ) } fn remove_in(dir: &std::path::Path, files: &[&str]) -> Result<()> { for file in files { match std::fs::remove_file(dir.join(file)) { Ok(()) => {} Err(e) if e.kind() == std::io::ErrorKind::NotFound => {} Err(e) => return Err(e).with_context(|| format!("removing {file}")), } } Ok(()) } #[cfg(test)] mod tests { use super::remove_in; #[test] fn the_listed_files_go_and_nothing_else() { let dir = tempfile::tempdir().unwrap(); for name in ["capabilities.json", "tool-groups.json", "topology.json"] { std::fs::write(dir.path().join(name), "{}").unwrap(); } remove_in(dir.path(), &["capabilities.json", "tool-groups.json"]).unwrap(); assert!(!dir.path().join("capabilities.json").exists()); assert!(!dir.path().join("tool-groups.json").exists()); assert!( dir.path().join("topology.json").exists(), "other state stays" ); // A file already gone is fine. remove_in(dir.path(), &["capabilities.json"]).unwrap(); } #[test] fn a_file_that_cannot_be_removed_is_an_error_naming_it() { let dir = tempfile::tempdir().unwrap(); // A directory where the file belongs fails with a non-NotFound error. std::fs::create_dir(dir.path().join("capabilities.json")).unwrap(); let err = remove_in(dir.path(), &["capabilities.json"]).unwrap_err(); assert!( format!("{err:#}").contains("removing capabilities.json"), "{err:#}" ); } }