mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-06 20:58:28 +00:00
Reuse unioned_filesystem() for WCGI
This commit is contained in:
@@ -409,7 +409,7 @@ impl RunWithPathBuf {
|
|||||||
.addr(self.wcgi.addr)
|
.addr(self.wcgi.addr)
|
||||||
.envs(self.wasi.env_vars.clone())
|
.envs(self.wasi.env_vars.clone())
|
||||||
.map_directories(self.wasi.mapped_dirs.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();
|
runner.config().forward_host_env();
|
||||||
}
|
}
|
||||||
if runner.can_run_command(id, command).unwrap_or(false) {
|
if runner.can_run_command(id, command).unwrap_or(false) {
|
||||||
@@ -706,16 +706,12 @@ pub(crate) struct WcgiOptions {
|
|||||||
/// The address to serve on.
|
/// The address to serve on.
|
||||||
#[clap(long, short, env, default_value_t = ([127, 0, 0, 1], 8000).into())]
|
#[clap(long, short, env, default_value_t = ([127, 0, 0, 1], 8000).into())]
|
||||||
pub(crate) addr: SocketAddr,
|
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 {
|
impl Default for WcgiOptions {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
addr: ([127, 0, 0, 1], 8000).into(),
|
addr: ([127, 0, 0, 1], 8000).into(),
|
||||||
forward_host_env: false,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -197,8 +197,7 @@ where
|
|||||||
let start: usize = self.cursor.try_into().unwrap();
|
let start: usize = self.cursor.try_into().unwrap();
|
||||||
let remaining = &bytes[start..];
|
let remaining = &bytes[start..];
|
||||||
let bytes_read = remaining.len().min(buf.remaining());
|
let bytes_read = remaining.len().min(buf.remaining());
|
||||||
let end = start + bytes_read;
|
let bytes = &remaining[..bytes_read];
|
||||||
let bytes = &bytes[start..end];
|
|
||||||
|
|
||||||
buf.put_slice(bytes);
|
buf.put_slice(bytes);
|
||||||
self.cursor += u64::try_from(bytes_read).unwrap();
|
self.cursor += u64::try_from(bytes_read).unwrap();
|
||||||
|
|||||||
@@ -132,13 +132,17 @@ impl WasiRunner {
|
|||||||
container: &WapmContainer,
|
container: &WapmContainer,
|
||||||
command: &str,
|
command: &str,
|
||||||
) -> Result<WasiEnvBuilder, anyhow::Error> {
|
) -> 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)
|
let mut builder = WasiEnv::builder(command)
|
||||||
.args(&self.args)
|
.args(&self.args)
|
||||||
.fs(Box::new(root_fs))
|
|
||||||
.preopen_dir("/")?;
|
.preopen_dir("/")?;
|
||||||
|
|
||||||
|
preopen(&fs, "/".as_ref(), &mut builder)?;
|
||||||
|
|
||||||
|
builder.set_fs(Box::new(fs));
|
||||||
|
|
||||||
if self.forward_host_env {
|
if self.forward_host_env {
|
||||||
for (k, v) in std::env::vars() {
|
for (k, v) in std::env::vars() {
|
||||||
builder.add_env(k, v);
|
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
|
/// Create a [`FileSystem`] which merges the WAPM container's volumes with any
|
||||||
/// directories that were mapped from the host.
|
/// directories that were mapped from the host.
|
||||||
fn unioned_filesystem(
|
pub(crate) fn unioned_filesystem(
|
||||||
mapped_dirs: &[MappedDirectory],
|
mapped_dirs: &[MappedDirectory],
|
||||||
container: &WapmContainer,
|
container: &WapmContainer,
|
||||||
) -> Result<impl FileSystem, Error> {
|
) -> Result<impl FileSystem, Error> {
|
||||||
@@ -236,6 +240,19 @@ fn unioned_filesystem(
|
|||||||
Ok(OverlayFileSystem::new(primary, [container.container_fs()]))
|
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> {
|
fn create_dir_all(fs: &(impl FileSystem + ?Sized), path: &Path) -> Result<(), Error> {
|
||||||
match fs.metadata(path) {
|
match fs.metadata(path) {
|
||||||
Ok(meta) if meta.is_dir() => return Ok(()),
|
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 {
|
mod tests {
|
||||||
use tempfile::TempDir;
|
use tempfile::TempDir;
|
||||||
use tokio::io::AsyncReadExt;
|
use tokio::io::AsyncReadExt;
|
||||||
use wasmer_vfs::host_fs;
|
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
@@ -313,6 +329,9 @@ mod tests {
|
|||||||
]
|
]
|
||||||
);
|
);
|
||||||
let abc = read_file(&fs, "/lib/python3.6/collections/abc.py").await;
|
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"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ use wcgi_host::CgiDialect;
|
|||||||
use crate::{
|
use crate::{
|
||||||
capabilities::Capabilities,
|
capabilities::Capabilities,
|
||||||
http::HttpClientCapabilityV1,
|
http::HttpClientCapabilityV1,
|
||||||
runners::{wcgi::Callbacks, MappedDirectory},
|
runners::{wcgi::Callbacks, MappedDirectory, WapmContainer},
|
||||||
Pipe, PluggableRuntime, VirtualTaskManager, WasiEnv,
|
Pipe, PluggableRuntime, VirtualTaskManager, WasiEnv,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -134,37 +134,8 @@ impl Handler {
|
|||||||
Ok(response)
|
Ok(response)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fs(&self) -> Result<TmpFileSystem, Error> {
|
fn fs(&self) -> Result<impl FileSystem, Error> {
|
||||||
let root_fs = RootFileSystemBuilder::new().build();
|
crate::runners::wasi::unioned_filesystem(&self.mapped_dirs, &self.container)
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -255,6 +226,7 @@ pub(crate) struct SharedState {
|
|||||||
pub(crate) env: HashMap<String, String>,
|
pub(crate) env: HashMap<String, String>,
|
||||||
pub(crate) args: Vec<String>,
|
pub(crate) args: Vec<String>,
|
||||||
pub(crate) mapped_dirs: Vec<MappedDirectory>,
|
pub(crate) mapped_dirs: Vec<MappedDirectory>,
|
||||||
|
pub(crate) container: WapmContainer,
|
||||||
pub(crate) module: Module,
|
pub(crate) module: Module,
|
||||||
pub(crate) dialect: CgiDialect,
|
pub(crate) dialect: CgiDialect,
|
||||||
pub(crate) task_manager: Arc<dyn VirtualTaskManager>,
|
pub(crate) task_manager: Arc<dyn VirtualTaskManager>,
|
||||||
|
|||||||
@@ -148,6 +148,7 @@ impl WcgiRunner {
|
|||||||
.clone()
|
.clone()
|
||||||
.unwrap_or_else(|| Arc::new(TokioTaskManager::default())),
|
.unwrap_or_else(|| Arc::new(TokioTaskManager::default())),
|
||||||
module,
|
module,
|
||||||
|
container: ctx.container.clone(),
|
||||||
dialect,
|
dialect,
|
||||||
callbacks: Arc::clone(&self.config.callbacks),
|
callbacks: Arc::clone(&self.config.callbacks),
|
||||||
};
|
};
|
||||||
@@ -225,8 +226,8 @@ impl RunnerContext<'_> {
|
|||||||
&self.store
|
&self.store
|
||||||
}
|
}
|
||||||
|
|
||||||
fn volume(&self, _name: &str) -> Option<Box<dyn FileSystem>> {
|
fn container_fs(&self) -> Box<dyn FileSystem + Send + Sync> {
|
||||||
todo!("Implement a read-only filesystem backed by a volume");
|
self.container.container_fs()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_atom(&self, name: &str) -> Option<&[u8]> {
|
fn get_atom(&self, name: &str) -> Option<&[u8]> {
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ use tempfile::TempDir;
|
|||||||
use wasmer_integration_tests_cli::get_wasmer_path;
|
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";
|
||||||
|
// const RUST_LOG: &str = "info,wasmer_wasi=trace";
|
||||||
|
|
||||||
mod webc_on_disk {
|
mod webc_on_disk {
|
||||||
use super::*;
|
use super::*;
|
||||||
@@ -81,13 +82,15 @@ mod webc_on_disk {
|
|||||||
let assert = Command::new(get_wasmer_path())
|
let assert = Command::new(get_wasmer_path())
|
||||||
.arg("run2")
|
.arg("run2")
|
||||||
.arg(fixtures::python())
|
.arg(fixtures::python())
|
||||||
.arg("--env")
|
.arg("--env=SOME_VAR=Hello, World!")
|
||||||
.arg("SOME_VAR=Hello, World!")
|
|
||||||
.arg("--")
|
.arg("--")
|
||||||
.arg("-c")
|
.arg("-c")
|
||||||
.arg("import os; print(os.environ['SOME_VAR'])")
|
.arg("import os; print(os.environ['SOME_VAR'])")
|
||||||
|
.env("RUST_LOG", RUST_LOG)
|
||||||
.assert();
|
.assert();
|
||||||
|
|
||||||
|
panic!("{}", String::from_utf8_lossy(&assert.get_output().stderr));
|
||||||
|
|
||||||
assert.success().stdout(contains("Hello, World!"));
|
assert.success().stdout(contains("Hello, World!"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user