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"));| Field | Type | Description |
|---|---|---|
kernel | PathBuf | Path to Linux kernel (bzImage format) |
initrd | PathBuf | Path to initial ramdisk |
root_disk | Option<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");| Field | Type | Description |
|---|---|---|
disk | DiskImage | Boot disk image |
efi_variable_store | Option<PathBuf> | EFI variables path |
create_variable_store | bool | Create 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 accessNetworking
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 ruleMatch 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 criteriaDisk 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();| Format | Extension | Linux KVM | macOS |
|---|---|---|---|
| Raw | .img, .raw | Supported | Supported |
| QCOW2 | .qcow2 | Supported | Not 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)| Field | Type | Description |
|---|---|---|
port | u32 | vsock port number |
socket_path | PathBuf | Unix socket path on host |
connect | bool | true = host connects, false = host listens |
auto_cleanup | bool | Delete 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 GuestOsConsole 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 AsyncWritePool 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?;