Keep world copies writable and include embedded host assets
This commit is contained in:
@@ -41,7 +41,8 @@
|
||||
in !(pkgs.lib.hasPrefix "userland/" relative || pkgs.lib.hasPrefix "spikes/" relative)
|
||||
&& (craneLib.filterCargoSources path type
|
||||
|| pkgs.lib.hasSuffix ".wit" path || pkgs.lib.hasSuffix ".witx" path
|
||||
|| pkgs.lib.hasSuffix ".js" path);
|
||||
|| pkgs.lib.hasSuffix ".js" path || pkgs.lib.hasSuffix ".html" path
|
||||
|| pkgs.lib.hasSuffix ".wasm" path);
|
||||
};
|
||||
v8Archive = pkgs.fetchurl {
|
||||
# deno_core enables rusty_v8's simdutf feature.
|
||||
|
||||
+43
-1
@@ -5,6 +5,7 @@
|
||||
//! - `host/`: host state outside the sandbox (harness storage, later the vault). No guest sees it.
|
||||
use sausage_vfs::{Generated, Host, Layer, Memory, Mounts, Process};
|
||||
use std::{
|
||||
os::unix::fs::PermissionsExt,
|
||||
path::{Path, PathBuf},
|
||||
sync::Arc,
|
||||
};
|
||||
@@ -21,13 +22,19 @@ 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());
|
||||
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(())
|
||||
@@ -85,3 +92,38 @@ 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(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user