isolate-integration 0.1.0

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

这个 crate 提供了一个 Rust 接口来使用 [ioi/isolate](https://github.com/ioi/isolate) 沙箱程序。

使用 `tokio` 异步运行时来管理沙箱的生命周期和执行命令。

## 前提条件

首先,确保系统已安装 isolate。请参考 [ioi/isolate](https://github.com/ioi/isolate)。

关于 `isolate` 的配置,参阅 [isolate document](https://github.com/ioi/isolate/blob/master/isolate.1.txt) 的 `INSTALLATION` 部分。

如果需要使用 `cgroup` 相关特性(推荐,如 `--cg-mem` 选项),请确保系统支持 cgroup v2。

## 基本用法

`isolate` 用法、选项含义等请参考 [isolate document](https://www.ucw.cz/isolate/isolate.1.html)。

下面是一个示例:

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

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    // 创建沙箱(默认启用 cgroup)
    let sandbox = IsolateSandbox::new(0)
        .with_stdin("input.txt")
        .with_stdout("output.txt")
        .with_stderr("error.txt");

    // 如果需要禁用 cgroup
    let sandbox_no_cg = IsolateSandbox::new(1)
        .disable_cgroups()
        .with_stdin("input.txt");

    // 设置资源限制
    let limits = ResourceLimits::new()
        .with_time_limit(1.0)      // 1 秒时间限制
        .with_cg_memory_limit(64 * 1024)  // 64 MB 内存限制
        .with_process_limit(1);        // 只允许 1 个进程

    // 初始化沙箱
    sandbox.init(&limits).await?;

    // 运行命令
    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);

    // 清理沙箱
    sandbox.cleanup().await?;
    
    Ok(())
}
```

## 高级配置

### 目录绑定

```rust
use isolate_integration::DirectoryRule;

let sandbox = IsolateSandbox::new(1)
    // 绑定外部目录到沙箱内部
    .with_directory_rule(DirectoryRule::bind("/tmp/work", "/tmp/sandbox_work").read_write())
    // 创建临时目录
    .with_directory_rule(DirectoryRule::tmp("/tmp/temp"))
    // 绑定系统目录(只读,禁止执行)
    .with_directory_rule(DirectoryRule::bind_same("/usr/bin").no_exec())
    // 挂载文件系统
    .with_directory_rule(DirectoryRule::filesystem("proc"));
```

### 环境变量

```rust
use isolate_integration::EnvRule;

let sandbox = IsolateSandbox::new(2)
    // 继承环境变量
    .with_env_rule(EnvRule::Inherit("HOME".to_string()))
    // 设置环境变量
    .with_env_rule(EnvRule::Set("PATH".to_string(), "/usr/bin:/bin".to_string()))
    // 继承所有环境变量
    .with_env_rule(EnvRule::FullEnv);
```

### 资源限制

```rust
let limits = ResourceLimits::new()
    .with_time_limit(2.0)              // CPU 时间限制
    .with_wall_time_limit(10.0)        // 墙钟时间限制
    .with_memory_limit(128 * 1024)     // 内存限制
    .with_cg_memory_limit(256 * 1024)  // 控制组内存限制
    .with_open_files_limit(64)         // 打开文件数限制
    .with_file_size_limit(1024)        // 单文件大小限制
    .with_process_limit(5);            // 进程数限制
```

### 特殊选项

```rust
let sandbox = IsolateSandbox::new(3)
    .use_cgroups()          // 启用控制组(默认已启用)
    .disable_cgroups()      // 禁用控制组
    .share_network()        // 共享网络命名空间
    .no_default_dirs()      // 不绑定默认目录
    .verbose();             // 详细输出
```

## 编译和运行示例

参见 `examples/sandbox_usage.rs` 中的完整示例,
运行示例:

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

## API 简要参考

### IsolateSandbox

主要的沙箱类,提供以下方法:

- `new(box_id: u32)` - 创建新的沙箱实例
- `init(&self, limits: &ResourceLimits)` - 初始化沙箱
- `run<I, S>(&self, program: &str, args: I, limits: &ResourceLimits)` - 运行命令
- `cleanup(&self)` - 清理沙箱
- `disable_cgroups(self)` - 禁用控制组(如果不需要)

### ResourceLimits

资源限制配置:

- `with_time_limit(seconds: f64)` - 设置 CPU 时间限制
- `with_memory_limit(kb: u32)` - 设置内存限制
- `with_wall_time_limit(seconds: f64)` - 设置墙上时间限制
- `with_process_limit(count: u32)` - 设置进程数限制。与 `isolate``--processes` 选项不同,不给出该限制时允许无限制的进程数。

### DirectoryRule

目录绑定规则:

- `bind(inside, outside)` - 绑定外部目录
- `bind_same(path)` - 绑定到相同路径
- `tmp(path)` - 创建临时目录
- `filesystem(name)` - 挂载文件系统

### ExecutionResult

执行结果包含:

- `exit_code: Option<i32>` - 退出码
- `signal: Option<i32>` - 信号
- `time_used: f64` - CPU 时间
- `wall_time_used: f64` - 墙上时间
- `memory_used: u32` - 内存使用
- `killed: bool` - 是否被杀死
- `stdout: String` - 标准输出
- `stderr: String` - 标准错误