2022-02-03T22:39:00

kvm & systemd

How to run kvm virtual guests using systemctl so they automatically start on boot and stop during shutdown. These will be quick notes, if anything needs more explanation just leave a comment.

Networking

Virtual switch for the virtual machines - vde2 + brctl

apt-get install bridge-utils qemu-system-x86 vde2 uml-utilities socat net-tools

edit /etc/network/interfaces

auto tap9
iface tap9 inet static
        address 0.0.0.0
        tunctl_user uml-net

auto br0
iface br0 inet dhcp
  bridge_ports eth0 tap9
  bridge_fd 0
  bridge_stp off

create /etc/systemd/system/vde_switch_internal.service

[Unit]
Description=vde switch for internal connections
After=networking.service
Wants=networking.service

[Service]
Type=forking
PIDFile=/run/vde_switch/vde_c.pid
Restart=always
RestartSec=3s
User=uml-net
ExecStartPre=+/usr/bin/install -o uml-net -g uml-net -d /run/vde_switch
ExecStart=/usr/bin/vde_switch -sock /run/vde_switch/vde_c.ctl -tap tap9 --daemon --pidfile /run/vde_switch/vde_c.pid --mode 0770

[Install]
WantedBy=multi-user.target

then systemctl start vde_switch_internal

create /usr/bin/kvm-stop-guest

#!/bin/bash

if [ "$1" == "" ]; then
	echo need one argument - guest name
	exit 1
fi

MON_FILE="/run/qemu-monitor-socket_$1"

if [ ! -e $MON_FILE ]; then
	echo $1 not running? $MON_FILE not present
	exit 0
fi

echo shutting down $1 via $MON_FILE

echo "system_powerdown" | socat - unix-connect:$MON_FILE
while [ -e $MON_FILE ]; do
	echo waiting for termination
	sleep 5
done

lvcreate -L 10G -n HNAME vg0 disk image using LVM or dd if=/dev/zero of=/srv/HNAME.img bs=1G count=10 disk image using file.

create /etc/systemd/system/kvm-HNAME.service, replace HNAME, in service name and 2x inside service, for name/hostname of the guest machine

[Unit]
Description=kvm machine
After=network-online.target
Wants=network-online.target

[Service]
Environment=SN=HNAME
Environment=DISKFN=/dev/vg0/HNAME
Environment=MACADDR=52:54:00:00:00:01
Environment=SPORT=6900
Environment=SPW=SUPERSECRET
Environment=BOOTCDIMG=/var/tmp/debian-11.2.0-amd64-netinst.iso
Type=simple
Restart=no
User=root
ExecStart=kvm -drive file=${DISKFN},format=raw,index=0,media=disk -m 1024 -smp 2 -cpu host -name ${SN},process=${SN} -machine type=pc,accel=kvm -monitor unix:/run/qemu-monitor-socket_${SN},server,nowait -net nic,macaddr=${MACADDR} -net vde,sock=/run/vde_switch/vde_c.ctl -vga qxl -spice port=${SPORT},password=${SPW} -display none -boot d -cdrom ${BOOTCDIMG}
ExecStop=/usr/bin/kvm-stop-guest ${SN}
TimeoutStopSec=60s

[Install]
WantedBy=multi-user.target

systemctl start kvm-HNAME and connect to the machine using spicy --uri spice://localhost:6900

once system is installed, remove -boot d -cdrom ${BOOTCDIMG} from service file, reload systemctl and enable both vde_switch_internal and kvm-HNAME to start on system start up.