diff --git a/lib/wasi/src/runners/wasi.rs b/lib/wasi/src/runners/wasi.rs index c4f1339cd06..23bff4cc87e 100644 --- a/lib/wasi/src/runners/wasi.rs +++ b/lib/wasi/src/runners/wasi.rs @@ -122,9 +122,9 @@ impl WasiRunner { program_name: &str, wasi: &Wasi, ) -> Result { - let mut builder = - self.wasi - .prepare_webc_env(container.container_fs(), program_name, wasi)?; + let mut builder = WasiEnvBuilder::new(program_name); + self.wasi + .prepare_webc_env(&mut builder, container.container_fs(), wasi)?; if let Some(tasks) = &self.tasks { let rt = PluggableRuntime::new(Arc::clone(tasks)); diff --git a/lib/wasi/src/runners/wasi_common.rs b/lib/wasi/src/runners/wasi_common.rs index 55ef2b74ff3..f1ec2d24f16 100644 --- a/lib/wasi/src/runners/wasi_common.rs +++ b/lib/wasi/src/runners/wasi_common.rs @@ -8,7 +8,7 @@ use anyhow::{Context, Error}; use virtual_fs::{FileSystem, OverlayFileSystem, RootFileSystemBuilder}; use webc::metadata::annotations::Wasi as WasiAnnotation; -use crate::{runners::MappedDirectory, WasiEnv, WasiEnvBuilder}; +use crate::{runners::MappedDirectory, WasiEnvBuilder}; #[derive(Debug, Default, Clone, serde::Serialize, serde::Deserialize)] pub(crate) struct CommonWasiOptions { @@ -21,11 +21,11 @@ pub(crate) struct CommonWasiOptions { impl CommonWasiOptions { pub(crate) fn prepare_webc_env( &self, + builder: &mut WasiEnvBuilder, container_fs: Arc, - program_name: &str, wasi: &WasiAnnotation, - ) -> Result { - let mut builder = WasiEnv::builder(program_name).args(&self.args); + ) -> Result<(), anyhow::Error> { + builder.add_args(&self.args); let fs = prepare_filesystem(&self.mapped_dirs, container_fs, |path| { builder.add_preopen_dir(path).map_err(Error::from) @@ -34,10 +34,10 @@ impl CommonWasiOptions { builder.add_preopen_dir("/")?; builder.add_preopen_dir(".")?; - self.populate_env(wasi, &mut builder); - self.populate_args(wasi, &mut builder); + self.populate_env(wasi, builder); + self.populate_args(wasi, builder); - Ok(builder) + Ok(()) } fn populate_env(&self, wasi: &WasiAnnotation, builder: &mut WasiEnvBuilder) { diff --git a/lib/wasi/src/runners/wcgi/handler.rs b/lib/wasi/src/runners/wcgi/handler.rs index cde9bc48812..2298b4261db 100644 --- a/lib/wasi/src/runners/wcgi/handler.rs +++ b/lib/wasi/src/runners/wcgi/handler.rs @@ -39,15 +39,21 @@ impl Handler { tracing::debug!("Creating the WebAssembly instance"); - let mut request_specific_env = HashMap::new(); + let mut builder = WasiEnvBuilder::new(&self.program_name); + // Note: We want to apply the CGI environment variables *before* + // anything specified by WASI annotations so users get a chance to + // override things like $DOCUMENT_ROOT and $SCRIPT_FILENAME. + let mut request_specific_env = HashMap::new(); self.dialect .prepare_environment_variables(parts, &mut request_specific_env); + builder.add_envs(request_specific_env); + + (self.setup_builder)(&mut builder)?; let rt = PluggableRuntime::new(Arc::clone(&self.task_manager)); - let builder = (self.setup_builder)()? - .envs(request_specific_env) + let builder = builder .stdin(Box::new(req_body_receiver)) .stdout(Box::new(res_body_sender)) .stderr(Box::new(stderr_sender)) @@ -201,13 +207,16 @@ async fn consume_stderr( } } +type SetupBuilder = Box Result<(), anyhow::Error> + Send + Sync>; + #[derive(derivative::Derivative)] #[derivative(Debug)] pub(crate) struct SharedState { pub(crate) module: Module, pub(crate) dialect: CgiDialect, + pub(crate) program_name: String, #[derivative(Debug = "ignore")] - pub(crate) setup_builder: Box Result + Send + Sync>, + pub(crate) setup_builder: SetupBuilder, #[derivative(Debug = "ignore")] pub(crate) callbacks: Arc, #[derivative(Debug = "ignore")] diff --git a/lib/wasi/src/runners/wcgi/runner.rs b/lib/wasi/src/runners/wcgi/runner.rs index 892a53b63dc..1b49c0d6269 100644 --- a/lib/wasi/src/runners/wcgi/runner.rs +++ b/lib/wasi/src/runners/wcgi/runner.rs @@ -138,15 +138,16 @@ impl WcgiRunner { }; let shared = SharedState { + module, + dialect, + program_name: self.program_name.clone(), + setup_builder: Box::new(self.setup_builder(ctx, wasi)), + callbacks: Arc::clone(&self.config.callbacks), task_manager: self .config .task_manager .clone() .unwrap_or_else(|| Arc::new(TokioTaskManager::default())), - module, - dialect, - callbacks: Arc::clone(&self.config.callbacks), - setup_builder: Box::new(self.setup_builder(ctx, wasi)), }; Ok(Handler::new(shared)) @@ -156,23 +157,21 @@ impl WcgiRunner { &self, ctx: &RunnerContext<'_>, wasi: &Wasi, - ) -> impl Fn() -> Result + Send + Sync { + ) -> impl Fn(&mut WasiEnvBuilder) -> Result<(), Error> + 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)?; + move |builder| { + wasi_common.prepare_webc_env(builder, Arc::clone(&container_fs), &wasi)?; if let Some(tasks) = &tasks { let rt = PluggableRuntime::new(Arc::clone(tasks)); builder.set_runtime(Arc::new(rt)); } - Ok(builder) + Ok(()) } } }