Skip to content
This repository was archived by the owner on Nov 10, 2022. It is now read-only.

Commit 8673bbe

Browse files
wgwoodsnpmccallum
authored andcommitted
Rework for wasmtime 0.29 and WASI changes
A lot has changed in upstream wasmtime / WASI, so wasmldr needs significant reworking to keep up. The biggest change upstream is that virtfs has been dropped from wasi_common. So we're dropping the bundle format and virtual filesystem view, for now, and we'll reimplement that functionality piece by piece, using things that are a little better aligned with current directions in WASI and WebAssembly. With this commit, enarx-wasmldr at least compiles and passes the remaining tests, and can successfully run some random wasm modules I had laying around. So this seems like a good start. Detailed changes: * bumped deps to wasmtime 0.29 and wasmparser 0.80 * removed bundle stuff from build.rs * removed config.rs and virtfs.rs * removed deps on serde, tar, tempfile from Cargo.toml * remove populate_virtfs() etc. from workload.rs * NOTE: this means we can't load modules on FD3 right now (that will be restored in a future commit) * moved CLI parsing into cli.rs, since this might get reused elsewhere * switched to structopt for CLI parsing, as we do elsewhere * use anyhow for error handling (like wasmtime does) * tweak trait bounds on workload::run() to work better with args/envs from structopt * enable module-linking and multi-memory in instantiated wasmtime engine Signed-off-by: Will Woods <[email protected]>
1 parent e4a4975 commit 8673bbe

File tree

8 files changed

+641
-927
lines changed

8 files changed

+641
-927
lines changed

Cargo.lock

Lines changed: 482 additions & 387 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
name = "enarx-wasmldr"
3-
version = "0.1.0"
4-
authors = ["Stefan Junker <[email protected]>", "Daiki Ueno <[email protected]>"]
3+
version = "0.2.0"
4+
authors = ["Will Woods <[email protected]>", "Stefan Junker <[email protected]>", "Daiki Ueno <[email protected]>"]
55
edition = "2018"
66
license = "Apache-2.0"
77
homepage = "https://github.com/enarx/enarx-wasmldr"
@@ -21,25 +21,24 @@ is-it-maintained-issue-resolution = { repository = "enarx/enarx-wasmldr" }
2121
is-it-maintained-open-issues = { repository = "enarx/enarx-wasmldr" }
2222

2323
[dependencies]
24-
wasmtime = { version = "0.22", default-features = false }
25-
wasmtime-wasi = { version = "0.22", default-features = false }
26-
wasi-common = { version = "0.22", default-features = false }
27-
env_logger = "0.8"
24+
wasmtime = { version = "0.29", default-features = false }
25+
wasmtime-wasi = { version = "0.29", default-features = false, features = ["sync"] }
26+
wasi-common = { version = "0.29", default-features = false }
27+
env_logger = "0.9"
2828
log = "0.4"
2929

30-
wasmparser = "0.73"
31-
tar = "0.4"
32-
tempfile = "3"
33-
clap = "2.33"
34-
35-
serde = { version = "1.0", features = ["derive"] }
36-
serde_yaml = "0.8"
37-
cfg-if = "1.0"
30+
wasmparser = "0.80"
31+
structopt = "0.3.22"
32+
anyhow = "1.0"
3833

3934
[build-dependencies]
4035
wat = "1.0"
4136

4237
[profile.release]
4338
incremental = false
4439
codegen-units = 1
40+
panic = "abort"
4541
lto = true
42+
opt-level = "s"
43+
# This only works in nightly...
44+
#strip = "debuginfo"

build.rs

Lines changed: 11 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// SPDX-License-Identifier: Apache-2.0
22

33
use std::path::Path;
4-
use std::process::Command;
54

65
fn main() {
76
let in_dir = Path::new("fixtures");
@@ -10,47 +9,18 @@ fn main() {
109
let out_dir = Path::new(&out_dir).join("fixtures");
1110
std::fs::create_dir_all(&out_dir).expect("Can't create output directory");
1211

13-
for entry in in_dir.read_dir().unwrap() {
14-
if let Ok(entry) = entry {
15-
let wat = entry.path();
16-
match wat.extension() {
17-
Some(ext) if ext == "wat" => {
18-
let wasm = out_dir
19-
.join(wat.file_name().unwrap())
20-
.with_extension("wasm");
21-
let binary = wat::parse_file(&wat).expect("Can't parse wat file");
22-
std::fs::write(&wasm, &binary).expect("Can't write wasm file");
23-
// If the "enarx" command is installed, create a
24-
// bundled Wasm file for testing.
25-
let status = Command::new("enarx")
26-
.arg("wasm")
27-
.arg("bundle")
28-
.arg("fixtures/bundle")
29-
.arg(&wasm)
30-
.arg(&wasm.with_extension("bundled.wasm"))
31-
.status();
32-
33-
if let Ok(status) = status {
34-
if !status.success() {
35-
println!(
36-
"cargo:warning=Error bundling resources for {:?}: {}",
37-
&wasm.file_name().unwrap(),
38-
status.code().unwrap()
39-
);
40-
} else {
41-
println!("cargo:rustc-cfg=bundle_tests");
42-
}
43-
} else {
44-
println!(
45-
"cargo:warning=Not bundling resources for {:?}",
46-
&wasm.file_name().unwrap()
47-
);
48-
}
49-
50-
println!("cargo:rerun-if-changed={}", &wat.display());
51-
}
52-
_ => {}
12+
for entry in in_dir.read_dir().unwrap().flatten() {
13+
let wat = entry.path();
14+
match wat.extension() {
15+
Some(ext) if ext == "wat" => {
16+
let wasm = out_dir
17+
.join(wat.file_name().unwrap())
18+
.with_extension("wasm");
19+
let binary = wat::parse_file(&wat).expect("Can't parse wat file");
20+
std::fs::write(&wasm, &binary).expect("Can't write wasm file");
21+
println!("cargo:rerun-if-changed={}", &wat.display());
5322
}
23+
_ => {}
5424
}
5525
}
5626
}

src/cli.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
3+
#![allow(missing_docs, unused_variables)] // This is a work-in-progress, so...
4+
5+
use structopt::{clap::AppSettings, StructOpt};
6+
7+
use anyhow::{bail, Result};
8+
use std::path::PathBuf;
9+
10+
// The main StructOpt for running `wasmldr` directly
11+
#[derive(StructOpt, Debug)]
12+
#[structopt(setting=AppSettings::TrailingVarArg)]
13+
pub struct RunOptions {
14+
/// Pass an environment variable to the program
15+
#[structopt(
16+
short = "e",
17+
long = "env",
18+
number_of_values = 1,
19+
value_name = "NAME=VAL",
20+
parse(try_from_str=parse_env_var),
21+
)]
22+
pub envs: Vec<(String, String)>,
23+
24+
/// Name of the function to invoke
25+
#[structopt(long, value_name = "FUNCTION")]
26+
invoke: Option<String>,
27+
28+
// TODO: --inherit-env
29+
// TODO: --stdin, --stdout, --stderr
30+
/// Path of the WebAssembly module to run
31+
#[structopt(index = 1, required = true, value_name = "MODULE", parse(from_os_str))]
32+
pub module: PathBuf,
33+
34+
// NOTE: this has to come last for TrailingVarArg
35+
/// Arguments to pass to the WebAssembly module
36+
#[structopt(value_name = "ARGS")]
37+
pub args: Vec<String>,
38+
}
39+
40+
fn parse_env_var(s: &str) -> Result<(String, String)> {
41+
let parts: Vec<&str> = s.splitn(2, '=').collect();
42+
if parts.len() != 2 {
43+
bail!("must be of the form `NAME=VAL`");
44+
}
45+
Ok((parts[0].to_owned(), parts[1].to_owned()))
46+
}

src/config.rs

Lines changed: 0 additions & 58 deletions
This file was deleted.

src/main.rs

Lines changed: 20 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -28,52 +28,41 @@
2828
#![deny(missing_docs)]
2929
#![deny(clippy::all)]
3030

31-
mod bundle;
32-
mod config;
33-
mod virtfs;
31+
mod cli;
3432
mod workload;
3533

36-
use cfg_if::cfg_if;
37-
use log::info;
34+
use log::{debug, info};
35+
use structopt::StructOpt;
3836

3937
use std::fs::File;
4038
use std::io::Read;
41-
#[cfg(unix)]
42-
use std::os::unix::io::FromRawFd;
43-
44-
#[cfg(unix)]
45-
const FD: std::os::unix::io::RawFd = 3;
4639

4740
fn main() {
48-
let _ = env_logger::try_init_from_env(env_logger::Env::default());
41+
// Initialize the logger, taking settings from the default env vars
42+
env_logger::Builder::from_default_env().init();
43+
44+
info!("version {} starting up", env!("CARGO_PKG_VERSION"));
4945

50-
// Skip the program name by default, but also skip the enarx-keepldr image
51-
// name if it happens to precede the regular command line arguments.
52-
let nskip = 1 + std::env::args()
53-
.take(1)
54-
.filter(|s| s.ends_with("enarx-keepldr"))
55-
.count();
56-
let mut args = std::env::args().skip(nskip);
57-
let vars = std::env::vars();
46+
debug!("parsing argv");
47+
let opts = cli::RunOptions::from_args();
48+
info!("opts: {:#?}", opts);
5849

59-
let mut reader = if let Some(path) = args.next() {
60-
File::open(&path).expect("Unable to open file")
61-
} else {
62-
cfg_if! {
63-
if #[cfg(unix)] {
64-
unsafe { File::from_raw_fd(FD) }
65-
} else {
66-
unreachable!();
67-
}
68-
}
69-
};
50+
info!("reading {:?}", opts.module);
51+
// TODO: don't just panic here...
52+
let mut reader = File::open(&opts.module).expect("Unable to open file");
7053

7154
let mut bytes = Vec::new();
7255
reader
7356
.read_to_end(&mut bytes)
7457
.expect("Failed to load workload");
7558

76-
let result = workload::run(&bytes, args, vars).expect("Failed to run workload");
59+
// FUTURE: measure opts.envs, opts.args, opts.wasm_features
60+
// FUTURE: fork() the workload off into a separate memory space
7761

62+
info!("running workload");
63+
// TODO: pass opts.wasm_features
64+
let result = workload::run(bytes, opts.args, opts.envs).expect("Failed to run workload");
7865
info!("got result: {:#?}", result);
66+
// TODO: exit with the resulting code, if the result is a return code
67+
// FUTURE: produce attestation report here
7968
}

0 commit comments

Comments
 (0)