isolate-integration 0.1.1

A Rust interface for the ioi/isolate sandbox program.
Documentation
# Isolate Integration

English | [简体中文]README_CN.md

A Rust interface for the [ioi/isolate]https://github.com/ioi/isolate sandbox program.

Uses the `tokio` async runtime to manage sandbox lifecycle and execute commands.

## Prerequisites

First, ensure that isolate is installed on your system. Please refer to [ioi/isolate](https://github.com/ioi/isolate).

For `isolate` configuration, see the `INSTALLATION` section of the [isolate document](https://github.com/ioi/isolate/blob/master/isolate.1.txt).

If you need to use `cgroup` related features (recommended, such as the `--cg-mem` option), ensure your system supports cgroup v2.

## Basic Usage

For `isolate` usage, option meanings, etc., please refer to the [isolate document](https://www.ucw.cz/isolate/isolate.1.html).

More examples can be found in the `examples` directory.

Here's an example:

```rust
use isolate_integration::{IsolateSandbox, ResourceLimits};

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    // Create sandbox
    let sandbox = IsolateSandbox::new(0)
        .with_stdin("input.txt")
        .with_stdout("output.txt")
        .with_stderr("error.txt");

    // If you need to disable cgroup
    let sandbox_no_cg = IsolateSandbox::new(1)
        .disable_cgroups()
        .with_stdin("input.txt");

    // Set resource limits
    let limits = ResourceLimits::new()
        .with_time_limit(1.0)      // 1 second time limit
        .with_cg_memory_limit(64 * 1024)  // 64 MB memory limit
        .with_process_limit(1);        // Allow only 1 process

    // Initialize sandbox
    sandbox.init(&limits).await?;

    // Run command
    let result = sandbox.run("echo", ["Hello, World!"], &limits).await?;

    println!("exit code: {:?}", result.exit_code);
    println!("time: {:.3}s", result.time_used);
    println!("memory: {} KB", result.cg_memory_used);
    println!("output: {}", result.stdout);

    // Cleanup sandbox
    sandbox.cleanup().await?;
    
    Ok(())
}
```

## Advanced Configuration

### Directory Binding

```rust
use isolate_integration::DirectoryRule;

let sandbox = IsolateSandbox::new(1)
    // Bind external directory to sandbox
    .with_directory_rule(DirectoryRule::bind("/tmp/work", "/tmp/sandbox_work").read_write())
    // Create temporary directory
    .with_directory_rule(DirectoryRule::tmp("/tmp/temp"))
    // Bind system directory (read-only, no execution)
    .with_directory_rule(DirectoryRule::bind_same("/usr/bin").no_exec())
    // Mount filesystem
    .with_directory_rule(DirectoryRule::filesystem("proc"));
```

### Environment Variables

```rust
use isolate_integration::EnvRule;

let sandbox = IsolateSandbox::new(2)
    // Inherit environment variable
    .with_env_rule(EnvRule::Inherit("HOME".to_string()))
    // Set environment variable
    .with_env_rule(EnvRule::Set("PATH".to_string(), "/usr/bin:/bin".to_string()))
    // Inherit all environment variables
    .with_env_rule(EnvRule::FullEnv);
```

### Resource Limits

```rust
let limits = ResourceLimits::new()
    .with_time_limit(2.0)              // CPU time limit
    .with_wall_time_limit(10.0)        // Wall clock time limit
    .with_memory_limit(128 * 1024)     // Memory limit
    .with_cg_memory_limit(256 * 1024)  // Control group memory limit
    .with_open_files_limit(64)         // Open files limit
    .with_file_size_limit(1024)        // File size limit
    .with_process_limit(5);            // Process limit
```

### Special Options

```rust
let sandbox = IsolateSandbox::new(3)
    .use_cgroups()          // Enable control groups
    .disable_cgroups()      // Disable control groups
    .share_network()        // Share network namespace
    .no_default_dirs()      // Don't bind default directories
    .verbose();             // Verbose output
```

## Build and Run Examples

See the complete example in `examples/sandbox_usage.rs`.
Run the example:

```bash
cargo run --example sandbox_usage
```

## API Quick Reference

### IsolateSandbox

Main sandbox class, provides the following methods:

- `new(box_id: u32)` - Create a new sandbox instance
- `init(&self, limits: &ResourceLimits)` - Initialize the sandbox
- `run<I, S>(&self, program: &str, args: I, limits: &ResourceLimits)` - Run a command
- `cleanup(&self)` - Clean up the sandbox
- `disable_cgroups(self)` - Disable control groups (if not needed)

### ResourceLimits

Resource limit configuration:

- `with_time_limit(seconds: f64)` - Set CPU time limit
- `with_memory_limit(kb: u32)` - Set memory limit
- `with_wall_time_limit(seconds: f64)` - Set wall clock time limit
- `with_process_limit(count: u32)` - Set process limit. Unlike isolate's `--processes` option, unlimited processes are allowed when this limit is not specified.

### DirectoryRule

Directory binding rules:

- `bind(inside, outside)` - Bind external directory
- `bind_same(path)` - Bind to the same path
- `tmp(path)` - Create temporary directory
- `filesystem(name)` - Mount filesystem

### ExecutionResult

Execution result contains:

- `exit_code: Option<i32>` - Exit code
- `signal: Option<i32>` - Signal
- `time_used: f64` - CPU time
- `wall_time_used: f64` - Wall clock time
- `memory_used: u32` - Memory usage
- `killed: bool` - Whether killed
- `stdout: String` - Standard output
- `stderr: String` - Standard error