Skip to content
Open
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
2 changes: 2 additions & 0 deletions docs/references/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ Start a new sandbox with specified configuration.
| `volumes` | `array[string]` | No | Volume mounts (format: `host:container`) |
| `ports` | `array[string]` | No | Port mappings (format: `host:container`) |
| `envs` | `array[string]` | No | Environment variables (format: `KEY=VALUE`) |
| `rlimits` | `array[string]` | No | Resource limits (format: `RLIMIT_NAME=soft:hard`, e.g., `RLIMIT_NOFILE=16384:65536` for file handles, `RLIMIT_NPROC=2048:4096` for processes/threads) |
| `depends_on` | `array[string]` | No | Dependencies on other sandboxes |
| `workdir` | `string` | No | Working directory |
| `shell` | `string` | No | Shell to use |
Expand All @@ -137,6 +138,7 @@ Start a new sandbox with specified configuration.
"memory": 1024,
"cpus": 2,
"envs": ["DEBUG=true"],
"rlimits": ["RLIMIT_NOFILE=16384:65536", "RLIMIT_NPROC=2048:4096"],
"workdir": "/workspace"
}
},
Expand Down
2 changes: 2 additions & 0 deletions microsandbox-cli/bin/msb/handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ pub async fn add_subcommand(
volumes: Vec<String>,
ports: Vec<String>,
envs: Vec<String>,
rlimits: Vec<String>,
env_file: Option<Utf8UnixPathBuf>,
depends_on: Vec<String>,
workdir: Option<Utf8UnixPathBuf>,
Expand Down Expand Up @@ -89,6 +90,7 @@ pub async fn add_subcommand(
volumes,
ports,
envs,
rlimits,
env_file,
depends_on,
workdir,
Expand Down
3 changes: 2 additions & 1 deletion microsandbox-cli/bin/msb/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ async fn main() -> MicrosandboxCliResult<()> {
volumes,
ports,
envs,
rlimits,
env_file,
depends_on,
workdir,
Expand All @@ -61,7 +62,7 @@ async fn main() -> MicrosandboxCliResult<()> {
}) => {
let (path, config) = handlers::parse_file_path(file);
handlers::add_subcommand(
sandbox, build, group, names, image, memory, cpus, volumes, ports, envs, env_file,
sandbox, build, group, names, image, memory, cpus, volumes, ports, envs, rlimits, env_file,
depends_on, workdir, shell, scripts, start, imports, exports, scope, path, config,
)
.await?;
Expand Down
20 changes: 19 additions & 1 deletion microsandbox-cli/bin/msbrun.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ use microsandbox_cli::{McrunArgs, McrunSubcommand};
use microsandbox_core::{
config::{EnvPair, PathPair, PortPair},
runtime::MicroVmMonitor,
vm::{MicroVm, Rootfs},
vm::{LinuxRlimit, MicroVm, Rootfs},
};
use microsandbox_utils::runtime::Supervisor;

Expand All @@ -86,6 +86,7 @@ async fn main() -> Result<()> {
workdir_path,
exec_path,
env,
rlimit,
mapped_dir,
port_map,
scope,
Expand All @@ -103,6 +104,7 @@ async fn main() -> Result<()> {
tracing::debug!("workdir_path: {:#?}", workdir_path);
tracing::debug!("exec_path: {:#?}", exec_path);
tracing::debug!("env: {:#?}", env);
tracing::debug!("rlimit: {:#?}", rlimit);
tracing::debug!("mapped_dir: {:#?}", mapped_dir);
tracing::debug!("port_map: {:#?}", port_map);
tracing::debug!("scope: {:#?}", scope);
Expand Down Expand Up @@ -139,6 +141,9 @@ async fn main() -> Result<()> {
// Parse environment variables
let env: Vec<EnvPair> = env.iter().map(|s| s.parse()).collect::<Result<_, _>>()?;

// Parse resource limits
let rlimit: Vec<LinuxRlimit> = rlimit.iter().map(|s| s.parse()).collect::<Result<_, _>>()?;

// Create and configure MicroVM
let mut builder = MicroVm::builder().rootfs(rootfs).exec_path(exec_path);

Expand Down Expand Up @@ -192,6 +197,11 @@ async fn main() -> Result<()> {
builder = builder.env(env);
}

// Set rlimits if provided
if !rlimit.is_empty() {
builder = builder.rlimits(rlimit);
}

// Set args if provided
if !args.is_empty() {
builder = builder.args(args.iter().map(|s| s.as_str()));
Expand All @@ -218,6 +228,7 @@ async fn main() -> Result<()> {
workdir_path,
exec_path,
env,
rlimit,
mapped_dir,
port_map,
scope,
Expand Down Expand Up @@ -296,6 +307,13 @@ async fn main() -> Result<()> {
}
}

// Set rlimits if provided
if !rlimit.is_empty() {
for rlimit in rlimit {
child_args.push(format!("--rlimit={}", rlimit));
}
}

// Set mapped dirs if provided
if !mapped_dir.is_empty() {
for dir in mapped_dir {
Expand Down
4 changes: 4 additions & 0 deletions microsandbox-cli/lib/args/msb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@ pub enum MicrosandboxSubcommand {
#[arg(long = "env", name = "ENV")]
envs: Vec<String>,

/// Resource limits, format: <resource>=<soft>:<hard>
#[arg(long = "rlimit", name = "RLIMIT")]
rlimits: Vec<String>,

/// Environment file
#[arg(long)]
env_file: Option<Utf8UnixPathBuf>,
Expand Down
8 changes: 8 additions & 0 deletions microsandbox-cli/lib/args/msbrun.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ pub enum McrunSubcommand {
#[arg(long)]
env: Vec<String>,

/// Resource limits (RLIMIT_RESOURCE=SOFT:HARD format)
#[arg(long)]
rlimit: Vec<String>,

/// Directory mappings (host:guest format)
#[arg(long)]
mapped_dir: Vec<String>,
Expand Down Expand Up @@ -139,6 +143,10 @@ pub enum McrunSubcommand {
#[arg(long)]
env: Vec<String>,

/// Resource limits (RLIMIT_RESOURCE=SOFT:HARD format)
#[arg(long)]
rlimit: Vec<String>,

/// Directory mappings (host:guest format)
#[arg(long)]
mapped_dir: Vec<String>,
Expand Down
11 changes: 11 additions & 0 deletions microsandbox-core/lib/config/microsandbox/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use typed_path::Utf8UnixPathBuf;

use crate::{
config::{EnvPair, PathPair, PortPair, ReferenceOrPath},
vm::LinuxRlimit,
MicrosandboxResult,
};

Expand Down Expand Up @@ -65,6 +66,7 @@ pub struct SandboxBuilder<I> {
volumes: Vec<PathPair>,
ports: Vec<PortPair>,
envs: Vec<EnvPair>,
rlimits: Vec<LinuxRlimit>,
env_file: Option<Utf8UnixPathBuf>,
groups: HashMap<String, SandboxGroup>,
depends_on: Vec<String>,
Expand Down Expand Up @@ -155,6 +157,7 @@ impl<I> SandboxBuilder<I> {
volumes: self.volumes,
ports: self.ports,
envs: self.envs,
rlimits: self.rlimits,
env_file: self.env_file,
groups: self.groups,
depends_on: self.depends_on,
Expand Down Expand Up @@ -198,6 +201,12 @@ impl<I> SandboxBuilder<I> {
self
}

/// Sets the resource limits for the sandbox
pub fn rlimits(mut self, rlimits: impl IntoIterator<Item = LinuxRlimit>) -> SandboxBuilder<I> {
self.rlimits = rlimits.into_iter().collect();
self
}

/// Sets the environment file for the sandbox
pub fn env_file(mut self, env_file: impl Into<Utf8UnixPathBuf>) -> SandboxBuilder<I> {
self.env_file = Some(env_file.into());
Expand Down Expand Up @@ -283,6 +292,7 @@ impl SandboxBuilder<ReferenceOrPath> {
volumes: self.volumes,
ports: self.ports,
envs: self.envs,
rlimits: self.rlimits,
groups: self.groups,
depends_on: self.depends_on,
workdir: self.workdir,
Expand Down Expand Up @@ -311,6 +321,7 @@ impl Default for SandboxBuilder<()> {
volumes: Vec::new(),
ports: Vec::new(),
envs: Vec::new(),
rlimits: Vec::new(),
env_file: None,
groups: HashMap::new(),
depends_on: Vec::new(),
Expand Down
5 changes: 5 additions & 0 deletions microsandbox-core/lib/config/microsandbox/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use typed_path::Utf8UnixPathBuf;

use crate::{
config::{EnvPair, PathPair, PortPair, ReferenceOrPath},
vm::LinuxRlimit, // Add LinuxRlimit import
MicrosandboxError, MicrosandboxResult,
};

Expand Down Expand Up @@ -289,6 +290,10 @@ pub struct Sandbox {
#[serde(skip_serializing_if = "Vec::is_empty", default)]
pub(crate) envs: Vec<EnvPair>,

/// The resource limits to use.
#[serde(skip_serializing_if = "Vec::is_empty", default)]
pub(crate) rlimits: Vec<LinuxRlimit>,

/// The groups to run in.
#[serde(skip_serializing_if = "HashMap::is_empty", default)]
pub(crate) groups: HashMap<String, SandboxGroup>,
Expand Down
15 changes: 15 additions & 0 deletions microsandbox-core/lib/management/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ pub enum Component {
/// The environment variables to use.
envs: Vec<String>,

/// The resource limits to use.
rlimits: Vec<String>,

/// The environment file to use.
env_file: Option<Utf8UnixPathBuf>,

Expand Down Expand Up @@ -133,6 +136,7 @@ pub async fn add(
volumes,
ports,
envs,
rlimits,
env_file,
depends_on,
workdir,
Expand Down Expand Up @@ -222,6 +226,17 @@ pub async fn add(
}
}

// Add rlimits if any
if !rlimits.is_empty() {
let mut rlimits_sequence = sandbox_mapping
.insert("rlimits", yaml::Separator::Auto)
.make_sequence();

for rlimit in rlimits {
rlimits_sequence.push_string(rlimit);
}
}

// Add env_file if provided
if let Some(env_file_path) = env_file {
sandbox_mapping.insert_str("env_file", env_file_path.to_string());
Expand Down
5 changes: 5 additions & 0 deletions microsandbox-core/lib/management/sandbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,11 @@ pub async fn prepare_run(
command.arg("--env").arg(env.to_string());
}

// Rlimits
for rlimit in sandbox_config.get_rlimits() {
command.arg("--rlimit").arg(rlimit.to_string());
}

// Ports
for port in sandbox_config.get_ports() {
command.arg("--port-map").arg(port.to_string());
Expand Down
12 changes: 12 additions & 0 deletions microsandbox-server/lib/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,18 @@ pub async fn sandbox_start_impl(
);
}

if !config.rlimits.is_empty() {
let rlimits_array = config
.rlimits
.iter()
.map(|r| serde_yaml::Value::String(r.to_string()))
.collect::<Vec<_>>();
sandbox_map.insert(
serde_yaml::Value::String("rlimits".to_string()),
serde_yaml::Value::Sequence(rlimits_array),
);
}

// Replace or add the sandbox in the config
sandboxes_map.insert(
serde_yaml::Value::String(sandbox.clone()),
Expand Down
5 changes: 5 additions & 0 deletions microsandbox-server/lib/mcp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,11 @@ pub async fn handle_mcp_list_tools(
"type": "array",
"items": {"type": "string"},
"description": "Environment variables"
},
"rlimits": {
"type": "array",
"items": {"type": "string"},
"description": "Resource limits in format RLIMIT_NAME=soft:hard (e.g., RLIMIT_NOFILE=16384:65536)"
}
}
}
Expand Down
6 changes: 6 additions & 0 deletions microsandbox-server/lib/payload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
//! - Success message formatting for sandbox operations
//! - Detailed error information handling

use microsandbox_core::vm::LinuxRlimit; // Import LinuxRlimit
use serde::{Deserialize, Serialize};
use serde_json::Value;

Expand Down Expand Up @@ -190,6 +191,11 @@ pub struct SandboxConfig {

/// The exec command to run
pub exec: Option<String>,

/// Resource limits for the sandbox process
#[serde(default)]
pub rlimits: Vec<LinuxRlimit>,

// SECURITY: Needs networking namespacing to be implemented
// /// The network scope for the sandbox
// pub scope: Option<String>,
Expand Down