From 5f097e9d4f958aa31f9e00d82d0f3a447b5361f2 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Wed, 1 Mar 2023 13:38:55 -0700 Subject: [PATCH] fix crash on Windows; add version embedding This fixes an issue causing `wizer` to fail due to `CPython` calling `fd_filestat_get` on stdio descriptors, which causes Wasmtime's WASI implementation to trap if those descriptors don't point to actual files. This also updates the `spin-sdk` dependency to allow version embedding per https://github.com/fermyon/spin/blob/main/docs/content/sips/011-component-versioning.md. Signed-off-by: Joel Dice --- crates/spin-python-cli/src/main.rs | 22 +++++++++++++++++++++- crates/spin-python-engine/Cargo.toml | 2 +- crates/spin-python-engine/src/lib.rs | 3 +++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/crates/spin-python-cli/src/main.rs b/crates/spin-python-cli/src/main.rs index 29b73fe..0bdd31a 100644 --- a/crates/spin-python-cli/src/main.rs +++ b/crates/spin-python-cli/src/main.rs @@ -5,7 +5,7 @@ use { clap::Parser, std::{ env, fs, - io::Cursor, + io::{self, Cursor, Seek}, path::{Path, PathBuf}, process::Command, str, @@ -105,6 +105,17 @@ fn main() -> Result<()> { ) } + // Spawn a subcommand to do the real work. This gives us an opportunity to clear the environment so that + // build-time environment variables don't end up in the Wasm module we're building. + // + // Note that we need to use temporary files for stdio instead of the default inheriting behavior since (as + // of this writing) CPython interacts poorly with Wasmtime's WASI implementation if any of the stdio + // descriptors point to non-files on Windows. Specifically, the WASI implementation will trap when CPython + // calls `fd_filestat_get` on non-files. + + let mut stdout = tempfile::tempfile()?; + let mut stderr = tempfile::tempfile()?; + let status = Command::new(env::args().next().unwrap()) .env_clear() .env("SPIN_PYTHON_WIZEN", "1") @@ -116,9 +127,18 @@ fn main() -> Result<()> { ) .arg(&python_path) .arg(&options.output) + .stdin(tempfile::tempfile()?) + .stdout(stdout.try_clone()?) + .stderr(stderr.try_clone()?) .status()?; if !status.success() { + stdout.rewind()?; + io::copy(&mut stdout, &mut io::stdout().lock())?; + + stderr.rewind()?; + io::copy(&mut stderr, &mut io::stderr().lock())?; + bail!("Couldn't create wasm from input"); } diff --git a/crates/spin-python-engine/Cargo.toml b/crates/spin-python-engine/Cargo.toml index 987ff58..24f4032 100644 --- a/crates/spin-python-engine/Cargo.toml +++ b/crates/spin-python-engine/Cargo.toml @@ -11,7 +11,7 @@ crate-type = [ "cdylib" ] anyhow = "1" bytes = { version = "1.2.1", features = ["serde"] } http = "0.2" -spin-sdk = { git = "https://github.com/fermyon/spin" } +spin-sdk = { git = "https://github.com/fermyon/spin", default-features = false } wit-bindgen-rust = { git = "https://github.com/bytecodealliance/wit-bindgen", rev = "dde4694aaa6acf9370206527a798ac4ba6a8c5b8" } pyo3 = { version = "0.17.3", features = [ "abi3-py310" ] } once_cell = "1.16.0" diff --git a/crates/spin-python-engine/src/lib.rs b/crates/spin-python-engine/src/lib.rs index a65e138..6f2f6a3 100644 --- a/crates/spin-python-engine/src/lib.rs +++ b/crates/spin-python-engine/src/lib.rs @@ -24,6 +24,9 @@ thread_local! { static ENVIRON: OnceCell> = OnceCell::new(); } +#[export_name = "spin-sdk-language-python"] +extern "C" fn __spin_sdk_language() {} + fn bytes(py: Python<'_>, src: &[u8]) -> PyResult> { Ok(PyBytes::new_with(py, src.len(), |dst| { dst.copy_from_slice(src);