# FireCracker Backend Design

**Date:** 2025-12-08  
**Task:** T014 S1  
**Status:** Design Complete

## Overview

FireCrackerはAWSが開発した軽量なmicroVMハイパーバイザーで、以下の特徴があります：
- 高速な起動時間（< 125ms）
- 低メモリオーバーヘッド
- セキュリティ重視（最小限のデバイスモデル）
- サーバーレス/関数ワークロードに最適

## FireCracker API

FireCrackerはREST API over Unix socketを使用します。デフォルトのソケットパスは `/tmp/firecracker.socket` ですが、起動時にカスタマイズ可能です。

### 主要エンドポイント

1. **PUT /machine-config**
   - CPU数、メモリサイズなどのマシン設定
   - 例: `{"vcpu_count": 2, "mem_size_mib": 512, "ht_enabled": false}`

2. **PUT /boot-source**
   - カーネルイメージとinitrdの設定
   - 例: `{"kernel_image_path": "/path/to/kernel", "initrd_path": "/path/to/initrd", "boot_args": "console=ttyS0"}`

3. **PUT /drives/{drive_id}**
   - ディスクドライブの設定（rootfsなど）
   - 例: `{"drive_id": "rootfs", "path_on_host": "/path/to/rootfs.ext4", "is_root_device": true, "is_read_only": false}`

4. **PUT /network-interfaces/{iface_id}**
   - ネットワークインターフェースの設定
   - 例: `{"iface_id": "eth0", "guest_mac": "AA:FC:00:00:00:01", "host_dev_name": "tap0"}`

5. **PUT /actions**
   - VMのライフサイクル操作
   - `InstanceStart`: VMを起動
   - `SendCtrlAltDel`: リブート（ACPI対応が必要）
   - `FlushMetrics`: メトリクスのフラッシュ

6. **GET /vm**
   - VMの状態情報を取得

### API通信パターン

1. FireCrackerプロセスを起動（jailerまたは直接実行）
2. Unix socketが利用可能になるまで待機
3. REST API経由で設定を送信（machine-config → boot-source → drives → network-interfaces）
4. `InstanceStart`アクションでVMを起動
5. ライフサイクル操作は`/actions`エンドポイント経由

## FireCrackerBackend構造体設計

```rust
pub struct FireCrackerBackend {
    /// FireCrackerバイナリのパス
    firecracker_path: PathBuf,
    /// Jailerバイナリのパス（オプション）
    jailer_path: Option<PathBuf>,
    /// VMのランタイムディレクトリ
    runtime_dir: PathBuf,
    /// FireCracker API socketのベースパス
    socket_base_path: PathBuf,
}
```

### 設定

環境変数による設定：
- `PLASMAVMC_FIRECRACKER_PATH`: FireCrackerバイナリのパス（デフォルト: `/usr/bin/firecracker`）
- `PLASMAVMC_FIRECRACKER_JAILER_PATH`: Jailerバイナリのパス（オプション、デフォルト: `/usr/bin/jailer`）
- `PLASMAVMC_FIRECRACKER_RUNTIME_DIR`: ランタイムディレクトリ（デフォルト: `/var/run/plasmavmc/firecracker`）
- `PLASMAVMC_FIRECRACKER_KERNEL_PATH`: カーネルイメージのパス（必須）
- `PLASMAVMC_FIRECRACKER_ROOTFS_PATH`: Rootfsイメージのパス（必須）
- `PLASMAVMC_FIRECRACKER_INITRD_PATH`: Initrdのパス（オプション）

## VmSpecからFireCracker設定へのマッピング

### Machine Config
- `vm.spec.cpu.vcpus` → `vcpu_count`
- `vm.spec.memory.size_mib` → `mem_size_mib`
- `ht_enabled`: 常に`false`（FireCrackerはHTをサポートしない）

### Boot Source
- `vm.spec.boot.kernel` → `kernel_image_path`（環境変数から解決）
- `vm.spec.boot.initrd` → `initrd_path`（環境変数から解決）
- `vm.spec.boot.cmdline` → `boot_args`（デフォルト: `"console=ttyS0"`）

### Drives
- `vm.spec.disks[0]` → rootfs drive（`is_root_device: true`）
- 追加のディスクは`is_root_device: false`で設定

### Network Interfaces
- `vm.spec.network` → 各NICを`/network-interfaces/{iface_id}`で設定
- MACアドレスは自動生成または`vm.spec.network[].mac_address`から取得
- TAPインターフェースは外部で作成する必要がある（将来的に統合）

## 制限事項とサポート状況

### FireCrackerの制限
- **Hot-plug**: サポートされない（起動前の設定のみ）
- **VNC Console**: サポートされない（シリアルコンソールのみ）
- **Nested Virtualization**: サポートされない
- **GPU Passthrough**: サポートされない
- **Live Migration**: サポートされない
- **最大vCPU**: 32（FireCrackerの制限）
- **最大メモリ**: 制限なし（実用的には数GiBまで）
- **Disk Bus**: Virtioのみ
- **NIC Model**: VirtioNetのみ

### BackendCapabilities

```rust
BackendCapabilities {
    live_migration: false,
    hot_plug_cpu: false,
    hot_plug_memory: false,
    hot_plug_disk: false,
    hot_plug_nic: false,
    vnc_console: false,
    serial_console: true,
    nested_virtualization: false,
    gpu_passthrough: false,
    max_vcpus: 32,
    max_memory_gib: 1024, // 実用的な上限
    supported_disk_buses: vec![DiskBus::Virtio],
    supported_nic_models: vec![NicModel::VirtioNet],
}
```

## 実装アプローチ

### 1. FireCrackerClient（REST API over Unix socket）

QMPクライアントと同様に、FireCracker用のREST APIクライアントを実装：
- Unix socket経由でHTTPリクエストを送信
- `hyper`または`ureq`などのHTTPクライアントを使用
- または、Unix socketに対して直接HTTPリクエストを構築

### 2. VM作成フロー

1. `create()`: 
   - ランタイムディレクトリを作成
   - FireCrackerプロセスを起動（jailerまたは直接）
   - API socketが利用可能になるまで待機
   - `/machine-config`、`/boot-source`、`/drives`、`/network-interfaces`を設定
   - `VmHandle`を返す（socketパスとPIDを保存）

2. `start()`:
   - `/actions`エンドポイントに`InstanceStart`を送信

3. `stop()`:
   - `/actions`エンドポイントに`SendCtrlAltDel`を送信（ACPI対応が必要）
   - または、プロセスをkill

4. `kill()`:
   - FireCrackerプロセスをkill

5. `status()`:
   - `/vm`エンドポイントから状態を取得
   - FireCrackerの状態を`VmState`にマッピング

6. `delete()`:
   - VMを停止
   - ランタイムディレクトリをクリーンアップ

### 3. エラーハンドリング

- FireCrackerプロセスの起動失敗
- API socketへの接続失敗
- 設定APIのエラーレスポンス
- VM起動失敗

## 依存関係

### 必須
- `firecracker`バイナリ（v1.x以上）
- カーネルイメージ（vmlinux形式、x86_64）
- Rootfsイメージ（ext4形式）

### オプション
- `jailer`バイナリ（セキュリティ強化のため推奨）

### Rust依存関係
- `plasmavmc-types`: VM型定義
- `plasmavmc-hypervisor`: HypervisorBackendトレイト
- `tokio`: 非同期ランタイム
- `async-trait`: 非同期トレイト
- `tracing`: ロギング
- `serde`, `serde_json`: シリアライゼーション
- `hyper`または`ureq`: HTTPクライアント（Unix socket対応）

## テスト戦略

### ユニットテスト
- FireCrackerClientのモック実装
- VmSpecからFireCracker設定へのマッピングテスト
- エラーハンドリングテスト

### 統合テスト（環境ゲート付き）
- `PLASMAVMC_FIRECRACKER_TEST=1`で有効化
- 実際のFireCrackerバイナリとカーネル/rootfsが必要
- VMのライフサイクル（create → start → status → stop → delete）を検証

## 次のステップ（S2）

1. `plasmavmc-firecracker`クレートを作成
2. `FireCrackerClient`を実装（REST API over Unix socket）
3. `FireCrackerBackend`を実装（HypervisorBackendトレイト）
4. ユニットテストを追加
5. 環境変数による設定を実装
