0

In Ubuntu 19.10 I'm trying to create a script to shut down my user's VM gracefully when the system shuts down, e.g. when run as root

runuser -l jamie -c "vboxmanage controlvm \"Windows 10" suspend"

I've tried a variety of techniques based on every systemctl example I can find, and none works: something always kills the VM before my script runs, and it says in the log:

runuser[11997]: pam_unix(runuser-l:session): session opened for user jamie by (uid=0)
Nov 12 23:51:48 media2 shutdown[11979]: VBoxManage: error: Machine 'Windows 10' is not currently running

At least I am reasonably confident this is why I'm getting this message - if I were not in the correct user context it would say the machine didn't exist.

There are a number of similar questions but none of these has worked for me, I've tried pretty much every variant I can find from similar questions here, here, here, here, and here, for example:

[Unit]
Description=Run Scripts at Start and Stop

[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/bin/true
ExecStop=/home/jamie/.scripts/shutdown

[Install]
WantedBy=multi-user.target

(and lots of other variants involving other targets, options, etc). These are running a script at the end of the multi-user.target which seems too late. Same result using reboot.target etc - script apparently runs too late.

I tried to use this technique -- creating a new custom target that runs after multiuser target -- but I couldn't get the custom target registered; it just crashed gnome. I couldn't find any further discussion of this approach elsewhere.

Any ideas how I can accomplish positively intercepting a reboot/shutdown event before running processes are terminated?

  • Have you seen this https://askubuntu.com/questions/1010120/intercept-shutdown-call-and-run-script-to-allow-or-prevent-shutdown – darksky Nov 15 '19 at 05:25
  • I had not seen that... I need to dig into it a little, but it looks like system-inhibit will prevent shutdown while something's running, but the problem is it would already be too late for that to be useful (afaict) since i still need a way to run my script at the right time. The "original" answer involved replacing the /sbin/shutdown, etc commands entirely. I think that would work but it just seems like a hack/blunt instrument and probably wouldn't work for every scenario (unless those are the only way to shutdown, truly). That said -- if I can't figure a more elegant way maybe good enuf – Jamie Treworgy Nov 15 '19 at 05:33
  • Also for VirtualBox specifically, you may find this thread helpful https://forums.virtualbox.org/viewtopic.php?f=6&t=53684#p285540 – darksky Nov 15 '19 at 05:42
  • @jamie-treworgy If I understand your issue correctly, I've got a similar setup: A script that starts and shuts down a VirtualBox VM, and that script is controlled by a systemd service file. Are you looking for a similar setup? Thanks. – Jags Nov 15 '19 at 05:45
  • More specifically, VBoxManage setextradata "VM NAME" GUI/DefaultCloseAction Shutdown. Though the thread is pretty old, so hopefully the syntax hasn’t changed. – darksky Nov 15 '19 at 05:46
  • @darksky Hmm, that's interesting, and worth a try. I would like to find a more general solution so I can do other things too (e.g. it also seems like docker containers are getting killed mercilessly) but the VM is definitely the bigger problem. That thread seems to be about Windows so I'm a little skeptical it would work the same in Ubuntu but definitely worth a try,. I'm done hacking for the night but will look into both of these tomorow. Generally I'm quite surprised there's no more obvious way to inject in this process with systemctl! – Jamie Treworgy Nov 15 '19 at 05:50
  • @Jags - that is exactly what I'm looking for, could you share? (I don't really care about starting it, actually I'd rather start it manually as I don't use it always, but if I can get it working with both starting and stopping anyway I'll be happy!) – Jamie Treworgy Nov 15 '19 at 05:51
  • @jamie-treworgy just posted the detailed answer. Thanks. – Jags Nov 15 '19 at 06:06

1 Answers1

0

This solution is in two parts. First part is to create a script, and second part is creating a systemd service file to run that script.

Part-1: Create a script: autovm.sh

Note: you can find virtual machine's UUID by: VBoxManage list vms

sudo nano /bin/autovm.sh

#!/bin/bash

VMUSER="username"
VMNAME="21b3afd8-8f71-4c31-9853-ce9aa2eb58fb"

case "$1" in
    start)
    echo "===Starting VirtualBox VM==="
    sudo -H -u $VMUSER VBoxManage startvm "$VMNAME" --type headless
    ;;
    stop)
    echo "===Shutting down Virtualbox VM==="
    sudo -H -u $VMUSER VBoxManage controlvm "$VMNAME" acpipowerbutton
    sleep 20
    ;;
    *)
    echo "Usage: /bin/autovm.sh {start|stop}"
    exit 1
    ;;
esac

exit 0

Now make the autovm.sh script executable and place it to: /bin/

Part-2: Create autovm.service file in /etc/systemd/system/ (Do NOT make this file executable)

sudo nano /etc/systemd/system/autovm.service

[Unit]
Description=Autostart VM

[Service]
Type=oneshot
ExecStartPre=/bin/sleep 20
ExecStart=/bin/autovm.sh start
ExecStop=/bin/autovm.sh stop
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

Now enable the service by:

sudo systemctl enable autovm.service

Jags
  • 2,176
  • This seems almost identical to the config I've already tried -- the only difference I can see in the unit, is that it's also responsible for starting the VM. I'll try this for sure - but is there some reason you think this would be run before the VM is otherwise killed during the shutdown process? That is, the only difference in my script is I've got ExecStart: /sbin/true to just do nothing instead of actually starting the VM. My actual script to shut it down is different (using runuser instead of sudo, and suspending) - maybe the problem isn't what I think it is? Will try an get back! – Jamie Treworgy Nov 15 '19 at 15:46
  • @jamie-treworgy yes, it does not kill the VM (in my case VM is a Debian testing) on my Ubuntu MATE 19.04 host. You can adjust sleep 20 to 30 or 45 if you think your VM needs more time in shutting down. Anyway, let us know if this works for you. – Jags Nov 15 '19 at 16:49
  • Thanks @Jags, going to try tonight. Will follow up! – Jamie Treworgy Nov 16 '19 at 02:33