Skip to content

Configuration Reference

This page documents all configuration options available in Capsa.

Boot Configurations

LinuxDirectBootConfig

Boot a VM directly with a Linux kernel and initrd (fastest method).

rust
use capsa::LinuxDirectBootConfig;

let config = LinuxDirectBootConfig::new(kernel_path, initrd_path);

// Optionally with root disk
let config = LinuxDirectBootConfig::new(kernel, initrd)
    .with_root_disk(DiskImage::new("disk.img"));
FieldTypeDescription
kernelPathBufPath to Linux kernel (bzImage format)
initrdPathBufPath to initial ramdisk
root_diskOption<DiskImage>Optional root disk

UefiBootConfig

Boot via UEFI firmware (macOS only currently).

rust
use capsa::{UefiBootConfig, DiskImage};

let disk = DiskImage::new("disk.img");
let config = UefiBootConfig::new(disk);

// With EFI variable store
let config = UefiBootConfig::new(disk)
    .with_efi_variable_store("efi_vars.bin");
FieldTypeDescription
diskDiskImageBoot disk image
efi_variable_storeOption<PathBuf>EFI variables path
create_variable_storeboolCreate if missing

VM Builder Methods

Resource Configuration

rust
let vm = Capsa::vm(config)
    .cpus(4)              // Number of vCPUs (default: 1)
    .memory_mb(2048)      // Memory in MB (default: 512)
    .timeout(Duration::from_secs(60))  // Operation timeout
    .build()
    .await?;

Console

rust
.console_enabled()  // Enable serial console access

Networking

rust
use capsa::NetworkMode;

// No networking
.network(NetworkMode::None)

// Platform-native NAT (macOS)
.network(NetworkMode::Nat)

// Userspace NAT with configuration
.network(NetworkMode::UserNat(UserNatConfig::default()))

// Userspace NAT with builder
.network(NetworkMode::user_nat()
    .subnet("192.168.100.0/24")
    .forward_tcp(8080, 80)
    .forward_udp(5353, 53)
    .policy(policy)
    .build())

// Cluster networking
.network(NetworkMode::cluster("my-cluster").build())

Shared Directories

rust
use capsa::MountMode;

// Basic share
.share("/host/path", "tag", MountMode::ReadOnly)
.share("/host/path", "tag", MountMode::ReadWrite)

// Multiple shares
.share("./src", "src", MountMode::ReadOnly)
.share("./out", "out", MountMode::ReadWrite)

VM Sockets (vsock)

rust
// Host listens, guest connects
.vsock_listen(1024)
.vsock_listen_at(1024, "/tmp/custom.sock")

// Host connects, guest listens
.vsock_connect(2049)
.vsock_connect_at(2049, "/tmp/custom.sock")

Disks

rust
use capsa::{DiskImage, ImageFormat};

// Add disk (becomes /dev/vdb, vdc, etc.)
.disk(DiskImage::new("data.img"))

// Read-only disk
.disk(DiskImage::new("data.img").read_only())

// Explicit format
.disk(DiskImage::with_format("data.qcow2", ImageFormat::Qcow2))

Kernel Command Line (Linux only)

rust
// Add arguments
.cmdline_arg("root", "/dev/vda")
.cmdline_arg("init", "/sbin/init")

// Add flags
.cmdline_flag("quiet")
.cmdline_flag("nosmp")

// Override entire command line
.cmdline_override("console=hvc0 root=/dev/vda")

Network Configuration

UserNatConfig

rust
use capsa::{UserNatConfig, NetworkPolicy, Protocol, PortForward};

let config = UserNatConfig {
    subnet: "10.0.2.0/24".to_string(),
    gateway: Ipv4Addr::new(10, 0, 2, 2),
    dhcp_start: Ipv4Addr::new(10, 0, 2, 15),
    dhcp_end: Ipv4Addr::new(10, 0, 2, 254),
    port_forwards: vec![
        PortForward {
            protocol: Protocol::Tcp,
            host_port: 8080,
            guest_port: 80,
        }
    ],
    policy: Some(NetworkPolicy::deny_all().allow_https()),
};

NetworkPolicy

rust
use capsa::{NetworkPolicy, PolicyAction, MatchCriteria, DomainPattern};

// Start with default action
let policy = NetworkPolicy::deny_all();  // or allow_all()

// Add rules (first match wins)
let policy = policy
    .allow_dns()                           // UDP port 53
    .allow_https()                         // TCP port 443
    .allow_port(80)                        // Any protocol, port 80
    .allow_ip(Ipv4Addr::new(8, 8, 8, 8))  // Specific IP
    .allow_ip_range("10.0.0.0", 8)         // IP range (CIDR)
    .allow_domain("api.example.com")       // Exact domain
    .allow_domain("*.github.com")          // Wildcard subdomain
    .deny_domain("*.evil.com")
    .rule(PolicyAction::Log, MatchCriteria::Any);  // Custom rule

Match Criteria

rust
use capsa::MatchCriteria;

MatchCriteria::Any                          // Match all traffic
MatchCriteria::Ip(ip)                       // Single IP
MatchCriteria::IpRange { network, prefix }  // CIDR range
MatchCriteria::Port(443)                    // Single port
MatchCriteria::PortRange { start, end }     // Port range
MatchCriteria::Protocol(Protocol::Tcp)      // TCP or UDP
MatchCriteria::Domain(DomainPattern::Exact("api.com".into()))
MatchCriteria::Domain(DomainPattern::Wildcard("*.github.com".into()))
MatchCriteria::All(vec![...])               // AND multiple criteria

Disk Configuration

DiskImage

rust
use capsa::{DiskImage, ImageFormat};

// Auto-detect format from extension
let disk = DiskImage::new("disk.img");      // Raw
let disk = DiskImage::new("disk.qcow2");    // QCOW2

// Explicit format
let disk = DiskImage::with_format(path, ImageFormat::Raw);

// Read-only
let disk = DiskImage::new("disk.img").read_only();
FormatExtensionLinux KVMmacOS
Raw.img, .rawSupportedSupported
QCOW2.qcow2SupportedNot Supported

Vsock Configuration

VsockPortConfig

rust
use capsa::VsockPortConfig;

// Listen mode (guest connects to host)
VsockPortConfig::listen(port, socket_path)
VsockPortConfig::listen_auto(port)  // Auto-generated path

// Connect mode (host connects to guest)
VsockPortConfig::connect(port, socket_path)
FieldTypeDescription
portu32vsock port number
socket_pathPathBufUnix socket path on host
connectbooltrue = host connects, false = host listens
auto_cleanupboolDelete socket on VM stop

VM Handle Methods

Lifecycle

rust
vm.start().await?;                    // Start VM (if not running)
vm.stop().await?;                     // Graceful shutdown (30s timeout)
vm.stop_with_timeout(Duration::from_secs(10)).await?;
vm.kill().await?;                     // Force terminate
vm.wait().await?;                     // Wait for exit
vm.wait_timeout(Duration::from_secs(60)).await?;

Status

rust
let status = vm.status();
match status {
    VmStatus::Created => {},
    VmStatus::Starting => {},
    VmStatus::Running => {},
    VmStatus::Stopping => {},
    VmStatus::Stopped { exit_code } => {},
    VmStatus::Failed { message } => {},
}

Access

rust
let console = vm.console().await?;    // Get console (requires console_enabled)
let socket = vm.vsock_socket(1024);   // Get vsock by port
let sockets = vm.vsock_sockets();     // Get all vsocks
let resources = vm.resources();       // Get ResourceConfig
let os = vm.guest_os();               // Get GuestOs

Console Methods

Reading

rust
console.wait_for("pattern").await?;
console.wait_for_timeout("pattern", Duration::from_secs(10)).await?;
console.wait_for_any(&["# ", "$ ", "> "]).await?;
console.read_available().await?;

Writing

rust
console.write(b"raw bytes").await?;
console.write_str("string").await?;
console.write_line("with newline").await?;

Execution

rust
let output = console.exec("command", Duration::from_secs(5)).await?;
let output = console.run_command("command", "# ").await?;

Control

rust
console.send_interrupt().await?;  // Ctrl+C
console.send_eof().await?;        // Ctrl+D
console.login("root", None).await?;
console.login("user", Some("password")).await?;

Splitting

rust
let (reader, writer) = console.split().await?;
// reader: impl AsyncRead
// writer: impl AsyncWrite

Pool Configuration

rust
let pool = Capsa::pool(config)
    .cpus(2)
    .memory_mb(512)
    .console_enabled()
    .build(4)  // Create 4 pre-warmed VMs
    .await?;

let vm = pool.reserve().await?;       // Wait for available
let vm = pool.try_reserve()?;         // Non-blocking
let count = pool.available_count().await;

Sandbox Configuration

rust
let vm = Capsa::sandbox()
    .cpus(2)
    .memory_mb(512)
    .share("./workspace", "/mnt/ws", MountMode::ReadWrite)
    .network(NetworkMode::UserNat(Default::default()))
    .run("/bin/sh", &["-c", "sleep infinity"])  // Required
    // OR .oci("python:3.11", &["python", "script.py"])
    .build()
    .await?;

Agent Client

rust
use capsa::sandbox;

let socket = vm.vsock_socket(sandbox::agent_port()).unwrap();
let agent = sandbox::wait_ready(&socket).await?;

agent.ping().await?;
let result = agent.exec("ls -la", HashMap::new()).await?;
let data = agent.read_file("/path").await?;
agent.write_file("/path", b"content").await?;
let exists = agent.exists("/path").await?;
let entries = agent.list_dir("/path").await?;
let info = agent.info().await?;
agent.shutdown().await?;

Released under the MIT License.