Reuse unioned_filesystem() for WCGI

This commit is contained in:
Michael-F-Bryan
2023-03-17 01:35:14 +08:00
parent e2a933c83b
commit 702972fb10
6 changed files with 38 additions and 48 deletions

View File

@@ -409,7 +409,7 @@ impl RunWithPathBuf {
.addr(self.wcgi.addr)
.envs(self.wasi.env_vars.clone())
.map_directories(self.wasi.mapped_dirs.clone());
if self.wcgi.forward_host_env {
if self.wasi.forward_host_env {
runner.config().forward_host_env();
}
if runner.can_run_command(id, command).unwrap_or(false) {
@@ -706,16 +706,12 @@ pub(crate) struct WcgiOptions {
/// The address to serve on.
#[clap(long, short, env, default_value_t = ([127, 0, 0, 1], 8000).into())]
pub(crate) addr: SocketAddr,
/// Forward all host env variables to the wcgi task.
#[clap(long)]
pub(crate) forward_host_env: bool,
}
impl Default for WcgiOptions {
fn default() -> Self {
Self {
addr: ([127, 0, 0, 1], 8000).into(),
forward_host_env: false,
}
}
}

View File

@@ -197,8 +197,7 @@ where
let start: usize = self.cursor.try_into().unwrap();
let remaining = &bytes[start..];
let bytes_read = remaining.len().min(buf.remaining());
let end = start + bytes_read;
let bytes = &bytes[start..end];
let bytes = &remaining[..bytes_read];
buf.put_slice(bytes);
self.cursor += u64::try_from(bytes_read).unwrap();

View File

@@ -132,13 +132,17 @@ impl WasiRunner {
container: &WapmContainer,
command: &str,
) -> Result<WasiEnvBuilder, anyhow::Error> {
let root_fs = unioned_filesystem(&self.mapped_dirs, container)?;
let fs = unioned_filesystem(&self.mapped_dirs, container)?;
let fs = container.container_fs();
let mut builder = WasiEnv::builder(command)
.args(&self.args)
.fs(Box::new(root_fs))
.preopen_dir("/")?;
preopen(&fs, "/".as_ref(), &mut builder)?;
builder.set_fs(Box::new(fs));
if self.forward_host_env {
for (k, v) in std::env::vars() {
builder.add_env(k, v);
@@ -192,7 +196,7 @@ impl crate::runners::Runner for WasiRunner {
/// Create a [`FileSystem`] which merges the WAPM container's volumes with any
/// directories that were mapped from the host.
fn unioned_filesystem(
pub(crate) fn unioned_filesystem(
mapped_dirs: &[MappedDirectory],
container: &WapmContainer,
) -> Result<impl FileSystem, Error> {
@@ -236,6 +240,19 @@ fn unioned_filesystem(
Ok(OverlayFileSystem::new(primary, [container.container_fs()]))
}
fn preopen(fs: &dyn FileSystem, path: &Path, builder: &mut WasiEnvBuilder) -> Result<(), Error> {
for result in fs.read_dir(path)? {
let entry = result?;
if entry.file_type()?.is_dir() {
builder.add_preopen_dir(&entry.path)?;
preopen(fs, &entry.path, builder)?;
}
}
Ok(())
}
fn create_dir_all(fs: &(impl FileSystem + ?Sized), path: &Path) -> Result<(), Error> {
match fs.metadata(path) {
Ok(meta) if meta.is_dir() => return Ok(()),
@@ -257,7 +274,6 @@ fn create_dir_all(fs: &(impl FileSystem + ?Sized), path: &Path) -> Result<(), Er
mod tests {
use tempfile::TempDir;
use tokio::io::AsyncReadExt;
use wasmer_vfs::host_fs;
use super::*;
@@ -313,6 +329,9 @@ mod tests {
]
);
let abc = read_file(&fs, "/lib/python3.6/collections/abc.py").await;
assert_eq!(abc, "from _collections_abc import *");
assert_eq!(
abc,
"from _collections_abc import *\nfrom _collections_abc import __all__\n"
);
}
}

View File

@@ -23,7 +23,7 @@ use wcgi_host::CgiDialect;
use crate::{
capabilities::Capabilities,
http::HttpClientCapabilityV1,
runners::{wcgi::Callbacks, MappedDirectory},
runners::{wcgi::Callbacks, MappedDirectory, WapmContainer},
Pipe, PluggableRuntime, VirtualTaskManager, WasiEnv,
};
@@ -134,37 +134,8 @@ impl Handler {
Ok(response)
}
fn fs(&self) -> Result<TmpFileSystem, Error> {
let root_fs = RootFileSystemBuilder::new().build();
if !self.mapped_dirs.is_empty() {
let fs_backing: Arc<dyn FileSystem + Send + Sync> =
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",
);
root_fs
.mount(guest.clone(), &fs_backing, host.clone())
.with_context(|| {
format!(
"Unable to mount \"{}\" to \"{}\"",
host.display(),
guest.display()
)
})
.unwrap();
}
}
Ok(root_fs)
fn fs(&self) -> Result<impl FileSystem, Error> {
crate::runners::wasi::unioned_filesystem(&self.mapped_dirs, &self.container)
}
}
@@ -255,6 +226,7 @@ pub(crate) struct SharedState {
pub(crate) env: HashMap<String, String>,
pub(crate) args: Vec<String>,
pub(crate) mapped_dirs: Vec<MappedDirectory>,
pub(crate) container: WapmContainer,
pub(crate) module: Module,
pub(crate) dialect: CgiDialect,
pub(crate) task_manager: Arc<dyn VirtualTaskManager>,

View File

@@ -148,6 +148,7 @@ impl WcgiRunner {
.clone()
.unwrap_or_else(|| Arc::new(TokioTaskManager::default())),
module,
container: ctx.container.clone(),
dialect,
callbacks: Arc::clone(&self.config.callbacks),
};
@@ -225,8 +226,8 @@ impl RunnerContext<'_> {
&self.store
}
fn volume(&self, _name: &str) -> Option<Box<dyn FileSystem>> {
todo!("Implement a read-only filesystem backed by a volume");
fn container_fs(&self) -> Box<dyn FileSystem + Send + Sync> {
self.container.container_fs()
}
fn get_atom(&self, name: &str) -> Option<&[u8]> {

View File

@@ -15,6 +15,7 @@ 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=trace";
mod webc_on_disk {
use super::*;
@@ -81,13 +82,15 @@ mod webc_on_disk {
let assert = Command::new(get_wasmer_path())
.arg("run2")
.arg(fixtures::python())
.arg("--env")
.arg("SOME_VAR=Hello, World!")
.arg("--env=SOME_VAR=Hello, World!")
.arg("--")
.arg("-c")
.arg("import os; print(os.environ['SOME_VAR'])")
.env("RUST_LOG", RUST_LOG)
.assert();
panic!("{}", String::from_utf8_lossy(&assert.get_output().stderr));
assert.success().stdout(contains("Hello, World!"));
}