Skip to content

Commit

Permalink
Add support for wasi:config/runtime virtualization
Browse files Browse the repository at this point in the history
  • Loading branch information
scothis committed Aug 8, 2024
1 parent 3da2d18 commit b1d6040
Show file tree
Hide file tree
Showing 13 changed files with 473 additions and 2 deletions.
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,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=VAR -o virt.wasm

# Setting config properties with all host config properties allowed:
wasi-virt component.wasm -c CUSTOM=VAR --allow-config -o virt.wasm

# Setting config properties with restricted host config property access:
wasi-virt component.wasm -c CUSTOM=VAR --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 @@ -59,6 +59,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 @@ -173,6 +182,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
24 changes: 22 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use anyhow::{Context, Result};
use serde::Deserialize;
use std::env;
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 @@ -12,12 +13,14 @@ use wit_component::{metadata, ComponentEncoder, DecodedWasm, StringEncoding};

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 @@ -42,6 +45,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 @@ -77,6 +82,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 @@ -88,6 +94,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 @@ -116,6 +123,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 All @@ -138,10 +149,13 @@ impl WasiVirt {
}?;
module.name = Some("wasi_virt".into());

// only env virtualization is independent of io
// only env and config virtualization are independent of io
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 @@ -191,6 +205,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 @@ -205,12 +220,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 b1d6040

Please sign in to comment.