Skip to content

Commit

Permalink
Add support for wasi:config/runtime virtualization
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
scothis committed Aug 28, 2024
1 parent c451261 commit 8313bf9
Show file tree
Hide file tree
Showing 26 changed files with 699 additions and 2 deletions.
8 changes: 8 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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",
]
Expand Down
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
Binary file modified lib/package.wasm
Binary file not shown.
Binary file modified lib/virtual_adapter.debug.wasm
Binary file not shown.
Binary file modified lib/virtual_adapter.wasm
Binary file not shown.
28 changes: 28 additions & 0 deletions src/bin/wasi-virt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,15 @@ struct Args {
#[arg(short, long, use_value_delimiter(true), value_name("ENV=VAR"), value_parser = parse_key_val::<String, String>, help_heading = "Env")]
env: Option<Vec<(String, String)>>,

// 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<Vec<String>>,

/// Set config property overrides
#[arg(short, long, use_value_delimiter(true), value_name("NAME=VALUE"), value_parser = parse_key_val::<String, String>, help_heading = "Config")]
config: Option<Vec<(String, String)>>,

// FS
/// Allow unrestricted access to host preopens
#[arg(long, default_missing_value="true", num_args=0..=1, help_heading = "Fs")]
Expand Down Expand Up @@ -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 {
Expand Down
25 changes: 24 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
@@ -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,
};
Expand All @@ -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};

Expand All @@ -44,6 +47,8 @@ pub struct WasiVirt {
pub debug: bool,
/// Environment virtualization
pub env: Option<VirtEnv>,
/// Configuration virtualization
pub config: Option<VirtConfig>,
/// Filesystem virtualization
pub fs: Option<VirtFs>,
/// Stdio virtualization
Expand Down Expand Up @@ -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();
}
Expand All @@ -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();
}
Expand Down Expand Up @@ -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)
}
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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"))?;
Expand All @@ -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)?;
Expand Down
Loading

0 comments on commit 8313bf9

Please sign in to comment.