You are not logged in.
Hello everybody. I have a problem that might be easy to solve to some of you. My goal is to shut down gracefully my system, taking down all the virtual machines running before actually shut the host system down.
At the moment, to do so I created these aliases in my .zshrc:
alias sudocheck="/bin/bash /home/damiano/.script/sudocheck"
alias sudo="sudocheck "
That point to this script here:
#!/bin/bash
# This script checks for what is being passed to sudo.
# If the command passed is poweroff or reboot, it
# launches a custom script instead, that also looks
# fur currently running virtual machines and shuts them.
sudocheck() {
if [ $1 == "poweroff" ] || [ $1 == "reboot" ]; then
eval "sudo /home/damiano/.script/graceful $@"
else
eval "sudo $@"
fi
}
sudocheck $@
That goes to this one if a sudo shutdown or a sudo reboot is being launched by me:
#!/bin/bash
i=0
e=0
## if virsh finds VMs running
virsh -c qemu:///system list | awk '{ print $3}' | \
if grep running > /dev/null ; then
virsh -c qemu:///system list --all | grep running | awk '{print "-c qemu:///system shutdown "$2}' | \
## shuts them dow gracefully
xargs -L1 virsh
## wait 30 seconds for them to go down
until (( i >= 30 || e == 1 )) ; do
## check every second for their status
virsh -c qemu:///system list --all | awk '{ print $3}' | \
if grep -E '(running|shutdown)' > /dev/null ; then
## keep waiting if still running
if (( i <= 30 )) ; then
sleep 1 && let i++ && echo $i
else
e=1 && notify-send 'Shutdown has been canceled' 'Please check the status of your virtual machines: seems like even though a stop signal has been sent, some are still running.' --urgency=critical
fi
else
## if no machine is running anymore, original power command can be executed
e=1 && eval $@
fi
done
fi
Now, despite it works, I would like to find something more elegant. First of all, this works only if I launch the command from a zsh shell. Second I don't like the idea that for every sudo I launch I have a custom script in the middle.
For example it would be so much better to put this more down in the line, so that even if I shut down the pc through a desktop environment GUI I still get that check done.
Please advice and help me, gurus!
Last edited by reddhawk (2020-03-13 12:30:56)
Offline
alias poweroff="<yourscript> && sudo /usr/bin/poweroff"
This will save you from running middle script for every sudo run.
Arch is home!
https://github.com/Docbroke
Offline
Another way of doing it more generically could be to create a systemd service and let systemd take care of it for you. That way, it will happen no matter how you poweroff!
Offline
alias poweroff="<yourscript> && sudo /usr/bin/poweroff"
This will save you from running middle script for every sudo run.
Thanks for the idea doc, I know. initially I didn't make an alias on poweroff to keep the command with sudo as I'm used to do. But yeah, guess I'd switch to this if I don't find anything better. Thanks for posting!
Another way of doing it more generically could be to create a systemd service and let systemd take care of it for you. That way, it will happen no matter how you poweroff!
This sounds reeeeally interesting What do you mean exactly? For example gnome uses this command to shutdown:
dbus-send --system --print-reply --dest=org.freedesktop.login1 /org/freedesktop/login1 "org.freedesktop.login1.Manager.PowerOff" boolean:true
What you had in mind would take care of something like this too?
Offline
I'm not DAMO238 but I would recommend the same. If you can make a systemd unit to start your virtual machines, the same systemd unit will take care of stopping them before poweroff/reboot/halt. Can you elaborate on how you start these virtual machines currently?
Offline
I'm not DAMO238 but I would recommend the same. If you can make a systemd unit to start your virtual machines, the same systemd unit will take care of stopping them before poweroff/reboot/halt. Can you elaborate on how you start these virtual machines currently?
At the moment I just use the "Start virtual machine on host boot up" flag in the "Boot Options" tab of virt-manager. But yeah, sure I can do a systemd unit like the following for example:
bootvm@.service
[Unit]
Description=This service manages the execution of the %i virtual machine
Documentation=https://libvirt.org/manpages/virsh.html
[Service]
ExecStartPre=virsh -c qemu:///system
ExecStart=virsh start %i
ExecStop=virsh -c qemu:///system
ExecStop=virsh shutdown %i
TimeoutStopSec=30
KillMode=none
[Install]
WantedBy=multi-user.target
But this still doesn't do what I want. I mean, what I want to reproduce is:
- A shutdown / poweroff / reboot / halt signal is sent to the system
- No action from the host, other then trying to shut down the virtual machines gracefully
- If the VMs are shut down gracefully after X seconds, proceeds with shutting down the host system too.
- If not, execute a different command
Any idea how to implement it somehow or in any of the above code?
Last edited by reddhawk (2020-03-15 03:39:59)
Offline