Merge v3-t17: Nix package with the complete userland, builder closure and seeded world tree; v2 removed (T17)

# Conflicts:
#	README.md
This commit is contained in:
2026-11-08 05:24:15 +00:00
145 changed files with 260 additions and 22270 deletions
+58 -1
View File
@@ -5,6 +5,7 @@
//! - `host/`: host state outside the sandbox (harness storage, later the vault). No guest sees it.
use sausage_vfs::{Device, Generated, Host, Layer, Memory, Mounts, Process};
use std::{
os::unix::fs::PermissionsExt,
path::{Path, PathBuf},
sync::Arc,
};
@@ -21,6 +22,9 @@ pub struct World {
fn copy_tree(source: &Path, destination: &Path) -> std::io::Result<()> {
std::fs::create_dir_all(destination)?;
let mut permissions = std::fs::metadata(destination)?.permissions();
permissions.set_mode(permissions.mode() | 0o200);
std::fs::set_permissions(destination, permissions)?;
for entry in std::fs::read_dir(source)? {
let entry = entry?;
let target = destination.join(entry.file_name());
@@ -29,7 +33,10 @@ fn copy_tree(source: &Path, destination: &Path) -> std::io::Result<()> {
} else if entry.file_type()?.is_dir() {
copy_tree(&entry.path(), &target)?;
} else {
std::fs::copy(entry.path(), target)?;
std::fs::copy(entry.path(), &target)?;
let mut permissions = std::fs::metadata(&target)?.permissions();
permissions.set_mode(permissions.mode() | 0o200);
std::fs::set_permissions(&target, permissions)?;
}
}
Ok(())
@@ -127,3 +134,53 @@ impl World {
})
}
}
#[cfg(test)]
#[test]
fn readonly_bundle_copies_are_writable() -> std::io::Result<()> {
use std::fs;
let bundle = tempfile::tempdir()?;
let world = tempfile::tempdir()?;
for (name, mode) in [("bin/tool.wasm", 0o555), ("src/lib.rs", 0o444)] {
let path = bundle.path().join(name);
fs::create_dir_all(path.parent().unwrap())?;
fs::write(&path, b"original")?;
fs::set_permissions(path, fs::Permissions::from_mode(mode))?;
}
for path in [
bundle.path().join("bin"),
bundle.path().join("src"),
bundle.path().to_owned(),
world.path().to_owned(),
] {
fs::set_permissions(path, fs::Permissions::from_mode(0o555))?;
}
let result = copy_tree(bundle.path(), world.path());
// Restore source directories so the temporary directory can remove its files.
for path in [
bundle.path(),
&bundle.path().join("bin"),
&bundle.path().join("src"),
] {
fs::set_permissions(path, fs::Permissions::from_mode(0o755))?;
}
result?;
assert_eq!(
fs::metadata(world.path())?.permissions().mode() & 0o777,
0o755
);
for (name, mode) in [("bin/tool.wasm", 0o555), ("src/lib.rs", 0o444)] {
let source = bundle.path().join(name);
let target = world.path().join(name);
assert_eq!(fs::metadata(&source)?.permissions().mode() & 0o777, mode);
assert_eq!(
fs::metadata(&target)?.permissions().mode() & 0o777,
mode | 0o200
);
fs::write(&target, b"changed")?;
assert_eq!(fs::read(source)?, b"original");
}
fs::write(world.path().join("bin/added.wasm"), b"new")?;
fs::write(world.path().join("src/added.rs"), b"new")?;
Ok(())
}