use anyhow::Result;
use isolate_integration::sandbox::{DirectoryRule, EnvRule, IsolateSandbox, ResourceLimits};
use std::path::PathBuf;
async fn create_dir_with_permissions(path: &str, mode: u32) -> Result<()> {
tokio::fs::create_dir_all(path).await?;
#[cfg(unix)]
{
use std::fs::Permissions;
use std::os::unix::fs::PermissionsExt;
let permissions = Permissions::from_mode(mode);
tokio::fs::set_permissions(path, permissions).await?;
}
Ok(())
}
#[tokio::main]
async fn main() -> Result<()> {
println!("=== Isolate Sandbox Usage Examples ===\n");
println!("Prerequisites: Make sure 'isolate' is installed on your system.");
println!("Installation: sudo apt-get install isolate (on Ubuntu/Debian)\n");
if let Err(e) = basic_example().await {
eprintln!("Basic example failed: {}", e);
}
if let Err(e) = environment_example().await {
eprintln!("Environment example failed: {}", e);
}
if let Err(e) = file_sharing_example().await {
eprintln!("File sharing example failed: {}", e);
}
if let Err(e) = resource_limits_example().await {
eprintln!("Resource limits example failed: {}", e);
}
if let Err(e) = compile_and_run_example().await {
eprintln!("Compile and run example failed: {}", e);
}
println!("\n=== All examples completed ===");
Ok(())
}
async fn basic_example() -> Result<()> {
println!("=== Example 1: Basic Command Execution ===");
let sandbox = IsolateSandbox::new(0)
.with_meta_file(PathBuf::from("/tmp/isolate_meta_0.txt"))
.verbose();
let limits = ResourceLimits::new();
sandbox.init(&limits).await?;
let result = sandbox
.run("/bin/echo", ["Hello from Isolate Sandbox!"], &limits)
.await?;
println!("Exit code: {:?}", result.exit_code);
println!("Output: {}", result.stdout.trim());
println!("Time used: {:.3}s", result.time_used);
println!("Memory used: {} KB", result.memory_used);
sandbox.cleanup().await?;
println!("✓ Basic example completed\n");
Ok(())
}
async fn environment_example() -> Result<()> {
println!("=== Example 2: Environment Variables ===");
let sandbox = IsolateSandbox::new(1)
.with_env_rule(EnvRule::Set("GREETING".to_string(), "Hello".to_string()))
.with_env_rule(EnvRule::Set("NAME".to_string(), "Isolate".to_string()))
.with_env_rule(EnvRule::Inherit("PATH".to_string()))
.with_meta_file(PathBuf::from("/tmp/isolate_meta_1.txt"))
.verbose();
let limits = ResourceLimits::new();
sandbox.init(&limits).await?;
let result = sandbox
.run(
"/bin/bash",
[
"-c",
"echo \"$GREETING, $NAME!\" && echo \"Current directory: $(pwd)\"",
],
&limits,
)
.await?;
println!("Output:\n{}", result.stdout);
println!("Exit code: {:?}", result.exit_code);
sandbox.cleanup().await?;
println!("✓ Environment example completed\n");
Ok(())
}
async fn file_sharing_example() -> Result<()> {
println!("=== Example 3: File Sharing ===");
let host_dir = "/tmp/isolate_shared";
create_dir_with_permissions(host_dir, 0o755).await?;
println!("Created directory: {} with permissions 0755", host_dir);
let test_data = "This is data from the host system.\nLine 2\nLine 3";
tokio::fs::write(format!("{}/input.txt", host_dir), test_data).await?;
println!("Created input file at: {}/input.txt", host_dir);
let sandbox = IsolateSandbox::new(2)
.with_directory_rule(DirectoryRule::bind("/data", host_dir).read_write())
.with_meta_file(PathBuf::from("/tmp/isolate_meta_2.txt"))
.verbose();
let limits = ResourceLimits::new();
sandbox.init(&limits).await?;
println!("\n1. Reading file from sandbox:");
let result = sandbox
.run("/bin/cat", ["/data/input.txt"], &limits)
.await?;
println!("{}", result.stdout);
println!("2. Writing new file from sandbox:");
let result = sandbox
.run(
"/bin/bash",
["-c", "echo 'Generated inside sandbox' > /data/output.txt && echo 'File written successfully'"],
&limits,
)
.await?;
println!("{}", result.stdout.trim());
let output_content = tokio::fs::read_to_string(format!("{}/output.txt", host_dir)).await?;
println!("3. Content read back from host:");
println!("{}", output_content.trim());
sandbox.cleanup().await?;
println!("✓ File sharing example completed\n");
Ok(())
}
async fn resource_limits_example() -> Result<()> {
println!("=== Example 4: Resource Limits ===");
let sandbox = IsolateSandbox::new(3)
.with_meta_file(PathBuf::from("/tmp/isolate_meta_3.txt"))
.verbose();
sandbox.init(&ResourceLimits::new()).await?;
println!("4a. Testing time limit (1 second):");
let time_limits = ResourceLimits::new()
.with_time_limit(1.0)
.with_wall_time_limit(2.0);
let result = sandbox
.run(
"/bin/bash",
[
"-c",
"echo 'Starting...'; sleep 5; echo 'Finished within time limit'",
],
&time_limits,
)
.await?;
println!("Output: {}", result.stdout.trim());
println!("Time used: {:.3}s (limit: 1.0s)", result.time_used);
println!("Killed: {}", result.killed);
println!("\n4b. Testing memory limit (32 MB):");
let memory_limits = ResourceLimits::new()
.with_memory_limit(32 * 1024) .with_time_limit(5.0);
let result = sandbox
.run(
"/bin/bash",
[
"-c",
"echo 'Running with memory limit'; echo 'Memory limit: 32 MB'",
],
&memory_limits,
)
.await?;
println!("Output: {}", result.stdout.trim());
println!("Memory used: {} KB (limit: 32768 KB)", result.memory_used);
sandbox.cleanup().await?;
println!("✓ Resource limits example completed\n");
Ok(())
}
async fn compile_and_run_example() -> Result<()> {
println!("=== Example 5: Compile and Run C Program ===");
let shared_dir = "/tmp/isolate_c_example";
create_dir_with_permissions(shared_dir, 0o777).await?;
println!("Created directory: {} with permissions 0777", shared_dir);
let c_code = r#"#include <stdio.h>
int main() {
int sum = 0;
for (int i = 1; i <= 10; i++) {
sum += i;
}
printf("Sum of 1 to 10 is: %d\n", sum);
printf("Program executed successfully!\n");
return 0;
}
"#;
tokio::fs::write(format!("{}/program.c", shared_dir), c_code).await?;
println!("Created C source file at: {}/program.c", shared_dir);
let sandbox = IsolateSandbox::new(4)
.with_directory_rule(DirectoryRule::bind("/workspace", shared_dir).read_write())
.with_meta_file(PathBuf::from("/tmp/isolate_meta_4.txt"))
.with_env_rule(EnvRule::FullEnv)
.verbose();
let compile_limits = ResourceLimits::new()
.with_time_limit(10.0)
.with_memory_limit(256 * 1024);
sandbox.init(&compile_limits).await?;
println!("\n1. Compiling C program:");
let compile_result = sandbox
.run(
"/usr/bin/gcc",
["/workspace/program.c", "-o", "/workspace/program"],
&compile_limits,
)
.await?;
if compile_result.exit_code == Some(0) {
println!("✓ Compilation successful!");
} else {
println!("✗ Compilation failed:");
println!("stderr: {}", compile_result.stderr);
sandbox.cleanup().await?;
return Ok(());
}
println!("\n2. Running compiled program:");
let run_limits = ResourceLimits::new()
.with_time_limit(2.0)
.with_memory_limit(64 * 1024) .with_process_limit(1);
let run_result = sandbox
.run("/workspace/program", Vec::<&str>::new(), &run_limits)
.await?;
println!("Output:\n{}", run_result.stdout);
println!("Exit code: {:?}", run_result.exit_code);
println!("Time used: {:.3}s", run_result.time_used);
println!("Memory used: {} KB", run_result.memory_used);
if run_result.killed {
println!("⚠ Program was killed (exceeded limits)");
}
sandbox.cleanup().await?;
println!("✓ Compile and run example completed\n");
Ok(())
}