31 KiB
Executable File
QCrows — Self-Describing VM Container Image Format
Version: 0.2.0-draft
Status: Draft
Date: 2026-07-16
1. Overview
QCrows (pronounced cue-crows) is a self-describing container image format for VM-based container runtimes such as Kata Containers. A .qcrows file bundles the guest OS filesystem, kernel, initrd, UI integration metadata, build provenance, and integrity verification into a single distributable artifact.
The format is inspired by OCI image manifests — the same principle of self-description applied to VM containers instead of namespace-containers. Where an OCI image has config.json + layers + manifest, a QCrows image has metadata.toml + rootfs + initrd + kernel + menu entry + build info.
Design Goals
- Self-describing — A management UI (Cockpit, etc.) can render a QCrows image's name, description, compatibility, and requirements without inspecting the filesystem contents.
- Build-system agnostic — Works equally well with source-based distros (Gentoo, Source Mage, Lunar), embedded build frameworks (Buildroot, LEDE), or any custom pipeline.
- Integrity-verifiable — Every component is checksummed; the entire bundle can be verified before import.
- Kernel-rootfs coupled — The guest kernel and its
.configtravel alongside the rootfs they were built for, eliminating the #1 operational pain point in Kata deployments. The kernel is a required component — every QCrows image must include one. - Cockpit-native — The
menu.tomlentry makes QCrows images first-class citizens in the Cockpit UI, enabling drag-and-drop import with automatic UI integration.
What QCrows Is Not
- Not a container runtime — it's an image format consumed by runtimes like Kata
- Not a replacement for OCI — it targets VM containers, not namespace containers
- Not a package manager — it's a distribution format for pre-built images
2. Format Specification
2.1 Outer Container
A QCrows image is a tar archive (uncompressed or gzip-compressed) with the .qcrows extension.
example.qcrows (uncompressed tar)
example.qcrows.gz (gzip-compressed tar)
example.qcrows.tar.gz (also valid)
The tar archive must use PAX (POSIX.1-2001) format for extended attributes. All paths inside the archive are relative.
2.2 Directory Layout
example.qcrows/
├── metadata.toml # REQUIRED — image manifest
├── menu.toml # REQUIRED — Cockpit UI menu entry
├── hashes.sha256 # REQUIRED — integrity verification
├── rootfs.tar.gz # REQUIRED — guest OS filesystem
├── initrd.img # ONE OF — initial ramdisk (initrd/initramfs/cramfs)
├── initrd.cpio.gz # alternative initrd format
├── initrd.cramfs # alternative cramfs format
├── kernel/ # REQUIRED — guest kernel binary + config
│ ├── vmlinuz # compressed guest kernel (one of vmlinuz/vmlinux required)
│ ├── vmlinux # uncompressed guest kernel (for Dragonball, some CLH configs)
│ └── config # REQUIRED — kernel .config for reproducibility and validation
├── boot-params.conf # OPTIONAL — kernel command line parameters
├── build.toml # OPTIONAL but recommended — build provenance
├── spec.md # OPTIONAL — build guide / documentation
├── firmware/ # OPTIONAL — additional firmware blobs
│ └── ...
└── device-tree/ # OPTIONAL — DTB files for ARM/RISC-V
└── ...
2.3 Component Specifications
metadata.toml — Image Manifest (REQUIRED)
The central manifest describing the image. This is the first file a consumer reads.
[ qcrows ]
format_version = "0.1.0"
[ image ]
name = "alpine-3.20-kata"
version = "3.20.1"
description = "Minimal Alpine Linux rootfs with kata-agent for Cloud Hypervisor and QEMU"
arch = "x86_64"
os = "linux"
created_at = "2026-07-16T10:00:00Z"
[ image.compatibility ]
hypervisors = [ "qemu", "cloud-hypervisor" ]
kata_runtime_min = "2.5"
kata_runtime_max = ""
[ image.resources ]
min_vcpus = 1
min_memory_mb = 256
recommended_vcpus = 2
recommended_memory_mb = 1024
[ kernel ]
version = "6.6.32"
included = true # true if kernel/ directory is present
path = "kernel/vmlinuz" # relative path within the archive
[ initrd ]
included = true
type = "cpio-gzip" # cpio-gzip | cpio-lz4 | cpio-xz | cramfs
path = "initrd.img"
[ rootfs ]
type = "tar-gzip" # tar-gzip | tar-xz | tar-zst
path = "rootfs.tar.gz"
size_mb = 42
[ agent ]
name = "kata-agent"
version = "2.5.0"
protocol = "vsock"
Field Reference:
| Section | Field | Type | Required | Description |
|---|---|---|---|---|
| qcrows | format_version | string | yes | QCrows spec version |
| image | name | string | yes | Human-readable image name |
| image | version | string | yes | Image version (semver recommended) |
| image | description | string | no | One-line description for UI |
| image | arch | string | yes | Target architecture (x86_64, aarch64, riscv64, s390x, ppc64le) |
| image | os | string | yes | Always "linux" for Kata |
| image | created_at | string | no | ISO 8601 timestamp |
| image.compatibility | hypervisors | [string] | yes | Supported VMM backends |
| image.compatibility | kata_runtime_min | string | no | Minimum kata-runtime version |
| image.compatibility | kata_runtime_max | string | no | Maximum kata-runtime version |
| image.resources | min_vcpus | int | no | Minimum vCPU count |
| image.resources | min_memory_mb | int | no | Minimum memory in MiB |
| image.resources | recommended_vcpus | int | no | Recommended vCPU count |
| image.resources | recommended_memory_mb | int | no | Recommended memory in MiB |
| kernel | version | string | yes | Guest kernel version string |
| kernel | included | bool | yes | Whether kernel/ directory is present |
| kernel | path | string | conditional | Required if included=true |
| initrd | included | bool | yes | Whether initrd is present |
| initrd | type | string | conditional | Required if included=true |
| initrd | path | string | conditional | Required if included=true |
| rootfs | type | string | yes | Compression format of rootfs |
| rootfs | path | string | yes | Relative path to rootfs archive |
| rootfs | size_mb | int | no | Approximate uncompressed size |
| agent | name | string | no | Agent binary name |
| agent | version | string | no | Agent version |
| agent | protocol | string | no | Communication protocol (always "vsock" for Kata) |
menu.toml — Cockpit UI Menu Entry (REQUIRED)
Defines how this image appears in the Cockpit Kata module's UI. This is the file that makes QCrows "Cockpit-native."
[ menu ]
label = "Alpine 3.20 Kata"
category = "minimal" # minimal | server | development | embedded | hardened | custom
icon = "box" # lucide-react icon name
priority = 10 # lower = higher in list
[ menu.details ]
distro = "Alpine Linux"
distro_version = "3.20"
init_system = "OpenRC" # systemd | OpenRC | runit | sinit | busybox | custom
package_count = 42
shell = "/bin/ash"
[ menu.tags ]
[ "suitable-for" ]
workloads = [ "microservice", "api-gateway", "sidecar" ]
environments = [ "production", "staging" ]
[ menu.actions ] # Quick actions shown in the UI
import = true
deploy = false # Not all images support one-click deploy
edit_config = true
Category Values:
| Category | Description | Typical Size |
|---|---|---|
| minimal | Smallest possible rootfs, single-process | < 50 MiB |
| server | General-purpose server with common packages | 100–500 MiB |
| development | Includes build tools, debug symbols, strace | 500 MiB–2 GiB |
| embedded | Built with Buildroot/LEDE for resource-constrained targets | < 30 MiB |
| hardened | Security-hardened (PaX, SELinux, musl, stripped) | 50–200 MiB |
| custom | User-defined category | varies |
hashes.sha256 — Integrity Verification (REQUIRED)
SHA-256 checksums for every file in the archive (except this file itself). Format follows the sha256sum output format.
4a2b3c... metadata.toml
7f8e9d... menu.toml
1a2b3c... rootfs.tar.gz
5d6e7f... initrd.img
8a9b0c... kernel/vmlinuz
3d4e5f... kernel/config
9a0b1c... boot-params.conf
2e3f4a... build.toml
Verification procedure:
- Extract the archive to a temp directory
- Compute SHA-256 of each file listed in
hashes.sha256 - Compare against the stored checksums
- Reject the image if any checksum mismatches
rootfs.tar.* — Guest OS Filesystem (REQUIRED)
A tar archive of the guest OS root filesystem. Supported compression formats:
| Format | Extension | Use Case |
|---|---|---|
| gzip | .tar.gz, .tgz |
General purpose, fastest decompression |
| xz | .tar.xz |
Smallest size, slower decompression |
| zstd | .tar.zst |
Best compression/decompression tradeoff |
The rootfs must contain:
/sbin/initor/usr/sbin/init— init system/usr/bin/kata-agentor/usr/local/bin/kata-agent— Kata agent/etc/resolv.conf— DNS configuration
initrd.* — Initial Ramdisk (ONE OF REQUIRED)
The initial ramdisk loaded into VM memory at boot. At least one of initrd or cramfs must be present.
| Format | Extension | Use Case |
|---|---|---|
| gzip cpio | .img, .cpio.gz |
Most common, used by QEMU and Dragonball |
| LZ4 cpio | .cpio.lz4 |
Fastest decompression, Firecracker |
| XZ cpio | .cpio.xz |
Smallest size, Cloud Hypervisor |
| cramfs | .cramfs |
Read-only compressed fs, embedded targets |
kernel/ — Guest Kernel (REQUIRED)
The guest kernel is a required component of every QCrows image. Bundling the kernel with its rootfs eliminates the #1 source of compatibility bugs in Kata deployments — mismatched kernel/rootfs pairs cause boot failures, missing modules, and silent data corruption. Since QCrows images are typically built from source-based distros where the kernel is compiled alongside the rootfs, there is no reason to ship them separately.
| File | Required | Description |
|---|---|---|
vmlinuz |
one of | Compressed kernel (QEMU, Firecracker, CLH on x86) |
vmlinux |
one of | Uncompressed ELF kernel (CLH on some arches, Dragonball) |
config |
required | Kernel .config for build reproducibility and validation |
Kernel Validation Rules:
When importing a QCrows image, the consumer MUST:
- Verify kernel binary exists — At least one of
kernel/vmlinuzorkernel/vmlinuxmust be present - Verify kernel config exists —
kernel/configmust be present and parseable - Verify kernel version — The version string embedded in the kernel binary must match
kernel.versioninmetadata.toml - Check required Kata config options — The kernel config must have these options enabled:
CONFIG_VSOCKETS=y— vsock communication for kata-agentCONFIG_VIRTIO=y— virtio device supportCONFIG_VIRTIO_PCI=y(orCONFIG_VIRTIO_MMIO=y) — virtio transportCONFIG_DEVTMPFS=y— device tmpfs for /devCONFIG_DEVTMPFS_MOUNT=y— auto-mount devtmpfs
- Check kernel format — The binary must be a valid ELF (vmlinux) or bzImage (vmlinuz) depending on the declared type
- Check kernel size — Warn if kernel exceeds 100MiB (uncompressed) or 50MiB (compressed)
Hypervisor–Kernel Format Requirements:
| VMM | Kernel Format | Required |
|---|---|---|
| QEMU | vmlinuz (bzImage) | x86_64 |
| QEMU | vmlinux (ELF) | aarch64, s390x, ppc64le |
| Cloud Hypervisor | vmlinux (ELF) | all arches |
| Firecracker | vmlinux (ELF) | all arches |
| Dragonball | vmlinux (ELF) | all arches |
When kernel.included = true in metadata.toml, the import tool MUST:
- Copy the kernel to
/usr/share/kata-containers/alongside the rootfs - Copy the kernel config to
/usr/share/kata-containers/for reference - Update the relevant
configuration.tomlto point to the new kernel path - If
boot-params.confexists, append its parameters to the hypervisor'skernel_paramsinconfiguration.toml - Verify the kernel version matches
kernel.versionin metadata - Validate required Kata config options are enabled in
kernel/config
boot-params.conf — Kernel Command Line (OPTIONAL)
Kernel command line parameters specific to this image. One parameter per line.
# boot-params.conf
console=ttyS0
root=/dev/vda1
rw
agent.log=debug
agent.vsock_port=1024
When present, the import tool appends these to the hypervisor's kernel_params in configuration.toml rather than replacing the global defaults.
build.toml — Build Provenance (OPTIONAL, Recommended)
Records how the image was built. Critical for source-based distros where reproducibility depends on knowing exact build flags and source versions.
[ build ]
system = "gentoo" # gentoo | sourcemage | buildroot | lunar | lede | btc | sorcery | custom
timestamp = "2026-07-16T10:00:00Z"
host_arch = "x86_64"
target_arch = "x86_64" # may differ for cross-compilation
[ build.options ]
# Gentoo-specific
profile = "default/linux/amd64/17.1"
cflags = "-O2 -pipe -march=native"
use_flags = "minimal -X -gtk -systemd kata agent vsock"
# Source Mage / Sorcery-specific
# grimoire = "stable"
# spells = "kata-agent glibc musl busybox"
# Buildroot-specific
# defconfig = "kata_x86_64_defconfig"
# br2_external = "/path/to/kata-br2-external"
# LEDE-specific
# target = "x86/64"
# packages = "kata-agent ca-certificates"
# Lunar-specific
# moonbase = "stable"
# modules = "kata-agent busybox musl"
[ build.sources ]
kernel_source = "https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.6.32.tar.xz"
kernel_hash = "abc123..."
agent_source = "https://github.com/kata-containers/kata-containers/archive/refs/tags/3.5.0.tar.gz"
agent_hash = "def456..."
[ build.reproducibility ]
reproducible = true
build_id = "20260716-alpine-3.20-kata-x86_64-v1"
Supported Build Systems:
| ID | Name | Package Manager | Typical Use |
|---|---|---|---|
gentoo |
Gentoo Linux | Portage | Full control, hardened builds |
sourcemage |
Source Mage GNU/Linux | Sorcery | Source-based, spell system |
sorcery |
Sorcery (Source Mage's pm) | cast/dispel | Alias for sourcemage |
buildroot |
Buildroot | make + kconfig | Embedded, cross-compilation |
lunar |
Lunar Linux | lin/lrm | Source-based, rolling |
lede |
LEDE / OpenWrt | opkg + make | Routers, embedded, IoT |
btc |
BTC / Blinkenlights | custom | Niche / custom pipeline |
custom |
Custom | — | Any unlisted build system |
spec.md — Build Guide (OPTIONAL)
A Markdown document describing how to reproduce or modify this image. Should include:
- Step-by-step build instructions
- Required host packages
- Configuration choices and their rationale
- Known limitations or incompatibilities
- References to the build system's documentation
firmware/ — Firmware Blobs (OPTIONAL)
Additional firmware files needed by the guest. Common in embedded/LEDE scenarios. Files are copied to /usr/share/kata-containers/firmware/ during import.
device-tree/ — Device Tree Blobs (OPTIONAL)
.dtb files for ARM or RISC-V targets. Required when the VMM doesn't support ACPI or when targeting custom hardware.
3. QCrows File Lifecycle
3.1 Creating a QCrows Image
Source Distro Build → rootfs + initrd + kernel
│
▼
qcrows-pack tool
(reads metadata.toml, menu.toml, build.toml)
│
▼
example.qcrows (tar archive)
The qcrows-pack tool (see Section 4) takes a build output directory and a set of metadata files, generates the hashes, and creates the .qcrows archive.
3.2 Importing into Cockpit
Drag .qcrows into Cockpit UI
│
▼
1. Extract to /tmp/qcrows-xxx/
2. Verify hashes.sha256
3. Read metadata.toml → validate format version, arch, compatibility
4. Read menu.toml → render UI entry
5. Copy rootfs → /usr/share/kata-containers/
6. Copy initrd → /usr/share/kata-containers/
7. Copy kernel → /usr/share/kata-containers/ (if included)
8. Update configuration.toml with new paths + boot params
9. Register in Cockpit's image catalog
3.3 Verification
Before import, the consumer MUST:
- Verify
hashes.sha256integrity - Validate
metadata.tomlschema - Check
image.compatibility.hypervisorsagainst the host's VMM - Check
image.archagainst the host's architecture - Verify rootfs contains
/sbin/initandkata-agent - Verify initrd format matches the
initrd.typedeclaration
4. Tooling
4.1 qcrows-pack — Create a QCrows Archive
qcrows-pack \
--rootfs ./build/rootfs.tar.gz \
--initrd ./build/initrd.img \
--kernel ./build/vmlinuz \
--kernel-config ./build/.config \
--metadata ./metadata.toml \
--menu ./menu.toml \
--build ./build.toml \
--boot-params ./boot-params.conf \
--output alpine-3.20-kata.qcrows
4.2 qcrows-verify — Verify Integrity
qcrows-verify alpine-3.20-kata.qcrows
# → PASS: all checksums match
# → PASS: metadata.toml valid (format_version 0.1.0)
# → PASS: rootfs contains /sbin/init
# → PASS: rootfs contains /usr/bin/kata-agent
# → PASS: kernel version matches metadata (6.6.32)
4.3 qcrows-inspect — Read Metadata Without Extraction
qcrows-inspect alpine-3.20-kata.qcrows
# → Name: alpine-3.20-kata
# → Version: 3.20.1
# → Arch: x86_64
# → Hypervisors: qemu, cloud-hypervisor
# → Kernel: 6.6.32 (included)
# → Initrd: cpio-gzip (included)
# → Rootfs: tar-gzip, ~42 MiB
# → Build: gentoo, 2026-07-16
4.4 qcrows-export — Export to qcow2 or ISO
Convert a .qcrows archive into a bootable disk image or live ISO. This enables three deployment scenarios beyond the standard Kata import flow:
- QEMU direct boot — Export to qcow2 and boot as a standalone VM without Kata
- Live USB — Write an ISO to a USB stick for portable, bootable Kata images
- Kata deployment from media — ISO contains a
/kata/directory with all components ready for host-side import
Export to qcow2
# Auto-sized qcow2 with MBR boot
qcrows-export --format qcow2 alpine-3.20-kata.qcrows -o alpine-3.20-kata.qcow2
# Fixed 2GB disk with EFI partition layout
qcrows-export --format qcow2 --disk-size 2G --efi alpine-3.20-kata.qcrows -o alpine-efi.qcow2
# Boot the result
qemu-system-x86_64 -m 1G -smp 2 -drive file=alpine-3.20-kata.qcow2,format=qcow2 -enable-kvm
The qcow2 export creates a partitioned disk image with the rootfs extracted onto an ext4 filesystem, the kernel installed in /boot, and an extlinux (MBR) or GRUB (EFI) bootloader configured. The disk size is auto-calculated from the compressed rootfs size with a 256MiB headroom minimum, or specified explicitly with --disk-size.
qcow2 export pipeline:
.qcrows archive
│ extract → verify hashes → locate components
▼
raw disk image (parted → mkfs → mount)
│ extract rootfs onto partition
│ install kernel to /boot
│ generate fstab + bootloader config
▼
qcow2 conversion (qemu-img convert -c)
qcow2 options:
| Option | Description | Default |
|---|---|---|
--disk-size SIZE |
Disk image size (e.g., 2G, 500M) | Auto: rootfs × 2.5 + 256M |
--no-compress |
Disable qcow2 compression | Compressed |
--efi |
Create GPT + EFI System Partition | MBR + extlinux |
Export to ISO
# MBR-bootable live ISO (hybrid — dd-able to USB)
qcrows-export --format iso alpine-3.20-kata.qcrows -o alpine-live.iso
# EFI-bootable ISO
qcrows-export --format iso --efi alpine-3.20-kata.qcrows -o alpine-efi.iso
# Write to USB
dd if=alpine-live.iso of=/dev/sdX bs=4M status=progress && sync
# Boot with QEMU
qemu-system-x86_64 -m 1G -smp 2 -cdrom alpine-live.iso -enable-kvm
The ISO export creates a bootable optical disc image with the kernel and initrd in /boot/, the rootfs in /live/, and a complete Kata deployment bundle in /kata/. The ISO uses isolinux for MBR boot (with isohybrid for USB support) or GRUB for EFI boot.
ISO directory layout:
iso-root/
├── boot/
│ ├── isolinux/
│ │ ├── isolinux.bin
│ │ ├── isolinux.cfg
│ │ └── ldlinux.c32
│ ├── grub/
│ │ └── grub.cfg
│ ├── vmlinuz # Guest kernel
│ ├── initrd # Initial ramdisk
│ └── config # Kernel .config
├── live/
│ ├── vmlinuz # Kernel for live boot
│ ├── initrd # Initrd for live boot
│ └── rootfs.tar.gz # Rootfs for live boot
├── kata/ # Kata deployment bundle
│ ├── vmlinuz
│ ├── rootfs.tar.gz
│ ├── initrd
│ ├── config
│ ├── metadata.toml
│ ├── menu.toml
│ ├── boot-params.conf
│ └── build.toml
└── README.txt
ISO options:
| Option | Description | Default |
|---|---|---|
--boot-label LABEL |
Volume label for the ISO | QCROWS |
--root-label LABEL |
Label for root filesystem reference | ROOTFS |
--efi |
Create EFI-bootable ISO with grub-mkrescue | MBR + isolinux |
Prerequisites:
| Format | Required Tools |
|---|---|
| qcow2 | qemu-img, parted, mkfs.ext4, mount, tar |
| iso (MBR) | xorriso or genisoimage, isolinux/syslinux |
| iso (EFI) | grub-mkrescue |
4.5 qcrows-initrd-regen — Environment-Aware Initrd Regeneration
Rebuild the initrd component of a QCrows bundle with precise awareness of the Kata Containers runtime environment. Unlike dracut or mkinitramfs, this tool produces an initrd where kata-agent IS the final process (no pivot_root, no switch_root) and includes ONLY the kernel modules required by the detected VMM transport layer.
# Auto-detect everything from the host environment
qcrows-initrd-regen alpine-3.20-kata.qcrows
# Target a specific VMM with lz4 compression
qcrows-initrd-regen alpine.qcrows --vmm qemu --compress lz4
# Update the bundle in-place
qcrows-initrd-regen alpine.qcrows --in-place --vmm cloud-hypervisor
# Custom agent binary and extra networking modules
qcrows-initrd-regen gentoo.qcrows --agent /usr/bin/kata-agent \
--extra-modules "tun,veth,bridge" -o custom-initrd.img
Auto-detection pipeline:
.qcrows bundle
│ extract → read kernel/config → read metadata.toml
▼
Environment Detection
├── VMM: kata-runtime symlink → configuration.toml → [hypervisor.*] section
├── Compression: kernel/.config → CONFIG_RD_LZ4/GZIP/XZ/ZSTD → fastest available
├── Init style: rootfs listing → /sbin/init|/sbin/openrc-init|busybox → systemd|openrc|busybox
└── Agent: rootfs scan → /usr/bin/kata-agent → copy into initrd
▼
Module Selection (VMM Matrix)
├── Core: ext4, vfat, squashfs, overlay, loop, dm_mod, nls_*
├── VMM Required: e.g., QEMU → virtio_pci, virtio_blk, virtio_net, ...
└── VMM Optional: only if compiled (=y or =m) in kernel config
▼
Initrd Assembly
├── Directory skeleton (bin, sbin, lib, etc, proc, sys, dev)
├── kata-agent binary + shared libraries (ldd resolution)
├── /init script (init-style-aware: systemd/openrc/busybox)
├── Kernel modules (deduplicated, exclusions applied)
├── Strip locales, docs, man, Python cache, static libs, debug symbols
▼
Archive + Compress + Validate
├── cpio newc format + selected compression
├── Validate: file exists, format matches, /init present, kata-agent present, size < 512MB
└── Optional: --in-place updates the QCrows bundle and recomputes hashes
VMM kernel module matrix:
| Module | QEMU | Cloud Hypervisor | Firecracker | Dragonball |
|---|---|---|---|---|
virtio_pci |
Required | — | — | — |
virtio_mmio |
— | Required | Required | — |
virtio_blk |
Required | Required | Required | Required |
virtio_net |
Required | Required | Required | Required |
virtio_rng |
Required | Required | Required | Required |
virtio_console |
Required | Required | Optional | Required |
virtio_balloon |
Required | Required | — | Optional |
virtio_gpu |
Required | Optional | — | Optional |
virtio_scsi |
Optional | Optional | — | — |
virtio_input |
Optional | — | — | — |
virtio_crypto |
Optional | — | — | — |
virtio_mem |
Optional | — | — | — |
virtio_pmem |
Optional | — | — | — |
9pnet_virtio |
Optional | Optional | — | Optional |
Core modules included for all VMMs: ext4, vfat, nls_cp437, nls_iso8859_1, dm_mod, dm_bufio, loop, squashfs, overlay.
Compression priority order (auto-detection selects the first supported):
| Priority | Format | Config Symbol | Boot Speed | Compression Ratio |
|---|---|---|---|---|
| 1 | cpio-lz4 | CONFIG_RD_LZ4 |
Fastest | Moderate |
| 2 | cpio-zstd | CONFIG_RD_ZSTD |
Fast | Good |
| 3 | cpio-gzip | CONFIG_RD_GZIP |
Moderate | Good |
| 4 | cpio-xz | CONFIG_RD_XZ |
Slowest | Best |
Init style generation:
| Style | Detection Trigger | /init Behavior |
|---|---|---|
| systemd | /sbin/init or /sbin/systemd in rootfs |
Mount vfs → depmod → exec /sbin/init |
| openrc | /sbin/openrc-init in rootfs |
Mount vfs → depmod → exec /sbin/openrc-init |
| busybox | Neither found (default) | Mount vfs → depmod → exec /usr/bin/kata-agent as PID 1 |
Options:
| Option | Description | Default |
|---|---|---|
--vmm VMM |
Target VMM: qemu/cloud-hypervisor/firecracker/dragonball | Auto-detect |
--compress ALGO |
Compression: gzip/lz4/xz/zstd | Auto-detect from kernel config |
--format FORMAT |
Force format: cpio-gzip/cpio-lz4/cpio-xz/cpio-zstd/cramfs | Auto-detect |
--init-style STYLE |
Init system: systemd/openrc/busybox | Auto-detect from rootfs |
--agent PATH |
Path to kata-agent binary | Auto-discover from rootfs |
--in-place |
Replace initrd inside the QCrows bundle | Output to file |
--extra-modules LIST |
Comma-separated additional modules | — |
--exclude-modules LIST |
Comma-separated modules to exclude | — |
--no-strip-locales |
Keep locale files | Stripped |
--no-strip-docs |
Keep documentation | Stripped |
--keep-temp |
Preserve temp directory for inspection | Cleaned up |
5. Integration with Build Systems
5.1 Gentoo
# Build rootfs from a Gentoo stage3 with kata-agent
ROOT=/tmp/gentoo-kata emerge --root=/tmp/gentoo-kata \
sys-apps/kata-agent sys-kernel/kata-kernel \
sys-apps/openrc net-dns/dnsmasq
# Pack the result
qcrows-pack --rootfs /tmp/gentoo-kata-rootfs.tar.gz \
--kernel /tmp/gentoo-kata/boot/vmlinuz-* \
--metadata metadata.toml --menu menu.toml \
--build build.toml --output gentoo-kata.qcrows
5.2 Source Mage (Sorcery)
# Cast the required spells
cast kata-agent busybox musl
# Create rootfs from the installed system
# (sorcery provides sorcery queue/install for rootfs creation)
qcrows-pack --rootfs ./rootfs.tar.gz \
--initrd ./initrd.img \
--metadata metadata.toml --menu menu.toml \
--build build.toml --output sourcemage-kata.qcrows
5.3 Buildroot
# Build with Kata-specific defconfig
make kata_x86_64_defconfig
make
# Output: output/images/rootfs.tar.gz, output/images/bzImage
qcrows-pack \
--rootfs output/images/rootfs.tar.gz \
--kernel output/images/bzImage \
--kernel-config output/build/linux-*/.config \
--metadata metadata.toml --menu menu.toml \
--build build.toml --output buildroot-kata.qcrows
5.4 LEDE / OpenWrt
# Build with Kata target
make menuconfig # Select x86/64 target, add kata-agent package
make -j$(nproc)
# LEDE output: bin/targets/x86/64/rootfs.tar.gz
qcrows-pack \
--rootfs bin/targets/x86/64/rootfs.tar.gz \
--kernel bin/targets/x86/64/vmlinux \
--metadata metadata.toml --menu menu.toml \
--build build.toml --output lede-kata.qcrows
5.5 Lunar Linux
# Create a minimal rootfs with Lunar's module system
lin kata-agent busybox musl
qcrows-pack --rootfs ./rootfs.tar.gz \
--metadata metadata.toml --menu menu.toml \
--build build.toml --output lunar-kata.qcrows
6. Relationship to Existing Formats
| Format | Target | Self-Describing | Includes Kernel | UI Metadata | Integrity |
|---|---|---|---|---|---|
| Raw rootfs.tar.gz | Kata | No | No | No | No |
| Raw initrd.img | Kata | No | N/A | No | No |
| OCI Image | runc/CRI-O | Yes (config.json) | No | No | Yes (digests) |
| QCOW2 | QEMU | No | No | No | No |
| Docker Image | Docker/Moby | Yes (manifest) | No | No | Yes (digests) |
| QCrows | Kata/VM | Yes (metadata.toml) | Required | Yes (menu.toml) | Yes (hashes.sha256) |
QCrows fills a specific gap: no existing format provides self-description AND kernel bundling AND UI metadata AND integrity for VM container images.
7. Versioning
QCrows format versions follow semver. The format_version field in metadata.toml indicates which spec version the image conforms to.
| Version | Status | Changes |
|---|---|---|
| 0.1.0 | Draft | Initial specification |
| 0.2.0 | Draft | Kernel promoted to REQUIRED; kernel config made required; added kernel validation rules (required Kata config options, version matching, format checking); added hypervisor–kernel format matrix; boot-params.conf integration with configuration.toml |
| 0.2.1 | Draft | Added qcrows-export tool for qcow2 and ISO export; ISO layout specification with /kata/ deployment bundle; qcow2 partitioning and bootloader configuration |
| 0.2.2 | Draft | Added qcrows-initrd-regen tool for environment-aware initrd regeneration; VMM kernel module matrix (QEMU/CLH/Firecracker/Dragonball); compression auto-detection from kernel config; init style detection (systemd/openrc/busybox); initrd validation pipeline |
Breaking changes in the format will increment the major version. Consumers MUST reject images with an unsupported format_version.
8. Security Considerations
- Hash verification — Consumers MUST verify
hashes.sha256before extracting any executable content from the archive. This prevents tampering in transit. - Build provenance — The
build.tomlfile enables supply chain auditing. Consumers can verify that an image was built from known sources with expected flags. - setuid scanning — Import tools SHOULD warn about setuid binaries in rootfs (matches existing Kata validation rules).
- Kernel module loading — The
boot-params.conffile should be inspected for dangerous parameters (e.g.,module.sig_enforce=0). - No automatic execution — QCrows files contain no executable hooks. Import is purely a file copy + config update operation.