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

Add support for wasi:config/runtime virtualization #82

Merged
merged 2 commits into from
Aug 29, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
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
- [Runtime Config](#runtime-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
```

### Runtime 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)>>,

// RUNTIME CONFIG
/// Allow unrestricted access to host runtime 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 = "Runtime Config")]
allow_config: Option<Vec<String>>,

/// Set runtime config property overrides
#[arg(short, long, use_value_delimiter(true), value_name("NAME=VALUE"), value_parser = parse_key_val::<String, String>, help_heading = "Runtime 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