Skip to content

Commit 11848df

Browse files
committed
Implement wasi-config
Signed-off-by: itowlson <[email protected]>
1 parent 967fdf3 commit 11848df

File tree

15 files changed

+196
-0
lines changed

15 files changed

+196
-0
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/expressions/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ edition = { workspace = true }
77
[dependencies]
88
anyhow = { workspace = true }
99
async-trait = { workspace = true }
10+
futures = { workspace = true }
1011
serde = { workspace = true }
1112
spin-locked-app = { path = "../locked-app" }
1213
thiserror = { workspace = true }

crates/expressions/src/lib.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,21 @@ impl ProviderResolver {
5252
self.resolve_template(template).await
5353
}
5454

55+
pub async fn resolve_all(&self, component_id: &str) -> Result<Vec<(String, String)>> {
56+
use futures::FutureExt;
57+
58+
let Some(keys2templates) = self.internal.component_configs.get(component_id) else {
59+
return Ok(vec![]);
60+
};
61+
62+
let resolve_futs = keys2templates.iter().map(|(key, template)| {
63+
self.resolve_template(template)
64+
.map(|r| r.map(|value| (key.to_string(), value)))
65+
});
66+
67+
futures::future::try_join_all(resolve_futs).await
68+
}
69+
5570
/// Resolves the given template.
5671
pub async fn resolve_template(&self, template: &Template) -> Result<String> {
5772
let mut resolved_parts: Vec<Cow<str>> = Vec::with_capacity(template.parts().len());

crates/factor-variables/src/host.rs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,61 @@ impl v1::config::Host for InstanceState {
3737
}
3838
}
3939

40+
#[async_trait]
41+
impl spin_world::wasi::config::store::Host for InstanceState {
42+
async fn get(
43+
&mut self,
44+
key: String,
45+
) -> Result<Option<String>, spin_world::wasi::config::store::Error> {
46+
match <Self as variables::Host>::get(self, key).await {
47+
Ok(value) => Ok(Some(value)),
48+
// Err(e) if matches!(e, variables::Error::Undefined(_)) => Ok(Ok(None)),
49+
Err(e) => {
50+
match e {
51+
variables::Error::Undefined(_) => Ok(None),
52+
variables::Error::InvalidName(msg) => {
53+
Err(spin_world::wasi::config::store::Error::Io(msg))
54+
} // TODO: this doesn't feel ideal, but wasi-config only allows two error cases
55+
variables::Error::Provider(msg) => {
56+
Err(spin_world::wasi::config::store::Error::Upstream(msg))
57+
}
58+
variables::Error::Other(msg) => {
59+
Err(spin_world::wasi::config::store::Error::Io(msg))
60+
} // TODO: again, hard to know how to map this (and the original expressions::Error is not more helpful)
61+
}
62+
}
63+
}
64+
}
65+
66+
async fn get_all(
67+
&mut self,
68+
) -> Result<Vec<(String, String)>, spin_world::wasi::config::store::Error> {
69+
let all = self
70+
.expression_resolver
71+
.resolve_all(&self.component_id)
72+
.await;
73+
all.map_err(|e| {
74+
match expressions_to_variables_err(e) {
75+
variables::Error::Undefined(msg) => spin_world::wasi::config::store::Error::Io(msg), // TODO: this should presumably not occur here
76+
variables::Error::InvalidName(msg) => {
77+
spin_world::wasi::config::store::Error::Io(msg)
78+
} // TODO: this doesn't feel ideal, but wasi-config only allows two error cases
79+
variables::Error::Provider(msg) => {
80+
spin_world::wasi::config::store::Error::Upstream(msg)
81+
}
82+
variables::Error::Other(msg) => spin_world::wasi::config::store::Error::Io(msg), // TODO: again, hard to know how to map this (and the original expressions::Error is not more helpful)
83+
}
84+
})
85+
}
86+
87+
fn convert_error(
88+
&mut self,
89+
err: spin_world::wasi::config::store::Error,
90+
) -> anyhow::Result<spin_world::wasi::config::store::Error> {
91+
Ok(err)
92+
}
93+
}
94+
4095
fn expressions_to_variables_err(err: spin_expressions::Error) -> variables::Error {
4196
use spin_expressions::Error;
4297
match err {

crates/factor-variables/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ impl Factor for VariablesFactor {
3131
fn init<T: Send + 'static>(&mut self, mut ctx: InitContext<T, Self>) -> anyhow::Result<()> {
3232
ctx.link_bindings(spin_world::v1::config::add_to_linker)?;
3333
ctx.link_bindings(spin_world::v2::variables::add_to_linker)?;
34+
ctx.link_bindings(spin_world::wasi::config::store::add_to_linker)?;
3435
Ok(())
3536
}
3637

crates/world/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ wasmtime::component::bindgen!({
2727
"fermyon:spin/[email protected]/error" => v2::sqlite::Error,
2828
"fermyon:spin/sqlite/error" => v1::sqlite::Error,
2929
"fermyon:spin/[email protected]/error" => v2::variables::Error,
30+
"wasi:config/store/error" => wasi::config::store::Error,
3031
},
3132
trappable_imports: true,
3233
});
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
spin_manifest_version = "1"
2+
authors = [""]
3+
description = ""
4+
name = "variables"
5+
trigger = { type = "http" }
6+
version = "0.1.0"
7+
8+
[variables]
9+
variable = { default = "value" }
10+
11+
[[component]]
12+
id = "variables"
13+
source = "%{source=variables}"
14+
[component.trigger]
15+
route = "/..."
16+
[component.config]
17+
variable = "{{ variable }}"
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
spin_manifest_version = "1"
2+
authors = [""]
3+
description = ""
4+
name = "wasi-config"
5+
trigger = { type = "http" }
6+
version = "0.1.0"
7+
8+
[variables]
9+
variable = { default = "value" }
10+
11+
[[component]]
12+
id = "wasi-config"
13+
source = "%{source=wasi-config}"
14+
[component.trigger]
15+
route = "/..."
16+
[component.config]
17+
variable = "{{ variable }}"

tests/test-components/components/Cargo.lock

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[package]
2+
name = "wasi-config"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[lib]
7+
crate-type = ["cdylib"]
8+
9+
[dependencies]
10+
helper = { path = "../../helper" }
11+
wit-bindgen = "0.16.0"

0 commit comments

Comments
 (0)