-
Notifications
You must be signed in to change notification settings - Fork 824
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Move the wcgi-runner crate into the Wasmer repo
- Loading branch information
Michael-F-Bryan
committed
Feb 22, 2023
1 parent
b42cd59
commit 95a3a2d
Showing
17 changed files
with
1,633 additions
and
21 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
[package] | ||
name = "wcgi-runner" | ||
version = "3.2.0-alpha.1" | ||
description = "A runner that can serve WCGI programs locally" | ||
authors = ["Wasmer Engineering Team <[email protected]>"] | ||
repository = "https://github.com/wasmerio/wasmer" | ||
license = "MIT" | ||
readme = "README.md" | ||
edition = "2018" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[dependencies] | ||
anyhow = { version = "1", features = ["backtrace"] } | ||
async-trait = "0.1.64" | ||
bytes = "1.4.0" | ||
clap = { version = "4", features = ["derive", "env"] } | ||
futures = "0.3.25" | ||
http = "0.2.8" | ||
hyper = { version = "0.14.23", features = ["server", "stream"] } | ||
md5 = "0.7.0" | ||
serde = { version = "1.0.152", features = ["derive"] } | ||
serde_cbor = "0.11.2" | ||
thiserror = "1.0.38" | ||
tiny_http = "0.12.0" | ||
tokio = { version = "1", features = ["rt-multi-thread", "macros"] } | ||
tower-service = "0.3" | ||
tracing = "0.1.37" | ||
tracing-subscriber = { version = "0.3.16", features = ["fmt", "env-filter"] } | ||
wasmer = { version = "3.2.0-alpha.1", path = "../api", default-features = false, features = [ | ||
"sys", | ||
"cranelift", | ||
"singlepass", | ||
] } | ||
wasmer-wasi = { version = "3.2.0-alpha.1", path = "../wasi", features = [ | ||
"sys-default", | ||
], default-features = false } | ||
wasmer-vfs = { version = "3.2.0-alpha.1", path = "../vfs", default-features = false } | ||
wcgi = { version = "0.1.1" } | ||
wcgi-host = { version = "0.1.0" } | ||
webc = { version = "5.0.0-rc.1", default-features = false } | ||
|
||
[dev-dependencies] | ||
reqwest = { version = "0.11.0", default-features = false, features = [ | ||
"rustls-tls", | ||
] } | ||
ureq = "2.6.2" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# wcgi-runner | ||
|
||
A server that can serve [wcgi][wcgi] web servers. | ||
|
||
## Usage | ||
|
||
`wcgi-runner --watch ./path/to/module.wasm` | ||
|
||
[wcgi]: https://github.com/wasmerio/wcgi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
use wcgi_host::CgiDialect; | ||
|
||
// FIXME(@Michael-F-Bryan): Make this public in the webc crate | ||
#[derive(Debug, Default, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)] | ||
pub struct WasiCommandAnnotation { | ||
#[serde(default)] | ||
pub atom: Option<String>, | ||
#[serde(default)] | ||
pub package: Option<String>, | ||
#[serde(default)] | ||
pub env: Option<Vec<String>>, | ||
#[serde(default)] | ||
pub main_args: Option<Vec<String>>, | ||
#[serde(default, rename = "mountAtomInVolume")] | ||
pub mount_atom_in_volume: Option<String>, | ||
} | ||
|
||
// FIXME(@Michael-F-Bryan): Add this to the webc crate and update | ||
// wapm-targz-to-pirita | ||
#[derive(Debug, Default, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)] | ||
pub struct WcgiAnnotation { | ||
#[serde(default)] | ||
pub dialect: Option<CgiDialect>, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
use std::{convert::Infallible, net::SocketAddr, path::PathBuf}; | ||
|
||
use anyhow::{Context, Error}; | ||
use clap::Parser; | ||
use tracing_subscriber::fmt::format::FmtSpan; | ||
use wcgi_runner::Runner; | ||
|
||
fn main() -> Result<(), Error> { | ||
if std::env::var("RUST_LOG").is_err() { | ||
std::env::set_var("RUST_LOG", "wcgi_runner=trace,info"); | ||
} | ||
tracing_subscriber::fmt() | ||
.with_span_events(FmtSpan::CLOSE) | ||
.init(); | ||
|
||
let Args { | ||
address, | ||
input, | ||
env_all, | ||
mapped_dirs, | ||
} = Args::parse(); | ||
|
||
// Hack to initialize the global shared tokio task manager handle. | ||
// Prevents "cannot drop runtime in async context" errors, because | ||
// the default will be initialized to the current tokio context. | ||
let rt = wasmer_wasi::runtime::task_manager::tokio::TokioTaskManager::default(); | ||
|
||
let mut builder = Runner::builder() | ||
.map_dirs(mapped_dirs) | ||
.tokio_handle(rt.runtime_handle()); | ||
|
||
if env_all { | ||
builder = builder.forward_host_env(); | ||
} | ||
|
||
let runner = builder | ||
.watch(input) | ||
.context("Unable to create the runner")?; | ||
|
||
let make_service = hyper::service::make_service_fn(move |_| { | ||
let runner = runner.clone(); | ||
async move { Ok::<_, Infallible>(runner) } | ||
}); | ||
|
||
tracing::info!(%address, "Started the server"); | ||
rt.runtime_handle() | ||
.block_on(async { hyper::Server::bind(&address).serve(make_service).await }) | ||
.context("Unable to start the server")?; | ||
|
||
Ok(()) | ||
} | ||
|
||
#[derive(Debug, Clone, Parser)] | ||
#[clap(about, version, author)] | ||
struct Args { | ||
/// Server address. | ||
#[clap(long, short, env, default_value_t = ([127, 0, 0, 1], 8000).into())] | ||
address: SocketAddr, | ||
|
||
/// Map a host directory to a different location for the Wasm module | ||
/// | ||
/// Example: | ||
/// | ||
/// --map-dir /www:./my-website | ||
/// => will make the ./my-website directory available for wazsm at /www | ||
#[clap( | ||
long = "mapdir", | ||
name = "GUEST_DIR:HOST_DIR", | ||
value_parser = parse_mapdir, | ||
)] | ||
mapped_dirs: Vec<(String, PathBuf)>, | ||
|
||
/// Forward all host env variables to the wcgi task. | ||
#[clap(long)] | ||
env_all: bool, | ||
|
||
/// A WCGI program. | ||
input: PathBuf, | ||
} | ||
|
||
/// Parses a mapdir from a string | ||
// NOTE: copied from wasmerio/wasmer lib/cli/src/utils.rs. | ||
pub fn parse_mapdir(entry: &str) -> Result<(String, PathBuf), anyhow::Error> { | ||
fn retrieve_alias_pathbuf( | ||
alias: &str, | ||
real_dir: &str, | ||
) -> Result<(String, PathBuf), anyhow::Error> { | ||
let pb = PathBuf::from(&real_dir); | ||
if let Ok(pb_metadata) = pb.metadata() { | ||
if !pb_metadata.is_dir() { | ||
anyhow::bail!("\"{real_dir}\" exists, but it is not a directory"); | ||
} | ||
} else { | ||
anyhow::bail!("Directory \"{real_dir}\" does not exist"); | ||
} | ||
Ok((alias.to_string(), pb)) | ||
} | ||
|
||
// We try first splitting by `::` | ||
if let Some((alias, real_dir)) = entry.split_once("::") { | ||
retrieve_alias_pathbuf(alias, real_dir) | ||
} | ||
// And then we try splitting by `:` (for compatibility with previous API) | ||
else if let Some((alias, real_dir)) = entry.split_once(':') { | ||
retrieve_alias_pathbuf(alias, real_dir) | ||
} else { | ||
anyhow::bail!( | ||
"Directory mappings must consist of two paths separate by a `::` or `:`. Found {entry}", | ||
) | ||
} | ||
} |
Oops, something went wrong.