From 8313bf944edf370bf517802d3c916060c5cbb8ff Mon Sep 17 00:00:00 2001 From: Scott Andrews Date: Wed, 28 Aug 2024 15:02:12 -0400 Subject: [PATCH] Add support for `wasi:config/runtime` virtualization The `wasi:config/runtime` interface is a way to pass configuration to other components with a standard interface. Similar to `wasi:cli/environment` the core data model is a set of key-value pairs. The proposed API and CLI support in WASI-Virt mirrors the support for environment variables that currently exists. The config runtime proposal is currently stage 2 and does not a have a release. Signed-off-by: Scott Andrews --- Cargo.lock | 8 + Cargo.toml | 1 + README.md | 14 ++ lib/package.wasm | Bin 97031 -> 97793 bytes lib/virtual_adapter.debug.wasm | Bin 239257 -> 243336 bytes lib/virtual_adapter.wasm | Bin 204397 -> 208476 bytes src/bin/wasi-virt.rs | 28 +++ src/lib.rs | 25 ++- src/virt_config.rs | 250 ++++++++++++++++++++++ tests/cases/config-allow.toml | 14 ++ tests/cases/config-deny.toml | 14 ++ tests/cases/config-none-overrides.toml | 11 + tests/cases/config-none.toml | 11 + tests/cases/config-passthrough.toml | 11 + tests/components/do-everything/src/lib.rs | 3 + tests/components/file-read/src/lib.rs | 3 + tests/components/get-config/Cargo.toml | 11 + tests/components/get-config/src/lib.rs | 26 +++ tests/components/get-env/src/lib.rs | 3 + tests/components/stdio/src/lib.rs | 3 + tests/virt.rs | 106 ++++++++- virtual-adapter/src/config.rs | 118 ++++++++++ virtual-adapter/src/lib.rs | 1 + wit/deps/config/runtime_config.wit | 25 +++ wit/deps/config/world.wit | 6 + wit/virt.wit | 9 + 26 files changed, 699 insertions(+), 2 deletions(-) create mode 100644 src/virt_config.rs create mode 100644 tests/cases/config-allow.toml create mode 100644 tests/cases/config-deny.toml create mode 100644 tests/cases/config-none-overrides.toml create mode 100644 tests/cases/config-none.toml create mode 100644 tests/cases/config-passthrough.toml create mode 100644 tests/components/get-config/Cargo.toml create mode 100644 tests/components/get-config/src/lib.rs create mode 100644 virtual-adapter/src/config.rs create mode 100644 wit/deps/config/runtime_config.wit create mode 100644 wit/deps/config/world.wit diff --git a/Cargo.lock b/Cargo.lock index e3ebe3a..5413e3c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -829,6 +829,14 @@ dependencies = [ "version_check", ] +[[package]] +name = "get-config" +version = "0.1.0" +dependencies = [ + "anyhow", + "wit-bindgen", +] + [[package]] name = "get-env" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index 664c5b4..7fde63d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,7 @@ members = [ "virtual-adapter", "tests/components/do-everything", "tests/components/file-read", + "tests/components/get-config", "tests/components/get-env", "tests/components/stdio", ] diff --git a/README.md b/README.md index 49d0a3c..369b511 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ Supports all of the current WASI subsystems: - [Clocks](#clocks): Allow / Deny - [Environment](#env): Set environment variables, configure host environment variable permissions +- [Config](#config): Set runtime configuration, configure host property permissions - [Exit](#exit): Allow / Deny - [Filesystem](#filesystem): Mount a read-only filesystem, configure host filesystem preopen remappings or pass-through. - [HTTP](#http): Allow / Deny @@ -82,6 +83,19 @@ wasi-virt component.wasm -e CUSTOM=VAR --allow-env -o virt.wasm wasi-virt component.wasm -e CUSTOM=VAR --allow-env=SOME,ENV_VARS -o virt.wasm ``` +### Config + +```sh +# Setting specific config properties (while disallowing all host config property access): +wasi-virt component.wasm -c custom=prop -o virt.wasm + +# Setting config properties with all host config properties allowed: +wasi-virt component.wasm -c custom=prop --allow-config -o virt.wasm + +# Setting config properties with restricted host config property access: +wasi-virt component.wasm -c custom=prop --allow-config=some,property -o virt.wasm +``` + ### Exit ```sh diff --git a/lib/package.wasm b/lib/package.wasm index 1f57d57aead91766d23b55930b07c2f4d67d233c..d31b54ad9411721091abcf32dc39451c0c6c2225 100644 GIT binary patch delta 1281 zcmcgsO-K}B82+A}8Q1?>6;~y9b<#tFZE2 zs3Bo>v5J70pMLjD~aJ)45b|GnXoDk6&t#h zR9ur6r7@4I$K?^t5hWbegigA2%SX?vR-C3GbroH?6-XRi^);f~;5tKp_-qh!kA!a( zv~I!<7u~Xq(By=Jcf&8}`C-)4u^KCVHPJww0T(R`*x=RkX^8X^`|P1wpdY>ZS_bT& zfCFdfYV9a(3%1h7!4bN>>qH+#-LSrU0|NaVbfBMBPUbO?do#Ib!61EkZ3{!WyP+xY z!|+cR4$RrbXC-v|K@&d$|5JTO&0{5S{I`9Q+$2%^+gw>?;IMF}{=!+eP)cq?NL?aViEK@W|)kGs0q<9)` zo*erP6jg?sr3;@7Yx62mc~V^{N9C9#vUG~T!}@?_Q+WYbwFt{9uRgzw4%jx=mT?Yn R>+f&ES!!nK;_Y*JegX%RQ!@Yn delta 499 zcmYk2KWGzi6vyv-xnH934>oCXrdZD$jj3%fm!@jdw1gy!(6kz(w3{}zX9?I|=pFtk zsZbn5C-q4WA&a7`AU9N{h?}F-$w8rxg4nc!ICSurOu}2`FYZ_Q?$1mee>W$n(nQPl0PHkl=HZZTl6dwMxVP1!$YBL1pS<~G2lLD ze-BV&T!BU#<5#2v3e4FYLzr>_nTo}u(5V(k(Lysqv&Dp?EQ8UzW(0#yc9~N@n^B}F z7v$`OiXmE@xQf$+&Kw<{RB?s|C$Hfwed=sb@_Y=#?po+;2PI}ANYnTDOZqj_gAuo* zQiha4;c`3KRkXKW+FI+vs9UO*nKUM$i!L^TZr*(QW8eErZPyD=*!A^CWxR;VqDNr< zIm4P=s@80C2?d|%5urGnw=snij#)ytGhKo#MgNo2p>naJ^Xd-TR>#rPG8#sV+l;W2 z{Aif&2E&Nc$KTVem-jO51o=DZ$nFqr?J&Brt?utb!P`n}P1E#wTUGjDik5}i0CIw$ zNy0(fuxxGKur*`xCePCA=nm<82|*J4?WJYURZS$FN*%p8w*Ih=bKvBc6~uksWFp1u EAI8O!hyVZp diff --git a/lib/virtual_adapter.debug.wasm b/lib/virtual_adapter.debug.wasm index 85b8a13307774c59c11194a5780d26c87a38c50f..6cf25b99c91b6f8f87079e8b6480f57f80cf1090 100755 GIT binary patch delta 61826 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

CVXXS(u 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 delta 58865 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

N*~i=QC3W&95d^c3#vVhcbC4Xkz8W z$=#?Fhb|f~uV!4`av$K~xx1yY7fEe($K>MDm8Cyq3P+CjmDe)Xkxz~Kz}9qq>W`Iu z7l-mE(#VmY>nrb(-tyA{(>tG`L@u&gVr&VOXa znxXx5+x_g6Y4=MHd9OBO)k8z%{bN4W>FxJR|MUkLefR;Hxb*>PrnM4@&&5$eeKEee z`e$aAe&+$;%9#&H_f`jC%DmV_Uoak0(Nq7*=%*f)i6hspT)uSWvbK21+Lg=D2Rz>2 zgjJY!Siit4bL!uj(43}^{^vYRS;$-RYEYYceRK+__QQ1e# z_|0yaJ}@?YRCIhrNM!ipDAuu=1Nm z<*R7Bt$lS;UixVx6d}+##zVl@K}dJi#=1}G4SVHuJ$0}2;vFv9z%e|SEE)#Ti#F-G zdm$MvD~KIVS8;(xIpmqm`lb7^aM3VgV|W<~M?*YD-gw5_t>_DO8@9qr+AfzwO~*Py*Sl5Uy&IPY`MM)5C4?(PU#@ccV#~w?q(85~b@-GZ8y}xV1WIUmnFt zTj^3J!a-a&uiK)R!KmFBPrU6hnY8s$>64>ziqN$3hz#iO5aexjXI0Ok&v_I90sqg& zY;}<`X)#3WxuZ^1H^tC^ZmEv8j#WmmE~1i`u!8al?=pDw3EZild{mCl@@^3=;CLco zF-E-z)%LCnchfT-!=i?kVh!?EKdp!afrSddoz2R6CMJr^4q^{YC}p_6xnuqEW85-t zGw{L{o+WP-@Ft_DcGNAXZPck>k-<6hW-x{>FS_z7C33aeS$A&j>+8NELtD@}XtG8m zMh~D3SM93wFCCYmW`SrNBi&Jz(hWqKuOGr*mtrAggWS6}<`OLd;!@wf~e z>+^ZVs!L4|2>qJ8)P`$K14_s;se9|Xb$)wa^~9shZ&%c`ebk&1;eZ2&dj@N-op?q2 lm(9pAgB+$C2_H!Ti-`bM57gDK=~%ryS^1!T`Ehyh{{cKB*)jkC diff --git a/lib/virtual_adapter.wasm b/lib/virtual_adapter.wasm index cd92b49767c27265b190b371c13dc1deb1dc7424..c5378a7b3d9dc56cd5c7d3b172c89558c5079033 100755 GIT binary patch delta 53417 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%0AF4$ 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 Do$Y`C diff --git a/src/bin/wasi-virt.rs b/src/bin/wasi-virt.rs index e078966..bcaa927 100644 --- a/src/bin/wasi-virt.rs +++ b/src/bin/wasi-virt.rs @@ -58,6 +58,15 @@ struct Args { #[arg(short, long, use_value_delimiter(true), value_name("ENV=VAR"), value_parser = parse_key_val::, help_heading = "Env")] env: Option>, + // CONFIG + /// Allow unrestricted access to host configuration properties, or to a comma-separated list of property names. + #[arg(long, num_args(0..), use_value_delimiter(true), require_equals(true), value_name("PROPERTY_NAME"), help_heading = "Config")] + allow_config: Option>, + + /// Set config property overrides + #[arg(short, long, use_value_delimiter(true), value_name("NAME=VALUE"), value_parser = parse_key_val::, help_heading = "Config")] + config: Option>, + // FS /// Allow unrestricted access to host preopens #[arg(long, default_missing_value="true", num_args=0..=1, help_heading = "Fs")] @@ -165,6 +174,25 @@ fn main() -> Result<()> { env.overrides = env_overrides; } + // config options + let config = virt_opts.config(); + match args.allow_config { + Some(allow_config) if allow_config.len() == 0 => { + config.allow_all(); + } + Some(allow_config) => { + config.allow(&allow_config); + } + None => { + if allow_all { + config.allow_all(); + } + } + }; + if let Some(config_overrides) = args.config { + config.overrides = config_overrides; + } + // fs options let fs = virt_opts.fs(); if let Some(preopens) = args.preopen { diff --git a/src/lib.rs b/src/lib.rs index 3b4df17..f7c89d4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,7 @@ use anyhow::{bail, Context, Result}; use serde::Deserialize; use std::{env, fs, path::PathBuf, time::SystemTime}; +use virt_config::{create_config_virt, strip_config_virt}; use virt_deny::{ deny_clocks_virt, deny_exit_virt, deny_http_virt, deny_random_virt, deny_sockets_virt, }; @@ -14,12 +15,14 @@ use wit_parser::WorldItem; mod data; mod stub_preview1; +mod virt_config; mod virt_deny; mod virt_env; mod virt_io; mod walrus_ops; pub use stub_preview1::stub_preview1; +pub use virt_config::{HostConfig, VirtConfig}; pub use virt_env::{HostEnv, VirtEnv}; pub use virt_io::{FsEntry, StdioCfg, VirtFs, VirtualFiles}; @@ -44,6 +47,8 @@ pub struct WasiVirt { pub debug: bool, /// Environment virtualization pub env: Option, + /// Configuration virtualization + pub config: Option, /// Filesystem virtualization pub fs: Option, /// Stdio virtualization @@ -81,6 +86,7 @@ impl WasiVirt { self.exit(true); self.random(true); self.env().allow_all(); + self.config().allow_all(); self.fs().allow_host_preopens(); self.stdio().allow(); } @@ -92,6 +98,7 @@ impl WasiVirt { self.exit(false); self.random(false); self.env().deny_all(); + self.config().deny_all(); self.fs().deny_host_preopens(); self.stdio().ignore(); } @@ -120,6 +127,10 @@ impl WasiVirt { self.env.get_or_insert_with(Default::default) } + pub fn config(&mut self) -> &mut VirtConfig { + self.config.get_or_insert_with(Default::default) + } + pub fn fs(&mut self) -> &mut VirtFs { self.fs.get_or_insert_with(Default::default) } @@ -165,6 +176,9 @@ impl WasiVirt { if !matches("wasi:cli/environment") { self.env = None; } + if !matches("wasi:config/runtime") { + self.config = None; + } if !matches("wasi:filesystem/") { self.fs = None; } @@ -207,6 +221,9 @@ impl WasiVirt { if let Some(env) = &self.env { create_env_virt(&mut module, env)?; } + if let Some(config) = &self.config { + create_config_virt(&mut module, config)?; + } let has_io = self.fs.is_some() || self.stdio.is_some() @@ -256,6 +273,7 @@ impl WasiVirt { let base_world = resolve.select_world(&pkg_ids, Some("virtual-base"))?; let env_world = resolve.select_world(&pkg_ids, Some("virtual-env"))?; + let config_world = resolve.select_world(&pkg_ids, Some("virtual-config"))?; let io_world = resolve.select_world(&pkg_ids, Some("virtual-io"))?; let io_clocks_world = resolve.select_world(&pkg_ids, Some("virtual-io-clocks"))?; @@ -270,12 +288,17 @@ impl WasiVirt { let http_world = resolve.select_world(&pkg_ids, Some("virtual-http"))?; let sockets_world = resolve.select_world(&pkg_ids, Some("virtual-sockets"))?; - // env, exit & random subsystems are fully independent + // env, config, exit & random subsystems are fully independent if self.env.is_some() { resolve.merge_worlds(env_world, base_world)?; } else { strip_env_virt(&mut module)?; } + if self.config.is_some() { + resolve.merge_worlds(config_world, base_world)?; + } else { + strip_config_virt(&mut module)?; + } if let Some(exit) = self.exit { if !exit { resolve.merge_worlds(exit_world, base_world)?; diff --git a/src/virt_config.rs b/src/virt_config.rs new file mode 100644 index 0000000..ca124a2 --- /dev/null +++ b/src/virt_config.rs @@ -0,0 +1,250 @@ +use anyhow::{bail, Context, Result}; +use serde::Deserialize; +use walrus::{ir::Value, ConstExpr, DataKind, ExportItem, GlobalKind, Module}; + +use crate::walrus_ops::{bump_stack_global, get_active_data_segment}; + +#[derive(Deserialize, Debug, Clone, Default)] +#[serde(deny_unknown_fields)] +pub struct VirtConfig { + /// Set specific configuration property overrides + #[serde(default)] + pub overrides: Vec<(String, String)>, + /// Define how to embed into the host configuration + /// (Pass-through / encapsulate / allow / deny) + #[serde(default)] + pub host: HostConfig, +} + +#[derive(Deserialize, Debug, Clone, Default)] +#[serde(rename_all = "kebab-case", deny_unknown_fields)] +pub enum HostConfig { + /// Fully encapsulate the configuration, removing all host + /// configuration import checks + #[default] + None, + /// Apart from the overrides, pass through all configuration + /// properties from the host + All, + /// Only allow the provided configuration property keys + Allow(Vec), + /// Allow all configuration properties, except the provided keys + Deny(Vec), +} + +impl VirtConfig { + /// Set the host configuration property allow list + pub fn allow(&mut self, allow_list: &[String]) -> &mut Self { + self.host = HostConfig::Allow(allow_list.iter().map(|s| s.to_string()).collect()); + self + } + + /// Set the host configuration property deny list + pub fn deny(&mut self, deny_list: &[&str]) -> &mut Self { + self.host = HostConfig::Deny(deny_list.iter().map(|s| s.to_string()).collect()); + self + } + + /// Enable all configuration properties on the host + pub fn allow_all(&mut self) -> &mut Self { + self.host = HostConfig::All; + self + } + + /// Deny all configuration properties on the host + pub fn deny_all(&mut self) -> &mut Self { + self.host = HostConfig::None; + self + } + + /// Set the configuration property overrides + pub fn overrides(&mut self, overrides: &[(&str, &str)]) -> &mut Self { + for (key, val) in overrides { + self.overrides.push((key.to_string(), val.to_string())); + } + self + } +} + +pub(crate) fn create_config_virt<'a>(module: &'a mut Module, config: &VirtConfig) -> Result<()> { + let config_ptr_addr = { + let config_ptr_export = module + .exports + .iter() + .find(|expt| expt.name.as_str() == "config") + .context("Adapter 'config' is not exported")?; + let ExportItem::Global(config_ptr_global) = config_ptr_export.item else { + bail!("Adapter 'config' not a global"); + }; + let GlobalKind::Local(ConstExpr::Value(Value::I32(config_ptr_addr))) = + &module.globals.get(config_ptr_global).kind + else { + bail!("Adapter 'config' not a local I32 global value"); + }; + *config_ptr_addr as u32 + }; + + // If host config is disabled, remove its import entirely + // replacing it with a stub panic + if matches!(config.host, HostConfig::None) { + stub_config_virt(module)?; + // we do arguments as well because virt assumes reactors for now... + } + + let memory = module.get_memory_id()?; + + // prepare the field data list vector for writing + // strings must be sorted as binary searches are used against this data + let mut field_data_vec: Vec<&str> = Vec::new(); + let mut sorted_overrides = config.overrides.clone(); + sorted_overrides.sort_by(|(a, _), (b, _)| a.cmp(b)); + for (key, value) in &sorted_overrides { + field_data_vec.push(key.as_ref()); + field_data_vec.push(value.as_ref()); + } + match &config.host { + HostConfig::Allow(allow_list) => { + let mut allow_list: Vec<&str> = allow_list.iter().map(|item| item.as_ref()).collect(); + allow_list.sort(); + for key in allow_list { + field_data_vec.push(key); + } + } + HostConfig::Deny(deny_list) => { + let mut deny_list: Vec<&str> = deny_list.iter().map(|item| item.as_ref()).collect(); + deny_list.sort(); + for key in deny_list { + field_data_vec.push(key); + } + } + _ => {} + } + + let mut field_data_bytes = Vec::new(); + for str in field_data_vec { + assert!(field_data_bytes.len() % 4 == 0); + // write the length at the aligned offset + field_data_bytes.extend_from_slice(&(str.len() as u32).to_le_bytes()); + let str_bytes = str.as_bytes(); + field_data_bytes.extend_from_slice(str_bytes); + let rem = str_bytes.len() % 4; + // add padding for alignment if necessary + if rem > 0 { + field_data_bytes.extend((0..4 - rem).map(|_| 0)); + } + } + + if field_data_bytes.len() % 8 != 0 { + field_data_bytes.resize(field_data_bytes.len() + 4, 0); + } + + let field_data_addr = if field_data_bytes.len() > 0 { + // Offset the stack global by the static field data length + let field_data_addr = bump_stack_global(module, field_data_bytes.len() as i32)?; + + // Add a new data segment for this new range created at the top of the stack + module.data.add( + DataKind::Active { + memory, + offset: ConstExpr::Value(Value::I32(field_data_addr as i32)), + }, + field_data_bytes, + ); + Some(field_data_addr) + } else { + None + }; + + // In the existing static data segment, update the static data options. + // + // From virtual-adapter/src/config.rs: + // + // #[repr(C)] + // pub struct Config { + // /// Whether to fallback to the host config + // /// [byte 0] + // host_fallback: bool, + // /// Whether we are providing an allow list or a deny list + // /// on the fallback lookups + // /// [byte 1] + // host_fallback_allow: bool, + // /// How many host fields are defined in the data pointer + // /// [byte 4] + // host_field_cnt: u32, + // /// Host many host fields are defined to be allow or deny + // /// (these are concatenated at the end of the data with empty values) + // /// [byte 8] + // host_allow_or_deny_cnt: u32, + // /// Byte data of u32 byte len followed by string bytes + // /// up to the lengths previously provided. + // /// [byte 12] + // host_field_data: *const u8, + // } + let (data, data_offset) = get_active_data_segment(module, memory, config_ptr_addr)?; + let bytes = data.value.as_mut_slice(); + + let host_field_cnt = config.overrides.len() as u32; + bytes[data_offset + 4..data_offset + 8].copy_from_slice(&host_field_cnt.to_le_bytes()); + match &config.host { + // All is already the default data + HostConfig::All => {} + HostConfig::None => { + bytes[data_offset] = 0; + } + HostConfig::Allow(allow_list) => { + bytes[data_offset + 1] = 1; + bytes[data_offset + 8..data_offset + 12] + .copy_from_slice(&(allow_list.len() as u32).to_le_bytes()); + } + HostConfig::Deny(deny_list) => { + bytes[data_offset + 1] = 0; + bytes[data_offset + 8..data_offset + 12] + .copy_from_slice(&(deny_list.len() as u32).to_le_bytes()); + } + }; + if let Some(field_data_addr) = field_data_addr { + bytes[data_offset + 12..data_offset + 16].copy_from_slice(&field_data_addr.to_le_bytes()); + } + + Ok(()) +} + +/// Functions that represent the configuration functionality provided by WASI CLI +const WASI_CONFIG_FNS: [&str; 2] = ["get", "get-all"]; + +/// Stub imported functions that implement the WASI runtime config functionality +/// +/// This function throws an error if any imported functions do not exist +pub(crate) fn stub_config_virt(module: &mut Module) -> Result<()> { + for fn_name in WASI_CONFIG_FNS { + module.replace_imported_func( + module + .imports + .get_func("wasi:config/runtime@0.2.0-draft", fn_name)?, + |(body, _)| { + body.unreachable(); + }, + )?; + } + + Ok(()) +} + +/// Strip exported functions that implement the WASI runtime config functionality +pub(crate) fn strip_config_virt(module: &mut Module) -> Result<()> { + stub_config_virt(module)?; + + for fn_name in WASI_CONFIG_FNS { + let Ok(fid) = module + .exports + .get_func(format!("wasi:config/runtime@0.2.0-draft#{fn_name}")) + else { + bail!("Expected CLI function {fn_name}") + }; + module.replace_exported_func(fid, |(body, _)| { + body.unreachable(); + })?; + } + + Ok(()) +} diff --git a/tests/cases/config-allow.toml b/tests/cases/config-allow.toml new file mode 100644 index 0000000..2c65057 --- /dev/null +++ b/tests/cases/config-allow.toml @@ -0,0 +1,14 @@ +component = "get-config" + +[host-config] +private_token = "private" +public_prop = "val" + +[virt-opts.config] +overrides = [["custom", "val"]] + +[virt-opts.config.host] +allow = ["public_prop"] + +[expect] +config = [["custom", "val"], ["public_prop", "val"]] diff --git a/tests/cases/config-deny.toml b/tests/cases/config-deny.toml new file mode 100644 index 0000000..7fe72c9 --- /dev/null +++ b/tests/cases/config-deny.toml @@ -0,0 +1,14 @@ +component = "get-config" + +[host-config] +private_token = "private" +public_prop = "val" + +[virt-opts.config] +overrides = [["custom", "val"]] + +[virt-opts.config.host] +deny = ["private_token"] + +[expect] +config = [["custom", "val"], ["public_prop", "val"]] diff --git a/tests/cases/config-none-overrides.toml b/tests/cases/config-none-overrides.toml new file mode 100644 index 0000000..30c996a --- /dev/null +++ b/tests/cases/config-none-overrides.toml @@ -0,0 +1,11 @@ +component = "get-config" + +[host-config] +custom = "test" + +[virt-opts.config] +host = "none" +overrides = [["prop_override", "Value"]] + +[expect] +config = [["prop_override", "Value"]] diff --git a/tests/cases/config-none.toml b/tests/cases/config-none.toml new file mode 100644 index 0000000..4af9621 --- /dev/null +++ b/tests/cases/config-none.toml @@ -0,0 +1,11 @@ +component = "get-config" + +[host-config] +custom = "test" + +[virt-opts.config] +host = "none" +overrides = [] + +[expect] +config = [] diff --git a/tests/cases/config-passthrough.toml b/tests/cases/config-passthrough.toml new file mode 100644 index 0000000..5171fcb --- /dev/null +++ b/tests/cases/config-passthrough.toml @@ -0,0 +1,11 @@ +component = "get-config" + +[host-config] +custom = "prop" + +[virt-opts.config] +host = "all" +overrides = [] + +[expect] +config = [["custom", "prop"]] diff --git a/tests/components/do-everything/src/lib.rs b/tests/components/do-everything/src/lib.rs index c613abb..bda623e 100644 --- a/tests/components/do-everything/src/lib.rs +++ b/tests/components/do-everything/src/lib.rs @@ -17,6 +17,9 @@ impl Guest for VirtTestComponent { fn test_get_env() -> Vec<(String, String)> { unreachable!(); } + fn test_get_config() -> Vec<(String, String)> { + unreachable!(); + } fn test_file_read(path: String) -> String { let vars: Vec<(String, String)> = env::vars().collect(); let mut rng = rand::thread_rng(); diff --git a/tests/components/file-read/src/lib.rs b/tests/components/file-read/src/lib.rs index ce74c84..02fc4d5 100644 --- a/tests/components/file-read/src/lib.rs +++ b/tests/components/file-read/src/lib.rs @@ -12,6 +12,9 @@ impl Guest for VirtTestComponent { fn test_get_env() -> Vec<(String, String)> { Vec::new() } + fn test_get_config() -> Vec<(String, String)> { + Vec::new() + } fn test_file_read(path: String) -> String { let meta = match fs::metadata(&path) { Ok(meta) => meta, diff --git a/tests/components/get-config/Cargo.toml b/tests/components/get-config/Cargo.toml new file mode 100644 index 0000000..1143778 --- /dev/null +++ b/tests/components/get-config/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "get-config" +version = "0.1.0" +publish = false + +[lib] +crate-type = ["cdylib"] + +[dependencies] +anyhow = { workspace = true } +wit-bindgen = { workspace = true } diff --git a/tests/components/get-config/src/lib.rs b/tests/components/get-config/src/lib.rs new file mode 100644 index 0000000..074979d --- /dev/null +++ b/tests/components/get-config/src/lib.rs @@ -0,0 +1,26 @@ +use std::env; + +wit_bindgen::generate!({ + path: "../../../wit", + world: "virt-test", + generate_all +}); + +struct VirtTestComponent; + +impl Guest for VirtTestComponent { + fn test_get_env() -> Vec<(String, String)> { + unimplemented!(); + } + fn test_get_config() -> Vec<(String, String)> { + wasi::config::runtime::get_all().unwrap() + } + fn test_file_read(_path: String) -> String { + unimplemented!(); + } + fn test_stdio() -> () { + unimplemented!(); + } +} + +export!(VirtTestComponent); diff --git a/tests/components/get-env/src/lib.rs b/tests/components/get-env/src/lib.rs index ea672d8..f17f8b5 100644 --- a/tests/components/get-env/src/lib.rs +++ b/tests/components/get-env/src/lib.rs @@ -12,6 +12,9 @@ impl Guest for VirtTestComponent { fn test_get_env() -> Vec<(String, String)> { env::vars().collect() } + fn test_get_config() -> Vec<(String, String)> { + unimplemented!(); + } fn test_file_read(_path: String) -> String { unimplemented!(); } diff --git a/tests/components/stdio/src/lib.rs b/tests/components/stdio/src/lib.rs index 441c3f1..05057ef 100644 --- a/tests/components/stdio/src/lib.rs +++ b/tests/components/stdio/src/lib.rs @@ -12,6 +12,9 @@ impl Guest for VirtTestComponent { fn test_get_env() -> Vec<(String, String)> { unimplemented!(); } + fn test_get_config() -> Vec<(String, String)> { + unimplemented!(); + } fn test_file_read(_path: String) -> String { unimplemented!(); } diff --git a/tests/virt.rs b/tests/virt.rs index 7444b77..a28cda0 100644 --- a/tests/virt.rs +++ b/tests/virt.rs @@ -2,6 +2,7 @@ use anyhow::{anyhow, bail, Context, Result}; use heck::ToSnakeCase; use serde::Deserialize; use std::collections::BTreeMap; +use std::pin::Pin; use std::process::Command; use std::{fs, path::PathBuf}; use wasi_virt::WasiVirt; @@ -47,6 +48,7 @@ fn cmd(arg: &str) -> Result<()> { #[serde(rename_all = "kebab-case", deny_unknown_fields)] struct TestExpectation { env: Option>, + config: Option>, file_read: Option, encapsulation: Option, stdout: Option, @@ -66,6 +68,7 @@ struct TestCase { component: String, compose: Option, host_env: Option>, + host_config: Option>, host_fs_path: Option, virt_opts: Option, expect: TestExpectation, @@ -217,6 +220,15 @@ async fn virt_test() -> Result<()> { builder.env(k, v); } } + let props: Vec<(String, String)> = { + let mut props = vec![]; + if let Some(host_config) = &test.host_config { + for (k, v) in host_config { + props.push((k.clone(), v.clone())) + } + } + props + }; let table = ResourceTable::new(); let wasi = builder.build(); @@ -234,6 +246,7 @@ async fn virt_test() -> Result<()> { struct CommandCtx { table: ResourceTable, wasi: WasiCtx, + props: Vec<(String, String)>, } impl WasiView for CommandCtx { fn table(&mut self) -> &mut ResourceTable { @@ -243,9 +256,19 @@ async fn virt_test() -> Result<()> { &mut self.wasi } } + impl CommandCtx { + fn config(&self) -> Vec<(String, String)> { + self.props.clone() + } + } wasmtime_wasi::add_to_linker_async(&mut linker)?; - let mut store = Store::new(&engine, CommandCtx { table, wasi }); + wasi::config::runtime::add_to_linker_get_host(&mut linker, |ctx: &mut CommandCtx| { + StubConfig { + props: ctx.config(), + } + })?; + let mut store = Store::new(&engine, CommandCtx { table, wasi, props }); let (instance, _instance) = VirtTest::instantiate_async(&mut store, &component, &linker).await?; @@ -273,6 +296,25 @@ async fn virt_test() -> Result<()> { } } + // config property expectation check + if let Some(expect_config) = &test.expect.config { + let config_props = instance.call_test_get_config(&mut store).await?; + if !config_props.eq(expect_config) { + return Err(anyhow!( + "Unexpected config properties testing {:?}: + + \x1b[1mExpected:\x1b[0m {:?} + \x1b[1mActual:\x1b[0m {:?} + + {:?}", + test_case_path, + expect_config, + config_props, + test + )); + } + } + // fs read expectation check if let Some(expect_file_read) = &test.expect.file_read { let file_read = instance @@ -396,3 +438,65 @@ fn collect_component_imports(component_bytes: Vec) -> Result> { Ok(import_ids) } + +// TODO remove this stub once wasi:runtime/config is implemented by wasmtime +struct StubConfig { + props: Vec<(String, String)>, +} +impl wasi::config::runtime::Host for StubConfig { + #[doc = " Gets a single opaque config value set at the given key if it exists"] + #[must_use] + #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)] + fn get<'life0, 'async_trait>( + &'life0 mut self, + key: String, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result, wasi::config::runtime::ConfigError>, + > + ::core::marker::Send + + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait, + { + let mut result = Ok(None); + for (k, v) in self.props.iter() { + if *k == key { + result = Ok(Some(v.clone())); + } + } + let result = std::future::ready(result); + let result = Box::new(result); + let result = Pin::new(result); + + result + } + + #[doc = " Gets a list of all set config data"] + #[must_use] + #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)] + fn get_all<'life0, 'async_trait>( + &'life0 mut self, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result, wasi::config::runtime::ConfigError>, + > + ::core::marker::Send + + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait, + { + let result = Ok(self.props.clone()); + let result = std::future::ready(result); + let result = Box::new(result); + let result = Pin::new(result); + + result + } +} diff --git a/virtual-adapter/src/config.rs b/virtual-adapter/src/config.rs new file mode 100644 index 0000000..a7d6324 --- /dev/null +++ b/virtual-adapter/src/config.rs @@ -0,0 +1,118 @@ +use crate::exports::wasi::config::runtime::{ConfigError, Guest as Runtime}; +use crate::wasi::config::runtime; +use crate::VirtAdapter; + +#[repr(C)] +pub struct Config { + /// Whether to fallback to the host config + /// [byte 0] + host_fallback: bool, + /// Whether we are providing an allow list or a deny list + /// on the fallback lookups + /// [byte 1] + host_fallback_allow: bool, + /// How many host fields are defined in the data pointer + /// [byte 4] + host_field_cnt: u32, + /// Host many host fields are defined to be allow or deny + /// (these are concatenated at the end of the data with empty values) + /// [byte 8] + host_allow_or_deny_cnt: u32, + /// Byte data of u32 byte len followed by string bytes + /// up to the lengths previously provided. + /// [byte 12] + host_field_data: *const u8, +} + +#[no_mangle] +pub static mut config: Config = Config { + host_fallback: true, + host_fallback_allow: false, + host_field_cnt: 0, + host_allow_or_deny_cnt: 0, + host_field_data: 0 as *const u8, +}; + +fn read_data_str(offset: &mut isize) -> &'static str { + let data: *const u8 = unsafe { config.host_field_data.offset(*offset) }; + let byte_len = unsafe { (data as *const u32).read() } as usize; + *offset += 4; + let data: *const u8 = unsafe { config.host_field_data.offset(*offset) }; + let str_data = unsafe { std::slice::from_raw_parts(data, byte_len) }; + *offset += byte_len as isize; + let rem = *offset % 4; + if rem > 0 { + *offset += 4 - rem; + } + unsafe { core::str::from_utf8_unchecked(str_data) } +} + +impl Runtime for VirtAdapter { + fn get(key: String) -> Result, ConfigError> { + let mut data_offset: isize = 0; + for _ in 0..unsafe { config.host_field_cnt } { + let config_key = read_data_str(&mut data_offset); + let config_val = read_data_str(&mut data_offset); + if key == config_key.to_string() { + return Ok(Some(config_val.to_string())); + } + } + + // fallback ASSUMES that all data is alphabetically ordered + if unsafe { config.host_fallback } { + let mut allow_or_deny = Vec::new(); + for _ in 0..unsafe { config.host_allow_or_deny_cnt } { + let allow_or_deny_key = read_data_str(&mut data_offset); + allow_or_deny.push(allow_or_deny_key); + } + + let is_allow_list = unsafe { config.host_fallback_allow }; + let in_list = allow_or_deny.binary_search(&key.as_ref()).is_ok(); + if is_allow_list && in_list || !is_allow_list && !in_list { + return runtime::get(&key).map_err(config_err_map); + } + } + Ok(None) + } + + fn get_all() -> Result, ConfigError> { + let mut configuration = Vec::new(); + let mut data_offset: isize = 0; + for _ in 0..unsafe { config.host_field_cnt } { + let config_key = read_data_str(&mut data_offset); + let config_val = read_data_str(&mut data_offset); + configuration.push((config_key.to_string(), config_val.to_string())); + } + let override_len = configuration.len(); + // fallback ASSUMES that all data is alphabetically ordered + if unsafe { config.host_fallback } { + let mut allow_or_deny = Vec::new(); + for _ in 0..unsafe { config.host_allow_or_deny_cnt } { + let allow_or_deny_key = read_data_str(&mut data_offset); + allow_or_deny.push(allow_or_deny_key); + } + + let is_allow_list = unsafe { config.host_fallback_allow }; + for (key, value) in runtime::get_all().map_err(config_err_map)? { + if configuration[0..override_len] + .binary_search_by_key(&&key, |(s, _)| s) + .is_ok() + { + continue; + } + let in_list = allow_or_deny.binary_search(&key.as_ref()).is_ok(); + if is_allow_list && in_list || !is_allow_list && !in_list { + configuration.push((key, value)); + } + } + } + Ok(configuration) + } +} + +fn config_err_map(err: runtime::ConfigError) -> ConfigError { + match err { + runtime::ConfigError::Upstream(msg) => ConfigError::Upstream(msg), + runtime::ConfigError::Io(msg) => ConfigError::Io(msg), + } +} diff --git a/virtual-adapter/src/lib.rs b/virtual-adapter/src/lib.rs index b328a9f..aab68d3 100644 --- a/virtual-adapter/src/lib.rs +++ b/virtual-adapter/src/lib.rs @@ -1,6 +1,7 @@ #![no_main] #![feature(ptr_sub_ptr)] +mod config; mod env; mod io; diff --git a/wit/deps/config/runtime_config.wit b/wit/deps/config/runtime_config.wit new file mode 100644 index 0000000..29d53b1 --- /dev/null +++ b/wit/deps/config/runtime_config.wit @@ -0,0 +1,25 @@ +interface runtime { + /// An error type that encapsulates the different errors that can occur fetching config + variant config-error { + /// This indicates an error from an "upstream" config source. + /// As this could be almost _anything_ (such as Vault, Kubernetes ConfigMaps, KeyValue buckets, etc), + /// the error message is a string. + upstream(string), + /// This indicates an error from an I/O operation. + /// As this could be almost _anything_ (such as a file read, network connection, etc), + /// the error message is a string. + /// Depending on how this ends up being consumed, + /// we may consider moving this to use the `wasi:io/error` type instead. + /// For simplicity right now in supporting multiple implementations, it is being left as a string. + io(string), + } + + /// Gets a single opaque config value set at the given key if it exists + get: func( + /// A string key to fetch + key: string + ) -> result, config-error>; + + /// Gets a list of all set config data + get-all: func() -> result>, config-error>; +} diff --git a/wit/deps/config/world.wit b/wit/deps/config/world.wit new file mode 100644 index 0000000..378c4a7 --- /dev/null +++ b/wit/deps/config/world.wit @@ -0,0 +1,6 @@ +package wasi:config@0.2.0-draft; + +world imports { + /// The runtime interface for config + import runtime; +} \ No newline at end of file diff --git a/wit/virt.wit b/wit/virt.wit index 7ed1cfb..612da37 100644 --- a/wit/virt.wit +++ b/wit/virt.wit @@ -43,6 +43,8 @@ world virtual-adapter { export wasi:sockets/tcp@0.2.0; import wasi:sockets/udp@0.2.0; export wasi:sockets/udp@0.2.0; + import wasi:config/runtime@0.2.0-draft; + export wasi:config/runtime@0.2.0-draft; } world virtual-base { @@ -160,6 +162,11 @@ world virtual-exit { export wasi:cli/exit@0.2.0; } +world virtual-config { + import wasi:config/runtime@0.2.0-draft; + export wasi:config/runtime@0.2.0-draft; +} + world virt-test { import wasi:clocks/wall-clock@0.2.0; import wasi:clocks/monotonic-clock@0.2.0; @@ -177,6 +184,7 @@ world virt-test { import wasi:io/poll@0.2.0; import wasi:io/streams@0.2.0; import wasi:cli/environment@0.2.0; + import wasi:config/runtime@0.2.0-draft; import wasi:filesystem/preopens@0.2.0; import wasi:cli/exit@0.2.0; import wasi:cli/stdin@0.2.0; @@ -189,6 +197,7 @@ world virt-test { import wasi:cli/terminal-stderr@0.2.0; export test-get-env: func() -> list>; + export test-get-config: func() -> list>; export test-file-read: func(path: string) -> string; export test-stdio: func() -> (); }