mvmctl docs

API Reference

Every CLI command maps 1:1 to a static method on an *Operation class in mvmctl.api.*. Import the API directly to build automation scripts, GUIs, or TUIs without going through the CLI.

Overview

Every CLI command maps 1:1 to a static method on an *Operation class in mvmctl.api.*. The CLI is a thin presentation layer — it handles argument parsing, output formatting, and exit codes, then calls the same functions documented here.

You can import the API directly to build automation scripts, GUIs, or TUIs without going through the CLI. All system interactions (KVM, iptables, bridge devices) happen lazily — importing the package has no side effects.

Installation

Terminal

# From source
git clone https://github.com/AlanD20/mvmctl
cd mvmctl
uv sync

Import Pattern

All public types are re-exported from mvmctl.api. Deep imports from sub-modules are not part of the public API.

Correct import

Terminal

from mvmctl.api import VMOperation, VMCreateInput

VMOperation.create(VMCreateInput(name="my-vm", ssh_keys=["my-key"], ...))

Avoid deep imports

Terminal

from mvmctl.api.vm_operations import VMOperation  # ❌ WRONG — use mvmctl.api instead

Module Overview

Operation Class Responsibility
VMOperation VM lifecycle: create, remove, list_all, get, start, stop, pause, resume, reboot, snapshot, load_snapshot, inspect, export, import_, prune, attach_volume, detach_volume
NetworkOperation Network management: create, remove, list_all, get, set_default, inspect, sync, create_default_network, prune
ImageOperation Image operations: pull, import_, remove, list_all, get, set_default, inspect, warm, find_existing_image, prune
KernelOperation Kernel operations: pull, list_all, get, set_default, remove, inspect, prune
KeyOperation SSH key registry: add, create, list_all, get, inspect, remove, set_default, get_defaults, clear_defaults, export
BinaryOperation Binary management: pull, list_all, get, set_default, remove, remove_by_version, ensure_default, prune
HostOperation Host init/clean/reset, privilege checks, KVM access, binary checks, state, get_running_vms, get_ip_forward_status, check_kvm_access, check_required_binaries, get_state
CacheOperation Cache lifecycle: init_all, prune_vms, prune_networks, prune_images, prune_kernels, prune_binaries, prune_misc, prune_all, clean
ConsoleOperation Console access: get_connection_info, get_state, kill
LogOperation Log streaming: stream (boot/OS logs following)
VolumeOperation Volume management: create, remove, list_all, get, inspect, resize
ConfigOperation Config management: get, set, reset, list_all
CPOperation File copy operations between host and microVMs (tar-over-SSH)
SSHOperation SSH connection (interactive or command execution)
InitOperation Onboarding wizard API: run, init_database, setup_host

Data Models

VM Models VMStatus

All data models are in mvmctl.models.*. Models are pure dataclasses with no business logic. Every domain record uses the *Item suffix.

Field Type Description
STARTING "starting" VM is starting up
RUNNING "running" VM is running
PAUSED "paused" VM is paused
STOPPING "stopping" VM is shutting down
STOPPED "stopped" VM is stopped
CRASHED "crashed" VM has crashed
ERROR "error" VM is in error state

VMInstanceItem VMInstanceItem

Field Type Description
id str VM ID (hash)
name str VM name; used as hostname inside guest
status str Current lifecycle state
pid int Firecracker process PID
ipv4 str Assigned guest IP address
mac str Assigned guest MAC address
network_id str Network ID this VM is attached to
tap_device str Host TAP interface name
image_id str Image ID
kernel_id str Kernel ID
binary_id str Firecracker/jailer binary ID
api_socket_path str Path to Firecracker API Unix socket
config_path str Path to Firecracker JSON config
cloud_init_mode str Cloud-init mode used
vcpu_count int Number of vCPUs
mem_size_mib int Memory in MiB
disk_size_mib int Rootfs disk size in MiB
rootfs_path str Path to rootfs image
rootfs_suffix str Rootfs file suffix (e.g. .ext4)
pci_enabled bool Whether PCI support is enabled
nested_virt bool Nested virtualization enabled
enable_logging bool Whether Firecracker logging is enabled
enable_metrics bool Whether Firecracker metrics are enabled
enable_console bool Whether serial console is enabled
created_at str ISO 8601 creation timestamp
updated_at str ISO 8601 update timestamp
exit_code int | None Firecracker process exit code
log_path str | None Path to Firecracker log file
serial_output_path str | None Path to serial console log
nocloud_net_port int | None Port for nocloud-net HTTP server
nocloud_net_pid int | None PID of nocloud-net server
relay_pid int | None PID of console relay process
relay_socket_path str | None Path to console relay Unix socket
process_start_time int | None Firecracker process start timestamp (epoch ms)
lsm_flags str | None Linux Security Module flags
boot_args str | None Custom kernel boot arguments
ssh_keys list[str] SSH key names injected into the VM
ssh_user str | None Default SSH user for the VM
volume_ids list[str] | None Attached volume IDs
cpu_config CpuConfig | None CPU template configuration (merged CPU config)

Resolved relations (populated on request):

Field Type Description
kernel KernelItem | None Resolved kernel record
image ImageItem | None Resolved image record
binary BinaryItem | None Resolved binary record
network NetworkItem | None Resolved network record
volumes list[VolumeItem] Resolved volume records

NetworkItem NetworkItem

Field Type Description
id str Network ID (hash)
name str Network name
subnet str IP subnet in CIDR notation
bridge str Linux bridge device name
ipv4_gateway str Host-side gateway IP
bridge_active bool Whether bridge device exists
nat_enabled bool Whether NAT rules are active
is_default bool Whether this is the default network
is_present bool Whether the network is present on the host
created_at str ISO 8601 creation timestamp
updated_at str ISO 8601 last update timestamp
deleted_at str | None ISO 8601 soft-delete timestamp
nat_gateways str | None Comma-separated physical NAT interfaces
leases list[NetworkLeaseItem] | None IP leases associated with this network
iptables_rules list[FirewallRule] | None Firewall rules associated with this network
vms list[VMInstanceItem] | None VMs attached to this network for relation enrichment

ImageItem ImageItem

Field Type Description
id str Image ID (SHA256 hash)
type str Image type identifier (e.g. ubuntu, alpine, debian)
version str Image version string (e.g. 24.04)
name str Human-readable image name
arch str Architecture (e.g. x86_64, arm64)
path str Relative path to image file
fs_type str Filesystem type (e.g. ext4, btrfs)
minimum_rootfs_size_mib int Minimum rootfs size in MiB
original_size int Original uncompressed size in bytes
is_default bool Whether this is the default image
is_present bool Whether the file exists on disk
pulled_at str ISO 8601 download timestamp
created_at str ISO 8601 creation timestamp
updated_at str ISO 8601 last update timestamp
distro str | None Detected Linux distribution (e.g. ubuntu)
fs_uuid str | None Filesystem UUID
compressed_size int | None Compressed size in bytes
compression_ratio float | None Compression ratio
compressed_format str | None Compression format (e.g. zst)
deleted_at str | None ISO 8601 soft-delete timestamp
vms list[VMInstanceItem] | None VMs referencing this image for relation enrichment

KernelItem KernelItem

Field Type Description
id str Kernel ID (SHA256 hash)
name str Full filename display name
base_name str Base kernel name (e.g. vmlinux-firecracker)
version str Kernel version string
arch str Architecture (x86_64, arm64)
type str Kernel type: firecracker or official
path str Relative path to kernel file
is_default bool Whether this is the default kernel
is_present bool Whether the file exists on disk
created_at str ISO 8601 creation timestamp
updated_at str ISO 8601 last update timestamp
deleted_at str | None ISO 8601 soft-delete timestamp
vms list[VMInstanceItem] | None VMs using this kernel for relation enrichment

KernelPullResult KernelPullResult

Unified result from kernel pull/build operations. Provides a consistent return type for both Firecracker download and official kernel build paths.

Field Type Description
path Path Path to the built/fetched vmlinux
version str Kernel version string
arch str Architecture
kernel_type str Kernel type: firecracker or official
warnings list[str] Build warnings
info_messages list[str] Informational messages

BinaryItem BinaryItem

Field Type Description
id str Binary ID (SHA256 hash)
name str Binary name: firecracker or jailer
version str Semantic version string
full_version str Full version string with metadata
ci_version str | None Firecracker CI version tag
path str Relative path to binary file
is_default bool Whether this is the active default binary
is_present bool Whether the file exists on disk
created_at str ISO 8601 creation timestamp
updated_at str ISO 8601 last update timestamp
deleted_at str | None ISO 8601 soft-delete timestamp
vms list[VMInstanceItem] | None VMs using this binary for relation enrichment

VolumeItem VolumeItem

A persistent data disk attachable to VMs. Each volume has a name, size, format, and an attached status.

Field Type Description
id str Volume ID (SHA256 hash of name + timestamp)
name str Volume name (used in --volume flag)
size_bytes int Volume size in bytes
format str Disk format: raw or qcow2
path str Relative path to volume disk file
status VolumeStatus Current status: AVAILABLE or ATTACHED
vm_id str | None VM ID this volume is attached to, if any
created_at str ISO 8601 creation timestamp
updated_at str ISO 8601 last update timestamp
is_read_only bool Whether the volume is mounted read-only

SSHKeyItem SSHKeyItem

Field Type Description
id str Key ID (SHA256 hash)
name str Key name (used in --ssh-key)
fingerprint str SHA256 fingerprint
algorithm str Key algorithm (ed25519, rsa, ecdsa)
comment str SSH key comment
public_key_path str Path to .pub file
is_default bool Whether this is a default key
is_present bool Whether the key file exists on disk
created_at str ISO 8601 creation timestamp
updated_at str ISO 8601 last update timestamp
private_key_path str | None Path to private key file

NetworkLeaseItem NetworkLeaseItem

Field Type Description
id int | None Lease ID
network_id str Network ID this lease belongs to
ipv4 str Leased IPv4 address
vm_id str | None VM ID this lease is assigned to
leased_at str ISO 8601 lease timestamp
expires_at str | None ISO 8601 lease expiry timestamp

FirewallRule FirewallRule

Field Type Description
id int | None Rule ID
table_name FirewallTable Firewall table (filter, nat, mangle, raw, security)
chain_name FirewallChain Firewall chain name
rule_type FirewallRuleType Rule type: masquerade, forward_in, forward_out, nocloudnet_input
protocol FirewallProtocol Protocol: tcp, udp, icmp, all
source str Source CIDR or IP
destination str Destination CIDR or IP
in_interface str Input interface
out_interface str Output interface
target FirewallTarget Firewall target: ACCEPT, DROP, MASQUERADE, etc.
sport int Source port
dport int Destination port
network_id str Network ID this rule belongs to
is_active bool Whether the rule is currently active
network_name str | None Network name
command_string str | None Full iptables command string
comment_tag str | None iptables comment tag
created_at str | None ISO 8601 creation timestamp
last_verified_at str | None ISO 8601 last verification timestamp

VMExportComputeConfig VMExportComputeConfig

Compute resources configuration for VM export (vcpus, memory). Used as a sub-config within VMExportConfig.

Field Type Description
vcpus int | None Number of vCPUs
mem int | None Memory in MiB

VMExportImageConfig VMExportImageConfig

Image specification using portable semantic refs (type, arch, disk_size). Part of VMExportConfig.

Field Type Description
type str | None Image type (e.g. ubuntu-24.04)
arch str | None Architecture (e.g. x86_64)
disk_size str | None Rootfs disk size (e.g. 2G)

VMExportKernelConfig VMExportKernelConfig

Kernel specification using portable semantic refs (version, arch, type). Part of VMExportConfig.

Field Type Description
version str | None Kernel version (e.g. 6.1.0)
arch str | None Architecture (e.g. x86_64)
type str | None Kernel type: vmlinux or bzImage

VMExportBinaryConfig VMExportBinaryConfig

Firecracker binary specification using portable semantic refs (name, version). Part of VMExportConfig.

Field Type Description
name str Binary name: firecracker
version str | None Semantic version string (e.g. v1.15.0)

VMExportNetworkConfig VMExportNetworkConfig

Network configuration with portable semantic refs (name, subnet, gateway, NAT). Part of VMExportConfig.

Field Type Description
name str | None Network name (e.g. default)
subnet str | None Subnet in CIDR notation (e.g. 172.27.0.0/24)
ipv4_gateway str | None Gateway IPv4 (e.g. 172.27.0.1)
nat_gateways str | None Comma-separated NAT gateway interfaces
nat_enabled bool | None Whether NAT rules are enabled
ip str | None Assigned guest IP
mac str | None Assigned guest MAC

VMExportBootConfig VMExportBootConfig

Boot configuration (kernel args, console). Part of VMExportConfig.

Field Type Description
args str | None Kernel boot arguments
enable_console bool | None Whether serial console is enabled

VMExportFirecrackerConfig VMExportFirecrackerConfig

Firecracker feature flags for VM export (PCI, LSM, nested virt, CPU config). Part of VMExportConfig.

Field Type Description
enable_api_socket bool | None Whether the API socket is enabled
pci_enabled bool | None Whether PCI support is enabled
lsm_flags str | None Linux Security Module flags
nested_virt bool | None Whether nested virtualization is enabled
cpu_config str | None JSON string of merged CPU template config

VMExportCloudInitConfig VMExportCloudInitConfig

Cloud-init configuration for VM export (mode, user, SSH key). Part of VMExportConfig.

Field Type Description
mode str | None Cloud-init mode: inject, iso, net, off
user str | None SSH user
ssh_key str | None SSH key name or path
keep_iso bool | None Retain cloud-init ISO after boot
nocloud_net_port int | None Port for nocloud-net server (0 or None = auto-assign)

VMExportConfig VMExportConfig

Portable VM configuration for export/import across hosts. Uses semantic field references (type, version, name) — NEVER internal IDs. On import, the API layer resolves semantic refs to actual paths via DB queries.

Field Type Description
schema_version str Schema version (fixed: 1.0)
name str VM name
compute VMExportComputeConfig Compute resources sub-config
image VMExportImageConfig Image specification sub-config
kernel VMExportKernelConfig Kernel specification sub-config
binary VMExportBinaryConfig Binary specification sub-config
network VMExportNetworkConfig Network configuration sub-config
boot VMExportBootConfig Boot configuration sub-config
firecracker VMExportFirecrackerConfig Firecracker feature flags sub-config
cloud_init VMExportCloudInitConfig Cloud-init configuration sub-config

Error Handling

All exceptions derive from mvmctl.exceptions.MVMError.

MVMError ├── MVMRuntimeError ├── VMError │ ├── VMNotFoundError │ ├── VMCreateError │ ├── VMStateError │ ├── VMRequestError │ └── VMBuilderError ├── BinaryNotFoundError ├── KernelNotFoundError ├── NetworkNotFoundError ├── KeyNotFoundError ├── ImageNotFoundError ├── ImageAcquireError ├── NetworkError ├── IPTablesTrackerError ├── ImageError │ ├── ImageCompressionError │ ├── ImageDecompressionError │ ├── ImageCorruptError │ ├── ImageEmptyError │ ├── ImageValidationError │ └── ChecksumMismatchError ├── KernelError ├── FirecrackerError │ ├── FirecrackerClientError │ │ └── SocketNotFoundError │ ├── FirecrackerSpawnError │ └── FirecrackerConfigError ├── ConfigError ├── DatabaseError │ └── MigrationError ├── HostError │ └── PrivilegeError ├── ConsoleError ├── LogsError ├── ProcessError ├── AssetNotFoundError ├── DownloadError ├── BundledAssetError │ └── BundledAssetNotFoundError ├── BinaryError │ └── BinaryAlreadyExistsError ├── VersionError ├── VersionGateError ├── SSHError │ └── CPError │ ├── CPSourceNotFoundError │ ├── CPDestinationExistsError │ └── CPDestinationNotDirectoryError ├── MVMKeyError │ ├── KeyExportError │ ├── KeyDependencyError │ └── KeyFileError ├── VolumeError ├── VolumeNotFoundError ├── CloudInitError │ ├── CloudInitProvisionError │ ├── CloudInitModeError │ ├── CloudInitOffModeError │ ├── CloudInitInjectModeError │ ├── CloudInitIsoModeError │ └── CloudInitNetModeError ├── GuestfsError │ ├── GuestfsNotAvailableError │ ├── GuestfsLaunchError │ ├── GuestfsMountError │ ├── GuestfsWriteError │ └── GuestfsApplianceError ├── LoopMountError │ ├── LoopMountBinaryNotFoundError │ └── LoopMountTimeoutError ├── RootPartitionDetectionError ├── TieDetectedError └── HttpDownloadError

Example

Terminal

from mvmctl.api import NetworkOperation, NetworkCreateInput
from mvmctl.exceptions import MVMError, NetworkError

try:
    result = NetworkOperation.create(
        NetworkCreateInput(name="my-net", subnet="192.168.100.0/24")
    )
except NetworkError as e:
    print(f"Network setup failed: {e}")
except MVMError as e:
    print(f"Unexpected MVM error: {e}")

VMOperation

All methods are @staticmethod. VM instances are identified using VMInput objects.

VMOperation.create(inputs: VMCreateInput, *, on_progress: Callable[[ProgressEvent], None] | None = None) -> OperationResult[list[VMInstanceItem]] | NeedsInteraction

Create and start a new Firecracker microVM. Copies the rootfs image, generates cloud-init data, sets up bridge networking, writes the Firecracker JSON config, starts the Firecracker process, and registers the VM in the database.

Parameters

Parameter Type Default Description
inputs.name str VM name (required)
inputs.ssh_keys list[str] SSH key names to inject
inputs.image str | None None Image name/ID or path
inputs.kernel_id str | None None Kernel ID (DB-backed default)
inputs.vcpu_count int | None None Number of vCPUs
inputs.mem_size_mib int | None None Memory in MiB
inputs.network_name str | None None Network name
inputs.cloud_init_mode str | None None off, inject, iso, or net (resolved to off by default)
inputs.user str | None None Default SSH user
inputs.disk_size str | None None Rootfs disk size (e.g. 1G)
inputs.requested_guest_ip str | None None Guest IP address
inputs.requested_guest_mac str | None None Guest MAC address
inputs.custom_user_data Path | None None Custom cloud-init user-data file
inputs.nocloud_net_port int | None None Port for nocloud-net server
inputs.pci_enabled bool | None None Enable PCI support
inputs.nested_virt bool | None None Enable nested virtualization
inputs.cpu_config CpuConfig | None None Pre-resolved CPU configuration (from import)
inputs.enable_logging bool | None None Enable Firecracker logging
inputs.enable_metrics bool | None None Enable Firecracker metrics
inputs.enable_console bool | None None Enable serial console (DB-backed default)
inputs.lsm_flags str | None None Linux Security Module flags
inputs.boot_args str | None None Custom kernel boot arguments
inputs.firecracker_bin str | None None Path to Firecracker binary
inputs.binary_id str | None None Firecracker/jailer binary ID
inputs.skip_cleanup bool False Skip cleanup on failure
inputs.skip_ci_network_config bool False Skip cloud-init network config
inputs.keep_cloud_init_iso bool False Keep cloud-init ISO after creation
inputs.skip_deblob bool False Skip OS cache cleanup (deblob)
inputs.count int | None None Number of VMs to create (batch mode)
inputs.atomic bool False Roll back all VMs if any creation fails (batch mode)
inputs.volumes list[str] | None None Volume names to attach on creation
inputs.cloud_init_iso_path Path | None None Path to a pre-built cloud-init ISO

Raises: VMCreateError, NetworkError, FirecrackerSpawnError, PrivilegeError

Example

Terminal

from mvmctl.api import VMOperation, VMCreateInput

VMOperation.create(
    VMCreateInput(
        name="my-vm",
        ssh_keys=["my-key"],
        vcpu_count=2,
        mem_size_mib=2048,
        image="ubuntu:24.04",
    )
)

VMOperation.remove(inputs: VMInput) -> BatchResult[VMInstanceItem]

Stop and remove one or more VMs. Sends SIGTERM (graceful shutdown), then SIGKILL if still running. Tears down TAP device and iptables rules.

Parameters

Parameter Type Default Description
inputs.identifiers list[str] [] VM identifiers (names or IDs) to remove
inputs.force bool False Skip graceful shutdown

VMOperation.list_all(status: VMStatus | list[VMStatus] | None = None) -> list[VMInstanceItem]

Return all registered VMs, optionally filtered by status.

VMOperation.get(inputs: VMInput) -> VMInstanceItem

Look up a single VM by name, ID, IP, or MAC.

Raises: VMNotFoundError if not found or ambiguous.

VMOperation.start(inputs: VMInput) -> BatchResult[VMInstanceItem]

Start one or more stopped VMs.

VMOperation.stop(inputs: VMInput) -> BatchResult[VMInstanceItem]

Stop one or more running VMs gracefully.

Parameters

Parameter Type Default Description
inputs.force bool False Skip graceful shutdown

VMOperation.pause(inputs: VMInput) -> BatchResult[VMInstanceItem]

Pause one or more running VMs.

VMOperation.resume(inputs: VMInput) -> BatchResult[VMInstanceItem]

Resume one or more paused VMs.

VMOperation.reboot(inputs: VMInput) -> BatchResult[VMInstanceItem]

Reboot one or more VMs.

VMOperation.snapshot(inputs: VMInput, mem_out: Path, state_out: Path) -> OperationResult[VMInstanceItem]

Create a snapshot of a single VM's memory and state. Requires memory and state file output paths.

VMOperation.load_snapshot(inputs: VMInput, mem_in: Path, state_in: Path, resume_after: bool | None = None) -> OperationResult[VMInstanceItem]

Load a VM from memory and state snapshot files. Optionally resume after loading.

VMOperation.inspect(inputs: VMInput) -> dict[str, Any]

Show detailed information about a VM including all paths, features, and relations.

VMOperation.export(inputs: VMInput) -> VMExportConfig

Export a VM's configuration to a portable VMExportConfig object.

VMOperation.import_(inputs: VMImportInput, *, on_progress: Callable[[ProgressEvent], None] | None = None) -> OperationResult[VMInstanceItem] | NeedsInteraction

Create a VM from a portable config file. Resolves images, kernels, binaries, and networks.

VMOperation.prune(dry_run: bool = False, include_all: bool = False) -> OperationResult[list[str]]

Prune VMs based on their status. By default, removes all VMs EXCEPT those in RUNNING or STARTING state. Use include_all=True to prune ALL VMs regardless of state.

Parameters

Parameter Type Default Description
dry_run bool False Only report what would be removed, without actually removing
include_all bool False Prune ALL VMs including RUNNING and STARTING

VMOperation.attach_volume(vm_inputs: VMInput, volume_name: str) -> OperationResult[VMInstanceItem]

Attach a volume to a running VM. Updates the VM record so the volume is included on next start.

VMOperation.detach_volume(vm_inputs: VMInput, volume_name: str) -> OperationResult[VMInstanceItem]

Detach a volume from a running VM. Updates the VM record so the volume is excluded on next start.

NetworkOperation

All methods are @staticmethod. Networks are identified using NetworkInput objects.

NetworkOperation.create(inputs: NetworkCreateInput) -> OperationResult[NetworkItem] | NeedsInteraction

Create a named bridge network: sets up the bridge device, assigns the gateway IP, optionally configures NAT rules.

Parameters

Parameter Type Default Description
inputs.name str Network name (must be unique)
inputs.subnet str Subnet in CIDR notation
inputs.ipv4_gateway str | None None Gateway IPv4 for the bridge
inputs.nat_enabled bool True Configure NAT/masquerade
inputs.nat_gateways list[str] [] Physical interfaces for NAT

NetworkOperation.remove(inputs: NetworkInput, force: bool = False) -> OperationResult[NetworkItem]

Remove a named network: tears down bridge and NAT rules, removes persisted state.

Parameters

Parameter Type Default Description
force bool False Remove even if VMs reference it

NetworkOperation.list_all() -> list[NetworkItem]

List all named networks with lease enrichment.

NetworkOperation.get(inputs: NetworkInput) -> NetworkItem

Get a single network by name or ID.

Raises: NetworkError if not found or ambiguous.

NetworkOperation.set_default(inputs: NetworkInput) -> OperationResult[NetworkItem]

Set a network as the default for VM creation.

NetworkOperation.inspect(inputs: NetworkInput) -> dict[str, Any]

Show detailed network information including leases and iptables rules.

NetworkOperation.sync(network_id: str | None = None) -> OperationResult[dict[str, dict[str, int]]]

Sync iptables rules between database and host. Optionally target a specific network.

NetworkOperation.create_default_network() -> OperationResult[NetworkItem]

Ensure the default network exists, creating it if needed. Called automatically by HostOperation.init(). Idempotent.

NetworkOperation.prune(dry_run: bool = False, include_all: bool = False) -> OperationResult[list[str]]

Prune unused networks. By default, skips the default network and networks referenced by VMs or with active leases. Use include_all=True to remove ALL networks.

Parameters

Parameter Type Default Description
dry_run bool False Only report what would be removed, without actually removing
include_all bool False Remove ALL networks including default and referenced

ImageOperation

All methods are @staticmethod. Images are identified using ImageInput objects.

ImageOperation.pull(inputs: ImagePullInput, *, on_progress: Callable[[ProgressEvent], None] | None = None) -> OperationResult[ImageItem] | NeedsInteraction

Pull (download) a VM rootfs image (qcow2, tar, or raw), convert to ext4, and register in the database.

Parameters

Parameter Type Default Description
inputs.type str Image type (e.g. ubuntu, alpine, debian)
inputs.version str | None None Image spec version
inputs.no_cache bool False Skip cached version listing
inputs.force bool False Re-download even if cached
inputs.skip_optimization bool False Skip shrink and compression
inputs.set_default bool False Set as default after download
inputs.arch str | None None Image architecture
inputs.disabled_detectors list[str] [] Detectors to disable: type, label, size, filesystem

ImageOperation.import_(inputs: ImageImportInput, *, on_progress: Callable[[ProgressEvent], None] | None = None) -> OperationResult[ImageItem]

Import an existing local image file (qcow2, raw, tar-rootfs) and register it in the database.

Parameters

Parameter Type Default Description
inputs.name str Display name for the image
inputs.source_path Path Path to local image file
inputs.format str | None None Image format: qcow2, raw, tar-rootfs, or auto
inputs.arch str | None None Image architecture
inputs.partition int | None None Root partition number
inputs.force bool False Overwrite existing
inputs.skip_optimization bool False Skip shrink and compression
inputs.set_default bool False Set as default after import
inputs.disabled_detectors list[str] [] Detectors to disable: type, label, size, filesystem

ImageOperation.remove(inputs: ImageInput, force: bool = False) -> BatchResult[ImageItem]

Remove an image from cache and database.

Parameters

Parameter Type Default Description
force bool False Remove even if referenced by VMs

ImageOperation.list_all(inputs: ImageInput | None = None, *, remote: bool = False, no_cache: bool = False, type_filter: str | None = None) -> list[ImageItem] | list[ImageVersion]

List local cached images or available remote images.

Parameters

Parameter Type Default Description
no_cache bool False Skip cached version listing and fetch live
type_filter str | None None Filter by image type (e.g. ubuntu)

ImageOperation.get(inputs: ImageInput) -> ImageItem

Get a single image by ID or OS slug.

ImageOperation.set_default(inputs: ImageInput) -> OperationResult[ImageItem]

Set an image as the default for new VMs.

ImageOperation.inspect(inputs: ImageInput) -> dict[str, Any]

Show detailed information about an image including compression stats and storage details.

ImageOperation.warm(inputs: ImageInput | None = None, *, all: bool = False, on_progress: Callable[[ProgressEvent], None] | None = None) -> OperationResult[list[Path]]

Pre-decompress image to tmpfs ready pool for fast VM creation.

Parameters

Parameter Type Default Description
all bool False Warm all images, not just the default

KernelOperation

All methods are @staticmethod. Kernels are identified using KernelInput objects.

KernelOperation.pull(inputs: KernelPullInput, *, on_progress: Callable[[ProgressEvent], None] | None = None) -> OperationResult[KernelItem] | NeedsInteraction

Pull (download) or build a Firecracker kernel. Requires kernel_type (firecracker or official).

Parameters

Parameter Type Default Description
inputs.kernel_type str firecracker or official
inputs.version str | None None Kernel version (default: 6.19.9 for official)
inputs.arch str | None None Architecture
inputs.set_default bool False Set as default after fetch
inputs.jobs int | None None Parallel build jobs (official only)
inputs.keep_build_dir bool False Keep build directory (official only)
inputs.clean_build bool False Skip build cache (official only)
inputs.kernel_config Path | None None Custom kernel config fragment
inputs.features str "" Comma-separated kernel features (kvm, nftables)

KernelOperation.remove(inputs: KernelInput, force: bool = False) -> BatchResult[KernelItem]

Remove a kernel from cache and database.

KernelOperation.list_all(remote: bool = False, *, no_cache: bool = False) -> list[KernelItem] | list[VersionInfo]

List kernels. When remote=True, returns available remote kernel versions from upstream providers (kernel.org for official kernels, Firecracker S3 for firecracker kernels). When remote=False (default), returns locally cached kernels.

Parameters

Parameter Type Default Description
remote bool False If True, list remote kernel versions instead of local
no_cache bool False Skip cached version listing and fetch live from upstream. Only relevant when remote=True.

KernelOperation.get(inputs: KernelInput) -> KernelItem

Get a single kernel by ID or name.

KernelOperation.inspect(inputs: KernelInput) -> dict[str, Any]

Show detailed kernel information.

KernelOperation.set_default(inputs: KernelInput) -> OperationResult[KernelItem]

Set a kernel as the default for VM creation.

KeyOperation

All methods are @staticmethod. Keys are identified using KeyInput objects.

KeyOperation.create(inputs: KeyCreateInput) -> OperationResult[SSHKeyItem]

Generate a new SSH keypair via ssh-keygen and register it.

Parameters

Parameter Type Default Description
inputs.name str Key name and base filename
inputs.algorithm str | None None Key algorithm: ed25519, rsa, or ecdsa
inputs.bits int | None None Key size in bits (RSA only; default 4096)
inputs.comment str | None None Key comment
inputs.set_default bool False Set as default after creation
inputs.overwrite bool False Overwrite existing key
inputs.output_dir Path | None None Output directory for the keypair

KeyOperation.add(name: str, pub_key_path: Path, overwrite: bool = False) -> OperationResult[SSHKeyItem]

Import an existing .pub file into the cache.

Parameters

Parameter Type Default Description
name str Name for the key
pub_key_path Path Path to .pub file
overwrite bool False Overwrite existing key with same name

KeyOperation.list_all() -> list[SSHKeyItem]

List all keys in the cache.

KeyOperation.get(inputs: KeyInput) -> SSHKeyItem

Get a single key by name or ID.

KeyOperation.inspect(inputs: KeyInput) -> dict[str, Any]

Show detailed key information.

KeyOperation.set_default(inputs: KeyInput) -> OperationResult[SSHKeyItem]

Set one or more keys as defaults for new VMs.

KeyOperation.get_defaults() -> list[SSHKeyItem]

Get all default keys.

KeyOperation.clear_defaults() -> OperationResult[None]

Clear all default key assignments.

KeyOperation.remove(inputs: KeyInput) -> BatchResult[SSHKeyItem]

Remove keys from the cache.

KeyOperation.export(inputs: KeyInput, destination: Path, overwrite: bool = False) -> OperationResult[tuple[Path, Path]]

Export a keypair to a destination directory.

BinaryOperation

All methods are @staticmethod. Binaries are identified using BinaryInput objects.

BinaryOperation.pull(inputs: BinaryPullInput) -> OperationResult[list[BinaryItem]] | NeedsInteraction

Pull (download) a specific Firecracker/jailer binary version from GitHub releases.

Parameters

Parameter Type Default Description
inputs.name str "firecracker" Binary name (only 'firecracker' is supported for download/build)
inputs.version str Semantic version string (e.g. 1.15.0)
inputs.git_ref str | None None Git ref to build from source (e.g. v1.15.0). When set, skips release download and builds from source instead.
inputs.set_default bool False Set as default after download
inputs.download_override bool True Re-download even if cached

BinaryOperation.remove(inputs: BinaryInput, force: bool = False) -> BatchResult[BinaryItem]

Remove binaries by identifier.

BinaryOperation.remove_by_version(version: str, force: bool = False) -> OperationResult[None]

Remove both firecracker and jailer by version string.

BinaryOperation.list_all(remote: bool = False, limit: int | None = None) -> list[BinaryItem] | list[str]

List binaries. When remote=False (default), returns locally installed binaries. When remote=True, returns available remote versions from GitHub.

Parameters

Parameter Type Default Description
remote bool False If True, list remote versions instead of local
limit int | None None Limit remote versions returned

BinaryOperation.get(inputs: BinaryInput) -> list[BinaryItem]

Get a binary by name and version.

BinaryOperation.set_default(inputs: BinaryInput) -> OperationResult[BinaryItem]

Set a binary (by ID) as the active default.

BinaryOperation.ensure_default() -> OperationResult[BinaryItem]

Ensure a default Firecracker binary exists.

VolumeOperation

All methods are @staticmethod. Volumes are identified using VolumeInput objects.

VolumeOperation.create(inputs: VolumeCreateInput) -> OperationResult[VolumeItem]

Create a new persistent data disk. Creates the disk file via fallocate (raw) or qemu-img (qcow2), registers the volume in the database.

Parameters

Parameter Type Default Description
inputs.name str Volume name (required)
inputs.size str Volume size (e.g. 10G, 512M)
inputs.format str | None None Disk format: raw or qcow2 (resolved to raw by default)
inputs.read_only bool | None None Mount volume as read-only (resolved to False by default)

Raises: VolumeError

Example

Terminal

from mvmctl.api import VolumeOperation, VolumeCreateInput
result = VolumeOperation.create(
    VolumeCreateInput(name="my-data", size="10G")
)

VolumeOperation.remove(inputs: VolumeInput, force: bool = False) -> BatchResult[VolumeItem]

Remove one or more volumes by name or ID prefix. Deletes the disk file and removes from the database.

Parameters

Parameter Type Default Description
inputs.identifiers list[str] [] Volume names or ID prefixes to remove
force bool False Remove even if attached to VMs

VolumeOperation.list_all() -> list[VolumeItem]

List all volumes from the database.

VolumeOperation.get(inputs: VolumeInput) -> VolumeItem

Get a single volume by name or ID.

Raises: VolumeNotFoundError if not found or ambiguous.

VolumeOperation.inspect(inputs: VolumeInput) -> dict[str, Any]

Show detailed information about a volume including qemu-img disk info.

VolumeOperation.resize(inputs: VolumeCreateInput) -> OperationResult[VolumeItem]

Resize a volume. Raw format supports grow only (fallocate). qcow2 supports both grow and shrink (qemu-img).

Parameters

Parameter Type Default Description
inputs.name str Volume name to resize
inputs.size str New size (e.g. 20G)

Raises: VolumeError

HostOperation

All methods are @staticmethod.

HostOperation.init(cache_dir: Path, *, on_progress: Callable[[ProgressEvent], None] | None = None) -> OperationResult[Any] | NeedsInteraction

Apply host configuration: enable IP forwarding, persist sysctl, load KVM modules, create the mvm unix group, configure sudoers, set up iptables chains, and ensure the default network. Fully idempotent.

Raises: HostError, PrivilegeError

HostOperation.clean(cache_dir: Path) -> OperationResult[list[str]]

Remove all networking config (bridges, TAPs, iptables rules). Does not touch sysctl, sudoers, or group.

HostOperation.reset(cache_dir: Path) -> OperationResult[list[str]]

Full rollback to pre-init state: networking, sysctl, sudoers, and group removal.

HostOperation.check_kvm_access() -> bool

Return True if /dev/kvm exists and is accessible by the current user.

HostOperation.check_required_binaries() -> list[str]

Return a list of missing required binary names.

HostOperation.get_ip_forward_status() -> str

Return the current net.ipv4.ip_forward value.

HostOperation.info() -> OperationResult[dict[str, object]]

Return current host info with capacity analysis. Returns hardware, limits, resource usage, and capacity projections from stored or auto-detected state.

HostOperation.refresh_capacity() -> OperationResult[dict[str, object]]

Redetect host hardware/limits and refresh info output. Returns the same structure as info() but forces fresh detection instead of using cached state.

HostOperation.get_state() -> HostStateItem | None

Return the saved host state if one exists.

HostOperation.get_running_vms() -> list[VMInstanceItem]

Return all currently running VMs.

CacheOperation

All methods are @staticmethod.

CacheOperation.init_all(*, on_progress: Callable[[ProgressEvent], None] | None = None) -> OperationResult[dict[str, str | list[str] | None]]

Initialize all cache directories and optionally build the libguestfs fixed appliance.

CacheOperation.prune_vms(dry_run: bool = False, include_all: bool = False) -> OperationResult[list[str]]

Prune VMs. By default prunes all except RUNNING/STARTING.

CacheOperation.prune_networks(dry_run: bool = False, include_all: bool = False) -> OperationResult[list[str]]

Prune unused networks.

CacheOperation.prune_images(dry_run: bool = False, include_all: bool = False) -> OperationResult[list[str]]

Prune unused images.

CacheOperation.prune_kernels(dry_run: bool = False, include_all: bool = False) -> OperationResult[list[str]]

Prune unused kernels.

CacheOperation.prune_binaries(dry_run: bool = False, include_all: bool = False) -> OperationResult[list[str]]

Prune unused binaries.

CacheOperation.prune_misc(dry_run: bool = False) -> OperationResult[dict[str, bool]]

Prune misc cache (libguestfs appliance, warm images).

CacheOperation.prune_all(dry_run: bool = False, include_all: bool = False) -> OperationResult[PruneAllResult]

Prune all cache resources in one call.

CacheOperation.clean(dry_run: bool = False) -> OperationResult[CleanResult]

Completely clean all cache — prune everything, clean host networking, remove cache directory.

SSHOperation

SSHOperation.connect(inputs: SSHInput) -> OperationResult[int]

Open an interactive SSH session into a VM, or execute a command.

Parameters

Parameter Type Default Description
inputs.identifier str VM identifier (name, ID, IP, or MAC)
inputs.user str | None None SSH user
inputs.key Path | None None SSH private key path or key name
inputs.cmd str | None None Command to execute (None = interactive)
inputs.timeout int | None None SSH connection timeout in seconds

CPOperation

File copy operations between host and microVMs via tar-over-SSH. Supports three directions: host_to_vm, vm_to_host, and vm_to_vm. Paths use vm_name:/path syntax to reference VM-side locations.

CPOperation.copy(inputs: CPInput, *, on_progress: Callable[[int], None] | None = None) -> OperationResult[dict[str, Any]]

Copy files between the host and microVMs. Uses tar-over-SSH for efficient streaming. Returns an OperationResult with bytes transferred and a summary message.

Parameters

Parameter Type Default Description
inputs.sources list[str] Source paths (local paths or vm_name:/remote/path)
inputs.dst str Destination path (local path or vm_name:/remote/path)
inputs.user str | None None SSH user (resolved from VM record if not set)
inputs.key str | None None SSH key name or path (resolved from VM record if not set)
inputs.force bool False Overwrite existing destination files

Raises: CPError, CPSourceNotFoundError, CPDestinationExistsError, CPDestinationNotDirectoryError, SSHError

ConsoleOperation

Methods for managing the VM serial console relay via vsock.

ConsoleOperation.get_connection_info(identifier: str) -> ConsoleConnectionInfo

Get connection info (socket path) for attaching to a VM serial console.

ConsoleOperation.get_state(identifier: str) -> dict[str, Any]

Check the console relay state for a VM (running, PID, socket path).

ConsoleOperation.kill(identifier: str) -> OperationResult[bool]

Kill the console relay process for a VM.

LogOperation

Methods for streaming VM logs.

LogOperation.stream(inputs: LogInput) -> Generator[str]

Stream VM boot or OS logs. Supports line limits and follow mode.

ConfigOperation

Methods for managing mvmctl settings.

ConfigOperation.get(category: str, key: str | None = None) -> Any

Get a config value by category and optional key.

ConfigOperation.set(category: str, key: str, value: Any) -> OperationResult[None]

Set a config value persistently in config.json.

ConfigOperation.reset(category: str | None = None, key: str | None = None, all_overrides: bool = False) -> OperationResult[int]

Reset config override(s) to defaults.

ConfigOperation.list_all() -> dict

List all overridable settings with their current values and types.

InitOperation

InitOperation.run(skip_host: bool = False, non_interactive: bool = False, *, on_progress: Callable[[ProgressEvent], None] | None = None, sudo_completed: bool = False, host_setup_message: str | None = None, download_version: str | None = None, guestfs_enabled: bool | None = None) -> InitResult

Run the full init wizard: local state → host setup → cache init → binary fetch.

InitOperation.init_database() -> None

Initialize the local SQLite database (run migrations).

InitOperation.setup_host(cache_dir: Path) -> OperationResult[Any] | NeedsInteraction

Set up host configuration. Delegates to HostOperation.init().

End-to-End Example

Complete orchestration script: initialize database, set up host, fetch binary, create SSH key, ensure default network, create a VM, and list running instances.

Terminal

#!/usr/bin/env python3
"""Orchestrate microVM lifecycle using the mvmctl Python API."""

from pathlib import Path
from mvmctl.api import (
    BinaryOperation, BinaryPullInput,
    HostOperation,
    ImageOperation, ImagePullInput,
    InitOperation,
    KeyOperation, KeyCreateInput,
    NetworkOperation,
    VMOperation, VMCreateInput,
)
from mvmctl.exceptions import MVMError
from mvmctl.models.result import NeedsInteraction, OperationResult


# CacheUtils.get_cache_dir() is not part of the public API —
# use Path.home() for the default cache path instead.
CACHE_DIR = Path.home() / ".cache" / "mvmctl"


def main() -> None:
    # 1. Initialise the SQLite database
    InitOperation.init_database()
    print("Database ready.")

    # 2. Initialise the host (idempotent)
    host_result = HostOperation.init(CACHE_DIR)
    if isinstance(host_result, NeedsInteraction):
        print("Host init requires sudo. Run: sudo mvm host init")
        return
    changes = host_result.metadata.get("changes", [])
    if changes:
        for change in changes:
            print(f"  Applied: {change.setting} = {change.applied_value}")
    else:
        print("Host already configured.")

    # 3. Ensure a Firecracker binary is available
    local = BinaryOperation.list_all()
    if not local:
        print("Downloading Firecracker 1.15.1 ...")
        result = BinaryOperation.pull(BinaryPullInput(version="1.15.1"))
        if isinstance(result, NeedsInteraction):
            print("Binary download requires privileges.")
            return
        if result.is_error:
            print(f"Download failed: {result.message}")
            return

    # 4. Ensure a kernel is available (via CLI: mvm kernel pull)
    #    or use KernelOperation.pull() directly

    # 5. Ensure an image is available (via CLI: mvm image pull)
    #    or use ImageOperation.pull() directly

    # 6. Create or register an SSH key
    key_result = KeyOperation.create(
        KeyCreateInput(name="my-api-key", set_default=True)
    )
    if key_result.is_error:
        print(f"Key creation failed: {key_result.message}")
        return
    key = key_result.item
    assert key is not None
    print(f"Created SSH key: {key.name} ({key.fingerprint})")

    # 7. Ensure the default network exists
    net_result = NetworkOperation.create_default_network()
    if net_result.is_error:
        print(f"Network creation failed: {net_result.message}")
        return
    default_net = net_result.item
    assert default_net is not None
    print(f"Default network: {default_net.name} ({default_net.subnet})")

    # 8. Create a VM using the API
    create_result = VMOperation.create(
        VMCreateInput(
            name="my-api-vm",
            ssh_keys=["my-api-key"],
            vcpu_count=2,
            mem_size_mib=2048,
            image="ubuntu",
            network_name="default",
        )
    )
    if isinstance(create_result, NeedsInteraction):
        print("VM creation requires privileges.")
        return
    if create_result.is_error:
        print(f"VM creation failed: {create_result.message}")
        return
    created_vms = create_result.item or []
    names = [vm.name for vm in created_vms]
    print(f"Created VM(s): {', '.join(names)}")

    # 9. List all VMs
    instances = VMOperation.list_all()
    print(f"\nRegistered VMs ({len(instances)}):")
    for vm in instances:
        print(f"  {vm.name:20s}  {vm.status:10s}  {vm.ipv4}")


if __name__ == "__main__":
    try:
        main()
    except MVMError as e:
        print(f"Error: {e}")
        raise SystemExit(1)