> For the complete documentation index, see [llms.txt](https://docs.layeronecloud.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.layeronecloud.com/pve-microvm/changelog.md).

# Changelog

Source project: `pve-microvm` (migrated from `docs/changelog.md`). Run commands from the code checkout and directory specified below, not from this documentation repository.

## Unreleased <a href="#unreleased" id="unreleased"></a>

* Defer the pvedaemon restart out of the postinst. pvedaemon owns the node's web-console sessions, so restarting it inline killed the shell an operator was installing from; dpkg never got an exit status and the package was left half-configured (`iF`), needing `dpkg --configure -a` from a console that was about to die the same way. Found installing 0.4.1 on a lab node.
* Probe for the guest-agent virtio-serial port instead of hardcoding `/dev/vport1p1`. The index follows virtio probe order, and a Debian trixie guest on PVE 9.1.9 / QEMU 10.1.2 gets `/dev/vport2p1`, so the previous unit could never bind. Confirmed on hardware: `qm agent <vmid> ping` now answers.
* Correct the docs' claim that `/dev/vport1p1` is created and that the named `/dev/virtio-ports/` symlink is merely sometimes missing. Neither held: the number moves, and the named device is never created on these guests.
* Refuse template refresh for ordinary or running VMs; check prerequisites before deleting a template and abort on failed deletion.
* Preserve build directories whenever bind mounts remain or mount inventory fails, avoiding recursive deletion through host mounts.
* Download the 9Front image before decompressing it.
* Preserve non-zero guest exit codes in the ephemeral runner and clean up clones after configuration failures.
* Start the single packaged QEMU guest-agent service against `/dev/vport1p1` so minimal systemd guests do not depend on a missing named udev symlink.
* Remove legacy custom-agent units, stale drop-ins and service masks during template construction to prevent competing `qemu-ga` processes.
* Detect the packaged agent binary under `/usr/sbin` or `/usr/bin`, covering Debian/Ubuntu and Enterprise Linux templates.
* Add rootfs contract tests plus live Debian 13 and AlmaLinux 10.2 guest-agent validation.
* Detect managed disk formats through `PVE::Storage::parse_volname()` so file-backed qcow2 linked clones boot with the correct QEMU block driver.
* Fail command generation when PVE cannot identify a managed volume format instead of silently treating it as raw.
* Document storage-specific formats and the fixed `scsi0` root / `scsi1` cloud-init device order.
* Repair empty or dangling OCI `/etc/resolv.conf` files before chroot package installation.
* Fail template builds when apt, apk, dnf, microdnf, tdnf, or yum package installation fails instead of publishing a bare rootfs.
* Use NetworkManager with an autoconnect DHCP profile and full `util-linux` on Enterprise Linux 8/9/10; remove the unavailable `dhclient` fallback from that path.
* Add regression coverage for resolver repair, Enterprise Linux detection and package/service contracts.

## v0.3.9 (2026-05-15) <a href="#v039-2026-05-15" id="v039-2026-05-15"></a>

* Kernel overlay: add BPF\_SYSCALL + BPF\_JIT for Docker/runc support
* CI: bump GitHub Actions to v5/v3 (Node.js 22, no deprecation warnings)
* Workaround: Debian stock kernel for Docker workloads until kernel rebuild

## v0.3.5 (2026-04-27) <a href="#v035-2026-04-27" id="v035-2026-04-27"></a>

50 shipped features, 21 guest OS types.

### Features <a href="#features" id="features"></a>

* `qm create/start/stop/destroy` with microvm
* Serial console via `qm terminal` and PVE web UI (xterm.js)
* OCI image import and template cloning
* All PVE storage backends (LVM, LVM-thin, ZFS, Ceph, NFS)
* Pre-built microvm kernel (6.12.22 from defconfig)
* Web UI machine type dropdown + Create µVM dialog
* Balloon device for memory reporting
* Guest agent (virtio-serial, auto-retry)
* Networking (tap, bridge, VLAN, DHCP via cloud-init)
* `microvm-init` for minimal OCI images
* GitHub Actions CI/CD with kernel + initrd build
* Cloud-init / user-data — SSH keys, hostname, network config
* Linked clones — instant LVM snapshot cloning
* dpkg trigger — auto-reapply patches on `qemu-server` upgrades
* SSH agent forwarding via vsock (`pve-microvm-ssh-agent`)
* vsock host↔guest sockets (CID = VMID + 1000)
* virtiofs shared folders (`pve-microvm-share`)
* 9p filesystem sharing (`pve-microvm-9p`, no daemon needed)
* `qm shutdown` — graceful shutdown via guest agent
* Disk resize (`qm disk resize`)
* vzdump backup (stop-mode)
* Offline migration between nodes (shared storage, 2s on CIFS)
* HA support (ha-manager add/relocate, stop-migrate-start cycle)
* Snapshots (`qm snapshot`)
* Firewall integration (tap on vmbr0)
* Resource accounting (cluster resources)
* `onboot` / startup order
* Nested virtualization (KVM passthrough)
* Template profiles (minimal/standard/full, --no-docker, --no-ssh, --no-agent)
* Performance benchmarking (`pve-microvm-bench`)
* Ephemeral VMs (`pve-microvm-run`)

### Guest OS (21 types) <a href="#guest-os-21-types" id="guest-os-21-types"></a>

* 13 Linux: Debian, Ubuntu, Alpine, Fedora, Rocky, Alma, Amazon, Oracle, UBI, Photon, Azure Linux
* SmolBSD (NetBSD, 31ms boot, virtio-mmio)
* OpenWrt (router OS, 13 MB)
* OPNsense (FreeBSD firewall, 500 MB)
* 9Front (Plan 9)
* OSv (unikernel)
* gokrazy (Go appliance)
* Firecracker rootfs (ext4 import)

### Web UI <a href="#web-ui" id="web-ui"></a>

* Create µVM dialog with OCI image picker
* ⚡ amber bolt icon for microvm VMs
* xterm.js console (auto-selected for microvm)
* Panel hiding (BIOS/EFI/USB/PCI/TPM hidden)
* One-click clone from templates
* Context menu: serial console + clone
* Dark mode support

### Bug fixes (v0.3.1–v0.3.5) <a href="#bug-fixes-v031v035" id="bug-fixes-v031v035"></a>

* Cloud-init drive order: scsi0 always first (/dev/vda)
* `valid_drive_names()` returns 0 at runtime on qemu-server 9.1.6
* `drive_is_cdrom($drive, 1)` excluded cloud-init from detection
* dpkg trigger loop (interest-noawait)
* postinst refreshes deployed files idempotently on upgrade without restoring stale backups

### Audit safety follow-up (unreleased) <a href="#audit-safety-follow-up-unreleased" id="audit-safety-follow-up-unreleased"></a>

* Refuse rollback when backup provenance is unknown or patched PVE files have since changed. This intentionally blocks unsafe removal on legacy installs until an operator reconciles backups with the installed qemu-server version.
* Refuse unsupported QemuServer patch layouts rather than writing a false success marker.
* Recheck Machine.pm on the stamped apply fast path.
* Fail release kernel builds when required Kconfig options are missing.
* Preserve OCI import diagnostics and fail on disk attachment errors.
* Validate both upstream Perl layouts before applying either transform; verify backup contents as well as live files before rollback.
* Remove only the injected UI script during rollback, retaining unrelated upstream template changes.
* Reject missing, non-integer, or out-of-range guest-exec exit codes.
* Honor read-only drive configuration and CD-ROM write protection in QEMU arguments.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.layeronecloud.com/pve-microvm/changelog.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
