You are not logged in.
I have a QEMU guest managed through libvirt as a regular (non-root) user. To start/stop it manually, I run "virsh start/stop" as that user, or alternatively, I start them via virt-manager (via "qemu:///session" URI).
Now I want to autostart/autostop this guest as a systemd service at system boot/shutdown. I have read through libvirt wiki page as well as man page for libvirt-guests, but it looks to me as if it only supports system sessions (i.e. guests that run as root).
Is it possible to use this service to also start/stop guests running under regular users' accounts? If yes, how? And if not, what would be the analogous way of doing it?
Last edited by bachtiar (2023-01-20 14:16:10)
Offline
Create a libvirt-guests user service...
https://wiki.archlinux.org/title/Systemd/User
Offline
But what should the user service unit call?
Offline
But what should the user service unit call?
Did you ever work out how to do this?
I have a specific user who runs the VMs, so I ran
$ sudo /usr/bin/runuser -u hass_user -- virsh autostart hass
Domain 'hass' marked as autostarted
$ sudo /usr/bin/runuser -u hass_user -- virsh dominfo hass
...
Autostart: enable
...
expecting it to autostart, but it doesn't. I'm not entirely sure how to do it the systemd way, especially since the user who runs the VMs never actually logs in, so presumably has no systemd jobs running. I presume that the root systemd job is not relevant here.
Another alternative might be to put in /etc/rc.local
sudo /usr/bin/runuser -u hass_user -- virsh start foobar
EDIT:
Okay, so /etc/rc.local is deprecated in Arch. Instead, I tried putting the following in /etc/systemd/system/start_hass.service
[Unit]
Description=Start Home Assistant VM
[Service]
Type=oneshot
ExecStart=/usr/bin/runuser -u hass -- virsh start hass
TimeoutSec=0
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
then enabling the service.
On reboot, this seems to start the VM. I can connect to the service, and I can see (e.g. in htop) that the correct user is running it. However, the systemd job itself fails, and journalctl says
Apr 14 15:09:09 qi runuser[688]: error: Domain is already active
Also, if I start it like this, virsh doesn't seem to know about it.
$ sudo /usr/bin/runuser -u hass -- virsh list --all
Id Name State
-----------------------
- hass shut off
This doesn't seem to work fully. I'm a bit loathe to start it up this way, since this might cause other issues downstream. Surely there has to be a better way to do this. It shouldn't be uncommon, but my searching hasn't brought up anything conclusive.
Possibly we could create a --user version of /usr/lib/systemd/system/libvirtd.service, but it's full of so many dependencies that this feels like a nightmare (e.g. libvirtd.socket, libvirtd-ro.socket, libvirtd-admin.socket, virtlogd.socket, virtlockd.socket, and a bunch of system services).
Last edited by Salkay (2024-04-14 06:30:09)
Offline
Here is the solution.
Create a systemd service, e.g. in /etc/systemd/system/start_hass.service
[Unit]
Description=Start Home Assistant VM
[Service]
Type=oneshot
ExecStart=-/usr/bin/runuser -u hass -- virsh start hass
TimeoutSec=0
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
then enable the service.
This took me hours and hours to work out. After rebooting, if you runuser from another user, virsh won't know anything about it.
$ sudo /usr/bin/runuser -u hass -- virsh list --all
Id Name State
-----------------------
- hass shut off
However, if you machinectl into the same user, virsh can see it fine.
$ sudo machinectl shell hass@
Connected to the local host. Press ^] three times within 1s to exit session.
[hass@hostname ~]$ virsh list --all
Id Name State
----------------------
1 hass running
The weird thing is if instead of this you manually run /usr/bin/runuser -u hass -- virsh start hass, virsh works fine from both commands above. In comparison, launching from systemd as above functions fine (i.e. the VM is indeed started), but you can only see it with the second of the two commands. Perhaps something to do with different environments when you launch it from systemd.
I also tried a bunch of different things in the service script, including putting it in a separate bash command, a separate script, using systemd-run, but none worked. The final issue is that systemd will report this service as failed, even though it (functionally) works. So I had to prepend "-" to the command so that systemd would ignore the failure.
Offline
Thanks for the suggestion. Have you perhaps tried using "User" and "Group" directives in systemd [Service] units?
Or perhaps "systemd --user"?
Or perhaps "loginctl enable-linger"?
Offline
I did try systemd --user, and that didn't work. I also read somewhere that this might need loginctl enable-linger, but I didn't get that far. And I didn't try User or Group at all.
I had spent so many hours working this out, so even though this wasn't perfect, I was happy enough!
Offline