qemu-system-generator#

qemu-system-generator turns a .qemu file into the systemd units that run a QEMU machine. With Nix, its own pages install it. On another distribution, build it once from its sources and install it under your home, without root. It has no crate to download: Cargo builds it offline, from the distribution’s packages alone. On Debian it also builds as a package, for every user of the host (On Debian).

host#
$ sudo apt install cargo scdoc socat virtiofsd qemu-system-x86
host#
$ sudo dnf install cargo scdoc socat virtiofsd qemu-system-x86
host#
$ sudo add-apt-repository universe
$ sudo apt install cargo scdoc socat virtiofsd qemu-system-x86

Build it. The generated units call qmp-powerdown by the path given here:

$ git clone https://github.com/linux-kdevops/qemu-system-generator
$ cd qemu-system-generator
$ QMP_POWERDOWN=~/.local/share/qemu/systemd/qmp-powerdown \
    cargo build --release --offline --locked

Install the generator, the file its units read and the two units that run it for your service manager:

$ install -D --verbose --target-directory ~/.local/bin \
    target/release/qemu-system-generator
$ install -D --verbose --mode=0644 \
    --target-directory ~/.local/share/qemu/systemd data/qmp-powerdown
$ install -D --verbose --mode=0644 \
    --target-directory ~/.local/share/systemd/user \
    data/qemu-system-generator.path data/qemu-system-generator.service

systemd looks for a bare command name in the system’s directories only, so name the generator by its path in the installed service:

~/.local/share/systemd/user/qemu-system-generator.service#
--- a/.local/share/systemd/user/qemu-system-generator.service
+++ b/.local/share/systemd/user/qemu-system-generator.service
@@ -16,7 +16,7 @@ [Service]
 # The generator never removes what it wrote for a file that is gone.
 ExecStartPre=find %t/systemd/user -maxdepth 1 -type f -exec grep --quiet --fixed-strings --line-regexp "# Automatically generated by qemu-system-generator" {} \; -delete
 ExecStartPre=find %t/systemd/user -mindepth 2 -maxdepth 2 -path "*.wants/*" -xtype l -delete
-ExecStart=qemu-system-generator --user %t/systemd/user
+ExecStart=%h/.local/bin/qemu-system-generator --user %t/systemd/user
 # Not a second ExecStart=: the generator exits 1 when one file fails but
 # still writes the others, and their units must load all the same.
 ExecStopPost=systemctl --user daemon-reload

Install the manual pages:

$ mkdir --parents --verbose ~/.local/share/man/man5 ~/.local/share/man/man8
$ scdoc <man/qemu-systemd.unit.5.scd >~/.local/share/man/man5/qemu-systemd.unit.5
$ scdoc <man/qemu-system-generator.8.scd \
    >~/.local/share/man/man8/qemu-system-generator.8

Enable the units. They run the generator at login and whenever ~/.config/qemu/systemd/ changes:

$ systemctl --user daemon-reload
$ systemctl --user enable --now qemu-system-generator.path \
    qemu-system-generator.service