keep the knowledge .git overlay unconditional
This commit is contained in:
parent
23b0c4cd55
commit
35a49aaf42
1 changed files with 22 additions and 9 deletions
|
|
@ -346,20 +346,25 @@ fn validate_bind_path(path: &str) -> Result<()> {
|
|||
/// Config mounts are matched by shape, not by a name list: the set is
|
||||
/// dynamic, growing with each child bound into a parent.
|
||||
///
|
||||
/// Only a bind whose host source has a `.git` entry gets the overlay: nspawn
|
||||
/// must create the mount point inside the read-only bind, which fails
|
||||
/// (`EROFS`) where there is nothing to mount over. An archetype agent's
|
||||
/// config is an empty directory. The entry is looked up without following a
|
||||
/// symlink, and a symlink named `.git` counts as present, so a path that
|
||||
/// leads somewhere else is still hidden.
|
||||
/// `/knowledge` is overlaid unconditionally: its directory is created empty
|
||||
/// and cloned into later, so a container started before the clone must
|
||||
/// already hide the `.git` that arrives. A config mount gets the overlay only
|
||||
/// when its host source has a `.git` entry: nspawn must create the mount
|
||||
/// point inside the read-only bind, which fails (`EROFS`) where there is
|
||||
/// nothing to mount over, as in an archetype agent's empty config directory.
|
||||
/// The entry is looked up without following a symlink, and a symlink named
|
||||
/// `.git` counts as present, so a path that leads somewhere else is still
|
||||
/// hidden.
|
||||
fn git_overlay_flags(binds: &[BindMount]) -> Vec<String> {
|
||||
binds
|
||||
.iter()
|
||||
.filter(|b| {
|
||||
let p = b.container_path.as_str();
|
||||
p == "/knowledge" || (p.starts_with("/agents/") && p.ends_with("/config"))
|
||||
p == "/knowledge"
|
||||
|| (p.starts_with("/agents/")
|
||||
&& p.ends_with("/config")
|
||||
&& std::fs::symlink_metadata(Path::new(&b.host_path).join(".git")).is_ok())
|
||||
})
|
||||
.filter(|b| std::fs::symlink_metadata(Path::new(&b.host_path).join(".git")).is_ok())
|
||||
.map(|b| format!("--tmpfs={}/.git", b.container_path))
|
||||
.collect()
|
||||
}
|
||||
|
|
@ -712,12 +717,20 @@ mod tests {
|
|||
let empty = scratch().to_string_lossy().into_owned();
|
||||
let flags = git_overlay_flags(&[
|
||||
bind_from(&empty, "/agents/updo/config"),
|
||||
bind_from(&empty, "/knowledge"),
|
||||
bind_from(&repo_source(), "/agents/atlas/config"),
|
||||
]);
|
||||
assert_eq!(flags, ["--tmpfs=/agents/atlas/config/.git"]);
|
||||
}
|
||||
|
||||
/// `/knowledge` is cloned into after the container may have started, so
|
||||
/// its overlay does not wait for a `.git` to exist.
|
||||
#[test]
|
||||
fn an_empty_knowledge_source_still_gets_the_overlay() {
|
||||
let empty = scratch().to_string_lossy().into_owned();
|
||||
let flags = git_overlay_flags(&[bind_from(&empty, "/knowledge")]);
|
||||
assert_eq!(flags, ["--tmpfs=/knowledge/.git"]);
|
||||
}
|
||||
|
||||
/// A symlink named `.git` is not followed: it counts as present, even
|
||||
/// dangling, so the path it leads to is hidden rather than skipped.
|
||||
#[test]
|
||||
|
|
|
|||
Loading…
Reference in a new issue