Repository navigation
Releases: contemper-project/contemper
Release list
v0.4.0
0.4.0 (2026-10-10)
Features
- build: build with podman, chosen with --engine or automatically (89c98ea)
- disk: show phases and debugfs write progress while populating ext4 (4e80b02)
- progress: add a phase label and percent readout to stages (84b0cab)
- source: add a containers-storage: source read through podman save (69720d4)
- source: allow variants outside the support image's namespace, pulled anonymously (9406630)
- support: read support image declarations from config labels (5b0dffb)
- target: default the incus targets to the Incus support image (7f68d05)
- target: show qcow2 conversion progress and the remaining assembly phases (1e88d81)
Bug Fixes
- disk: refuse a NUL byte in a debugfs script argument (762339c)
- examples: use only the firmware console for GRUB on arm64 (dc7591d)
- guestmeta: add a repeated fstab line once (60be5c7)
- guestmeta: split fstab fields on spaces and tabs only (e41a9b1)
- progress: clear the spinner line when a stage fails in TTY mode (9b45642)
- progress: don't panic on an empty stage icon in TTY mode (039595b)
- progress: print a stage's final line only once (dec2cdc)
- progress: wait for the spinner goroutine when a stage stops (1019b9a)
- qemu: use neoverse-n1 for arm64 guests under TCG (0fa28e1)
- source: keep an archive named only by its extension (8086bc2)
- uki: refuse implausible stub layouts and section names (ad7d258)
- uki: require the MZ signature in a PE stub (89b13b9)
Dependencies
- gomod: update go module directive to v1.27.2 (bab7d2d)
- gomod: update go module updates (minor & patch) (b93c04c)
Documentation
- build: cover podman in the build docs and getting started (3710222)
- build: mention podman as a build engine (c77aa1d)
- comparison: add d2vm (dafa4d3)
- comparison: correct the bootc scope and semantics for both boot modes (c50038b)
- contributing: describe the fuzz tests (9a0becf)
- contributing: note that releases wait for the checks (5954a12)
- design: drop the implemented notices (7e3bb07)
- design: keep only the planned part of the phases note (7a78252)
- design: mark bootloader images and multi-arch as shipped (8f0ded6)
- getting-started: verify downloads offline with the Sigstore bundle (ece4dc9)
- guide: describe the assembly step readout (67736b8)
- list podman builds as shipped, not planned (927ffa1)
- readme: compare contemper with d2vm (a8b1305)
- readme: describe the UKI and bootloader boot modes (f4563e2)
- readme: list Secure Boot and multi-arch under works today (4076d2c)
- sources: document the containers-storage: source (944cfa1)
- support: describe support images as Containerfiles with labels (eff4d38)
- target: describe the Incus support image as the incus default (3b0204f)
v0.3.0
0.3.0 (2026-10-04)
Features
- bundle: add the group file format for multi-arch runs (ce95b4b)
- bundle: record the boot mode in the manifest (0849c18)
- convert: boot an image from its own bootloader when it asks to (0154cfb)
- convert: convert every requested architecture in one run (d283159)
- convert: support the io.contemper.secure-boot label (1926e00)
- convert: write a group file when several architectures are requested (13b0f5e)
- deploy: boot the host's architecture from a multi-arch group file (f584c72)
- disk: size the ESP per image and copy a file tree onto it (39a91b0)
- examples: add a Debian image that boots with its own GRUB (2608e60)
- guestmeta: mount the ESP at /boot/efi in bootloader images (8fcb1b9)
- qemu: boot Secure Boot firmware for bundles that ask for it (96d7fac)
- source: list a source's platforms and parse multi-arch --arch values (a1b674b)
- source: read the io.contemper.boot label (fc1cb62)
- validate: check the bootloader tree of images that bring their own (8e77a26)
- volume: add a per-volume seed opt-out and report it at convert time (ebe1d9d)
- volumes-support: seed a newly formatted volume from the image's content (73d1a0e)
Bug Fixes
- convert: cap the sizes an image label can request (465d1f6)
- convert: return a bundle value from the Secure Boot checks (683a0a5)
- deploy: refuse bundle disks that refer to other host files (3c52a44)
- deploy: tie an instance's volumes to the image that created them (afc8456)
- disk: create the root filesystem with a fixed ext4 feature set (9bfd1c0)
- disk: only pass known extended attribute names to debugfs (bc6bddf)
- examples: include fsck in the Debian example's initrd (c31b398)
- examples: include fsck in the Debian GRUB example's initrd (9baf382)
- progress: escape control characters in printed image strings (3248fbd)
- rootfs: bound the content read from an image (82bc823)
- support: keep variant images in the support image's namespace (d840352)
Performance Improvements
- convert: keep disk.raw sparse (14dff18)
- disk: copy the root filesystem into the disk image sparsely (039499e)
Documentation
- bootloader: document images that bring their own bootloader (74c23a1)
- bootloader: document Secure Boot for bootloader images (c016487)
- contributing: describe adding a distribution to the test matrix (e945b62)
- contributing: describe the scheduled distribution tests (5555cbf)
- contributing: document bug-reporting and new-functionality testing (c2680b7)
- contributing: point to make lint instead of a bare golangci-lint invocation (48934d8)
- examples: note that debian-grub can boot with Secure Boot (6ae8718)
- getting-started: lead with contemper build and deploy (d0bd8f4)
- guide: add a distributions page (383bb04)
- guide: describe long-lived VMs and what changes for them (f1a1bdf)
- guide: describe the fixed root filesystem feature set (b85f2f3)
- guide: explain choosing between UKI and bootloader images (7dbd2c3)
- guide: name the openSUSE arm64 kernel image (3becd0d)
- guide: note FSTYPE for initramfs-tools root fsck (e366c01)
- guide: note that disk.raw is written sparse (b9dde34)
- multi-arch: document converting every architecture and the group file (72b9815)
- multi-arch: document deploying from a group file (37228f6)
- security: add a direct reporting link and a disclosure timeline (ca1c592)
- uki: explain where the embedded systemd-stub binaries come from (64c53d3)
- volume: document seeding a volume from the image's content (68dfbf1)
v0.2.0
0.2.0 (2026-09-29)
Features
- cli: add contemper build to build and convert in one step (59753af)
- release: ship shell completions in archives, packages and the cask (1575a8c)
- source: read images from the local Docker daemon via docker-daemon: (4a3cf9e)
Bug Fixes
- cli: stop subprocesses and clean up temporary files on interrupt (f3c847d)
- progress: print no failure line for a step stopped by an interrupt (5f48f16)
- qemu: report a deploy stopped by an interrupt as interrupted (ccef0f4)
- release: use postflight_steps in the Homebrew cask (db460fe)
Documentation
v0.1.1
0.1.1 (2026-09-28)
Bug fixes
- Files in converted images could get wrong modification times: debugfs
read some timestamps as calendar dates, and a few were far enough off
that conversion failed. Convert again with 0.1.1 to get correct times. - Converting an image with hardlinks into a full directory could
silently drop the link and fail later in e2fsck. contemper now makes
room first, and fails right away if debugfs can't create a link.
Examples and docs
- New Arch Linux example (amd64), boot-tested in CI.
- Install instructions give the correct .deb file name.
- CONTRIBUTING describes how work is planned, prioritized and triaged.
New contributors
- @DarkressX made their first
contribution in #89:
the Arch Linux example, and finding and fixing the modification-time
and hardlink bugs above.
v0.1.0
0.1.0 (2026-09-28)
The first release of contemper: build bootable VM images from container
images. You author a VM image as an ordinary container build, push it
like any other image, and contemper turns it into a disk.
This is an early, proof-of-concept release. The path from image to
booting VM works end to end and is tested in CI, but expect rough edges,
missing features and breaking changes before 1.0.
What it does
contemper convertturns a contemper-ready OCI image into a
bundle: a UEFI-bootable qcow2 disk (a Unified Kernel Image on the EFI
partition, a writable ext4 root) pluscontemper.json, which records
the image digests and support images the disk came from. A failed
conversion leaves no partial bundle behind, and converting again
replaces the previous bundle as a whole.- Nothing from the image runs during conversion. contemper merges
layers and reads files; it needs no container runtime, no root and no
emulation. An arm64 disk builds on an x86-64 host, and the other way
round. - Sources: registry references (using the docker/podman
credentials you already have), OCI archives, OCI layouts and docker
archives. Multi-platform images resolve to the target architecture. - Support images layer what a platform needs on top of your image.
Their variants let one support image adapt to what it's merged into,
for example OpenRC vs. systemd. - Volumes:
VOLUMEdeclarations become separate data disks, sized
by an image label or at deploy time (deploy --volume /data=10GiB),
and attached per instance. A helper merged into the image formats a
blank volume on first boot and reuses an existing one, on OpenRC and
systemd. contemper deploy --to local-qemuboots a bundle under QEMU, with
KVM or HVF acceleration where available and software emulation for a
foreign architecture.- Runs on Linux and macOS, amd64 and arm64.
Install
- macOS (Homebrew):
brew install contemper-project/tap/contemper
(also installs e2fsprogs and QEMU). - Debian/Ubuntu: download the
.debbelow and
sudo apt install ./contemper_0.1.0_amd64.deb. - Fedora/RHEL: download the
.rpmbelow and
sudo dnf install ./contemper-0.1.0-1.x86_64.rpm. - Anything else: the
.tar.gzarchives below, plus the host tools:
e2fsprogs (mkfs.ext4,debugfs,e2fsck) andqemu-imgto convert,
QEMU and UEFI firmware to deploy.
The packages install what convert needs; for deploy, add the
emulator and firmware for the bundles you boot. See
Install
and Host tools.
Every archive and package is listed in checksums.txt and carries a
signed build provenance attestation:
$ gh attestation verify contemper_0.1.0_linux_amd64.tar.gz --repo contemper-project/contemperGetting started
- Documentation: https://contemper-project.github.io/contemper/
- An image needs a kernel, a generic initrd and an init system at fixed
paths, and theio.contemper.ready="true"label. See
Authoring images;
examples/has an Alpine (OpenRC) and a Debian (systemd) image.
Before you rely on it
This release is for trying contemper out, not for production use. CLI
flags and the bundle format will still change (bundles are
formatVersion 1). Known limitations:
- An image where a later layer removes or replaces the target of a
hardlink is rejected. - Paths and symlink targets longer than about 1000 bytes are rejected.
- A bundle for a foreign architecture boots under software emulation,
which is slow.
Please report bugs and ideas in the
issue tracker,
and security issues as described in
SECURITY.md.