# Cloud Hypervisor VM Management

A Rust module for managing virtual machines using [Cloud Hypervisor](https://github.com/cloud-hypervisor/cloud-hypervisor).

## Overview

This module provides a high-level API for creating, starting, stopping, and managing VMs using the Cloud Hypervisor static binaries (`cloud-hypervisor-static` and `ch-remote-static`).

## Prerequisites

- `cloud-hypervisor-static` binary on PATH
- `ch-remote-static` binary on PATH
- `qemu-img` (optional, for qcow2 to raw conversion)

## Module Structure

```
cloudhv/
├── mod.rs        # Module re-exports and documentation
├── error.rs      # CloudHvError type definitions
├── types.rs      # VmSpec, VmRuntime, VmRecord structs
├── paths.rs      # Path utilities for VM data storage
├── utils.rs      # Shell helpers and utility functions
├── operations.rs # VM lifecycle operations
└── README.md     # This file
```

## Types

### VmSpec

VM configuration specification:

| Field | Type | Description |
|-------|------|-------------|
| `id` | `String` | Unique VM identifier |
| `kernel_path` | `Option<String>` | Path to kernel for direct boot |
| `firmware_path` | `Option<String>` | Path to firmware (e.g., UEFI) |
| `disk_path` | `String` | Path to disk image (qcow2 or raw) |
| `api_socket` | `String` | API socket path for management |
| `vcpus` | `u32` | Number of virtual CPUs |
| `memory_mb` | `u32` | Memory size in MB |
| `cmdline` | `Option<String>` | Kernel command line |
| `extra_args` | `Option<Vec<String>>` | Extra cloud-hypervisor arguments |

### VmRuntime

Runtime state of a VM:

| Field | Type | Description |
|-------|------|-------------|
| `pid` | `Option<i64>` | Process ID if running |
| `status` | `String` | "running" or "stopped" |
| `log_file` | `String` | Path to console log |

### VmRecord

Complete VM record containing `spec` and `runtime`.

## API

### vm_create

Creates and persists a VM specification.

```rust
use herolib_virt::cloudhv::{VmSpec, vm_create};

let spec = VmSpec {
    id: "my-vm".into(),
    kernel_path: Some("/path/to/vmlinux".into()),
    firmware_path: None,
    disk_path: "/path/to/disk.raw".into(),
    api_socket: "".into(),
    vcpus: 2,
    memory_mb: 1024,
    cmdline: None,
    extra_args: None,
};

let id = vm_create(&spec)?;
```

### vm_start

Starts a previously created VM.

```rust
use herolib_virt::cloudhv::vm_start;

vm_start("my-vm")?;
```

### vm_stop

Stops a running VM. Set `force` to `true` for SIGKILL.

```rust
use herolib_virt::cloudhv::vm_stop;

// Graceful shutdown
vm_stop("my-vm", false)?;

// Force kill
vm_stop("my-vm", true)?;
```

### vm_info

Gets VM information (spec + runtime state).

```rust
use herolib_virt::cloudhv::vm_info;

let record = vm_info("my-vm")?;
println!("Status: {}", record.runtime.status);
```

### vm_list

Lists all VMs.

```rust
use herolib_virt::cloudhv::vm_list;

let vms = vm_list()?;
for vm in vms {
    println!("{}: {}", vm.spec.id, vm.runtime.status);
}
```

### vm_delete

Deletes a VM. Optionally deletes disk images.

```rust
use herolib_virt::cloudhv::vm_delete;

// Keep disk
vm_delete("my-vm", false)?;

// Delete disk too
vm_delete("my-vm", true)?;
```

## Data Storage

VM data is stored in `$HOME/hero/virt/vms/<vm-id>/`:

```
~/hero/virt/vms/my-vm/
├── vm.json       # VM specification and runtime state
├── api.sock      # API socket for ch-remote
├── pid           # Process ID file
├── disk.raw      # Converted disk (if source was qcow2)
└── logs/
    └── console.log
```

## Boot Methods

The module supports two boot methods:

1. **Direct kernel boot**: Set `kernel_path` to a vmlinux binary
2. **Firmware boot**: Set `firmware_path` to UEFI firmware

At least one of these must be provided.

## Error Handling

All operations return `Result<T, CloudHvError>`:

```rust
pub enum CloudHvError {
    CommandFailed(String),
    IoError(String),
    JsonError(String),
    DependencyMissing(String),
    InvalidSpec(String),
    NotFound(String),
}
```

## License

See repository root for license information.
