virtctl is an instantiable systemd service for starting/stopping libvirt-based virtual machines (it interacts with virsh
). It works out of the box with libvirt's default directory layout, i.e. systemctl start virtctl@DomainName
starts /etc/libvirt/qemu/DomainName.xml
, but can also be easily configured if you keep your files somewhere else.
If you're looking for an easy and customizable way to start and stop your VMs with systemd, you might want to take a look!
Copy the files from this repository to the following directories (alternative: AUR) and issue a systemctl daemon-reload
afterwards:
root
┣━━━etc
┃ ┣━━━systemd
┃ ┃ ┗━━━system
┃ ┃ ┣━━━hypervisor.target
┃ ┃ ┣━━━[email protected]
┃ ┃ ┗━━━[email protected]
┃ ┃ ┗━━━file_layout.conf.example
┃ ┗━━━virtctl.d
┃ ┣━━━functions.sh
┃ ┣━━━instance_startpost.example
┃ ┗━━━instance_stoppost.example
┃
...
This is the full installation. For a minimal installation, only [email protected]
is required (at the expense of some functionalities, of course).
In its default configuration, virtctl can already start and stop your VMs if
- you adopted libvirt's directory layout and keep your domain XML in
/etc/libvirt/qemu
- you kept your naming consistent, i.e. for every domain the filename
DomainName.xml
matches exactly with the real name inside the XML,<name>DomainName</name>
.
If your domain XML is somewhere else, take a look at file_layout.conf.example
on how to override that setting with a drop-in file. The second requirement however must always be followed.
virtctl provides its own mechanism to run "post start" and "post stop" actions for your VMs, similar to libvirt's own hooks. Just create a file DomainName_startpost
and/or DomainName_stoppost
, put your commands in there (these files get sourced by a bash shell, so no shebang!) and place it in /etc/virtctl.d
or in the directory your domain XML is in.
If you have "post start" or "post stop" files in both locations, the one besides your domain XML takes precedence and the other one in /etc/virtctl.d
will be ignored (they do not stack up / no include hierarchy).
If you want to forward ports from your host to your guest, you can use the function forward_port
in your "post start" action. Check the example in instance_startpost.example
.
Port forwardings are automatically cleared when the VM shuts down.
virtctl provides a target named hypervisor.target
. It depends on and is reached after multi-user.target
. If you choose to systemctl enable virtctl@DomainName
, it gets linked into hypervisor.target.wants
.
The intention is to stay clear of multi-user.target
so that you have a way to easily enable (or disable) all VMs at once, be it temporarily with systemctl isolate hypervisor
or permanent/on boot with systemctl set-default hypervisor
.
- Multiple physical and/or virtual network adapters aren't supported.
systemctl start virtctl@DomainName
systemctl status virtctl@DomainName
systemctl stop virtctl@DomainName
If you want systemd to automatically start/stop your VMs on boot/shutdown, enable them and set your default target.
systemctl enable virtctl@DomainName
systemctl set-default hypervisor
"It should work!" - and I'm hoping it does for you as well. Of course I cannot guarantee for anything, but I'm using this myself on a daily basis on multiple Arch Linux boxes.
virtctl is available in AUR, provided by NihlisticPandemonium. Thank you very much 🙂!