cockpit-kata/qcrows-spec.md

809 lines
31 KiB
Markdown
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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
1. **Self-describing** — A management UI (Cockpit, etc.) can render a QCrows image's name, description, compatibility, and requirements without inspecting the filesystem contents.
2. **Build-system agnostic** — Works equally well with source-based distros (Gentoo, Source Mage, Lunar), embedded build frameworks (Buildroot, LEDE), or any custom pipeline.
3. **Integrity-verifiable** — Every component is checksummed; the entire bundle can be verified before import.
4. **Kernel-rootfs coupled** — The guest kernel and its `.config` travel 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.
5. **Cockpit-native** — The `menu.toml` entry 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.
```toml
[ 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."
```toml
[ 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 | 100500 MiB |
| development | Includes build tools, debug symbols, strace | 500 MiB2 GiB |
| embedded | Built with Buildroot/LEDE for resource-constrained targets | < 30 MiB |
| hardened | Security-hardened (PaX, SELinux, musl, stripped) | 50200 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:
1. Extract the archive to a temp directory
2. Compute SHA-256 of each file listed in `hashes.sha256`
3. Compare against the stored checksums
4. 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/init` or `/usr/sbin/init` init system
- `/usr/bin/kata-agent` or `/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:
1. **Verify kernel binary exists** At least one of `kernel/vmlinuz` or `kernel/vmlinux` must be present
2. **Verify kernel config exists** `kernel/config` must be present and parseable
3. **Verify kernel version** The version string embedded in the kernel binary must match `kernel.version` in `metadata.toml`
4. **Check required Kata config options** The kernel config must have these options enabled:
- `CONFIG_VSOCKETS=y` vsock communication for kata-agent
- `CONFIG_VIRTIO=y` virtio device support
- `CONFIG_VIRTIO_PCI=y` (or `CONFIG_VIRTIO_MMIO=y`) virtio transport
- `CONFIG_DEVTMPFS=y` device tmpfs for /dev
- `CONFIG_DEVTMPFS_MOUNT=y` auto-mount devtmpfs
5. **Check kernel format** The binary must be a valid ELF (vmlinux) or bzImage (vmlinuz) depending on the declared type
6. **Check kernel size** Warn if kernel exceeds 100MiB (uncompressed) or 50MiB (compressed)
**HypervisorKernel 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:
1. Copy the kernel to `/usr/share/kata-containers/` alongside the rootfs
2. Copy the kernel config to `/usr/share/kata-containers/` for reference
3. Update the relevant `configuration.toml` to point to the new kernel path
4. If `boot-params.conf` exists, append its parameters to the hypervisor's `kernel_params` in `configuration.toml`
5. Verify the kernel version matches `kernel.version` in metadata
6. 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.
```ini
# 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.
```toml
[ 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:
1. Verify `hashes.sha256` integrity
2. Validate `metadata.toml` schema
3. Check `image.compatibility.hypervisors` against the host's VMM
4. Check `image.arch` against the host's architecture
5. Verify rootfs contains `/sbin/init` and `kata-agent`
6. Verify initrd format matches the `initrd.type` declaration
---
## 4. Tooling
### 4.1 `qcrows-pack` — Create a QCrows Archive
```bash
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
```bash
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
```bash
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:
1. **QEMU direct boot** Export to qcow2 and boot as a standalone VM without Kata
2. **Live USB** Write an ISO to a USB stick for portable, bootable Kata images
3. **Kata deployment from media** ISO contains a `/kata/` directory with all components ready for host-side import
#### Export to qcow2
```bash
# 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
```bash
# 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.
```bash
# 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
```bash
# 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)
```bash
# 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
```bash
# 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
```bash
# 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
```bash
# 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 hypervisorkernel 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
1. **Hash verification** Consumers MUST verify `hashes.sha256` before extracting any executable content from the archive. This prevents tampering in transit.
2. **Build provenance** The `build.toml` file enables supply chain auditing. Consumers can verify that an image was built from known sources with expected flags.
3. **setuid scanning** Import tools SHOULD warn about setuid binaries in rootfs (matches existing Kata validation rules).
4. **Kernel module loading** The `boot-params.conf` file should be inspected for dangerous parameters (e.g., `module.sig_enforce=0`).
5. **No automatic execution** QCrows files contain no executable hooks. Import is purely a file copy + config update operation.