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?

Jamie Treworgy
  • 141
  • 1
  • 5

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,235
  • 3
  • 28
  • 44