I am a little confused with the behavior of systemd services. I have the above systemd service.
[Unit]
After=libvirtd.service
[Service]
Type=simple
Environment=VM_XML=xxxxxxx
ExecStartPre=/usr/bin/bash /usr/local/lib/common/createQcowImage.sh ${VM_XML}
ExecStart=/usr/bin/bash /usr/local/lib/common/createVM.sh ${VM_XML}
ExecStop=/usr/bin/bash /usr/local/lib/common/destroyVM.sh ${VM_XML}
Restart=always
[Install]
WantedBy=multi-user.target
When this unit starts inside the createVM.sh script it creates a VM and it monitors it state. In case the PID for the VM does not exist any more the script exits with return code 1. What I noticed is that when this happens the ExecStop is executed (I was manitoring the /var/log/messages and when I destroyed manually the VM with virsh destroy I sow the echo that I put for debugging inside the script executed from ExecStop to be printed in /var/log/messages). Is this default behaviour of systemd? To execute the ExecStop when unit exits (I also tried to exit with code 0 and it was same bahaviour). This is not what I really want to do because after I destroy a VM the ExecStop tries to destroy the same VM which bring a systemd unit failure. Is there any way to avoid that?
Best Answer
You need to have a good knowledge of all the options meaning if you want to create a systemd service configuration that behaves as expected.
I suggest you to start reading the documentation (you can use e.g.
man systemd.service
) aboutType=
,ExecStart=
,ExecStop=
. MaybeType=exec
, orType=oneshot
would be more appropriate for your scripts?The behaviour that you described seems to me to be as expected indeed.
To handle the case that your VM was already stopped by its user, you need to test whether it still runs and avoid destroying it if not. Also don't forget that the ExecStop has to wait for the machine to be stopped and not just ask it to stop.
I attach my user service that I use to launch VirtualBox VM, maybe you can find some inspiration there.