diff --git a/bls-runtime/src/cli_clap.rs b/bls-runtime/src/cli_clap.rs index afe5f51..1db1d3d 100644 --- a/bls-runtime/src/cli_clap.rs +++ b/bls-runtime/src/cli_clap.rs @@ -1,19 +1,18 @@ #![allow(unused)] use anyhow::{bail, Result}; use blockless::{ - BlocklessConfig, BlocklessModule, BlsNnGraph, BlsOptions, ModuleType, OptimizeOpts, Permission, - Stderr, Stdin, Stdout, + BlocklessConfig, BlocklessModule, BlsNnGraph, BlsOptions, ModuleType, OptimizeOpts, OptionParser, Permission, PermissionAllow, Stderr, Stdin, Stdout }; use clap::{ builder::{TypedValueParser, ValueParser}, Arg, ArgMatches, Command, Parser, }; use std::{ - collections::HashMap, - net::{IpAddr, SocketAddr, TcpListener, ToSocketAddrs}, - option, - path::{Path, PathBuf}, - str::FromStr, + collections::HashMap, + net::{ + IpAddr, SocketAddr, TcpListener, ToSocketAddrs + }, + option, path::{Path, PathBuf}, str::FromStr }; use url::Url; @@ -86,6 +85,10 @@ const NN_GRAPH_HELP: &str = "Pre-load machine learning graphs (i.e., models) for use by wasi-nn. \ Each use of the flag will preload a ML model from the host directory using the given model encoding"; +const ALLOW_READ_HELP: &str = "Allow the app to read permissions."; + +const ALLOW_WRITE_HELP: &str = "Allow the app to write permissions."; + fn parse_envs(envs: &str) -> Result<(String, String)> { let parts: Vec<_> = envs.splitn(2, "=").collect(); if parts.len() != 2 { @@ -149,6 +152,10 @@ fn parse_permission(permsion: &str) -> Result { }) } +fn parser_allow(allow: &str) -> Result { + PermissionAllow::parse(&allow) +} + fn parse_module(module: &str) -> Result { let mods: Vec<_> = module.splitn(2, "=").collect(); Ok(BlocklessModule { @@ -211,6 +218,18 @@ pub enum RuntimeType { Wasm, } +#[derive(Parser, Debug)] +struct PermissionFlags { + #[clap(long = "read-allow", num_args=(0..), short = 'R', value_name = "[FILE[,]]", help = ALLOW_READ_HELP, value_parser = parser_allow)] + allow_read: Option, + + #[clap(long = "write-allow", num_args=(0..) , value_name = "[FILE[,]]", help = ALLOW_WRITE_HELP, value_parser = parser_allow)] + allow_write: Option, + + #[clap(long = "allow-all", help = "Allow all permissions.")] + allow_all: Option, +} + /// The latest version from Cargo.toml pub(crate) const SHORT_VERSION: &str = concat!("v", env!("CARGO_PKG_VERSION")); @@ -298,11 +317,17 @@ pub(crate) struct CliCommandOpts { #[clap(long = "max_memory_size", value_name = "MAX_MEMORY_SIZE", help = MAX_MEMORY_SIZE_HELP)] max_memory_size: Option, + #[clap(flatten)] + permission_flags: PermissionFlags, + #[clap(long = "nn", value_name = "NN", help = NN_HELP)] nn: bool, #[clap(long = "nn-graph", value_name = "NN_GRAPH", value_parser = parse_nn_graph, help = NN_GRAPH_HELP)] nn_graph: Vec, + + #[arg(long)] + pub help: bool, } impl CliCommandOpts { diff --git a/crates/wasi-common/src/blockless/config.rs b/crates/wasi-common/src/blockless/config.rs index 5b68ac2..fa86213 100644 --- a/crates/wasi-common/src/blockless/config.rs +++ b/crates/wasi-common/src/blockless/config.rs @@ -278,6 +278,30 @@ impl OptionParser for wasmtime::RegallocAlgorithm { } } +#[derive(Clone, Debug)] +pub enum PermissionAllow { + AllowAll, + Allow(Vec), +} + +impl Default for PermissionAllow { + fn default() -> Self { + PermissionAllow::AllowAll + } +} + +impl OptionParser<&str> for PermissionAllow { + fn parse(val: &&str) -> anyhow::Result { + match *val { + "" => Ok(PermissionAllow::AllowAll), + val@_ => { + let val = val.split(',').map(String::from).collect::>(); + Ok(PermissionAllow::Allow(val)) + }, + } + } +} + bls_options! { #[derive(PartialEq, Clone)] pub struct OptimizeOpts { @@ -471,6 +495,23 @@ pub struct BlsNnGraph { pub dir: String, } +#[derive(Clone, Debug)] +pub struct PermissionConfig { + pub allow_read: Option, + pub allow_write: Option, + pub allow_all: Option, +} + +impl Default for PermissionConfig { + fn default() -> Self { + PermissionConfig { + allow_read: None, + allow_write: None, + allow_all: None, + } + } +} + #[derive(Clone)] pub struct BlocklessConfig { pub entry: String, @@ -504,6 +545,7 @@ pub struct BlocklessConfig { pub cli_exit_with_code: bool, pub network_error_code: bool, pub group_permisions: HashMap>, + pub permissions: PermissionConfig, } impl BlocklessConfig { @@ -542,6 +584,7 @@ impl BlocklessConfig { opts: Default::default(), runtime_logger_level: LoggerLevel::WARN, version: BlocklessConfigVersion::Version0, + permissions: Default::default(), } }