Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update to Wasmtime 17 and WASI 0.2.0-rc-2023-12-05 #2222

Merged
merged 3 commits into from
Jan 11, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
382 changes: 206 additions & 176 deletions Cargo.lock

Large diffs are not rendered by default.

16 changes: 9 additions & 7 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ edition = "2021"
license = "Apache-2.0 WITH LLVM-exception"
homepage = "https://developer.fermyon.com/spin"
repository = "https://github.com/fermyon/spin"
rust-version = "1.71"
rust-version = "1.73"

[dependencies]
anyhow = { workspace = true }
Expand Down Expand Up @@ -91,6 +91,7 @@ which = "4.2.5"
e2e-testing = { path = "crates/e2e-testing" }
http-body-util = { workspace = true }
testing-framework = { path = "tests/testing-framework" }
hyper-util = { version = "0.1.2", features = ["tokio"] }
runtime-tests = { path = "tests/runtime-tests" }
test-components = { path = "tests/test-components" }
test-codegen-macro = { path = "crates/test-codegen-macro" }
Expand Down Expand Up @@ -125,15 +126,16 @@ members = [

[workspace.dependencies]
anyhow = "1.0.75"
http-body-util = "=0.1.0-rc.2"
hyper = { version = "=1.0.0-rc.3", features = ["full"] }
http-body-util = "0.1.0"
hyper = { version = "1.0.0", features = ["full"] }
reqwest = { version = "0.11", features = ["stream", "blocking"] }
tracing = { version = "0.1", features = ["log"] }

wasi-common-preview1 = { version = "15.0.0", package = "wasi-common" }
wasmtime = { version = "15.0.0", features = ["component-model"] }
wasmtime-wasi = { version = "15.0.0", features = ["tokio"] }
wasmtime-wasi-http = "15.0.0"
# TODO: update to final 17.0.0 release once it's available
wasi-common-preview1 = { git = "https://github.com/bytecodealliance/wasmtime", branch = "release-17.0.0", package = "wasi-common" }
wasmtime = { git = "https://github.com/bytecodealliance/wasmtime", branch = "release-17.0.0", features = ["component-model"] }
wasmtime-wasi = { git = "https://github.com/bytecodealliance/wasmtime", branch = "release-17.0.0", features = ["tokio"] }
wasmtime-wasi-http = { git = "https://github.com/bytecodealliance/wasmtime", branch = "release-17.0.0" }

spin-componentize = { git = "https://github.com/fermyon/spin-componentize", rev = "191789170abde10cd55590466c0660dd6c7d472a" }

Expand Down
29 changes: 29 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const TIMER_TRIGGER_INTEGRATION_TEST: &str = "examples/spin-timer/app-example";
const WASI_HTTP_INTEGRATION_TEST: &str = "examples/wasi-http-rust-streaming-outgoing-body";
const OUTBOUND_HTTP_POST_INTEGRATION_TEST: &str = "examples/http-rust-outbound-post";
const WASI_HTTP_RC_11_10_INTEGRATION_TEST: &str = "tests/http/wasi-http-rust-0.2.0-rc-2023-11-10";
const WASI_HTTP_RC_12_05_INTEGRATION_TEST: &str = "tests/http/wasi-http-rust-0.2.0-rc-2023-12-05";

fn main() {
// Extract environment information to be passed to plugins.
Expand Down Expand Up @@ -116,6 +117,34 @@ error: the `wasm32-wasi` target is not installed
.unwrap(),
)
.unwrap();

cargo_build(WASI_HTTP_RC_12_05_INTEGRATION_TEST);

// Rather than let `spin-componentize` turn the `WASI_HTTP_RC_12_05_INTEGRATION_TEST` module into a component,
// we use Wasmtime 16.0.0's adapter to ensure it uses the WASI 0.2.0-rc-2023-12-05 snapshot for everything.
let wasi_http_rc_12_05_module = format!(
"{WASI_HTTP_RC_12_05_INTEGRATION_TEST}/target/wasm32-wasi/release/wasi_http_rust_rc_2023_12_05.wasm"
);
let wasi_http_rc_12_05_adapter =
format!("{WASI_HTTP_RC_12_05_INTEGRATION_TEST}/wasi_snapshot_preview1.reactor.wasm");
let wasi_http_rc_12_05_component = format!(
"{WASI_HTTP_RC_12_05_INTEGRATION_TEST}/target/wasm32-wasi/release/wasi_http_rust_rc_2023_12_05.component.wasm"
);
std::fs::write(
wasi_http_rc_12_05_component,
wit_component::ComponentEncoder::default()
.validate(true)
.module(&std::fs::read(wasi_http_rc_12_05_module).unwrap())
.unwrap()
.adapter(
"wasi_snapshot_preview1",
&std::fs::read(wasi_http_rc_12_05_adapter).unwrap(),
)
.unwrap()
.encode()
.unwrap(),
)
.unwrap();
}

fn build_wasm_test_program(name: &'static str, root: &'static str) {
Expand Down
1 change: 1 addition & 0 deletions crates/core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ wasmtime-wasi-http = { workspace = true }
wasi-common-preview1 = { workspace = true }
system-interface = { version = "0.26.0", features = ["cap_std_impls"] }
cap-std = "2.0.0"
cap-primitives = "2.0.0"
tokio = "1.0"
bytes = "1.0"

Expand Down
11 changes: 6 additions & 5 deletions crates/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,15 @@ mod limits;
mod preview1;
mod store;
pub mod wasi_2023_10_18;
pub mod wasi_2023_11_10;

use std::{path::PathBuf, sync::Arc, time::Duration};

use anyhow::Result;
use crossbeam_channel::Sender;
use tracing::instrument;
use wasmtime::{InstanceAllocationStrategy, PoolingAllocationConfig};
use wasmtime_wasi::preview2::Table;
use wasmtime_wasi::preview2::ResourceTable;
use wasmtime_wasi_http::types::{default_send_request, WasiHttpCtx, WasiHttpView};

use self::host_component::{HostComponents, HostComponentsBuilder};
Expand Down Expand Up @@ -146,7 +147,7 @@ pub struct Data<T> {
wasi: Wasi,
host_components_data: HostComponentsData,
store_limits: limits::StoreLimitsAsync,
table: Table,
table: ResourceTable,
}

impl<T> Data<T> {
Expand All @@ -169,11 +170,11 @@ impl<T> AsMut<T> for Data<T> {
}

impl<T: Send> wasmtime_wasi::preview2::WasiView for Data<T> {
fn table(&self) -> &wasmtime_wasi::preview2::Table {
fn table(&self) -> &ResourceTable {
&self.table
}

fn table_mut(&mut self) -> &mut wasmtime_wasi::preview2::Table {
fn table_mut(&mut self) -> &mut ResourceTable {
&mut self.table
}

Expand All @@ -200,7 +201,7 @@ impl<T: Send + OutboundWasiHttpHandler> WasiHttpView for Data<T> {
}
}

fn table(&mut self) -> &mut Table {
fn table(&mut self) -> &mut ResourceTable {
&mut self.table
}

Expand Down
29 changes: 23 additions & 6 deletions crates/core/src/store.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
use anyhow::{anyhow, Result};
use bytes::Bytes;
use cap_primitives::net::Pool;
use cap_std::ipnet::IpNet;
use std::{
io::{Read, Write},
mem,
path::{Path, PathBuf},
sync::{Arc, Mutex},
time::{Duration, Instant},
Expand Down Expand Up @@ -137,6 +139,7 @@ pub struct StoreBuilder {
wasi: std::result::Result<WasiCtxBuilder, String>,
host_components_data: HostComponentsData,
store_limits: StoreLimitsAsync,
net_pool: Pool,
}

impl StoreBuilder {
Expand All @@ -153,6 +156,7 @@ impl StoreBuilder {
wasi: Ok(wasi.into()),
host_components_data: host_components.new_data(),
store_limits: StoreLimitsAsync::default(),
net_pool: Pool::default(),
}
}

Expand Down Expand Up @@ -187,10 +191,15 @@ impl StoreBuilder {
WasiCtxBuilder::Preview1(_) => {
panic!("Enabling network only allowed in preview2")
}
WasiCtxBuilder::Preview2(ctx) => {
ctx.insert_ip_net_port_range(ip_net, ports_start, ports_end);
}
WasiCtxBuilder::Preview2(_) => {}
});

self.net_pool.insert_ip_net_port_range(
ip_net,
ports_start,
ports_end,
cap_primitives::ambient_authority(),
);
}

/// Inherit the host network with a few hardcoded caveats
Expand All @@ -201,7 +210,7 @@ impl StoreBuilder {
}
WasiCtxBuilder::Preview2(ctx) => {
// TODO: ctx.allow_udp(false);
ctx.inherit_network(cap_std::ambient_authority());
ctx.inherit_network();
}
});
}
Expand Down Expand Up @@ -398,7 +407,15 @@ impl StoreBuilder {
/// Builds a [`Store`] from this builder with given host state data.
///
/// If `T: Default`, it may be preferable to use [`Store::build`].
pub fn build_with_data<T>(self, inner_data: T) -> Result<Store<T>> {
pub fn build_with_data<T>(mut self, inner_data: T) -> Result<Store<T>> {
let net_pool = mem::take(&mut self.net_pool);
self.with_wasi(move |wasi| match wasi {
WasiCtxBuilder::Preview1(_) => {}
WasiCtxBuilder::Preview2(ctx) => {
ctx.socket_addr_check(move |addr, _| net_pool.check_addr(addr).is_ok());
}
});

let wasi = self.wasi.map_err(anyhow::Error::msg)?.build();

let mut inner = wasmtime::Store::new(
Expand All @@ -408,7 +425,7 @@ impl StoreBuilder {
wasi,
host_components_data: self.host_components_data,
store_limits: self.store_limits,
table: wasi_preview2::Table::new(),
table: wasi_preview2::ResourceTable::new(),
},
);

Expand Down
17 changes: 10 additions & 7 deletions crates/core/src/wasi_2023_10_18.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ where
{
fn filesystem_error_code(
&mut self,
err: Resource<Error>,
err: Resource<wasi::filesystem::types::Error>,
) -> wasmtime::Result<Option<FsErrorCode>> {
Ok(
<T as latest::filesystem::types::Host>::filesystem_error_code(self, err)?
Expand Down Expand Up @@ -2033,11 +2033,12 @@ where
self_: wasmtime::component::Resource<FutureTrailers>,
) -> wasmtime::Result<Option<Result<wasmtime::component::Resource<Trailers>, HttpError>>> {
match <T as latest::http::types::HostFutureTrailers>::get(self, self_)? {
Some(Ok(Some(trailers))) => Ok(Some(Ok(trailers))),
Some(Ok(Ok(Some(trailers)))) => Ok(Some(Ok(trailers))),
// Return an empty trailers if no trailers popped out since this
// version of WASI couldn't represent the lack of trailers.
Some(Ok(None)) => Ok(Some(Ok(<T as latest::http::types::HostFields>::new(self)?))),
Some(Err(e)) => Ok(Some(Err(e.into()))),
Some(Ok(Ok(None))) => Ok(Some(Ok(<T as latest::http::types::HostFields>::new(self)?))),
Some(Ok(Err(e))) => Ok(Some(Err(e.into()))),
Some(Err(())) => Err(anyhow::anyhow!("trailers have already been retrieved")),
None => Ok(None),
}
}
Expand Down Expand Up @@ -2101,7 +2102,7 @@ where

if let Some(ms) = connect_timeout_ms {
if let Err(()) =
<T as latest::http::types::HostRequestOptions>::set_connect_timeout_ms(
<T as latest::http::types::HostRequestOptions>::set_connect_timeout(
self,
borrow(),
Some(ms.into()),
Expand All @@ -2114,7 +2115,7 @@ where

if let Some(ms) = first_byte_timeout_ms {
if let Err(()) =
<T as latest::http::types::HostRequestOptions>::set_first_byte_timeout_ms(
<T as latest::http::types::HostRequestOptions>::set_first_byte_timeout(
self,
borrow(),
Some(ms.into()),
Expand All @@ -2127,7 +2128,7 @@ where

if let Some(ms) = between_bytes_timeout_ms {
if let Err(()) =
<T as latest::http::types::HostRequestOptions>::set_between_bytes_timeout_ms(
<T as latest::http::types::HostRequestOptions>::set_between_bytes_timeout(
self,
borrow(),
Some(ms.into()),
Expand Down Expand Up @@ -2234,6 +2235,8 @@ macro_rules! convert {
};
}

pub(crate) use convert;

convert! {
struct latest::clocks::wall_clock::Datetime [<=>] Datetime {
seconds,
Expand Down
Loading
Loading