Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Virtual fs refactor #4298

Open
wants to merge 65 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
3446ebe
Refactored files and fs
syrusakbary Nov 7, 2023
7ebdd61
Added NativeFS
syrusakbary Nov 7, 2023
d0bc9e7
Fixed hostfs naming
syrusakbary Nov 7, 2023
22f9f30
Make native use clean_safely for Paths
syrusakbary Nov 7, 2023
1a4b5c4
Fix linting and formatting
syrusakbary Nov 7, 2023
cd7e98b
More linting fixes
syrusakbary Nov 7, 2023
c2d2c38
Improved errors a bit further
syrusakbary Nov 7, 2023
e4785c5
Added new union fs
syrusakbary Nov 8, 2023
5cb8d10
Remove memory fs from WebC
syrusakbary Nov 8, 2023
b911ee4
Simplified webc implementation
syrusakbary Nov 8, 2023
3a6f6bf
Fixed overflow
syrusakbary Nov 8, 2023
09a300d
Fix linting
syrusakbary Nov 8, 2023
55b5a38
Improved a bit the codebase
syrusakbary Nov 9, 2023
31ebe2d
Fixed virtual-fs implementation
syrusakbary Nov 9, 2023
db392b0
Fixed running
syrusakbary Nov 10, 2023
b4b05f4
Fixed new union
syrusakbary Nov 10, 2023
e9749ae
Merge branch 'master' into virtual-fs-refactor
syrusakbary Nov 10, 2023
e7d4cc9
Replace the UnionFS
syrusakbary Nov 10, 2023
0d75a8d
Replace HostFs completely
syrusakbary Nov 10, 2023
a2116ac
Small fixes (including fixing lint)
syrusakbary Nov 10, 2023
18de2d3
Improved union
syrusakbary Nov 10, 2023
c855ef3
Fix union
syrusakbary Nov 10, 2023
8361c6b
Remove unused code
syrusakbary Nov 10, 2023
b3b66d6
Added current_dir to wasi runner
syrusakbary Nov 10, 2023
5e52097
Use dashmap in the workspace
syrusakbary Nov 10, 2023
ec0c871
Removed all dependency hacks
syrusakbary Nov 10, 2023
19140cc
Improved package fetching
syrusakbary Nov 10, 2023
dd875df
Remove unused function
syrusakbary Nov 11, 2023
4e4fe92
Removed a lot of unused code
syrusakbary Nov 11, 2023
5d0ce2e
Move things into workspace
syrusakbary Nov 11, 2023
6d2e724
Remove union_fs (can be easily achieved with memfs)
syrusakbary Nov 11, 2023
fd1fc4c
Fix use in simple wasm modules
syrusakbary Nov 11, 2023
093fa8f
Most tests now fully work
syrusakbary Nov 11, 2023
dd78a69
Removed more unused stuff. Fixed linting
syrusakbary Nov 11, 2023
551f8b5
Merge branch 'master' into virtual-fs-refactor
syrusakbary Nov 11, 2023
cbd6bdf
Improved overlay fs
syrusakbary Nov 11, 2023
3760628
Introduced directory trait
syrusakbary Nov 11, 2023
c33a895
More refactors
syrusakbary Nov 12, 2023
1162406
More fixes and improvements
syrusakbary Nov 12, 2023
daac7fe
Updated cargo
syrusakbary Nov 12, 2023
ef2b31d
Added a unique_id to the VirtualFile and Directory
syrusakbary Nov 13, 2023
a2a4655
Removed ArcFile
syrusakbary Nov 13, 2023
751cbe9
Almost there
syrusakbary Nov 13, 2023
c24da83
Fixed iterator
syrusakbary Nov 13, 2023
ec984b6
Removed FallbackFileSystem
syrusakbary Nov 13, 2023
6e3b544
Fixed a few things on virtual-fs
syrusakbary Nov 13, 2023
850e318
Removed passthru fs from testing
syrusakbary Nov 14, 2023
23e0bbd
More improvements on the virtual fs
syrusakbary Nov 14, 2023
850dac7
WASIX code is now compiling (but doesn’t work)
syrusakbary Nov 14, 2023
68e954a
Improved a bit the tests
syrusakbary Nov 17, 2023
b48bff5
Implemented much improvements in virtual-fs
syrusakbary Nov 18, 2023
892124d
More improvements on virtualfs
syrusakbary Nov 20, 2023
1683b95
Revert "WASIX code is now compiling (but doesn’t work)"
syrusakbary Nov 21, 2023
6593691
Fix chdir
syrusakbary Nov 22, 2023
183ad55
Merge branch 'master' into virtual-fs-refactor
syrusakbary Nov 22, 2023
5eebbb7
Multiple lint fixes
syrusakbary Nov 22, 2023
6873c0f
Fix python
syrusakbary Nov 22, 2023
d6b0ee0
Fixed small bugs
syrusakbary Nov 22, 2023
9e8e0b8
Use latest webc package
syrusakbary Nov 22, 2023
41a071f
Fixed mounting
syrusakbary Nov 22, 2023
7da34d5
Fix tests
syrusakbary Nov 22, 2023
5fb577f
Fix overlay test
syrusakbary Nov 22, 2023
239c322
Removed union fs wast tests
syrusakbary Nov 22, 2023
03c9517
Fixed WASIX envs
syrusakbary Nov 24, 2023
2b766e8
Added wasi.fyi tests
syrusakbary Nov 24, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 5 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,10 @@ version = "4.2.3"
enumset = "1.1.0"
memoffset = "0.9.0"
wasmer-toml = "0.9.2"
webc = { version = "5.8.0", default-features = false, features = ["package"] }
dashmap = "5.4.0"
webc = { version = "5.8.1", default-features = false, features = ["package"] }
shared-buffer = "0.1"
tempfile = "3.6.0"

[build-dependencies]
test-generator = { path = "tests/lib/test-generator" }
Expand All @@ -107,7 +110,7 @@ criterion = { version = "0.5", default-features = false }
lazy_static = "1.4"
serial_test = "0.5"
compiler-test-derive = { path = "tests/lib/compiler-test-derive" }
tempfile = "3.6.0"
tempfile.workspace = true
# For logging tests using the `RUST_LOG=debug` when testing
test-log = { version = "0.2", default-features = false, features = ["trace"] }
tracing = { version = "0.1", default-features = false, features = ["log"] }
Expand Down
2 changes: 0 additions & 2 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,6 @@ fn main() -> anyhow::Result<()> {
("host_fs", "WasiFileSystemKind::Host"),
("mem_fs", "WasiFileSystemKind::InMemory"),
("tmp_fs", "WasiFileSystemKind::Tmp"),
("passthru_fs", "WasiFileSystemKind::PassthruMemory"),
("union_fs", "WasiFileSystemKind::UnionHostMemory"),
("root_fs", "WasiFileSystemKind::RootFileSystemBuilder"),
] {
with_test_module(wasitests, wasi_filesystem_test_name, |wasitests| {
Expand Down
4 changes: 2 additions & 2 deletions lib/api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ bytes = "1"
wat = { version = "=1.0.71", optional = true }
tracing = { version = "0.1", optional = true }
rustc-demangle = "0.1"
shared-buffer = "0.1"
shared-buffer.workspace = true

# Dependencies and Development Dependencies for `sys`.
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
Expand All @@ -60,7 +60,7 @@ winapi = "0.3"
# - Development Dependencies for `sys`.
[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies]
wat = "1.0"
tempfile = "3.6.0"
tempfile.workspace = true
anyhow = "1.0"
macro-wasmer-universal-test = { version = "4.2.3", path = "./macro-wasmer-universal-test" }

Expand Down
2 changes: 1 addition & 1 deletion lib/c-api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ wasmer-emscripten = { version = "=4.2.3", path = "../emscripten", optional = tru
wasmer-middlewares = { version = "=4.2.3", path = "../middlewares", optional = true }
wasmer-types = { version = "=4.2.3", path = "../types" }
wasmer-wasix = { version = "0.16.0", path = "../wasix", features = ["host-fs", "host-vnet"], optional = true }
webc = { version = "5.0", optional = true }
webc = { workspace = true, optional = true }
virtual-fs = { version = "0.9.0", path = "../virtual-fs", optional = true, default-features = false, features = ["static-fs"] }
enumset.workspace = true
cfg-if = "1.0"
Expand Down
8 changes: 4 additions & 4 deletions lib/c-api/src/wasm_c_api/wasi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use std::sync::Arc;
#[cfg(feature = "webc_runner")]
use wasmer_api::{AsStoreMut, Imports, Module};
use wasmer_wasix::{
default_fs_backing, get_wasi_version,
get_wasi_version,
runtime::task_manager::{tokio::TokioTaskManager, InlineWaker},
virtual_fs::AsyncReadExt,
virtual_fs::VirtualFile,
Expand Down Expand Up @@ -55,7 +55,7 @@ pub unsafe extern "C" fn wasi_config_new(
inherit_stdout: true,
inherit_stderr: true,
inherit_stdin: true,
builder: WasiEnv::builder(prog_name).fs(default_fs_backing()),
builder: WasiEnv::builder(prog_name),
runtime: Some(runtime),
}))
}
Expand Down Expand Up @@ -259,7 +259,7 @@ fn prepare_webc_env(
len: usize,
package_name: &str,
) -> Option<(WasiFunctionEnv, Imports)> {
use virtual_fs::static_fs::StaticFileSystem;
use virtual_fs::static_fs::WebCStaticFileSystem;
use webc::v1::{FsEntryType, WebC};

let store_mut = store.as_store_mut();
Expand Down Expand Up @@ -294,7 +294,7 @@ fn prepare_webc_env(
})
.collect::<Vec<_>>();

let filesystem = Box::new(StaticFileSystem::init(slice, package_name)?);
let filesystem = Box::new(WebCStaticFileSystem::init(slice, package_name)?);
let mut builder = config.builder.runtime(Arc::new(rt));

if !config.inherit_stdout {
Expand Down
2 changes: 1 addition & 1 deletion lib/cache/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ blake3 = "1.0"

[dev-dependencies]
criterion = { version = "0.5", default-features = false }
tempfile = "3.6.0"
tempfile.workspace = true
rand = "0.8.3"
wasmer = { path = "../api", version = "=4.2.3", default-features = false, features = ["sys", "cranelift"] }
wasmer-compiler-singlepass = { path = "../compiler-singlepass", version = "=4.2.3" }
Expand Down
5 changes: 3 additions & 2 deletions lib/cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,9 @@ virtual-fs = { version = "0.9.0", path = "../virtual-fs", default-features = fal
virtual-net = { version = "0.6.1", path = "../virtual-net" }

# Wasmer-owned dependencies.
webc = { workspace = true }
wasmer-deploy-cli = { version = "=0.1.29", default-features = false }
webc.workspace = true
shared-buffer.workspace = true

# Third-party dependencies.

Expand All @@ -78,7 +79,7 @@ distance = "0.4"
# For the inspect subcommand
bytesize = "1.0"
cfg-if = "1.0"
tempfile = "3.6.0"
tempfile.workspace = true
serde = { version = "1.0.147", features = ["derive"] }
dirs = { version = "4.0" }
serde_json = { version = "1.0" }
Expand Down
147 changes: 121 additions & 26 deletions lib/cli/src/commands/run/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,91 @@ use wasmer_wasix::{
},
Runtime,
};
use webc::{metadata::Manifest, Container};
use webc::{
metadata::{Manifest, UrlOrManifest},
AbstractWebc, Container, Volume,
};

use crate::{commands::run::wasi::Wasi, error::PrettyError, logging::Output, store::StoreOptions};

const TICK: Duration = Duration::from_millis(250);

use shared_buffer::OwnedBuffer;
use std::borrow::Cow;

#[derive(Debug)]
struct WebcPatch {
pub(crate) base: Option<Container>,
pub patched_manifest: Manifest,
}

impl WebcPatch {
pub fn new(base: Container, uses: Vec<String>) -> Self {
let mut manifest = base.manifest().clone();
Self {
base: Some(base),
patched_manifest: Self::add_uses_to_manifest(manifest, uses),
}
}
fn add_uses_to_manifest(mut manifest: Manifest, uses: Vec<String>) -> Manifest {
for use_ in uses {
manifest
.use_map
.insert(use_.clone(), UrlOrManifest::RegistryDependentUrl(use_));
}
manifest
}
pub fn with_uses(uses: Vec<String>) -> Self {
let manifest = Manifest::default();
Self {
base: None,
patched_manifest: Self::add_uses_to_manifest(manifest, uses),
}
}
}

/// We use this to patch the dependencies at runtime
/// So the user can do `--use` to set their own dependencies
impl AbstractWebc for WebcPatch {
fn manifest(&self) -> &Manifest {
&self.patched_manifest
}

fn atom_names(&self) -> Vec<Cow<'_, str>> {
self.base
.as_ref()
.map(|base| {
base.atoms()
.keys()
.map(String::to_owned)
.map(Cow::from)
.collect()
})
.unwrap_or(vec![])
}

fn get_atom(&self, name: &str) -> Option<OwnedBuffer> {
self.base.as_ref().and_then(|base| base.get_atom(name))
}

fn volume_names(&self) -> Vec<Cow<'_, str>> {
self.base
.as_ref()
.map(|base| {
base.volumes()
.keys()
.map(String::to_owned)
.map(Cow::from)
.collect()
})
.unwrap_or(vec![])
}

fn get_volume(&self, name: &str) -> Option<Volume> {
self.base.as_ref().and_then(|base| base.get_volume(name))
}
}

/// The unstable `wasmer run` subcommand.
#[derive(Debug, Parser)]
pub struct Run {
Expand Down Expand Up @@ -122,9 +201,33 @@ impl Run {
let result = {
match target {
ExecutableTarget::WebAssembly { module, path } => {
self.execute_wasm(&path, &module, store, runtime)
let pkg = if !self.wasi.uses.is_empty() {
let patched_container =
Container::new(WebcPatch::with_uses(self.wasi.uses.clone()));
let inner_runtime = runtime.clone();
let pkg = runtime.task_manager().spawn_and_block_on(async move {
BinaryPackage::from_webc(&patched_container, inner_runtime.as_ref())
.await
})?;
Some(pkg)
} else {
None
};

self.execute_wasm(&path, &module, store, pkg.as_ref(), runtime)
}
ExecutableTarget::Container(container) => {
pb.set_message("Resolving dependencies");

let patched_container =
Container::new(WebcPatch::new(container, self.wasi.uses.clone()));
let inner_runtime = runtime.clone();
let pkg = runtime.task_manager().spawn_and_block_on(async move {
BinaryPackage::from_webc(&patched_container, inner_runtime.as_ref()).await
})?;

self.execute_webc(&pkg, runtime)
}
ExecutableTarget::Package(pkg) => self.execute_webc(&pkg, runtime),
}
};

Expand All @@ -141,12 +244,13 @@ impl Run {
path: &Path,
module: &Module,
mut store: Store,
pkg: Option<&BinaryPackage>,
runtime: Arc<dyn Runtime + Send + Sync>,
) -> Result<(), Error> {
if wasmer_emscripten::is_emscripten_module(module) {
self.execute_emscripten_module()
} else if wasmer_wasix::is_wasi_module(module) || wasmer_wasix::is_wasix_module(module) {
self.execute_wasi_module(path, module, runtime, store)
self.execute_wasi_module(path, module, runtime, pkg, store)
} else {
self.execute_pure_wasm_module(module, &mut store)
}
Expand Down Expand Up @@ -228,12 +332,13 @@ impl Run {
) -> Result<(), Error> {
let mut runner = wasmer_wasix::runners::wcgi::WcgiRunner::new();

let root_fs = self.wasi.get_fs()?;
runner
.config()
.args(self.args.clone())
.addr(self.wcgi.addr)
.envs(self.wasi.env_vars.clone())
.map_directories(self.wasi.mapped_dirs.clone())
.with_fs(root_fs)
.callbacks(Callbacks::new(self.wcgi.addr))
.inject_packages(uses);
*runner.config().capabilities() = self.wasi.capabilities();
Expand Down Expand Up @@ -298,8 +403,9 @@ impl Run {
.with_args(&self.args)
.with_injected_packages(packages)
.with_envs(self.wasi.env_vars.clone())
.with_fs(self.wasi.get_fs()?)
.with_current_dir(PathBuf::from(Wasi::MAPPED_CURRENT_DIR_DEFAULT_PATH))
.with_mapped_host_commands(self.wasi.build_mapped_commands()?)
.with_mapped_directories(self.wasi.build_mapped_directories()?)
.with_forward_host_env(self.wasi.forward_host_env)
.with_capabilities(self.wasi.capabilities());

Expand All @@ -312,15 +418,17 @@ impl Run {
wasm_path: &Path,
module: &Module,
runtime: Arc<dyn Runtime + Send + Sync>,
pkg: Option<&BinaryPackage>,
mut store: Store,
) -> Result<(), Error> {
let program_name = wasm_path.display().to_string();

let runner = self.build_wasi_runner(&runtime)?;
let mut runner = self.build_wasi_runner(&runtime)?;
runner.run_wasm(
runtime,
&program_name,
module,
pkg,
self.wasi.enable_async_threads,
)
}
Expand Down Expand Up @@ -488,10 +596,10 @@ impl PackageSource {
pb.set_message("Loading from the registry");
let inner_pck = pkg.clone();
let inner_rt = rt.clone();
let pkg = rt.task_manager().spawn_and_block_on(async move {
BinaryPackage::from_registry(&inner_pck, inner_rt.as_ref()).await
let container = rt.task_manager().spawn_and_block_on(async move {
BinaryPackage::get_container_from_registry(&inner_pck, inner_rt.as_ref()).await
})?;
Ok(ExecutableTarget::Package(pkg))
Ok(ExecutableTarget::Container(container))
}
}
}
Expand Down Expand Up @@ -557,7 +665,7 @@ impl TargetOnDisk {
#[derive(Debug, Clone)]
enum ExecutableTarget {
WebAssembly { module: Module, path: PathBuf },
Package(BinaryPackage),
Container(Container),
}

impl ExecutableTarget {
Expand All @@ -574,14 +682,7 @@ impl ExecutableTarget {
let manifest_path = dir.join("wasmer.toml");
let webc = webc::wasmer_package::Package::from_manifest(manifest_path)?;
let container = Container::from(webc);

pb.set_message("Resolving dependencies");
let inner_runtime = runtime.clone();
let pkg = runtime.task_manager().spawn_and_block_on(async move {
BinaryPackage::from_webc(&container, inner_runtime.as_ref()).await
})?;

Ok(ExecutableTarget::Package(pkg))
Ok(ExecutableTarget::Container(container))
}

/// Try to load a file into something that can be used to run it.
Expand Down Expand Up @@ -619,13 +720,7 @@ impl ExecutableTarget {
}
TargetOnDisk::LocalWebc => {
let container = Container::from_disk(path)?;
pb.set_message("Resolving dependencies");

let inner_runtime = runtime.clone();
let pkg = runtime.task_manager().spawn_and_block_on(async move {
BinaryPackage::from_webc(&container, inner_runtime.as_ref()).await
})?;
Ok(ExecutableTarget::Package(pkg))
Ok(ExecutableTarget::Container(container))
}
}
}
Expand Down
Loading
Loading