Skip to content

macOS (Virtualization.framework)

Capsa's macOS backend uses Apple's Virtualization.framework, available on macOS 11 (Big Sur) and later.

Requirements

System

  • macOS 11.0 (Big Sur) or later
  • Apple Silicon (M1/M2/M3) or Intel Mac with Hypervisor.framework support

Code Signing

Virtualization.framework requires your application to be signed with the com.apple.security.virtualization entitlement.

For distribution, add this entitlement to your app:

xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
  "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>com.apple.security.virtualization</key>
    <true/>
</dict>
</plist>

Development

For development, see the Development Guide which covers how to use the codesign-run tool for automatic signing during development.

Cargo Configuration

toml
[dependencies]
capsa = { version = "0.1", features = ["macos-subprocess"] }
tokio = { version = "1", features = ["full"] }

Supported Features

FeatureStatusNotes
Linux Direct BootSupportedkernel + initrd
UEFI BootSupportedVia EFI firmware
virtio-fs SharesNot YetPlanned for future release
NAT NetworkingSupportedPlatform-native NAT
UserNat NetworkingSupportedUserspace NAT with policies
Cluster NetworkingSupportedMulti-VM communication
VM Sockets (vsock)SupportedHost-guest communication
VM PoolsSupportedPre-warmed VMs
Sandbox ModeSupportedWith guest agent

Shared Directories

virtio-fs shared directories are not yet implemented on macOS. This is planned for a future release.

Boot Configuration

Linux Direct Boot

rust
use capsa::{Capsa, LinuxDirectBootConfig};

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

let vm = Capsa::vm(config)
    .cpus(2)
    .memory_mb(1024)
    .console_enabled()
    .build()
    .await?;

UEFI Boot

macOS supports UEFI boot with disk images:

rust
use capsa::{Capsa, UefiBootConfig, DiskImage};

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

let vm = Capsa::vm(config)
    .cpus(2)
    .memory_mb(2048)
    .console_enabled()
    .build()
    .await?;

INFO

UEFI boot is slower than direct boot but supports more operating systems.

Networking

Platform NAT

The simplest option using macOS's built-in NAT:

rust
use capsa::NetworkMode;

let vm = Capsa::vm(config)
    .network(NetworkMode::Nat)
    .build()
    .await?;

For network policies and port forwarding:

rust
use capsa::{NetworkMode, NetworkPolicy};

let policy = NetworkPolicy::deny_all()
    .allow_dns()
    .allow_https();

let vm = Capsa::vm(config)
    .network(NetworkMode::user_nat()
        .policy(policy)
        .forward_tcp(8080, 80)
        .build())
    .build()
    .await?;

Troubleshooting

Entitlement Errors

Error: The operation couldn't be completed. (Virtualization error -1)

Solution: Your binary needs to be signed with the virtualization entitlement. For development, use the devenv which provides automatic signing.

Slow First Start

First VM launch may be slower as macOS initializes Virtualization.framework. Subsequent launches are faster.

Limitations

  1. Single vsock Connection: Each vsock port currently supports only one connection
  2. No virtio-fs: Shared directories not yet implemented
  3. Linux Guests Only: macOS guests cannot be run via Virtualization.framework directly

Example

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

#[tokio::main]
async fn main() -> capsa::Result<()> {
    let config = LinuxDirectBootConfig::new("kernel", "initrd");

    let vm = Capsa::vm(config)
        .cpus(4)
        .memory_mb(2048)
        .console_enabled()
        .network(NetworkMode::user_nat().build())
        .vsock_listen(1024)
        .build()
        .await?;

    let console = vm.console().await?;
    console.wait_for_timeout("# ", Duration::from_secs(30)).await?;

    // Your workload here...
    let output = console.exec("uname -a", Duration::from_secs(5)).await?;
    println!("{}", output);

    vm.stop().await?;
    Ok(())
}

Performance

MetricApple SiliconIntel Mac
Boot Time~2-3 seconds~3-5 seconds
Memory OverheadLowModerate
CPU OverheadVery LowLow

Apple Silicon Macs generally provide better virtualization performance due to hardware optimizations.

Released under the MIT License.