diff --git a/Cargo.lock b/Cargo.lock index 754f61cc32a..958ce2c2cf1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2601,9 +2601,9 @@ checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" [[package]] name = "openssl" -version = "0.10.47" +version = "0.10.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8b277f87dacc05a6b709965d1cbafac4649d6ce9f3ce9ceb88508b5666dfec9" +checksum = "518915b97df115dd36109bfa429a48b8f737bd05508cf9588977b599648926d2" dependencies = [ "bitflags", "cfg-if 1.0.0", @@ -2633,9 +2633,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.82" +version = "0.9.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a95792af3c4e0153c3914df2261bedd30a98476f94dc892b67dfe1d89d433a04" +checksum = "666416d899cf077260dac8698d60a60b435a46d57e82acb1be3d0dad87284e5b" dependencies = [ "autocfg", "cc", diff --git a/lib/vfs/src/host_fs.rs b/lib/vfs/src/host_fs.rs index ef4f3fc4633..0cc925adaa3 100644 --- a/lib/vfs/src/host_fs.rs +++ b/lib/vfs/src/host_fs.rs @@ -1267,7 +1267,7 @@ mod tests { "creating `b.txt`", ); - let readdir = fs.read_dir(&temp.path()); + let readdir = fs.read_dir(temp.path()); assert!( readdir.is_ok(), diff --git a/lib/vfs/src/lib.rs b/lib/vfs/src/lib.rs index e20f42b4580..0bb51c1acd3 100644 --- a/lib/vfs/src/lib.rs +++ b/lib/vfs/src/lib.rs @@ -37,6 +37,7 @@ mod overlay_fs; pub mod pipe; #[cfg(feature = "static-fs")] pub mod static_fs; +mod trace_fs; #[cfg(feature = "webc-fs")] pub mod webc_fs; @@ -54,6 +55,7 @@ pub use passthru_fs::*; pub use pipe::*; pub use special_file::*; pub use tmp_fs::*; +pub use trace_fs::TraceFileSystem; pub use union_fs::*; pub use zero_file::*; @@ -535,7 +537,7 @@ impl ReadDir { } } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct DirEntry { pub path: PathBuf, // weird hack, to fix this we probably need an internal trait object or callbacks or something @@ -565,7 +567,7 @@ impl DirEntry { } #[allow(clippy::len_without_is_empty)] // Clippy thinks it's an iterator. -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug, Default, PartialEq, Eq)] // TODO: review this, proper solution would probably use a trait object internally pub struct Metadata { pub ft: FileType, @@ -605,7 +607,7 @@ impl Metadata { } } -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug, Default, PartialEq, Eq)] // TODO: review this, proper solution would probably use a trait object internally pub struct FileType { pub dir: bool, diff --git a/lib/vfs/src/overlay_fs.rs b/lib/vfs/src/overlay_fs.rs index d65a81c0ecd..3c304bc8de8 100644 --- a/lib/vfs/src/overlay_fs.rs +++ b/lib/vfs/src/overlay_fs.rs @@ -1,4 +1,11 @@ -use std::{fmt::Debug, path::Path}; +use std::{ + fmt::Debug, + path::{Path, PathBuf}, + pin::Pin, + task::Poll, +}; + +use tokio::io::{AsyncRead, AsyncSeek, AsyncWrite}; use crate::{ ops, FileOpener, FileSystem, FileSystems, FsError, Metadata, OpenOptions, OpenOptionsConfig, @@ -120,14 +127,7 @@ where } had_at_least_one_success = true; } - Err(e) - if { - let e = e; - matches!(e, FsError::EntryNotFound) - } => - { - continue - } + Err(e) if should_continue(e) => continue, Err(e) => return Err(e), } } @@ -148,11 +148,7 @@ where fn create_dir(&self, path: &Path) -> Result<(), FsError> { match self.primary.create_dir(path) { - Err(e) - if { - let e = e; - matches!(e, FsError::EntryNotFound) - } => {} + Err(e) if should_continue(e) => {} other => return other, } @@ -161,11 +157,7 @@ where fn remove_dir(&self, path: &Path) -> Result<(), FsError> { match self.primary.remove_dir(path) { - Err(e) - if { - let e = e; - matches!(e, FsError::EntryNotFound) - } => {} + Err(e) if should_continue(e) => {} other => return other, } @@ -174,11 +166,7 @@ where fn rename(&self, from: &Path, to: &Path) -> Result<(), FsError> { match self.primary.rename(from, to) { - Err(e) - if { - let e = e; - matches!(e, FsError::EntryNotFound) - } => {} + Err(e) if should_continue(e) => {} other => return other, } @@ -188,24 +176,13 @@ where fn metadata(&self, path: &Path) -> Result { match self.primary.metadata(path) { Ok(meta) => return Ok(meta), - Err(e) - if { - let e = e; - matches!(e, FsError::EntryNotFound) - } => {} + Err(e) if should_continue(e) => {} Err(e) => return Err(e), } for fs in self.secondaries.filesystems() { match fs.metadata(path) { - Err(e) - if { - let e = e; - matches!(e, FsError::EntryNotFound) - } => - { - continue - } + Err(e) if should_continue(e) => continue, other => return other, } } @@ -215,11 +192,7 @@ where fn remove_file(&self, path: &Path) -> Result<(), FsError> { match self.primary.remove_file(path) { - Err(e) - if { - let e = e; - matches!(e, FsError::EntryNotFound) - } => {} + Err(e) if should_continue(e) => {} other => return other, } @@ -247,11 +220,7 @@ where .options(conf.clone()) .open(path) { - Err(e) - if { - let e = e; - matches!(e, FsError::EntryNotFound) - } => {} + Err(e) if should_continue(e) => {} other => return other, } @@ -279,19 +248,13 @@ where } if opening_would_require_mutations(&self.secondaries, path, conf) { - return Err(FsError::PermissionDenied); + // HACK: we should return Err(FsError::PermissionDenied) here + return open_readonly_file_hack(path, conf, &self.secondaries); } for fs in self.secondaries.filesystems() { match fs.new_open_options().options(conf.clone()).open(path) { - Err(e) - if { - let e = e; - matches!(e, FsError::EntryNotFound) - } => - { - continue - } + Err(e) if should_continue(e) => continue, other => return other, } } @@ -300,6 +263,147 @@ where } } +/// HACK(Michael-F-Bryan): In theory, you shouldn't be able to open a file in +/// one of the [`OverlayFileSystem`]'s secondaries in write mode because the +/// filesystem is meant to be readonly. However, Python does things like +/// `open("./lib/python3.6/io.py", "rw")` when importing its standard library +/// and we want Python to work, so we'll defer the [`FsError::PermissionDenied`] +/// error until the first write operation. +/// +/// We shouldn't need to do this because opening a secondary fs's file in write +/// mode goes against the "read-write primary, readonly secondaries" goal. +fn open_readonly_file_hack( + path: &Path, + conf: &OpenOptionsConfig, + secondaries: &S, +) -> Result, FsError> +where + S: for<'a> FileSystems<'a> + Send + Sync + 'static, +{ + #[derive(Debug)] + struct ReadOnlyFile { + path: PathBuf, + inner: Box, + } + + impl VirtualFile for ReadOnlyFile { + fn last_accessed(&self) -> u64 { + self.inner.last_accessed() + } + + fn last_modified(&self) -> u64 { + self.inner.last_modified() + } + + fn created_time(&self) -> u64 { + self.inner.created_time() + } + + fn size(&self) -> u64 { + self.inner.size() + } + + fn set_len(&mut self, new_size: u64) -> crate::Result<()> { + self.inner.set_len(new_size) + } + + fn unlink(&mut self) -> crate::Result<()> { + Err(FsError::PermissionDenied) + } + + fn poll_read_ready( + mut self: Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> Poll> { + Pin::new(&mut *self.inner).poll_read_ready(cx) + } + + fn poll_write_ready( + mut self: Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> Poll> { + Pin::new(&mut *self.inner).poll_write_ready(cx) + } + } + + impl AsyncWrite for ReadOnlyFile { + fn poll_write( + self: Pin<&mut Self>, + _cx: &mut std::task::Context<'_>, + _buf: &[u8], + ) -> Poll> { + tracing::warn!( + path=%self.path.display(), + "Attempting to write to a readonly file", + ); + Poll::Ready(Err(std::io::ErrorKind::PermissionDenied.into())) + } + + fn poll_flush( + self: Pin<&mut Self>, + _cx: &mut std::task::Context<'_>, + ) -> Poll> { + tracing::warn!( + path=%self.path.display(), + "Attempting to flush a readonly file", + ); + Poll::Ready(Err(std::io::ErrorKind::PermissionDenied.into())) + } + + fn poll_shutdown( + self: Pin<&mut Self>, + _cx: &mut std::task::Context<'_>, + ) -> Poll> { + tracing::warn!( + path=%self.path.display(), + "Attempting to shutdown a readonly file", + ); + Poll::Ready(Err(std::io::ErrorKind::PermissionDenied.into())) + } + } + + impl AsyncRead for ReadOnlyFile { + fn poll_read( + mut self: Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + buf: &mut tokio::io::ReadBuf<'_>, + ) -> Poll> { + Pin::new(&mut *self.inner).poll_read(cx, buf) + } + } + + impl AsyncSeek for ReadOnlyFile { + fn start_seek( + mut self: Pin<&mut Self>, + position: std::io::SeekFrom, + ) -> std::io::Result<()> { + Pin::new(&mut *self.inner).start_seek(position) + } + + fn poll_complete( + mut self: Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> Poll> { + Pin::new(&mut *self.inner).poll_complete(cx) + } + } + + for fs in secondaries.filesystems() { + match fs.new_open_options().options(conf.clone()).open(path) { + Ok(f) => { + return Ok(Box::new(ReadOnlyFile { + path: path.to_path_buf(), + inner: f, + })); + } + Err(e) if should_continue(e) => continue, + other => return other, + } + } + + Err(FsError::EntryNotFound) +} + fn opening_would_require_mutations( secondaries: &S, path: &Path, @@ -356,16 +460,30 @@ where } } +fn should_continue(e: FsError) -> bool { + // HACK: We shouldn't really be ignoring FsError::BaseNotDirectory, but + // it's needed because the mem_fs::FileSystem doesn't return + // FsError::EntryNotFound when an intermediate directory doesn't exist + // (i.e. the "/path/to" in "/path/to/file.txt"). + matches!( + e, + FsError::EntryNotFound | FsError::InvalidInput | FsError::BaseNotDirectory + ) +} + #[cfg(test)] mod tests { use std::{path::PathBuf, sync::Arc}; use tempfile::TempDir; - use tokio::io::AsyncWriteExt; + use tokio::io::{AsyncReadExt, AsyncWriteExt}; + use webc::v1::{ParseOptions, WebCOwned}; use super::*; use crate::{mem_fs::FileSystem as MemFS, webc_fs::WebcFileSystem, RootFileSystemBuilder}; + const PYTHON: &[u8] = include_bytes!("../../c-api/examples/assets/python-0.1.0.wasmer"); + #[test] fn object_safe() { fn _box_with_memfs( @@ -413,7 +531,7 @@ mod tests { FsError::EntryNotFound, "Deleted from primary" ); - assert!(!ops::exists(&overlay.secondaries[0], &second)); + assert!(!ops::exists(&overlay.secondaries[0], second)); // Directory on the primary fs isn't empty assert_eq!( @@ -540,11 +658,7 @@ mod tests { .unwrap(); } // Set up the secondary file systems - let webc = webc::v1::WebCOwned::parse( - include_bytes!("../../c-api/examples/assets/python-0.1.0.wasmer").to_vec(), - &webc::v1::ParseOptions::default(), - ) - .unwrap(); + let webc = WebCOwned::parse(PYTHON.to_vec(), &ParseOptions::default()).unwrap(); let webc = WebcFileSystem::init_all(Arc::new(webc)); let fs = OverlayFileSystem::new(primary, [webc]); @@ -557,14 +671,19 @@ mod tests { // We also want to see files from the WEBC volumes (secondary) assert!(ops::is_dir(&fs, "/lib/python3.6")); assert!(ops::is_file(&fs, "/lib/python3.6/collections/__init__.py")); - // files on a secondary fs aren't writable - assert_eq!( - fs.new_open_options() - .append(true) - .open("/lib/python3.6/collections/__init__.py") - .unwrap_err(), - FsError::PermissionDenied, - ); + #[cfg(never)] + { + // files on a secondary fs aren't writable + // TODO(Michael-F-Bryan): re-enable this if/when we fix + // open_readonly_file_hack() + assert_eq!( + fs.new_open_options() + .append(true) + .open("/lib/python3.6/collections/__init__.py") + .unwrap_err(), + FsError::PermissionDenied, + ); + } // you are allowed to create files that look like they are in a secondary // folder, though ops::touch(&fs, "/lib/python3.6/collections/something-else.py").unwrap(); @@ -612,4 +731,100 @@ mod tests { "asdf" ); } + + fn load_webc(bytes: &'static [u8]) -> WebcFileSystem { + let options = ParseOptions::default(); + let webc = WebCOwned::parse(bytes.into(), &options).unwrap(); + WebcFileSystem::init_all(Arc::new(webc)) + } + + #[track_caller] + fn assert_same_directory_contents( + original: &dyn FileSystem, + path: impl AsRef, + candidate: &dyn FileSystem, + ) { + let path = path.as_ref(); + + let original_entries: Vec<_> = original + .read_dir(path) + .unwrap() + .map(|r| r.unwrap()) + .collect(); + let candidate_entries: Vec<_> = candidate + .read_dir(path) + .unwrap() + .map(|r| r.unwrap()) + .collect(); + + assert_eq!(original_entries, candidate_entries); + } + + #[test] + fn absolute_and_relative_paths_are_passed_through() { + let python = Arc::new(load_webc(PYTHON)); + + // The underlying filesystem doesn't care about absolute/relative paths + assert_eq!(python.read_dir("/lib".as_ref()).unwrap().count(), 4); + assert_eq!(python.read_dir("lib".as_ref()).unwrap().count(), 4); + + // read_dir() should be passed through to the primary + let webc_primary = + OverlayFileSystem::new(Arc::clone(&python), [crate::EmptyFileSystem::default()]); + assert_same_directory_contents(&python, "/lib", &webc_primary); + assert_same_directory_contents(&python, "lib", &webc_primary); + + // read_dir() should also be passed through to the secondary + let webc_secondary = + OverlayFileSystem::new(crate::EmptyFileSystem::default(), [Arc::clone(&python)]); + assert_same_directory_contents(&python, "/lib", &webc_secondary); + assert_same_directory_contents(&python, "lib", &webc_secondary); + + // It should be fine to overlay the root fs on top of our webc file + let overlay_rootfs = OverlayFileSystem::new( + RootFileSystemBuilder::default().build(), + [Arc::clone(&python)], + ); + assert_same_directory_contents(&python, "/lib", &overlay_rootfs); + assert_same_directory_contents(&python, "lib", &overlay_rootfs); + } + + #[tokio::test] + async fn open_secondary_fs_files_in_write_mode_and_error_on_first_write() { + // TODO(Michael-F-Bryan): remove this test if/when we fix + // open_readonly_file_hack() + let primary = MemFS::default(); + let secondary = MemFS::default(); + ops::create_dir_all(&secondary, "/secondary").unwrap(); + ops::write(&secondary, "/secondary/file.txt", b"Hello, World!") + .await + .unwrap(); + + let fs = OverlayFileSystem::new(primary, [secondary]); + + let mut f = fs + .new_open_options() + .write(true) + .read(true) + .open("/secondary/file.txt") + .unwrap(); + // reading is fine + let mut buf = String::new(); + f.read_to_string(&mut buf).await.unwrap(); + assert_eq!(buf, "Hello, World!"); + // but trying to write will error out + assert_eq!( + f.write(b"..").await.unwrap_err().kind(), + std::io::ErrorKind::PermissionDenied, + ); + // Same with flushing and shutdown + assert_eq!( + f.flush().await.unwrap_err().kind(), + std::io::ErrorKind::PermissionDenied, + ); + assert_eq!( + f.shutdown().await.unwrap_err().kind(), + std::io::ErrorKind::PermissionDenied, + ); + } } diff --git a/lib/vfs/src/trace_fs.rs b/lib/vfs/src/trace_fs.rs new file mode 100644 index 00000000000..d6346f9a463 --- /dev/null +++ b/lib/vfs/src/trace_fs.rs @@ -0,0 +1,240 @@ +use std::{ + path::PathBuf, + pin::Pin, + task::{Context, Poll}, +}; + +use tokio::io::{AsyncRead, AsyncSeek, AsyncWrite, ReadBuf}; + +use crate::{FileOpener, FileSystem, OpenOptionsConfig, VirtualFile}; + +/// A [`FileSystem`] wrapper that will automatically log all operations at the +/// `trace` level. +/// +/// To see these logs, you will typically need to set the `$RUST_LOG` +/// environment variable to `virtual_fs::trace_fs=trace`. +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct TraceFileSystem(pub F); + +impl TraceFileSystem { + pub fn new(filesystem: F) -> Self { + TraceFileSystem(filesystem) + } + + pub fn inner(&self) -> &F { + &self.0 + } + + pub fn inner_mut(&mut self) -> &mut F { + &mut self.0 + } + + pub fn into_inner(self) -> F { + self.0 + } +} + +impl FileSystem for TraceFileSystem +where + F: FileSystem, +{ + #[tracing::instrument(level = "trace", skip(self), err)] + fn read_dir(&self, path: &std::path::Path) -> crate::Result { + self.0.read_dir(path) + } + + #[tracing::instrument(level = "trace", skip(self), err)] + fn create_dir(&self, path: &std::path::Path) -> crate::Result<()> { + self.0.create_dir(path) + } + + #[tracing::instrument(level = "trace", skip(self), err)] + fn remove_dir(&self, path: &std::path::Path) -> crate::Result<()> { + self.0.remove_dir(path) + } + + #[tracing::instrument(level = "trace", skip(self), err)] + fn rename(&self, from: &std::path::Path, to: &std::path::Path) -> crate::Result<()> { + self.0.rename(from, to) + } + + #[tracing::instrument(level = "trace", skip(self), err)] + fn metadata(&self, path: &std::path::Path) -> crate::Result { + self.0.metadata(path) + } + + #[tracing::instrument(level = "trace", skip(self), err)] + fn remove_file(&self, path: &std::path::Path) -> crate::Result<()> { + self.0.remove_file(path) + } + + #[tracing::instrument(level = "trace", skip(self))] + fn new_open_options(&self) -> crate::OpenOptions { + crate::OpenOptions::new(self) + } +} + +impl FileOpener for TraceFileSystem +where + F: FileSystem, +{ + #[tracing::instrument(level = "trace", skip(self))] + fn open( + &self, + path: &std::path::Path, + conf: &OpenOptionsConfig, + ) -> crate::Result> { + let file = self.0.new_open_options().options(conf.clone()).open(path)?; + + Ok(Box::new(TraceFile { + file, + path: path.to_path_buf(), + })) + } +} + +#[derive(Debug)] +struct TraceFile { + path: PathBuf, + file: Box, +} + +impl VirtualFile for TraceFile { + #[tracing::instrument(level = "trace", skip(self), fields(path=%self.path.display()))] + fn last_accessed(&self) -> u64 { + self.file.last_accessed() + } + + #[tracing::instrument(level = "trace", skip(self), fields(path=%self.path.display()))] + fn last_modified(&self) -> u64 { + self.file.last_modified() + } + + #[tracing::instrument(level = "trace", skip(self), fields(path=%self.path.display()))] + fn created_time(&self) -> u64 { + self.file.created_time() + } + + #[tracing::instrument(level = "trace", skip(self), fields(path=%self.path.display()))] + fn size(&self) -> u64 { + self.file.size() + } + + #[tracing::instrument(level = "trace", skip(self), fields(path=%self.path.display()), err)] + fn set_len(&mut self, new_size: u64) -> crate::Result<()> { + self.file.set_len(new_size) + } + + #[tracing::instrument(level = "trace", skip(self), fields(path=%self.path.display()), err)] + fn unlink(&mut self) -> crate::Result<()> { + self.file.unlink() + } + + #[tracing::instrument(level = "trace", skip_all, fields(path=%self.path.display()))] + fn poll_read_ready( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll> { + let result = Pin::new(&mut *self.file).poll_read_ready(cx); + + if let Poll::Ready(Err(e)) = &result { + tracing::trace!(error = e as &dyn std::error::Error); + } + + result + } + + #[tracing::instrument(level = "trace", skip_all, fields(path=%self.path.display()))] + fn poll_write_ready( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll> { + let result = Pin::new(&mut *self.file).poll_write_ready(cx); + + if let Poll::Ready(Err(e)) = &result { + tracing::trace!(error = e as &dyn std::error::Error); + } + + result + } +} + +impl AsyncRead for TraceFile { + #[tracing::instrument(level = "trace", skip_all, fields(path=%self.path.display()))] + fn poll_read( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &mut ReadBuf<'_>, + ) -> Poll> { + let result = Pin::new(&mut *self.file).poll_read(cx, buf); + + if let Poll::Ready(Err(e)) = &result { + tracing::trace!(error = e as &dyn std::error::Error); + } + + result + } +} + +impl AsyncWrite for TraceFile { + #[tracing::instrument(level = "trace", skip_all, fields(path=%self.path.display()))] + fn poll_write( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &[u8], + ) -> Poll> { + let result = Pin::new(&mut *self.file).poll_write(cx, buf); + + if let Poll::Ready(Err(e)) = &result { + tracing::trace!(error = e as &dyn std::error::Error); + } + + result + } + + #[tracing::instrument(level = "trace", skip_all, fields(path=%self.path.display()))] + fn poll_flush( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll> { + let result = Pin::new(&mut *self.file).poll_flush(cx); + + if let Poll::Ready(Err(e)) = &result { + tracing::trace!(error = e as &dyn std::error::Error); + } + + result + } + + #[tracing::instrument(level = "trace", skip_all, fields(path=%self.path.display()))] + fn poll_shutdown( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll> { + let result = Pin::new(&mut *self.file).poll_shutdown(cx); + + if let Poll::Ready(Err(e)) = &result { + tracing::trace!(error = e as &dyn std::error::Error); + } + + result + } +} + +impl AsyncSeek for TraceFile { + #[tracing::instrument(level = "trace", skip_all, fields(path=%self.path.display()), err)] + fn start_seek(mut self: Pin<&mut Self>, position: std::io::SeekFrom) -> std::io::Result<()> { + Pin::new(&mut *self.file).start_seek(position) + } + + #[tracing::instrument(level = "trace", skip_all, fields(path=%self.path.display()))] + fn poll_complete(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let result = Pin::new(&mut *self.file).poll_complete(cx); + + if let Poll::Ready(Err(e)) = &result { + tracing::trace!(error = e as &dyn std::error::Error); + } + + result + } +} diff --git a/lib/wasi/src/runners/container.rs b/lib/wasi/src/runners/container.rs index 810f5b6c0ca..3a9a45c4acf 100644 --- a/lib/wasi/src/runners/container.rs +++ b/lib/wasi/src/runners/container.rs @@ -111,17 +111,15 @@ impl WapmContainer { /// Get the entire container as a single filesystem and a list of suggested /// directories to preopen. - pub(crate) fn container_fs(&self) -> (Box, Vec) { + pub(crate) fn container_fs(&self) -> Arc { match &self.repr { Repr::V1Mmap(mapped) => { let fs = WebcFileSystem::init_all(Arc::clone(mapped)); - let top_level_dirs = fs.top_level_dirs().clone(); - (Box::new(fs), top_level_dirs) + Arc::new(fs) } Repr::V1Owned(owned) => { let fs = WebcFileSystem::init_all(Arc::clone(owned)); - let top_level_dirs = fs.top_level_dirs().clone(); - (Box::new(fs), top_level_dirs) + Arc::new(fs) } } } diff --git a/lib/wasi/src/runners/mod.rs b/lib/wasi/src/runners/mod.rs index 95206dd097e..d08667ba8df 100644 --- a/lib/wasi/src/runners/mod.rs +++ b/lib/wasi/src/runners/mod.rs @@ -5,6 +5,8 @@ mod runner; pub mod emscripten; #[cfg(feature = "webc_runner_rt_wasi")] pub mod wasi; +#[cfg(any(feature = "webc_runner_rt_wasi", feature = "webc_runner_rt_wcgi"))] +mod wasi_common; #[cfg(feature = "webc_runner_rt_wcgi")] pub mod wcgi; @@ -13,10 +15,8 @@ pub use self::{ runner::Runner, }; -use std::path::PathBuf; - #[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)] pub struct MappedDirectory { - pub host: PathBuf, + pub host: std::path::PathBuf, pub guest: String, } diff --git a/lib/wasi/src/runners/wasi.rs b/lib/wasi/src/runners/wasi.rs index d17b72382ac..03b36436bf1 100644 --- a/lib/wasi/src/runners/wasi.rs +++ b/lib/wasi/src/runners/wasi.rs @@ -1,45 +1,39 @@ //! WebC container support for running WASI modules -use std::{collections::HashMap, sync::Arc}; +use std::sync::Arc; -use crate::{ - runners::{MappedDirectory, WapmContainer}, - PluggableRuntime, VirtualTaskManager, -}; -use crate::{WasiEnv, WasiEnvBuilder}; use anyhow::{Context, Error}; use serde::{Deserialize, Serialize}; use wasmer::{Module, Store}; use webc::metadata::{annotations::Wasi, Command}; +use crate::{ + runners::{wasi_common::CommonWasiOptions, MappedDirectory, WapmContainer}, + PluggableRuntime, VirtualTaskManager, WasiEnvBuilder, +}; + #[derive(Debug, Serialize, Deserialize)] pub struct WasiRunner { - args: Vec, - env: HashMap, - forward_host_env: bool, - mapped_dirs: Vec, + wasi: CommonWasiOptions, #[serde(skip, default)] store: Store, #[serde(skip, default)] - tasks: Option>, + pub(crate) tasks: Option>, } impl WasiRunner { /// Constructs a new `WasiRunner` given an `Store` pub fn new(store: Store) -> Self { Self { - args: Vec::new(), - env: HashMap::new(), store, - mapped_dirs: Vec::new(), - forward_host_env: false, + wasi: CommonWasiOptions::default(), tasks: None, } } /// Returns the current arguments for this `WasiRunner` pub fn get_args(&self) -> Vec { - self.args.clone() + self.wasi.args.clone() } /// Builder method to provide CLI args to the runner @@ -58,7 +52,7 @@ impl WasiRunner { A: IntoIterator, S: Into, { - self.args = args.into_iter().map(|s| s.into()).collect(); + self.wasi.args = args.into_iter().map(|s| s.into()).collect(); } /// Builder method to provide environment variables to the runner. @@ -69,7 +63,7 @@ impl WasiRunner { /// Provide environment variables to the runner. pub fn set_env(&mut self, key: impl Into, value: impl Into) { - self.env.insert(key.into(), value.into()); + self.wasi.env.insert(key.into(), value.into()); } pub fn with_envs(mut self, envs: I) -> Self @@ -89,7 +83,7 @@ impl WasiRunner { V: Into, { for (key, value) in envs { - self.env.insert(key.into(), value.into()); + self.wasi.env.insert(key.into(), value.into()); } } @@ -99,7 +93,7 @@ impl WasiRunner { } pub fn set_forward_host_env(&mut self) { - self.forward_host_env = true; + self.wasi.forward_host_env = true; } pub fn with_mapped_directories(mut self, dirs: I) -> Self @@ -107,7 +101,9 @@ impl WasiRunner { I: IntoIterator, D: Into, { - self.mapped_dirs.extend(dirs.into_iter().map(|d| d.into())); + self.wasi + .mapped_dirs + .extend(dirs.into_iter().map(|d| d.into())); self } @@ -123,27 +119,12 @@ impl WasiRunner { fn prepare_webc_env( &self, container: &WapmContainer, - command: &str, + program_name: &str, + wasi: &Wasi, ) -> Result { - let (fs, preopen_dirs) = container.container_fs(); - - let mut builder = WasiEnv::builder(command).args(&self.args); - - for dir in preopen_dirs { - builder.add_preopen_dir(dir)?; - } - - builder.set_fs(Box::new(fs)); - - if self.forward_host_env { - for (k, v) in std::env::vars() { - builder.add_env(k, v); - } - } - - for (k, v) in &self.env { - builder.add_env(k, v); - } + let mut builder = + self.wasi + .prepare_webc_env(container.container_fs(), program_name, wasi)?; if let Some(tasks) = &self.tasks { let rt = PluggableRuntime::new(Arc::clone(tasks)); @@ -169,18 +150,19 @@ impl crate::runners::Runner for WasiRunner { command: &Command, container: &WapmContainer, ) -> Result { - let atom_name = match command.get_annotation("wasi")? { - Some(Wasi { atom, .. }) => atom, - None => command_name.to_string(), - }; + let wasi = command + .get_annotation("wasi")? + .unwrap_or_else(|| Wasi::new(command_name)); + let atom_name = &wasi.atom; let atom = container - .get_atom(&atom_name) + .get_atom(atom_name) .with_context(|| format!("Unable to get the \"{atom_name}\" atom"))?; let mut module = Module::new(&self.store, atom)?; - module.set_name(&atom_name); + module.set_name(atom_name); - self.prepare_webc_env(container, &atom_name)?.run(module)?; + self.prepare_webc_env(container, atom_name, &wasi)? + .run(module)?; Ok(()) } diff --git a/lib/wasi/src/runners/wasi_common.rs b/lib/wasi/src/runners/wasi_common.rs new file mode 100644 index 00000000000..55ef2b74ff3 --- /dev/null +++ b/lib/wasi/src/runners/wasi_common.rs @@ -0,0 +1,167 @@ +use std::{ + collections::HashMap, + path::{Path, PathBuf}, + sync::Arc, +}; + +use anyhow::{Context, Error}; +use virtual_fs::{FileSystem, OverlayFileSystem, RootFileSystemBuilder}; +use webc::metadata::annotations::Wasi as WasiAnnotation; + +use crate::{runners::MappedDirectory, WasiEnv, WasiEnvBuilder}; + +#[derive(Debug, Default, Clone, serde::Serialize, serde::Deserialize)] +pub(crate) struct CommonWasiOptions { + pub(crate) args: Vec, + pub(crate) env: HashMap, + pub(crate) forward_host_env: bool, + pub(crate) mapped_dirs: Vec, +} + +impl CommonWasiOptions { + pub(crate) fn prepare_webc_env( + &self, + container_fs: Arc, + program_name: &str, + wasi: &WasiAnnotation, + ) -> Result { + let mut builder = WasiEnv::builder(program_name).args(&self.args); + + let fs = prepare_filesystem(&self.mapped_dirs, container_fs, |path| { + builder.add_preopen_dir(path).map_err(Error::from) + })?; + builder.set_fs(fs); + builder.add_preopen_dir("/")?; + builder.add_preopen_dir(".")?; + + self.populate_env(wasi, &mut builder); + self.populate_args(wasi, &mut builder); + + Ok(builder) + } + + fn populate_env(&self, wasi: &WasiAnnotation, builder: &mut WasiEnvBuilder) { + for item in wasi.env.as_deref().unwrap_or_default() { + // TODO(Michael-F-Bryan): Convert "wasi.env" in the webc crate from an + // Option> to a HashMap so we avoid this + // string.split() business + match item.split_once('=') { + Some((k, v)) => { + builder.add_env(k, v); + } + None => { + builder.add_env(item, String::new()); + } + } + } + + if self.forward_host_env { + builder.add_envs(std::env::vars()); + } + + builder.add_envs(self.env.clone()); + } + + fn populate_args(&self, wasi: &WasiAnnotation, builder: &mut WasiEnvBuilder) { + if let Some(main_args) = &wasi.main_args { + builder.add_args(main_args); + } + + builder.add_args(&self.args); + } +} + +fn prepare_filesystem( + mapped_dirs: &[MappedDirectory], + container_fs: Arc, + mut preopen: impl FnMut(&Path) -> Result<(), Error>, +) -> Result, Error> { + let root_fs = RootFileSystemBuilder::default().build(); + + if !mapped_dirs.is_empty() { + let host_fs: Arc = Arc::new(crate::default_fs_backing()); + dbg!(mapped_dirs); + + for dir in mapped_dirs { + let MappedDirectory { host, guest } = dir; + let guest = PathBuf::from(guest); + tracing::debug!( + guest=%guest.display(), + host=%host.display(), + "Mounting host folder", + ); + + if let Some(parent) = guest.parent() { + create_dir_all(&root_fs, parent).with_context(|| { + format!("Unable to create the \"{}\" directory", parent.display()) + })?; + } + + root_fs + .mount(guest.clone(), &host_fs, host.clone()) + .with_context(|| { + format!( + "Unable to mount \"{}\" to \"{}\"", + host.display(), + guest.display() + ) + })?; + + preopen(&guest) + .with_context(|| format!("Unable to preopen \"{}\"", guest.display()))?; + } + } + + Ok(Box::new(OverlayFileSystem::new(root_fs, [container_fs]))) +} + +fn create_dir_all(fs: &dyn FileSystem, path: &Path) -> Result<(), Error> { + if fs.metadata(path).is_ok() { + return Ok(()); + } + + if let Some(parent) = path.parent() { + create_dir_all(fs, parent)?; + } + + fs.create_dir(path)?; + + Ok(()) +} + +#[cfg(test)] +mod tests { + use tempfile::TempDir; + + use crate::runners::WapmContainer; + + use super::*; + + const PYTHON: &[u8] = include_bytes!("../../../c-api/examples/assets/python-0.1.0.wasmer"); + + #[test] + fn python_use_case() { + let temp = TempDir::new().unwrap(); + let sub_dir = temp.path().join("path").join("to"); + std::fs::create_dir_all(&sub_dir).unwrap(); + std::fs::write(sub_dir.join("file.txt"), b"Hello, World!").unwrap(); + let mapping = [MappedDirectory { + guest: "/home".to_string(), + host: sub_dir, + }]; + let container = WapmContainer::from_bytes(PYTHON.into()).unwrap(); + + let fs = prepare_filesystem(&mapping, container.container_fs(), |_| Ok(())).unwrap(); + + assert!(fs.metadata("/home/file.txt".as_ref()).unwrap().is_file()); + assert!(fs.metadata("lib".as_ref()).unwrap().is_dir()); + assert!(fs + .metadata("lib/python3.6/collections/__init__.py".as_ref()) + .unwrap() + .is_file()); + assert!(fs + .metadata("lib/python3.6/encodings/__init__.py".as_ref()) + .unwrap() + .is_file()); + } +} diff --git a/lib/wasi/src/runners/wcgi/handler.rs b/lib/wasi/src/runners/wcgi/handler.rs index 565f3be8b28..e04e23e0517 100644 --- a/lib/wasi/src/runners/wcgi/handler.rs +++ b/lib/wasi/src/runners/wcgi/handler.rs @@ -1,13 +1,6 @@ -use std::{ - collections::HashMap, - ops::Deref, - path::{Path, PathBuf}, - pin::Pin, - sync::Arc, - task::Poll, -}; +use std::{collections::HashMap, ops::Deref, pin::Pin, sync::Arc, task::Poll}; -use anyhow::{Context, Error}; +use anyhow::Error; use futures::{Future, FutureExt, StreamExt, TryFutureExt}; use http::{Request, Response}; use hyper::{service::Service, Body}; @@ -16,15 +9,12 @@ use tokio::{ runtime::Handle, }; use tracing::Instrument; -use virtual_fs::{FileSystem, PassthruFileSystem, RootFileSystemBuilder, TmpFileSystem}; use wasmer::Module; use wcgi_host::CgiDialect; use crate::{ - capabilities::Capabilities, - http::HttpClientCapabilityV1, - runners::{wcgi::Callbacks, MappedDirectory, WapmContainer}, - Pipe, PluggableRuntime, VirtualTaskManager, WasiEnv, + capabilities::Capabilities, http::HttpClientCapabilityV1, runners::wcgi::Callbacks, Pipe, + PluggableRuntime, VirtualTaskManager, WasiEnvBuilder, }; /// The shared object that manages the instantiaion of WASI executables and @@ -37,6 +27,7 @@ impl Handler { Handler(Arc::new(state)) } + #[tracing::instrument(level = "debug", skip_all, err)] pub(crate) async fn handle(&self, req: Request) -> Result, Error> { tracing::debug!(headers=?req.headers()); @@ -48,17 +39,14 @@ impl Handler { tracing::debug!("Creating the WebAssembly instance"); - let builder = WasiEnv::builder(self.program.to_string()); - let mut request_specific_env = HashMap::new(); self.dialect .prepare_environment_variables(parts, &mut request_specific_env); let rt = PluggableRuntime::new(Arc::clone(&self.task_manager)); - let mut builder = builder - .envs(self.env.iter()) + + let builder = (self.setup_builder)()? .envs(request_specific_env) - .args(self.args.iter()) .stdin(Box::new(req_body_receiver)) .stdout(Box::new(res_body_sender)) .stderr(Box::new(stderr_sender)) @@ -67,15 +55,7 @@ impl Handler { http_client: HttpClientCapabilityV1::new_allow_all(), threading: Default::default(), }) - .runtime(Arc::new(rt)) - .fs(Box::new(self.fs()?)) - .preopen_dir(Path::new("/"))?; - - for mapping in &self.mapped_dirs { - builder - .add_preopen_dir(&mapping.guest) - .with_context(|| format!("Unable to preopen \"{}\"", mapping.guest))?; - } + .runtime(Arc::new(rt)); let module = self.module.clone(); @@ -135,45 +115,6 @@ impl Handler { Ok(response) } - - fn fs(&self) -> Result { - let root_fs = RootFileSystemBuilder::new().build(); - - if !self.mapped_dirs.is_empty() { - let fs_backing: Arc = - Arc::new(PassthruFileSystem::new(crate::default_fs_backing())); - - for MappedDirectory { host, guest } in self.mapped_dirs.iter() { - let guest = match guest.starts_with('/') { - true => PathBuf::from(guest), - false => Path::new("/").join(guest), - }; - tracing::debug!( - host=%host.display(), - guest=%guest.display(), - "mounting host directory", - ); - - if let Some(parent) = guest.parent() { - create_dir_all(&root_fs, parent) - .with_context(|| format!("Unable to create \"{}\"", parent.display()))?; - } - - root_fs - .mount(guest.clone(), &fs_backing, host.clone()) - .with_context(|| { - format!( - "Unable to mount \"{}\" to \"{}\"", - host.display(), - guest.display() - ) - }) - .map_err(|e| dbg!(e))?; - } - } - - Ok(root_fs) - } } impl Deref for Handler { @@ -184,20 +125,6 @@ impl Deref for Handler { } } -fn create_dir_all(fs: &dyn FileSystem, path: &Path) -> Result<(), Error> { - if fs.metadata(path).is_ok() { - return Ok(()); - } - - if let Some(parent) = path.parent() { - create_dir_all(fs, parent)?; - } - - fs.create_dir(path)?; - - Ok(()) -} - /// Drive the request to completion by streaming the request body to the /// instance and waiting for it to exit. async fn drive_request_to_completion( @@ -270,19 +197,17 @@ async fn consume_stderr( } } -#[derive(Clone, derivative::Derivative)] +#[derive(derivative::Derivative)] #[derivative(Debug)] pub(crate) struct SharedState { - pub(crate) program: String, - pub(crate) env: HashMap, - pub(crate) args: Vec, - pub(crate) mapped_dirs: Vec, - pub(crate) container: WapmContainer, pub(crate) module: Module, pub(crate) dialect: CgiDialect, - pub(crate) task_manager: Arc, + #[derivative(Debug = "ignore")] + pub(crate) setup_builder: Box Result + Send + Sync>, #[derivative(Debug = "ignore")] pub(crate) callbacks: Arc, + #[derivative(Debug = "ignore")] + pub(crate) task_manager: Arc, } impl Service> for Handler { diff --git a/lib/wasi/src/runners/wcgi/runner.rs b/lib/wasi/src/runners/wcgi/runner.rs index ed6dd3bfde8..de1f1c80238 100644 --- a/lib/wasi/src/runners/wcgi/runner.rs +++ b/lib/wasi/src/runners/wcgi/runner.rs @@ -1,4 +1,4 @@ -use std::{collections::HashMap, net::SocketAddr, sync::Arc, time::Duration}; +use std::{net::SocketAddr, sync::Arc, time::Duration}; use anyhow::{Context, Error}; use futures::future::AbortHandle; @@ -7,6 +7,7 @@ use hyper::Body; use tower::{make::Shared, ServiceBuilder}; use tower_http::{catch_panic::CatchPanicLayer, cors::CorsLayer, trace::TraceLayer}; use tracing::Span; +use virtual_fs::FileSystem; use wasmer::{Engine, Module, Store}; use wcgi_host::CgiDialect; use webc::metadata::{ @@ -16,11 +17,12 @@ use webc::metadata::{ use crate::{ runners::{ + wasi_common::CommonWasiOptions, wcgi::handler::{Handler, SharedState}, MappedDirectory, WapmContainer, }, runtime::task_manager::tokio::TokioTaskManager, - VirtualTaskManager, + PluggableRuntime, VirtualTaskManager, WasiEnvBuilder, }; pub struct WcgiRunner { @@ -126,9 +128,6 @@ impl WcgiRunner { wasi: &Wasi, ctx: &RunnerContext<'_>, ) -> Result { - let env = construct_env(wasi, self.config.forward_host_env, &self.config.env); - let args = construct_args(wasi, &self.config.args); - let Wcgi { dialect, .. } = ctx.command().get_annotation("wcgi")?.unwrap_or_default(); let dialect = match dialect { @@ -137,68 +136,46 @@ impl WcgiRunner { }; let shared = SharedState { - program: self.program_name.clone(), - env, - args, - mapped_dirs: self.config.mapped_dirs.clone(), task_manager: self .config .task_manager .clone() .unwrap_or_else(|| Arc::new(TokioTaskManager::default())), module, - container: ctx.container.clone(), dialect, callbacks: Arc::clone(&self.config.callbacks), + setup_builder: Box::new(self.setup_builder(ctx, wasi)), }; Ok(Handler::new(shared)) } -} - -fn construct_args(wasi: &Wasi, extras: &[String]) -> Vec { - let mut args = Vec::new(); - - if let Some(main_args) = &wasi.main_args { - args.extend(main_args.iter().cloned()); - } - args.extend(extras.iter().cloned()); - - args -} - -fn construct_env( - wasi: &Wasi, - forward_host_env: bool, - overrides: &HashMap, -) -> HashMap { - let mut env: HashMap = HashMap::new(); - - for item in wasi.env.as_deref().unwrap_or_default() { - // TODO(Michael-F-Bryan): Convert "wasi.env" in the webc crate from an - // Option> to a HashMap so we avoid this - // string.split() business - match item.split_once('=') { - Some((k, v)) => { - env.insert(k.to_string(), v.to_string()); - } - None => { - env.insert(item.to_string(), String::new()); + fn setup_builder( + &self, + ctx: &RunnerContext<'_>, + wasi: &Wasi, + ) -> impl Fn() -> Result + Send + Sync { + let container_fs = ctx.container_fs(); + let wasi_common = self.config.wasi.clone(); + let program_name = self.program_name.clone(); + let wasi = wasi.clone(); + let tasks = self.config.task_manager.clone(); + + move || { + let mut builder = + wasi_common.prepare_webc_env(Arc::clone(&container_fs), &program_name, &wasi)?; + + if let Some(tasks) = &tasks { + let rt = PluggableRuntime::new(Arc::clone(tasks)); + builder.set_runtime(Arc::new(rt)); } - } - } - if forward_host_env { - env.extend(std::env::vars()); + Ok(builder) + } } - - env.extend(overrides.clone()); - - env } -// TODO(Michael-F-Bryan): Pass this to Runner::run() as "&dyn RunnerContext" +// TODO(Michael-F-Bryan): Pass this to Runner::run() as a "&dyn RunnerContext" // when we rewrite the "Runner" trait. struct RunnerContext<'a> { container: &'a WapmContainer, @@ -233,6 +210,10 @@ impl RunnerContext<'_> { // TODO(Michael-F-Bryan): wire this up to wasmer-cache Module::new(&self.engine, wasm).map_err(Error::from) } + + fn container_fs(&self) -> Arc { + self.container.container_fs() + } } impl crate::runners::Runner for WcgiRunner { @@ -265,11 +246,8 @@ impl crate::runners::Runner for WcgiRunner { #[derivative(Debug)] pub struct Config { task_manager: Option>, + wasi: CommonWasiOptions, addr: SocketAddr, - args: Vec, - env: HashMap, - forward_host_env: bool, - mapped_dirs: Vec, #[derivative(Debug = "ignore")] callbacks: Arc, store: Option>, @@ -288,7 +266,7 @@ impl Config { /// Add an argument to the WASI executable's command-line arguments. pub fn arg(&mut self, arg: impl Into) -> &mut Self { - self.args.push(arg.into()); + self.wasi.args.push(arg.into()); self } @@ -298,13 +276,13 @@ impl Config { A: IntoIterator, S: Into, { - self.args.extend(args.into_iter().map(|s| s.into())); + self.wasi.args.extend(args.into_iter().map(|s| s.into())); self } /// Expose an environment variable to the guest. pub fn env(&mut self, name: impl Into, value: impl Into) -> &mut Self { - self.env.insert(name.into(), value.into()); + self.wasi.env.insert(name.into(), value.into()); self } @@ -315,19 +293,20 @@ impl Config { K: Into, V: Into, { - self.env + self.wasi + .env .extend(variables.into_iter().map(|(k, v)| (k.into(), v.into()))); self } /// Forward all of the host's environment variables to the guest. pub fn forward_host_env(&mut self) -> &mut Self { - self.forward_host_env = true; + self.wasi.forward_host_env = true; self } pub fn map_directory(&mut self, dir: MappedDirectory) -> &mut Self { - self.mapped_dirs.push(dir); + self.wasi.mapped_dirs.push(dir); self } @@ -335,7 +314,7 @@ impl Config { &mut self, mappings: impl IntoIterator, ) -> &mut Self { - self.mapped_dirs.extend(mappings.into_iter()); + self.wasi.mapped_dirs.extend(mappings.into_iter()); self } @@ -357,10 +336,7 @@ impl Default for Config { Self { task_manager: None, addr: ([127, 0, 0, 1], 8000).into(), - env: HashMap::new(), - forward_host_env: false, - mapped_dirs: Vec::new(), - args: Vec::new(), + wasi: CommonWasiOptions::default(), callbacks: Arc::new(NoopCallbacks), store: None, } diff --git a/lib/wasi/src/state/builder.rs b/lib/wasi/src/state/builder.rs index 32d810197a5..7fbb1892006 100644 --- a/lib/wasi/src/state/builder.rs +++ b/lib/wasi/src/state/builder.rs @@ -182,13 +182,27 @@ impl WasiEnvBuilder { Key: AsRef<[u8]>, Value: AsRef<[u8]>, { - env_pairs.into_iter().for_each(|(key, value)| { - self.add_env(key, value); - }); + self.add_envs(env_pairs); self } + /// Add multiple environment variable pairs. + /// + /// Both the key and value of the environment variables must not + /// contain a nul byte (`0x0`), and the key must not contain the + /// `=` byte (`0x3d`). + pub fn add_envs(&mut self, env_pairs: I) + where + I: IntoIterator, + Key: AsRef<[u8]>, + Value: AsRef<[u8]>, + { + for (key, value) in env_pairs { + self.add_env(key, value); + } + } + /// Get a reference to the configured environment variables. pub fn get_env(&self) -> &[(String, Vec)] { &self.envs @@ -231,13 +245,24 @@ impl WasiEnvBuilder { I: IntoIterator, Arg: AsRef<[u8]>, { - args.into_iter().for_each(|arg| { - self.add_arg(arg); - }); + self.add_args(args); self } + /// Add multiple arguments. + /// + /// Arguments must not contain the nul (0x0) byte + pub fn add_args(&mut self, args: I) + where + I: IntoIterator, + Arg: AsRef<[u8]>, + { + for arg in args { + self.add_arg(arg); + } + } + /// Get a reference to the configured arguments. pub fn get_args(&self) -> &[String] { &self.args @@ -999,7 +1024,7 @@ mod test { )); let output = WasiEnvBuilder::new("test_prog") - .args(&["--help", "--wat\0"]) + .args(["--help", "--wat\0"]) .build_init(); let err = output.expect_err("should fail"); assert!(matches!( diff --git a/lib/wasi/src/syscalls/wasi/clock_time_get.rs b/lib/wasi/src/syscalls/wasi/clock_time_get.rs index 742ea17ad14..c7f530f02ce 100644 --- a/lib/wasi/src/syscalls/wasi/clock_time_get.rs +++ b/lib/wasi/src/syscalls/wasi/clock_time_get.rs @@ -11,7 +11,7 @@ use crate::syscalls::*; /// Output: /// - `Timestamp *time` /// The value of the clock in nanoseconds -#[instrument(level = "trace", skip_all, fields(clock_id, precision), ret)] +#[instrument(level = "trace", skip_all, fields(?clock_id, %precision), ret)] pub fn clock_time_get( ctx: FunctionEnvMut<'_, WasiEnv>, clock_id: Snapshot0Clockid, diff --git a/lib/wasi/src/syscalls/wasi/clock_time_set.rs b/lib/wasi/src/syscalls/wasi/clock_time_set.rs index f6614f22ea5..be78283306c 100644 --- a/lib/wasi/src/syscalls/wasi/clock_time_set.rs +++ b/lib/wasi/src/syscalls/wasi/clock_time_set.rs @@ -8,7 +8,7 @@ use crate::syscalls::*; /// The ID of the clock to query /// - `Timestamp *time` /// The value of the clock in nanoseconds -#[instrument(level = "trace", skip_all, fields(clock_id, time), ret)] +#[instrument(level = "trace", skip_all, fields(?clock_id, %time), ret)] pub fn clock_time_set( ctx: FunctionEnvMut<'_, WasiEnv>, clock_id: Snapshot0Clockid, diff --git a/lib/wasi/src/syscalls/wasi/fd_advise.rs b/lib/wasi/src/syscalls/wasi/fd_advise.rs index eb2eba9403e..0426d6da07c 100644 --- a/lib/wasi/src/syscalls/wasi/fd_advise.rs +++ b/lib/wasi/src/syscalls/wasi/fd_advise.rs @@ -12,7 +12,7 @@ use crate::syscalls::*; /// The length from the offset to which the advice applies /// - `__wasi_advice_t advice` /// The advice to give -#[instrument(level = "debug", skip_all, fields(fd, offset, len, advice), ret)] +#[instrument(level = "debug", skip_all, fields(%fd, %offset, %len, ?advice), ret)] pub fn fd_advise( ctx: FunctionEnvMut<'_, WasiEnv>, fd: WasiFd, diff --git a/lib/wasi/src/syscalls/wasi/fd_allocate.rs b/lib/wasi/src/syscalls/wasi/fd_allocate.rs index ff44ff21215..9d5bcdb8579 100644 --- a/lib/wasi/src/syscalls/wasi/fd_allocate.rs +++ b/lib/wasi/src/syscalls/wasi/fd_allocate.rs @@ -10,7 +10,7 @@ use crate::syscalls::*; /// The offset from the start marking the beginning of the allocation /// - `Filesize len` /// The length from the offset marking the end of the allocation -#[instrument(level = "debug", skip_all, fields(fd, offset, len), ret)] +#[instrument(level = "debug", skip_all, fields(%fd, %offset, %len), ret)] pub fn fd_allocate( ctx: FunctionEnvMut<'_, WasiEnv>, fd: WasiFd, diff --git a/lib/wasi/src/syscalls/wasi/fd_close.rs b/lib/wasi/src/syscalls/wasi/fd_close.rs index cd270b4f52a..febc4c81e58 100644 --- a/lib/wasi/src/syscalls/wasi/fd_close.rs +++ b/lib/wasi/src/syscalls/wasi/fd_close.rs @@ -12,7 +12,7 @@ use crate::syscalls::*; /// If `fd` is a directory /// - `Errno::Badf` /// If `fd` is invalid or not open -#[instrument(level = "debug", skip_all, fields(pid = ctx.data().process.pid().raw(), fd), ret, err)] +#[instrument(level = "debug", skip_all, fields(pid = ctx.data().process.pid().raw(), %fd), ret, err)] pub fn fd_close(mut ctx: FunctionEnvMut<'_, WasiEnv>, fd: WasiFd) -> Result { let env = ctx.data(); let (_, mut state) = env.get_memory_and_wasi_state(&ctx, 0); diff --git a/lib/wasi/src/syscalls/wasi/fd_datasync.rs b/lib/wasi/src/syscalls/wasi/fd_datasync.rs index cf370430311..f9a7da17e2f 100644 --- a/lib/wasi/src/syscalls/wasi/fd_datasync.rs +++ b/lib/wasi/src/syscalls/wasi/fd_datasync.rs @@ -6,7 +6,7 @@ use crate::syscalls::*; /// Inputs: /// - `Fd fd` /// The file descriptor to sync -#[instrument(level = "debug", skip_all, fields(fd), ret, err)] +#[instrument(level = "debug", skip_all, fields(%fd), ret, err)] pub fn fd_datasync(mut ctx: FunctionEnvMut<'_, WasiEnv>, fd: WasiFd) -> Result { let env = ctx.data(); let state = env.state.clone(); diff --git a/lib/wasi/src/syscalls/wasi/fd_dup.rs b/lib/wasi/src/syscalls/wasi/fd_dup.rs index deea9f8daf0..79be5cc7870 100644 --- a/lib/wasi/src/syscalls/wasi/fd_dup.rs +++ b/lib/wasi/src/syscalls/wasi/fd_dup.rs @@ -9,7 +9,7 @@ use crate::syscalls::*; /// Outputs: /// - `Fd fd` /// The new file handle that is a duplicate of the original -#[instrument(level = "debug", skip_all, fields(fd, ret_fd = field::Empty), ret)] +#[instrument(level = "debug", skip_all, fields(%fd, ret_fd = field::Empty), ret)] pub fn fd_dup( ctx: FunctionEnvMut<'_, WasiEnv>, fd: WasiFd, diff --git a/lib/wasi/src/syscalls/wasi/fd_event.rs b/lib/wasi/src/syscalls/wasi/fd_event.rs index 69d791bb400..52d6c22a0ce 100644 --- a/lib/wasi/src/syscalls/wasi/fd_event.rs +++ b/lib/wasi/src/syscalls/wasi/fd_event.rs @@ -3,7 +3,7 @@ use crate::{fs::NotificationInner, syscalls::*}; /// ### `fd_event()` /// Creates a file handle for event notifications -#[instrument(level = "debug", skip_all, fields(initial_val, ret_fd = field::Empty), ret)] +#[instrument(level = "debug", skip_all, fields(%initial_val, ret_fd = field::Empty), ret)] pub fn fd_event( ctx: FunctionEnvMut<'_, WasiEnv>, initial_val: u64, diff --git a/lib/wasi/src/syscalls/wasi/fd_fdstat_get.rs b/lib/wasi/src/syscalls/wasi/fd_fdstat_get.rs index 78d094d17e7..229c11ca16a 100644 --- a/lib/wasi/src/syscalls/wasi/fd_fdstat_get.rs +++ b/lib/wasi/src/syscalls/wasi/fd_fdstat_get.rs @@ -9,7 +9,7 @@ use crate::syscalls::*; /// Output: /// - `Fdstat *buf` /// The location where the metadata will be written -#[instrument(level = "trace", skip_all, fields(fd), ret)] +#[instrument(level = "trace", skip_all, fields(%fd), ret)] pub fn fd_fdstat_get( ctx: FunctionEnvMut<'_, WasiEnv>, fd: WasiFd, diff --git a/lib/wasi/src/syscalls/wasi/fd_fdstat_set_flags.rs b/lib/wasi/src/syscalls/wasi/fd_fdstat_set_flags.rs index 6fb25a9c46d..64269bb70ee 100644 --- a/lib/wasi/src/syscalls/wasi/fd_fdstat_set_flags.rs +++ b/lib/wasi/src/syscalls/wasi/fd_fdstat_set_flags.rs @@ -8,7 +8,7 @@ use crate::syscalls::*; /// The file descriptor to apply the new flags to /// - `Fdflags flags` /// The flags to apply to `fd` -#[instrument(level = "debug", skip_all, fields(fd), ret, err)] +#[instrument(level = "debug", skip_all, fields(%fd), ret, err)] pub fn fd_fdstat_set_flags( mut ctx: FunctionEnvMut<'_, WasiEnv>, fd: WasiFd, diff --git a/lib/wasi/src/syscalls/wasi/fd_fdstat_set_rights.rs b/lib/wasi/src/syscalls/wasi/fd_fdstat_set_rights.rs index 194e49bc07f..d3d87fb0b30 100644 --- a/lib/wasi/src/syscalls/wasi/fd_fdstat_set_rights.rs +++ b/lib/wasi/src/syscalls/wasi/fd_fdstat_set_rights.rs @@ -10,7 +10,7 @@ use crate::syscalls::*; /// The rights to apply to `fd` /// - `Rights fs_rights_inheriting` /// The inheriting rights to apply to `fd` -#[instrument(level = "debug", skip_all, fields(fd), ret)] +#[instrument(level = "debug", skip_all, fields(%fd), ret)] pub fn fd_fdstat_set_rights( ctx: FunctionEnvMut<'_, WasiEnv>, fd: WasiFd, diff --git a/lib/wasi/src/syscalls/wasi/fd_filestat_get.rs b/lib/wasi/src/syscalls/wasi/fd_filestat_get.rs index e1b98f7c335..a51e7e83fd6 100644 --- a/lib/wasi/src/syscalls/wasi/fd_filestat_get.rs +++ b/lib/wasi/src/syscalls/wasi/fd_filestat_get.rs @@ -9,7 +9,7 @@ use crate::syscalls::*; /// Output: /// - `Filestat *buf` /// Where the metadata from `fd` will be written -#[instrument(level = "debug", skip_all, fields(fd), ret)] +#[instrument(level = "debug", skip_all, fields(%fd), ret)] pub fn fd_filestat_get( mut ctx: FunctionEnvMut<'_, WasiEnv>, fd: WasiFd, diff --git a/lib/wasi/src/syscalls/wasi/fd_filestat_set_size.rs b/lib/wasi/src/syscalls/wasi/fd_filestat_set_size.rs index 30792e1f211..05ff6bb7f02 100644 --- a/lib/wasi/src/syscalls/wasi/fd_filestat_set_size.rs +++ b/lib/wasi/src/syscalls/wasi/fd_filestat_set_size.rs @@ -8,7 +8,7 @@ use crate::syscalls::*; /// File descriptor to adjust /// - `Filesize st_size` /// New size that `fd` will be set to -#[instrument(level = "debug", skip_all, fields(fd, st_size), ret)] +#[instrument(level = "debug", skip_all, fields(%fd, %st_size), ret)] pub fn fd_filestat_set_size( ctx: FunctionEnvMut<'_, WasiEnv>, fd: WasiFd, diff --git a/lib/wasi/src/syscalls/wasi/fd_filestat_set_times.rs b/lib/wasi/src/syscalls/wasi/fd_filestat_set_times.rs index e46663afd9f..3f9c987c530 100644 --- a/lib/wasi/src/syscalls/wasi/fd_filestat_set_times.rs +++ b/lib/wasi/src/syscalls/wasi/fd_filestat_set_times.rs @@ -10,7 +10,7 @@ use crate::syscalls::*; /// Last modified time /// - `Fstflags fst_flags` /// Bit-vector for controlling which times get set -#[instrument(level = "debug", skip_all, fields(fd, st_atim, st_mtim), ret)] +#[instrument(level = "debug", skip_all, fields(%fd, %st_atim, %st_mtim), ret)] pub fn fd_filestat_set_times( ctx: FunctionEnvMut<'_, WasiEnv>, fd: WasiFd, diff --git a/lib/wasi/src/syscalls/wasi/fd_prestat_dir_name.rs b/lib/wasi/src/syscalls/wasi/fd_prestat_dir_name.rs index 13547b5dea1..77305bd509b 100644 --- a/lib/wasi/src/syscalls/wasi/fd_prestat_dir_name.rs +++ b/lib/wasi/src/syscalls/wasi/fd_prestat_dir_name.rs @@ -1,7 +1,7 @@ use super::*; use crate::syscalls::*; -#[instrument(level = "trace", skip_all, fields(fd, path = field::Empty), ret)] +#[instrument(level = "trace", skip_all, fields(%fd, path = field::Empty), ret)] pub fn fd_prestat_dir_name( ctx: FunctionEnvMut<'_, WasiEnv>, fd: WasiFd, diff --git a/lib/wasi/src/syscalls/wasi/fd_prestat_get.rs b/lib/wasi/src/syscalls/wasi/fd_prestat_get.rs index 1b7ee155ec1..73023338fdd 100644 --- a/lib/wasi/src/syscalls/wasi/fd_prestat_get.rs +++ b/lib/wasi/src/syscalls/wasi/fd_prestat_get.rs @@ -9,7 +9,7 @@ use crate::syscalls::*; /// Output: /// - `__wasi_prestat *buf` /// Where the metadata will be written -#[instrument(level = "trace", skip_all, fields(fd), ret)] +#[instrument(level = "trace", skip_all, fields(%fd), ret)] pub fn fd_prestat_get( ctx: FunctionEnvMut<'_, WasiEnv>, fd: WasiFd, diff --git a/lib/wasi/src/syscalls/wasi/fd_read.rs b/lib/wasi/src/syscalls/wasi/fd_read.rs index 7d7ad723ad2..b67a5bdf7be 100644 --- a/lib/wasi/src/syscalls/wasi/fd_read.rs +++ b/lib/wasi/src/syscalls/wasi/fd_read.rs @@ -18,7 +18,7 @@ use crate::{fs::NotificationInner, syscalls::*}; /// - `u32 *nread` /// Number of bytes read /// -#[instrument(level = "trace", skip_all, fields(fd, nread = field::Empty), ret, err)] +#[instrument(level = "trace", skip_all, fields(%fd, nread = field::Empty), ret, err)] pub fn fd_read( mut ctx: FunctionEnvMut<'_, WasiEnv>, fd: WasiFd, @@ -78,7 +78,7 @@ pub fn fd_read( /// Output: /// - `size_t nread` /// The number of bytes read -#[instrument(level = "trace", skip_all, fields(fd, offset, nread), ret, err)] +#[instrument(level = "trace", skip_all, fields(%fd, %offset, ?nread), ret, err)] pub fn fd_pread( mut ctx: FunctionEnvMut<'_, WasiEnv>, fd: WasiFd, diff --git a/lib/wasi/src/syscalls/wasi/fd_readdir.rs b/lib/wasi/src/syscalls/wasi/fd_readdir.rs index e5f21330b1a..9004574c80b 100644 --- a/lib/wasi/src/syscalls/wasi/fd_readdir.rs +++ b/lib/wasi/src/syscalls/wasi/fd_readdir.rs @@ -16,7 +16,7 @@ use crate::syscalls::*; /// - `u32 *bufused` /// The Number of bytes stored in `buf`; if less than `buf_len` then entire /// directory has been read -#[instrument(level = "trace", skip_all, fields(fd), ret)] +#[instrument(level = "trace", skip_all, fields(%fd), ret)] pub fn fd_readdir( ctx: FunctionEnvMut<'_, WasiEnv>, fd: WasiFd, diff --git a/lib/wasi/src/syscalls/wasi/fd_renumber.rs b/lib/wasi/src/syscalls/wasi/fd_renumber.rs index fac8a574c5b..5c4a097af2d 100644 --- a/lib/wasi/src/syscalls/wasi/fd_renumber.rs +++ b/lib/wasi/src/syscalls/wasi/fd_renumber.rs @@ -8,7 +8,7 @@ use crate::syscalls::*; /// File descriptor to copy /// - `Fd to` /// Location to copy file descriptor to -#[instrument(level = "debug", skip_all, fields(from, to), ret)] +#[instrument(level = "debug", skip_all, fields(%from, %to), ret)] pub fn fd_renumber(ctx: FunctionEnvMut<'_, WasiEnv>, from: WasiFd, to: WasiFd) -> Errno { if from == to { return Errno::Success; diff --git a/lib/wasi/src/syscalls/wasi/fd_seek.rs b/lib/wasi/src/syscalls/wasi/fd_seek.rs index 0d146ef928a..6997146a08a 100644 --- a/lib/wasi/src/syscalls/wasi/fd_seek.rs +++ b/lib/wasi/src/syscalls/wasi/fd_seek.rs @@ -13,7 +13,7 @@ use crate::syscalls::*; /// Output: /// - `Filesize *fd` /// The new offset relative to the start of the file -#[instrument(level = "trace", skip_all, fields(fd, offset, whence), ret)] +#[instrument(level = "trace", skip_all, fields(%fd, %offset, ?whence), ret)] pub fn fd_seek( mut ctx: FunctionEnvMut<'_, WasiEnv>, fd: WasiFd, diff --git a/lib/wasi/src/syscalls/wasi/fd_sync.rs b/lib/wasi/src/syscalls/wasi/fd_sync.rs index bcfaf37c8ef..8d160b27080 100644 --- a/lib/wasi/src/syscalls/wasi/fd_sync.rs +++ b/lib/wasi/src/syscalls/wasi/fd_sync.rs @@ -10,7 +10,7 @@ use crate::syscalls::*; /// TODO: figure out which errors this should return /// - `Errno::Perm` /// - `Errno::Notcapable` -#[instrument(level = "debug", skip_all, fields(fd), ret)] +#[instrument(level = "debug", skip_all, fields(%fd), ret)] pub fn fd_sync(mut ctx: FunctionEnvMut<'_, WasiEnv>, fd: WasiFd) -> Result { let env = ctx.data(); let (_, mut state) = env.get_memory_and_wasi_state(&ctx, 0); diff --git a/lib/wasi/src/syscalls/wasi/fd_tell.rs b/lib/wasi/src/syscalls/wasi/fd_tell.rs index 223518426cf..79a2b1cf3ad 100644 --- a/lib/wasi/src/syscalls/wasi/fd_tell.rs +++ b/lib/wasi/src/syscalls/wasi/fd_tell.rs @@ -9,7 +9,7 @@ use crate::syscalls::*; /// Output: /// - `Filesize *offset` /// The offset of `fd` relative to the start of the file -#[instrument(level = "debug", skip_all, fields(fd, offset = field::Empty), ret)] +#[instrument(level = "debug", skip_all, fields(%fd, offset = field::Empty), ret)] pub fn fd_tell( ctx: FunctionEnvMut<'_, WasiEnv>, fd: WasiFd, diff --git a/lib/wasi/src/syscalls/wasi/fd_write.rs b/lib/wasi/src/syscalls/wasi/fd_write.rs index 1342324ff1a..4f553d404df 100644 --- a/lib/wasi/src/syscalls/wasi/fd_write.rs +++ b/lib/wasi/src/syscalls/wasi/fd_write.rs @@ -15,7 +15,7 @@ use crate::syscalls::*; /// Number of bytes written /// Errors: /// -#[instrument(level = "trace", skip_all, fields(fd, nwritten = field::Empty), ret, err)] +#[instrument(level = "trace", skip_all, fields(%fd, nwritten = field::Empty), ret, err)] pub fn fd_write( mut ctx: FunctionEnvMut<'_, WasiEnv>, fd: WasiFd, @@ -49,7 +49,7 @@ pub fn fd_write( /// Output: /// - `u32 *nwritten` /// Number of bytes written -#[instrument(level = "trace", skip_all, fields(fd, offset, nwritten = field::Empty), ret, err)] +#[instrument(level = "trace", skip_all, fields(%fd, %offset, nwritten = field::Empty), ret, err)] pub fn fd_pwrite( mut ctx: FunctionEnvMut<'_, WasiEnv>, fd: WasiFd, diff --git a/lib/wasi/src/syscalls/wasi/path_create_directory.rs b/lib/wasi/src/syscalls/wasi/path_create_directory.rs index 87662fadc19..99278e49a51 100644 --- a/lib/wasi/src/syscalls/wasi/path_create_directory.rs +++ b/lib/wasi/src/syscalls/wasi/path_create_directory.rs @@ -14,7 +14,7 @@ use crate::syscalls::*; /// Required Rights: /// - Rights::PATH_CREATE_DIRECTORY /// This right must be set on the directory that the file is created in (TODO: verify that this is true) -#[instrument(level = "trace", skip_all, fields(fd, path = field::Empty), ret)] +#[instrument(level = "trace", skip_all, fields(%fd, path = field::Empty), ret)] pub fn path_create_directory( ctx: FunctionEnvMut<'_, WasiEnv>, fd: WasiFd, diff --git a/lib/wasi/src/syscalls/wasi/path_filestat_get.rs b/lib/wasi/src/syscalls/wasi/path_filestat_get.rs index c722ff7d095..b277aee1612 100644 --- a/lib/wasi/src/syscalls/wasi/path_filestat_get.rs +++ b/lib/wasi/src/syscalls/wasi/path_filestat_get.rs @@ -15,7 +15,7 @@ use crate::syscalls::*; /// Output: /// - `__wasi_file_stat_t *buf` /// The location where the metadata will be stored -#[instrument(level = "trace", skip_all, fields(fd, path = field::Empty), ret)] +#[instrument(level = "trace", skip_all, fields(%fd, path = field::Empty), ret)] pub fn path_filestat_get( ctx: FunctionEnvMut<'_, WasiEnv>, fd: WasiFd, diff --git a/lib/wasi/src/syscalls/wasi/path_filestat_set_times.rs b/lib/wasi/src/syscalls/wasi/path_filestat_set_times.rs index 3c2dc914520..2af25ede982 100644 --- a/lib/wasi/src/syscalls/wasi/path_filestat_set_times.rs +++ b/lib/wasi/src/syscalls/wasi/path_filestat_set_times.rs @@ -18,7 +18,7 @@ use crate::syscalls::*; /// The timestamp that the last modified time attribute is set to /// - `Fstflags fst_flags` /// A bitmask controlling which attributes are set -#[instrument(level = "debug", skip_all, fields(fd, path = field::Empty, st_atim, st_mtim), ret)] +#[instrument(level = "debug", skip_all, fields(%fd, path = field::Empty, %st_atim, %st_mtim), ret)] pub fn path_filestat_set_times( ctx: FunctionEnvMut<'_, WasiEnv>, fd: WasiFd, diff --git a/lib/wasi/src/syscalls/wasi/path_link.rs b/lib/wasi/src/syscalls/wasi/path_link.rs index f60187e0a9e..14be958d3a3 100644 --- a/lib/wasi/src/syscalls/wasi/path_link.rs +++ b/lib/wasi/src/syscalls/wasi/path_link.rs @@ -18,7 +18,7 @@ use crate::syscalls::*; /// String containing the new file path /// - `u32 old_path_len` /// Length of the `new_path` string -#[instrument(level = "debug", skip_all, fields(old_fd, new_fd, old_path = field::Empty, new_path = field::Empty, follow_symlinks = false), ret)] +#[instrument(level = "debug", skip_all, fields(%old_fd, %new_fd, old_path = field::Empty, new_path = field::Empty, follow_symlinks = false), ret)] pub fn path_link( ctx: FunctionEnvMut<'_, WasiEnv>, old_fd: WasiFd, diff --git a/lib/wasi/src/syscalls/wasi/path_open.rs b/lib/wasi/src/syscalls/wasi/path_open.rs index 54ceb01e0d3..ac45fde6a11 100644 --- a/lib/wasi/src/syscalls/wasi/path_open.rs +++ b/lib/wasi/src/syscalls/wasi/path_open.rs @@ -25,7 +25,7 @@ use crate::syscalls::*; /// The new file descriptor /// Possible Errors: /// - `Errno::Access`, `Errno::Badf`, `Errno::Fault`, `Errno::Fbig?`, `Errno::Inval`, `Errno::Io`, `Errno::Loop`, `Errno::Mfile`, `Errno::Nametoolong?`, `Errno::Nfile`, `Errno::Noent`, `Errno::Notdir`, `Errno::Rofs`, and `Errno::Notcapable` -#[instrument(level = "debug", skip_all, fields(dirfd, path = field::Empty, follow_symlinks = false, ret_fd = field::Empty), ret)] +#[instrument(level = "debug", skip_all, fields(%dirfd, path = field::Empty, follow_symlinks = field::Empty, ret_fd = field::Empty), ret)] pub fn path_open( ctx: FunctionEnvMut<'_, WasiEnv>, dirfd: WasiFd, diff --git a/lib/wasi/src/syscalls/wasi/path_readlink.rs b/lib/wasi/src/syscalls/wasi/path_readlink.rs index 60067c73139..ac320c55620 100644 --- a/lib/wasi/src/syscalls/wasi/path_readlink.rs +++ b/lib/wasi/src/syscalls/wasi/path_readlink.rs @@ -17,7 +17,7 @@ use crate::syscalls::*; /// Pointer to characters containing the path that the symlink points to /// - `u32 buf_used` /// The number of bytes written to `buf` -#[instrument(level = "debug", skip_all, fields(dir_fd, path = field::Empty), ret)] +#[instrument(level = "debug", skip_all, fields(%dir_fd, path = field::Empty), ret)] pub fn path_readlink( ctx: FunctionEnvMut<'_, WasiEnv>, dir_fd: WasiFd, diff --git a/lib/wasi/src/syscalls/wasi/path_remove_directory.rs b/lib/wasi/src/syscalls/wasi/path_remove_directory.rs index 71ab4bc3aef..0a22520d44b 100644 --- a/lib/wasi/src/syscalls/wasi/path_remove_directory.rs +++ b/lib/wasi/src/syscalls/wasi/path_remove_directory.rs @@ -2,7 +2,7 @@ use super::*; use crate::syscalls::*; /// Returns Errno::Notemtpy if directory is not empty -#[instrument(level = "debug", skip_all, fields(fd, path = field::Empty), ret)] +#[instrument(level = "debug", skip_all, fields(%fd, path = field::Empty), ret)] pub fn path_remove_directory( ctx: FunctionEnvMut<'_, WasiEnv>, fd: WasiFd, diff --git a/lib/wasi/src/syscalls/wasi/path_rename.rs b/lib/wasi/src/syscalls/wasi/path_rename.rs index 316fec63ffa..67100b6879c 100644 --- a/lib/wasi/src/syscalls/wasi/path_rename.rs +++ b/lib/wasi/src/syscalls/wasi/path_rename.rs @@ -16,7 +16,7 @@ use crate::syscalls::*; /// Pointer to UTF8 bytes, the new file name /// - `u32 new_path_len` /// The number of bytes to read from `new_path` -#[instrument(level = "debug", skip_all, fields(old_fd, new_fd, old_path = field::Empty, new_path = field::Empty), ret)] +#[instrument(level = "debug", skip_all, fields(%old_fd, %new_fd, old_path = field::Empty, new_path = field::Empty), ret)] pub fn path_rename( ctx: FunctionEnvMut<'_, WasiEnv>, old_fd: WasiFd, diff --git a/lib/wasi/src/syscalls/wasi/path_symlink.rs b/lib/wasi/src/syscalls/wasi/path_symlink.rs index 999b7250b32..a03b13afa44 100644 --- a/lib/wasi/src/syscalls/wasi/path_symlink.rs +++ b/lib/wasi/src/syscalls/wasi/path_symlink.rs @@ -14,7 +14,7 @@ use crate::syscalls::*; /// Array of UTF-8 bytes representing the target path /// - `u32 new_path_len` /// The number of bytes to read from `new_path` -#[instrument(level = "debug", skip_all, fields(fd, old_path = field::Empty, new_path = field::Empty), ret)] +#[instrument(level = "debug", skip_all, fields(%fd, old_path = field::Empty, new_path = field::Empty), ret)] pub fn path_symlink( ctx: FunctionEnvMut<'_, WasiEnv>, old_path: WasmPtr, diff --git a/lib/wasi/src/syscalls/wasi/path_unlink_file.rs b/lib/wasi/src/syscalls/wasi/path_unlink_file.rs index 54a55713e85..eaac44916e5 100644 --- a/lib/wasi/src/syscalls/wasi/path_unlink_file.rs +++ b/lib/wasi/src/syscalls/wasi/path_unlink_file.rs @@ -10,7 +10,7 @@ use crate::syscalls::*; /// Array of UTF-8 bytes representing the path /// - `u32 path_len` /// The number of bytes in the `path` array -#[instrument(level = "debug", skip_all, fields(fd, path = field::Empty), ret)] +#[instrument(level = "debug", skip_all, fields(%fd, path = field::Empty), ret)] pub fn path_unlink_file( ctx: FunctionEnvMut<'_, WasiEnv>, fd: WasiFd, diff --git a/lib/wasi/src/syscalls/wasi/random_get.rs b/lib/wasi/src/syscalls/wasi/random_get.rs index ea633aca03f..06b65cac446 100644 --- a/lib/wasi/src/syscalls/wasi/random_get.rs +++ b/lib/wasi/src/syscalls/wasi/random_get.rs @@ -8,7 +8,7 @@ use crate::syscalls::*; /// A pointer to a buffer where the random bytes will be written /// - `size_t buf_len` /// The number of bytes that will be written -#[instrument(level = "trace", skip_all, fields(buf_len), ret)] +#[instrument(level = "trace", skip_all, fields(%buf_len), ret)] pub fn random_get( ctx: FunctionEnvMut<'_, WasiEnv>, buf: WasmPtr, diff --git a/lib/wasi/src/syscalls/wasix/futex_wait.rs b/lib/wasi/src/syscalls/wasix/futex_wait.rs index dc806195fdf..739b7fe14d6 100644 --- a/lib/wasi/src/syscalls/wasix/futex_wait.rs +++ b/lib/wasi/src/syscalls/wasix/futex_wait.rs @@ -66,7 +66,7 @@ where /// * `futex` - Memory location that holds the value that will be checked /// * `expected` - Expected value that should be currently held at the memory location /// * `timeout` - Timeout should the futex not be triggered in the allocated time -#[instrument(level = "trace", skip_all, fields(futex_idx = field::Empty, expected, timeout = field::Empty, woken = field::Empty), err)] +#[instrument(level = "trace", skip_all, fields(futex_idx = field::Empty, %expected, timeout = field::Empty, woken = field::Empty), err)] pub fn futex_wait( mut ctx: FunctionEnvMut<'_, WasiEnv>, futex_ptr: WasmPtr, diff --git a/lib/wasi/src/syscalls/wasix/port_addr_list.rs b/lib/wasi/src/syscalls/wasix/port_addr_list.rs index 33637e776ba..cb4b49ca27c 100644 --- a/lib/wasi/src/syscalls/wasix/port_addr_list.rs +++ b/lib/wasi/src/syscalls/wasix/port_addr_list.rs @@ -14,7 +14,7 @@ use crate::syscalls::*; /// ## Return /// /// The number of addresses returned. -#[instrument(level = "debug", skip_all, fields(naddrs = field::Empty)ret, err)] +#[instrument(level = "debug", skip_all, fields(naddrs = field::Empty), ret, err)] pub fn port_addr_list( mut ctx: FunctionEnvMut<'_, WasiEnv>, addrs_ptr: WasmPtr<__wasi_cidr_t, M>, diff --git a/lib/wasi/src/syscalls/wasix/port_bridge.rs b/lib/wasi/src/syscalls/wasix/port_bridge.rs index 8d893c72ddf..1a3a5320349 100644 --- a/lib/wasi/src/syscalls/wasix/port_bridge.rs +++ b/lib/wasi/src/syscalls/wasix/port_bridge.rs @@ -9,7 +9,7 @@ use crate::syscalls::*; /// * `network` - Fully qualified identifier for the network /// * `token` - Access token used to authenticate with the network /// * `security` - Level of encryption to encapsulate the network connection with -#[instrument(level = "debug", skip_all, fields(network = field::Empty, security), ret, err)] +#[instrument(level = "debug", skip_all, fields(network = field::Empty, ?security), ret, err)] pub fn port_bridge( mut ctx: FunctionEnvMut<'_, WasiEnv>, network: WasmPtr, diff --git a/lib/wasi/src/syscalls/wasix/proc_exec.rs b/lib/wasi/src/syscalls/wasix/proc_exec.rs index 40371d0c220..6e1160f6c1e 100644 --- a/lib/wasi/src/syscalls/wasix/proc_exec.rs +++ b/lib/wasi/src/syscalls/wasix/proc_exec.rs @@ -15,7 +15,7 @@ use crate::{ /// ## Return /// /// Returns a bus process id that can be used to invoke calls -#[instrument(level = "debug", skip_all, fields(name = field::Empty, args_len), ret, err)] +#[instrument(level = "debug", skip_all, fields(name = field::Empty, %args_len), ret, err)] pub fn proc_exec( mut ctx: FunctionEnvMut<'_, WasiEnv>, name: WasmPtr, diff --git a/lib/wasi/src/syscalls/wasix/proc_parent.rs b/lib/wasi/src/syscalls/wasix/proc_parent.rs index 1d5e5e5fa6d..afb3b01cf1d 100644 --- a/lib/wasi/src/syscalls/wasix/proc_parent.rs +++ b/lib/wasi/src/syscalls/wasix/proc_parent.rs @@ -3,7 +3,7 @@ use crate::syscalls::*; /// ### `proc_parent()` /// Returns the parent handle of the supplied process -#[instrument(level = "debug", skip_all, fields(pid, parent = field::Empty), ret)] +#[instrument(level = "debug", skip_all, fields(%pid, parent = field::Empty), ret)] pub fn proc_parent( ctx: FunctionEnvMut<'_, WasiEnv>, pid: Pid, diff --git a/lib/wasi/src/syscalls/wasix/proc_signal.rs b/lib/wasi/src/syscalls/wasix/proc_signal.rs index 8067b8118a5..0af18956081 100644 --- a/lib/wasi/src/syscalls/wasix/proc_signal.rs +++ b/lib/wasi/src/syscalls/wasix/proc_signal.rs @@ -8,7 +8,7 @@ use crate::syscalls::*; /// /// * `pid` - Handle of the child process to wait on /// * `sig` - Signal to send the child process -#[instrument(level = "trace", skip_all, fields(pid, sig), ret, err)] +#[instrument(level = "trace", skip_all, fields(%pid, ?sig), ret, err)] pub fn proc_signal( mut ctx: FunctionEnvMut<'_, WasiEnv>, pid: Pid, diff --git a/lib/wasi/src/syscalls/wasix/resolve.rs b/lib/wasi/src/syscalls/wasix/resolve.rs index 9eab1e52215..498e107fba3 100644 --- a/lib/wasi/src/syscalls/wasix/resolve.rs +++ b/lib/wasi/src/syscalls/wasix/resolve.rs @@ -19,7 +19,7 @@ use crate::syscalls::*; /// ## Return /// /// The number of IP addresses returned during the DNS resolution. -#[instrument(level = "debug", skip_all, fields(host = field::Empty, port), ret, err)] +#[instrument(level = "debug", skip_all, fields(host = field::Empty, %port), ret, err)] pub fn resolve( mut ctx: FunctionEnvMut<'_, WasiEnv>, host: WasmPtr, diff --git a/lib/wasi/src/syscalls/wasix/sock_accept.rs b/lib/wasi/src/syscalls/wasix/sock_accept.rs index 5b279a17585..9858ef8cfb7 100644 --- a/lib/wasi/src/syscalls/wasix/sock_accept.rs +++ b/lib/wasi/src/syscalls/wasix/sock_accept.rs @@ -13,7 +13,7 @@ use crate::syscalls::*; /// ## Return /// /// New socket connection -#[instrument(level = "debug", skip_all, fields(sock, fd = field::Empty), ret, err)] +#[instrument(level = "debug", skip_all, fields(%sock, fd = field::Empty), ret, err)] pub fn sock_accept( mut ctx: FunctionEnvMut<'_, WasiEnv>, sock: WasiFd, diff --git a/lib/wasi/src/syscalls/wasix/sock_addr_local.rs b/lib/wasi/src/syscalls/wasix/sock_addr_local.rs index a243b3ce54d..0272b255d39 100644 --- a/lib/wasi/src/syscalls/wasix/sock_addr_local.rs +++ b/lib/wasi/src/syscalls/wasix/sock_addr_local.rs @@ -12,7 +12,7 @@ use crate::syscalls::*; /// ## Parameters /// /// * `fd` - Socket that the address is bound to -#[instrument(level = "debug", skip_all, fields(sock, addr = field::Empty), ret)] +#[instrument(level = "debug", skip_all, fields(%sock, addr = field::Empty), ret)] pub fn sock_addr_local( mut ctx: FunctionEnvMut<'_, WasiEnv>, sock: WasiFd, diff --git a/lib/wasi/src/syscalls/wasix/sock_addr_peer.rs b/lib/wasi/src/syscalls/wasix/sock_addr_peer.rs index 4972e64cefa..c2b498ad776 100644 --- a/lib/wasi/src/syscalls/wasix/sock_addr_peer.rs +++ b/lib/wasi/src/syscalls/wasix/sock_addr_peer.rs @@ -12,7 +12,7 @@ use crate::syscalls::*; /// ## Parameters /// /// * `fd` - Socket that the address is bound to -#[instrument(level = "debug", skip_all, fields(sock, addr = field::Empty), ret)] +#[instrument(level = "debug", skip_all, fields(%sock, addr = field::Empty), ret)] pub fn sock_addr_peer( mut ctx: FunctionEnvMut<'_, WasiEnv>, sock: WasiFd, diff --git a/lib/wasi/src/syscalls/wasix/sock_bind.rs b/lib/wasi/src/syscalls/wasix/sock_bind.rs index b9afa615001..21d0c324fc9 100644 --- a/lib/wasi/src/syscalls/wasix/sock_bind.rs +++ b/lib/wasi/src/syscalls/wasix/sock_bind.rs @@ -9,7 +9,7 @@ use crate::syscalls::*; /// /// * `fd` - File descriptor of the socket to be bind /// * `addr` - Address to bind the socket to -#[instrument(level = "debug", skip_all, fields(sock, addr = field::Empty), ret)] +#[instrument(level = "debug", skip_all, fields(%sock, addr = field::Empty), ret)] pub fn sock_bind( mut ctx: FunctionEnvMut<'_, WasiEnv>, sock: WasiFd, diff --git a/lib/wasi/src/syscalls/wasix/sock_connect.rs b/lib/wasi/src/syscalls/wasix/sock_connect.rs index 453e7cea781..6eb8b3bb42a 100644 --- a/lib/wasi/src/syscalls/wasix/sock_connect.rs +++ b/lib/wasi/src/syscalls/wasix/sock_connect.rs @@ -13,7 +13,7 @@ use crate::syscalls::*; /// /// * `fd` - Socket descriptor /// * `addr` - Address of the socket to connect to -#[instrument(level = "debug", skip_all, fields(sock, addr = field::Empty), ret)] +#[instrument(level = "debug", skip_all, fields(%sock, addr = field::Empty), ret)] pub fn sock_connect( mut ctx: FunctionEnvMut<'_, WasiEnv>, sock: WasiFd, diff --git a/lib/wasi/src/syscalls/wasix/sock_get_opt_flag.rs b/lib/wasi/src/syscalls/wasix/sock_get_opt_flag.rs index d024b2c2894..3849a280915 100644 --- a/lib/wasi/src/syscalls/wasix/sock_get_opt_flag.rs +++ b/lib/wasi/src/syscalls/wasix/sock_get_opt_flag.rs @@ -9,7 +9,7 @@ use crate::syscalls::*; /// /// * `fd` - Socket descriptor /// * `sockopt` - Socket option to be retrieved -#[instrument(level = "debug", skip_all, fields(sock, opt), ret)] +#[instrument(level = "debug", skip_all, fields(%sock, %opt), ret)] pub fn sock_get_opt_flag( mut ctx: FunctionEnvMut<'_, WasiEnv>, sock: WasiFd, diff --git a/lib/wasi/src/syscalls/wasix/sock_get_opt_size.rs b/lib/wasi/src/syscalls/wasix/sock_get_opt_size.rs index a187a00ff7d..361bf2158db 100644 --- a/lib/wasi/src/syscalls/wasix/sock_get_opt_size.rs +++ b/lib/wasi/src/syscalls/wasix/sock_get_opt_size.rs @@ -9,7 +9,7 @@ use crate::syscalls::*; /// /// * `fd` - Socket descriptor /// * `sockopt` - Socket option to be retrieved -#[instrument(level = "debug", skip_all, fields(sock, opt), ret)] +#[instrument(level = "debug", skip_all, fields(%sock, %opt), ret)] pub fn sock_get_opt_size( mut ctx: FunctionEnvMut<'_, WasiEnv>, sock: WasiFd, diff --git a/lib/wasi/src/syscalls/wasix/sock_get_opt_time.rs b/lib/wasi/src/syscalls/wasix/sock_get_opt_time.rs index 45e5f760486..9f706540560 100644 --- a/lib/wasi/src/syscalls/wasix/sock_get_opt_time.rs +++ b/lib/wasi/src/syscalls/wasix/sock_get_opt_time.rs @@ -8,7 +8,7 @@ use crate::{net::socket::TimeType, syscalls::*}; /// /// * `fd` - Socket descriptor /// * `sockopt` - Socket option to be retrieved -#[instrument(level = "debug", skip_all, fields(sock, opt), ret)] +#[instrument(level = "debug", skip_all, fields(%sock, %opt), ret)] pub fn sock_get_opt_time( mut ctx: FunctionEnvMut<'_, WasiEnv>, sock: WasiFd, diff --git a/lib/wasi/src/syscalls/wasix/sock_join_multicast_v4.rs b/lib/wasi/src/syscalls/wasix/sock_join_multicast_v4.rs index a30b7d17e4e..158ea2cfc75 100644 --- a/lib/wasi/src/syscalls/wasix/sock_join_multicast_v4.rs +++ b/lib/wasi/src/syscalls/wasix/sock_join_multicast_v4.rs @@ -9,7 +9,7 @@ use crate::syscalls::*; /// * `fd` - Socket descriptor /// * `multiaddr` - Multicast group to joined /// * `interface` - Interface that will join -#[instrument(level = "debug", skip_all, fields(sock), ret)] +#[instrument(level = "debug", skip_all, fields(%sock), ret)] pub fn sock_join_multicast_v4( mut ctx: FunctionEnvMut<'_, WasiEnv>, sock: WasiFd, diff --git a/lib/wasi/src/syscalls/wasix/sock_join_multicast_v6.rs b/lib/wasi/src/syscalls/wasix/sock_join_multicast_v6.rs index eb396430408..44cf50ca52b 100644 --- a/lib/wasi/src/syscalls/wasix/sock_join_multicast_v6.rs +++ b/lib/wasi/src/syscalls/wasix/sock_join_multicast_v6.rs @@ -9,7 +9,7 @@ use crate::syscalls::*; /// * `fd` - Socket descriptor /// * `multiaddr` - Multicast group to joined /// * `interface` - Interface that will join -#[instrument(level = "debug", skip_all, fields(sock, iface), ret)] +#[instrument(level = "debug", skip_all, fields(%sock, %iface), ret)] pub fn sock_join_multicast_v6( mut ctx: FunctionEnvMut<'_, WasiEnv>, sock: WasiFd, diff --git a/lib/wasi/src/syscalls/wasix/sock_leave_multicast_v4.rs b/lib/wasi/src/syscalls/wasix/sock_leave_multicast_v4.rs index 8f0802a3a35..4597748520c 100644 --- a/lib/wasi/src/syscalls/wasix/sock_leave_multicast_v4.rs +++ b/lib/wasi/src/syscalls/wasix/sock_leave_multicast_v4.rs @@ -9,7 +9,7 @@ use crate::syscalls::*; /// * `fd` - Socket descriptor /// * `multiaddr` - Multicast group to leave /// * `interface` - Interface that will left -#[instrument(level = "debug", skip_all, fields(sock), ret)] +#[instrument(level = "debug", skip_all, fields(%sock), ret)] pub fn sock_leave_multicast_v4( mut ctx: FunctionEnvMut<'_, WasiEnv>, sock: WasiFd, diff --git a/lib/wasi/src/syscalls/wasix/sock_leave_multicast_v6.rs b/lib/wasi/src/syscalls/wasix/sock_leave_multicast_v6.rs index 76a3b719fd0..b958ee1597a 100644 --- a/lib/wasi/src/syscalls/wasix/sock_leave_multicast_v6.rs +++ b/lib/wasi/src/syscalls/wasix/sock_leave_multicast_v6.rs @@ -9,7 +9,7 @@ use crate::syscalls::*; /// * `fd` - Socket descriptor /// * `multiaddr` - Multicast group to leave /// * `interface` - Interface that will left -#[instrument(level = "debug", skip_all, fields(sock, iface), ret)] +#[instrument(level = "debug", skip_all, fields(%sock, %iface), ret)] pub fn sock_leave_multicast_v6( mut ctx: FunctionEnvMut<'_, WasiEnv>, sock: WasiFd, diff --git a/lib/wasi/src/syscalls/wasix/sock_listen.rs b/lib/wasi/src/syscalls/wasix/sock_listen.rs index 8bb364895bf..50126ce6dce 100644 --- a/lib/wasi/src/syscalls/wasix/sock_listen.rs +++ b/lib/wasi/src/syscalls/wasix/sock_listen.rs @@ -13,7 +13,7 @@ use crate::syscalls::*; /// /// * `fd` - File descriptor of the socket to be bind /// * `backlog` - Maximum size of the queue for pending connections -#[instrument(level = "debug", skip_all, fields(sock, backlog), ret)] +#[instrument(level = "debug", skip_all, fields(%sock, %backlog), ret)] pub fn sock_listen( mut ctx: FunctionEnvMut<'_, WasiEnv>, sock: WasiFd, diff --git a/lib/wasi/src/syscalls/wasix/sock_open.rs b/lib/wasi/src/syscalls/wasix/sock_open.rs index dd68b5c851d..9013aaa582e 100644 --- a/lib/wasi/src/syscalls/wasix/sock_open.rs +++ b/lib/wasi/src/syscalls/wasix/sock_open.rs @@ -20,7 +20,7 @@ use crate::syscalls::*; /// ## Return /// /// The file descriptor of the socket that has been opened. -#[instrument(level = "debug", skip_all, fields(af, ty, pt, sock = field::Empty), ret)] +#[instrument(level = "debug", skip_all, fields(?af, ?ty, ?pt, sock = field::Empty), ret)] pub fn sock_open( ctx: FunctionEnvMut<'_, WasiEnv>, af: Addressfamily, diff --git a/lib/wasi/src/syscalls/wasix/sock_recv.rs b/lib/wasi/src/syscalls/wasix/sock_recv.rs index 8dd1ee2688e..ead4dda89b6 100644 --- a/lib/wasi/src/syscalls/wasix/sock_recv.rs +++ b/lib/wasi/src/syscalls/wasix/sock_recv.rs @@ -16,7 +16,7 @@ use crate::syscalls::*; /// ## Return /// /// Number of bytes stored in ri_data and message flags. -#[instrument(level = "trace", skip_all, fields(sock, nread = field::Empty), ret, err)] +#[instrument(level = "trace", skip_all, fields(%sock, nread = field::Empty), ret, err)] pub fn sock_recv( mut ctx: FunctionEnvMut<'_, WasiEnv>, sock: WasiFd, diff --git a/lib/wasi/src/syscalls/wasix/sock_recv_from.rs b/lib/wasi/src/syscalls/wasix/sock_recv_from.rs index b4127856c93..2314428ce94 100644 --- a/lib/wasi/src/syscalls/wasix/sock_recv_from.rs +++ b/lib/wasi/src/syscalls/wasix/sock_recv_from.rs @@ -16,7 +16,7 @@ use crate::syscalls::*; /// ## Return /// /// Number of bytes stored in ri_data and message flags. -#[instrument(level = "trace", skip_all, fields(sock, nread = field::Empty, peer = field::Empty), ret, err)] +#[instrument(level = "trace", skip_all, fields(%sock, nread = field::Empty, peer = field::Empty), ret, err)] pub fn sock_recv_from( mut ctx: FunctionEnvMut<'_, WasiEnv>, sock: WasiFd, diff --git a/lib/wasi/src/syscalls/wasix/sock_send.rs b/lib/wasi/src/syscalls/wasix/sock_send.rs index af49002283f..e8263e93742 100644 --- a/lib/wasi/src/syscalls/wasix/sock_send.rs +++ b/lib/wasi/src/syscalls/wasix/sock_send.rs @@ -16,7 +16,7 @@ use crate::syscalls::*; /// ## Return /// /// Number of bytes transmitted. -#[instrument(level = "trace", skip_all, fields(sock, nsent = field::Empty), ret, err)] +#[instrument(level = "trace", skip_all, fields(%sock, nsent = field::Empty), ret, err)] pub fn sock_send( mut ctx: FunctionEnvMut<'_, WasiEnv>, sock: WasiFd, diff --git a/lib/wasi/src/syscalls/wasix/sock_send_file.rs b/lib/wasi/src/syscalls/wasix/sock_send_file.rs index 49e7d149ffa..3acc59b9136 100644 --- a/lib/wasi/src/syscalls/wasix/sock_send_file.rs +++ b/lib/wasi/src/syscalls/wasix/sock_send_file.rs @@ -15,7 +15,7 @@ use crate::{syscalls::*, WasiInodes}; /// ## Return /// /// Number of bytes transmitted. -#[instrument(level = "debug", skip_all, fields(sock, in_fd, offset, count, nsent = field::Empty), ret, err)] +#[instrument(level = "debug", skip_all, fields(%sock, %in_fd, %offset, %count, nsent = field::Empty), ret, err)] pub fn sock_send_file( mut ctx: FunctionEnvMut<'_, WasiEnv>, sock: WasiFd, diff --git a/lib/wasi/src/syscalls/wasix/sock_send_to.rs b/lib/wasi/src/syscalls/wasix/sock_send_to.rs index 200db74ea3c..aad2b4a6662 100644 --- a/lib/wasi/src/syscalls/wasix/sock_send_to.rs +++ b/lib/wasi/src/syscalls/wasix/sock_send_to.rs @@ -15,7 +15,7 @@ use crate::syscalls::*; /// ## Return /// /// Number of bytes transmitted. -#[instrument(level = "trace", skip_all, fields(sock, addr, nsent = field::Empty), ret, err)] +#[instrument(level = "trace", skip_all, fields(%sock, ?addr, nsent = field::Empty), ret, err)] pub fn sock_send_to( mut ctx: FunctionEnvMut<'_, WasiEnv>, sock: WasiFd, diff --git a/lib/wasi/src/syscalls/wasix/sock_set_opt_flag.rs b/lib/wasi/src/syscalls/wasix/sock_set_opt_flag.rs index 352295160fd..df6eb21bcfa 100644 --- a/lib/wasi/src/syscalls/wasix/sock_set_opt_flag.rs +++ b/lib/wasi/src/syscalls/wasix/sock_set_opt_flag.rs @@ -10,7 +10,7 @@ use crate::syscalls::*; /// * `fd` - Socket descriptor /// * `sockopt` - Socket option to be set /// * `flag` - Value to set the option to -#[instrument(level = "debug", skip_all, fields(sock, opt, flag), ret)] +#[instrument(level = "debug", skip_all, fields(%sock, %opt, %flag), ret)] pub fn sock_set_opt_flag( mut ctx: FunctionEnvMut<'_, WasiEnv>, sock: WasiFd, diff --git a/lib/wasi/src/syscalls/wasix/sock_set_opt_size.rs b/lib/wasi/src/syscalls/wasix/sock_set_opt_size.rs index 021508ec5a0..a66291b5be1 100644 --- a/lib/wasi/src/syscalls/wasix/sock_set_opt_size.rs +++ b/lib/wasi/src/syscalls/wasix/sock_set_opt_size.rs @@ -10,7 +10,7 @@ use crate::{net::socket::TimeType, syscalls::*}; /// * `fd` - Socket descriptor /// * `opt` - Socket option to be set /// * `size` - Buffer size -#[instrument(level = "debug", skip_all, fields(sock, opt, size), ret)] +#[instrument(level = "debug", skip_all, fields(%sock, %opt, %size), ret)] pub fn sock_set_opt_size( mut ctx: FunctionEnvMut<'_, WasiEnv>, sock: WasiFd, diff --git a/lib/wasi/src/syscalls/wasix/sock_set_opt_time.rs b/lib/wasi/src/syscalls/wasix/sock_set_opt_time.rs index 2f6e83c5ff4..52365506745 100644 --- a/lib/wasi/src/syscalls/wasix/sock_set_opt_time.rs +++ b/lib/wasi/src/syscalls/wasix/sock_set_opt_time.rs @@ -9,7 +9,7 @@ use crate::{net::socket::TimeType, syscalls::*}; /// * `fd` - Socket descriptor /// * `sockopt` - Socket option to be set /// * `time` - Value to set the time to -#[instrument(level = "debug", skip_all, fields(sock, opt, time = field::Empty), ret)] +#[instrument(level = "debug", skip_all, fields(%sock, %opt, time = field::Empty), ret)] pub fn sock_set_opt_time( mut ctx: FunctionEnvMut<'_, WasiEnv>, sock: WasiFd, diff --git a/lib/wasi/src/syscalls/wasix/sock_shutdown.rs b/lib/wasi/src/syscalls/wasix/sock_shutdown.rs index e081ec602fa..36cdd22cbcd 100644 --- a/lib/wasi/src/syscalls/wasix/sock_shutdown.rs +++ b/lib/wasi/src/syscalls/wasix/sock_shutdown.rs @@ -8,7 +8,7 @@ use crate::syscalls::*; /// ## Parameters /// /// * `how` - Which channels on the socket to shut down. -#[instrument(level = "debug", skip_all, fields(sock), ret)] +#[instrument(level = "debug", skip_all, fields(%sock), ret)] pub fn sock_shutdown(mut ctx: FunctionEnvMut<'_, WasiEnv>, sock: WasiFd, how: SdFlags) -> Errno { let both = __WASI_SHUT_RD | __WASI_SHUT_WR; let how = match how { diff --git a/lib/wasi/src/syscalls/wasix/sock_status.rs b/lib/wasi/src/syscalls/wasix/sock_status.rs index c1f64647be0..5f24d6120e1 100644 --- a/lib/wasi/src/syscalls/wasix/sock_status.rs +++ b/lib/wasi/src/syscalls/wasix/sock_status.rs @@ -3,7 +3,7 @@ use crate::syscalls::*; /// ### `sock_status()` /// Returns the current status of a socket -#[instrument(level = "debug", skip_all, fields(sock, status = field::Empty), ret)] +#[instrument(level = "debug", skip_all, fields(%sock, status = field::Empty), ret)] pub fn sock_status( mut ctx: FunctionEnvMut<'_, WasiEnv>, sock: WasiFd, diff --git a/lib/wasi/src/syscalls/wasix/thread_exit.rs b/lib/wasi/src/syscalls/wasix/thread_exit.rs index aab730de729..77ff6d1f8c9 100644 --- a/lib/wasi/src/syscalls/wasix/thread_exit.rs +++ b/lib/wasi/src/syscalls/wasix/thread_exit.rs @@ -10,7 +10,7 @@ use crate::syscalls::*; /// ## Parameters /// /// * `rval` - The exit code returned by the process. -#[instrument(level = "debug", skip_all, fields(exitcode), ret)] +#[instrument(level = "debug", skip_all, fields(%exitcode), ret)] pub fn thread_exit(ctx: FunctionEnvMut<'_, WasiEnv>, exitcode: ExitCode) -> Result<(), WasiError> { tracing::debug!(%exitcode); Err(WasiError::Exit(exitcode)) diff --git a/lib/wasi/src/syscalls/wasix/thread_join.rs b/lib/wasi/src/syscalls/wasix/thread_join.rs index db2015936bc..87631f6f149 100644 --- a/lib/wasi/src/syscalls/wasix/thread_join.rs +++ b/lib/wasi/src/syscalls/wasix/thread_join.rs @@ -8,7 +8,7 @@ use crate::syscalls::*; /// ## Parameters /// /// * `tid` - Handle of the thread to wait on -#[instrument(level = "debug", skip_all, fields(join_tid), ret, err)] +#[instrument(level = "debug", skip_all, fields(%join_tid), ret, err)] pub fn thread_join( mut ctx: FunctionEnvMut<'_, WasiEnv>, join_tid: Tid, diff --git a/lib/wasi/src/syscalls/wasix/thread_local_create.rs b/lib/wasi/src/syscalls/wasix/thread_local_create.rs index c96ae7f602d..5a4ae21175e 100644 --- a/lib/wasi/src/syscalls/wasix/thread_local_create.rs +++ b/lib/wasi/src/syscalls/wasix/thread_local_create.rs @@ -10,7 +10,7 @@ use crate::syscalls::*; /// /// * `user_data` - User data that will be passed to the destructor /// when the thread variable goes out of scope -#[instrument(level = "trace", skip_all, fields(user_data), ret)] +#[instrument(level = "trace", skip_all, fields(%user_data), ret)] pub fn thread_local_create( ctx: FunctionEnvMut<'_, WasiEnv>, user_data: TlUser, diff --git a/lib/wasi/src/syscalls/wasix/thread_local_destroy.rs b/lib/wasi/src/syscalls/wasix/thread_local_destroy.rs index f1f1281ecdb..3aa5a868756 100644 --- a/lib/wasi/src/syscalls/wasix/thread_local_destroy.rs +++ b/lib/wasi/src/syscalls/wasix/thread_local_destroy.rs @@ -9,7 +9,7 @@ use crate::syscalls::*; /// * `user_data` - User data that will be passed to the destructor /// when the thread variable goes out of scope /// * `key` - Thread key that was previously created -#[instrument(level = "trace", skip_all, fields(key), ret)] +#[instrument(level = "trace", skip_all, fields(%key), ret)] pub fn thread_local_destroy(mut ctx: FunctionEnvMut<'_, WasiEnv>, key: TlKey) -> Errno { let process = ctx.data().process.clone(); let mut inner = process.write(); diff --git a/lib/wasi/src/syscalls/wasix/thread_local_get.rs b/lib/wasi/src/syscalls/wasix/thread_local_get.rs index cf971bf4373..8130728e2ca 100644 --- a/lib/wasi/src/syscalls/wasix/thread_local_get.rs +++ b/lib/wasi/src/syscalls/wasix/thread_local_get.rs @@ -7,7 +7,7 @@ use crate::syscalls::*; /// ## Parameters /// /// * `key` - Thread key that this local variable that was previous set -#[instrument(level = "trace", skip_all, fields(key, val = field::Empty), ret)] +#[instrument(level = "trace", skip_all, fields(%key, val = field::Empty), ret)] pub fn thread_local_get( ctx: FunctionEnvMut<'_, WasiEnv>, key: TlKey, diff --git a/lib/wasi/src/syscalls/wasix/thread_local_set.rs b/lib/wasi/src/syscalls/wasix/thread_local_set.rs index 0de1d028517..58d720394d4 100644 --- a/lib/wasi/src/syscalls/wasix/thread_local_set.rs +++ b/lib/wasi/src/syscalls/wasix/thread_local_set.rs @@ -8,7 +8,7 @@ use crate::syscalls::*; /// /// * `key` - Thread key that this local variable will be associated with /// * `val` - Value to be set for the thread local variable -#[instrument(level = "trace", skip_all, fields(key, val), ret)] +#[instrument(level = "trace", skip_all, fields(%key, %val), ret)] pub fn thread_local_set(ctx: FunctionEnvMut<'_, WasiEnv>, key: TlKey, val: TlVal) -> Errno { let env = ctx.data(); diff --git a/lib/wasi/src/syscalls/wasix/thread_parallelism.rs b/lib/wasi/src/syscalls/wasix/thread_parallelism.rs index 76d9050721d..3f6b65605f3 100644 --- a/lib/wasi/src/syscalls/wasix/thread_parallelism.rs +++ b/lib/wasi/src/syscalls/wasix/thread_parallelism.rs @@ -4,7 +4,7 @@ use crate::syscalls::*; /// ### `thread_parallelism()` /// Returns the available parallelism which is normally the /// number of available cores that can run concurrently -#[instrument(level = "debug", skip_all, fields(parallelism), ret)] +#[instrument(level = "debug", skip_all, fields(parallelism = field::Empty), ret)] pub fn thread_parallelism( ctx: FunctionEnvMut<'_, WasiEnv>, ret_parallelism: WasmPtr, diff --git a/lib/wasi/src/syscalls/wasix/thread_signal.rs b/lib/wasi/src/syscalls/wasix/thread_signal.rs index 2bb45ee33d7..cea9d4caeea 100644 --- a/lib/wasi/src/syscalls/wasix/thread_signal.rs +++ b/lib/wasi/src/syscalls/wasix/thread_signal.rs @@ -7,7 +7,7 @@ use crate::syscalls::*; /// Inputs: /// - `Signal` /// Signal to be raised for this process -#[instrument(level = "debug", skip_all, fields(tid, sig), ret, err)] +#[instrument(level = "debug", skip_all, fields(%tid, ?sig), ret, err)] pub fn thread_signal( mut ctx: FunctionEnvMut<'_, WasiEnv>, tid: Tid, diff --git a/lib/wasi/src/syscalls/wasix/thread_sleep.rs b/lib/wasi/src/syscalls/wasix/thread_sleep.rs index d4ae2da2d84..b5d643a471b 100644 --- a/lib/wasi/src/syscalls/wasix/thread_sleep.rs +++ b/lib/wasi/src/syscalls/wasix/thread_sleep.rs @@ -7,7 +7,7 @@ use crate::syscalls::*; /// ## Parameters /// /// * `duration` - Amount of time that the thread should sleep -#[instrument(level = "debug", skip_all, fields(duration), ret, err)] +#[instrument(level = "debug", skip_all, fields(%duration), ret, err)] pub fn thread_sleep( mut ctx: FunctionEnvMut<'_, WasiEnv>, duration: Timestamp, diff --git a/lib/wasi/tests/runners.rs b/lib/wasi/tests/runners.rs index 8792fe14e8f..729bc0aa95f 100644 --- a/lib/wasi/tests/runners.rs +++ b/lib/wasi/tests/runners.rs @@ -52,7 +52,7 @@ mod wasi { WasiError::Exit(code) => *code, other => unreachable!("Something else went wrong: {:?}", other), }; - assert_eq!(exit_code.is_success(), true); + assert!(exit_code.is_success()); } #[tokio::test] diff --git a/lib/wasi/tests/stdio.rs b/lib/wasi/tests/stdio.rs index 7c719a0f6b4..bcdabf8d0ca 100644 --- a/lib/wasi/tests/stdio.rs +++ b/lib/wasi/tests/stdio.rs @@ -75,7 +75,7 @@ async fn test_stdout() { let (stdout_tx, mut stdout_rx) = Pipe::channel(); let builder = WasiEnv::builder("command-name") - .args(&["Gordon"]) + .args(["Gordon"]) .stdout(Box::new(stdout_tx)); #[cfg(feature = "js")] @@ -111,7 +111,7 @@ async fn test_env() { let (pipe_tx, mut pipe_rx) = Pipe::channel(); let builder = WasiEnv::builder("command-name") - .args(&["Gordon"]) + .args(["Gordon"]) .env("DOG", "X") .env("TEST", "VALUE") .env("TEST2", "VALUE2") diff --git a/tests/integration/cli/tests/run_unstable.rs b/tests/integration/cli/tests/run_unstable.rs index 8877c3fe44a..a1da778bc23 100644 --- a/tests/integration/cli/tests/run_unstable.rs +++ b/tests/integration/cli/tests/run_unstable.rs @@ -8,13 +8,19 @@ use std::{ time::{Duration, Instant}, }; -use assert_cmd::{assert::Assert, prelude::OutputAssertExt, Command}; +use assert_cmd::{assert::Assert, prelude::OutputAssertExt}; use predicates::str::contains; use reqwest::{blocking::Client, IntoUrl}; use tempfile::TempDir; use wasmer_integration_tests_cli::get_wasmer_path; -const RUST_LOG: &str = "info,wasmer_wasi::runners=debug"; +const RUST_LOG: &str = "info,wasmer_wasi::runners=debug,virtual_fs::trace_fs=trace"; + +fn wasmer_run_unstable() -> std::process::Command { + let mut cmd = std::process::Command::new(get_wasmer_path()); + cmd.env("RUST_LOG", RUST_LOG).arg("run-unstable"); + cmd +} mod webc_on_disk { use super::*; @@ -26,8 +32,7 @@ mod webc_on_disk { ignore = "wasmer run-unstable segfaults on musl" )] fn wasi_runner() { - let assert = Command::new(get_wasmer_path()) - .arg("run-unstable") + let assert = wasmer_run_unstable() .arg(fixtures::qjs()) .arg("--") .arg("--eval") @@ -46,8 +51,7 @@ mod webc_on_disk { let temp = TempDir::new().unwrap(); std::fs::write(temp.path().join("index.js"), "console.log('Hello, World!')").unwrap(); - let assert = Command::new(get_wasmer_path()) - .arg("run-unstable") + let assert = wasmer_run_unstable() .arg(fixtures::qjs()) .arg(format!("--mapdir=/app:{}", temp.path().display())) .arg("--") @@ -58,7 +62,6 @@ mod webc_on_disk { } #[test] - #[ignore = "WASI runners only give you access to the webc fs for now"] #[cfg_attr( all(target_env = "musl", target_os = "linux"), ignore = "wasmer run-unstable segfaults on musl" @@ -67,11 +70,11 @@ mod webc_on_disk { let temp = TempDir::new().unwrap(); std::fs::write(temp.path().join("main.py"), "print('Hello, World!')").unwrap(); - let assert = Command::new(get_wasmer_path()) - .arg("run-unstable") + let assert = wasmer_run_unstable() .arg(fixtures::python()) .arg(format!("--mapdir=/app:{}", temp.path().display())) .arg("--") + .arg("-B") .arg("/app/main.py") .assert(); @@ -84,10 +87,7 @@ mod webc_on_disk { ignore = "wasmer run-unstable segfaults on musl" )] fn webc_files_with_multiple_commands_require_an_entrypoint_flag() { - let assert = Command::new(get_wasmer_path()) - .arg("run-unstable") - .arg(fixtures::wabt()) - .assert(); + let assert = wasmer_run_unstable().arg(fixtures::wabt()).assert(); let msg = r#"Unable to determine the WEBC file's entrypoint. Please choose one of ["wat2wasm", "wast2json", "wasm2wat", "wasm-interp", "wasm-validate", "wasm-strip"]"#; assert.failure().stderr(contains(msg)); @@ -99,14 +99,13 @@ mod webc_on_disk { ignore = "wasmer run-unstable segfaults on musl" )] fn wasi_runner_with_env_vars() { - let assert = Command::new(get_wasmer_path()) - .arg("run-unstable") + let assert = wasmer_run_unstable() .arg(fixtures::python()) .arg("--env=SOME_VAR=Hello, World!") .arg("--") + .arg("-B") .arg("-c") .arg("import os; print(os.environ['SOME_VAR'])") - .env("RUST_LOG", RUST_LOG) .assert(); assert.success().stdout(contains("Hello, World!")); @@ -120,11 +119,9 @@ mod webc_on_disk { fn wcgi_runner() { // Start the WCGI server in the background let port = rand::thread_rng().gen_range(10_000_u16..u16::MAX); - let mut cmd = std::process::Command::new(get_wasmer_path()); - cmd.arg("run-unstable") - .arg(format!("--addr=127.0.0.1:{port}")) - .arg(fixtures::static_server()) - .env("RUST_LOG", RUST_LOG); + let mut cmd = wasmer_run_unstable(); + cmd.arg(format!("--addr=127.0.0.1:{port}")) + .arg(fixtures::static_server()); let child = JoinableChild::spawn(cmd); // make the request @@ -155,12 +152,10 @@ mod webc_on_disk { std::fs::write(temp.path().join("file.txt"), "Hello, World!").unwrap(); // Start the WCGI server in the background let port = rand::thread_rng().gen_range(10_000_u16..u16::MAX); - let mut cmd = std::process::Command::new(get_wasmer_path()); - cmd.arg("run-unstable") - .arg(format!("--addr=127.0.0.1:{port}")) + let mut cmd = wasmer_run_unstable(); + cmd.arg(format!("--addr=127.0.0.1:{port}")) .arg(format!("--mapdir=/path/to:{}", temp.path().display())) - .arg(fixtures::static_server()) - .env("RUST_LOG", RUST_LOG); + .arg(fixtures::static_server()); let child = JoinableChild::spawn(cmd); let body = http_get(format!("http://127.0.0.1:{port}/path/to/file.txt")).unwrap(); @@ -178,6 +173,8 @@ mod webc_on_disk { } mod wasm_on_disk { + use std::process::Command; + use super::*; use predicates::str::contains; @@ -187,8 +184,7 @@ mod wasm_on_disk { ignore = "wasmer run-unstable segfaults on musl" )] fn wasi_executable() { - let assert = Command::new(get_wasmer_path()) - .arg("run-unstable") + let assert = wasmer_run_unstable() .arg(fixtures::qjs()) .arg("--") .arg("--eval") @@ -204,10 +200,7 @@ mod wasm_on_disk { ignore = "wasmer run-unstable segfaults on musl" )] fn no_abi() { - let assert = Command::new(get_wasmer_path()) - .arg("run-unstable") - .arg(fixtures::fib()) - .assert(); + let assert = wasmer_run_unstable().arg(fixtures::fib()).assert(); assert.success(); } @@ -218,10 +211,7 @@ mod wasm_on_disk { ignore = "wasmer run-unstable segfaults on musl" )] fn error_if_no_start_function_found() { - let assert = Command::new(get_wasmer_path()) - .arg("run-unstable") - .arg(fixtures::wat_no_start()) - .assert(); + let assert = wasmer_run_unstable().arg(fixtures::wat_no_start()).assert(); assert .failure() @@ -248,8 +238,7 @@ mod wasm_on_disk { assert!(dest.exists()); // Now we can try to run the compiled artifact - let assert = Command::new(get_wasmer_path()) - .arg("run-unstable") + let assert = wasmer_run_unstable() .arg(&dest) .arg("--") .arg("--eval") @@ -270,8 +259,7 @@ fn wasmer_package_directory() { std::fs::copy(fixtures::qjs(), temp.path().join("qjs.wasm")).unwrap(); std::fs::copy(fixtures::qjs_wasmer_toml(), temp.path().join("wasmer.toml")).unwrap(); - let assert = Command::new(get_wasmer_path()) - .arg("run-unstable") + let assert = wasmer_run_unstable() .arg(temp.path()) .arg("--") .arg("--eval") @@ -290,8 +278,7 @@ mod remote_webc { ignore = "wasmer run-unstable segfaults on musl" )] fn quickjs_as_package_name() { - let assert = Command::new(get_wasmer_path()) - .arg("run-unstable") + let assert = wasmer_run_unstable() .arg("saghul/quickjs") .arg("--entrypoint=quickjs") .arg("--registry=https://wapm.io/") @@ -309,8 +296,7 @@ mod remote_webc { ignore = "wasmer run-unstable segfaults on musl" )] fn quickjs_as_url() { - let assert = Command::new(get_wasmer_path()) - .arg("run-unstable") + let assert = wasmer_run_unstable() .arg("https://wapm.io/saghul/quickjs") .arg("--entrypoint=quickjs") .arg("--")