Skip to content

Getting Started

This guide walks you through setting up Capsa and running your first virtual machine.

Prerequisites

Rust

Capsa requires Rust 1.70 or later (edition 2021). Install or update Rust via rustup:

bash
rustup update stable

Platform Requirements

Linux

  • KVM support: Your CPU must support hardware virtualization (Intel VT-x or AMD-V)
  • Access to /dev/kvm: Your user must have permission to access the KVM device

Check KVM availability:

bash
# Verify KVM is available
ls -la /dev/kvm

# Add your user to the kvm group if needed
sudo usermod -aG kvm $USER

TIP

After adding yourself to the kvm group, log out and back in for the change to take effect.

macOS

  • macOS 11 (Big Sur) or later: Virtualization.framework requires Big Sur or newer
  • Apple Silicon or Intel: Both architectures are supported
  • Entitlements: Your application must be signed with the com.apple.security.virtualization entitlement

Code Signing Required

The Virtualization.framework entitlement is required even for development. See the macOS platform guide for details on code signing.

Installation

Not Yet Published

Capsa is not yet available on crates.io. For now, add it as a git dependency:

toml
[dependencies]
capsa = { git = "https://github.com/luizribeiro/capsa", features = ["linux-kvm"] }
# or for macOS
capsa = { git = "https://github.com/luizribeiro/capsa", features = ["macos-subprocess"] }

tokio = { version = "1", features = ["rt-multi-thread", "macros"] }

Feature Flags

FeatureDescription
linux-kvmLinux KVM backend
macos-subprocessmacOS Virtualization.framework backend

For cross-platform projects, enable features conditionally:

toml
[target.'cfg(target_os = "linux")'.dependencies]
capsa = { git = "https://github.com/luizribeiro/capsa", features = ["linux-kvm"] }

[target.'cfg(target_os = "macos")'.dependencies]
capsa = { git = "https://github.com/luizribeiro/capsa", features = ["macos-subprocess"] }

Getting a Kernel and Initrd

Capsa boots VMs using Linux direct boot, which requires a kernel and initrd. You have several options:

Option 1: Extract from a Linux Distribution

Most Linux distributions include a kernel and initrd you can use:

bash
# On Debian/Ubuntu
cp /boot/vmlinuz-$(uname -r) ./kernel
cp /boot/initrd.img-$(uname -r) ./initrd

Option 2: Use Alpine Linux

Alpine provides minimal root filesystems:

bash
# Download Alpine mini root filesystem
curl -LO https://dl-cdn.alpinelinux.org/alpine/v3.19/releases/x86_64/alpine-minirootfs-3.19.0-x86_64.tar.gz

# You'll need to create an initrd from this (see Alpine documentation)

Option 3: Build Custom (Advanced)

For production use, you'll likely want a custom minimal kernel and initrd. See the Development Guide for how Capsa's test VMs are built.

Quick Start

Here is a complete example that creates a VM, boots it, runs a command, and shuts it down:

rust
use capsa::{Capsa, LinuxDirectBootConfig};
use std::time::Duration;

#[tokio::main]
async fn main() -> capsa::Result<()> {
    // Configure Linux direct boot with kernel and initrd
    let config = LinuxDirectBootConfig::new("./kernel", "./initrd");

    // Build and start the VM
    let vm = Capsa::vm(config)
        .cpus(2)
        .memory_mb(1024)
        .console_enabled()
        .build()
        .await?;

    // Get the console interface
    let console = vm.console().await?;

    // Wait for shell prompt (adjust based on your initrd)
    console.wait_for_timeout("# ", Duration::from_secs(60)).await?;

    // Run a command
    let output = console.exec("uname -a", Duration::from_secs(5)).await?;
    println!("Kernel info: {}", output);

    // Gracefully shut down the VM
    vm.stop().await?;

    Ok(())
}

Builder API Overview

The VmBuilder provides a fluent API for configuring VMs:

rust
use capsa::{Capsa, LinuxDirectBootConfig, MountMode, NetworkMode};

let config = LinuxDirectBootConfig::new("./kernel", "./initrd");

let vm = Capsa::vm(config)
    // Resources
    .cpus(4)                              // Number of virtual CPUs
    .memory_mb(2048)                      // Memory in megabytes

    // Console
    .console_enabled()                    // Enable serial console access

    // Networking
    .network(NetworkMode::user_nat().build())  // NAT networking

    // Shared directories (Linux only currently)
    .share("/host/path", "tag", MountMode::ReadOnly)

    // Host-guest communication
    .vsock_listen(1024)                   // Host listens on port 1024

    .build()
    .await?;

Command-Line Interface

Work in Progress

The capsa CLI is under active development. For now, use the Rust library directly.

Checking Platform Support

Query available backends at runtime:

rust
use capsa::capabilities::available_backends;

fn main() {
    let backends = available_backends();

    if backends.is_empty() {
        eprintln!("No hypervisor backends available");
        return;
    }

    for backend in &backends {
        println!("Backend: {}", backend.name());
        println!("  Available: {}", backend.is_available());

        let caps = backend.capabilities();
        println!("  Linux direct boot: {}", caps.boot_methods.linux_direct);
        println!("  UEFI boot: {}", caps.boot_methods.uefi);
        println!("  virtio-fs: {}", caps.share_mechanisms.virtio_fs);
    }
}

Next Steps

Released under the MIT License.