#!/bin/bash

### BEGIN INIT INFO
# Provides:       vmboot
# Required-Start: vboxdrv $local_fs
# Required-Stop:  vboxdrv $local_fs
# Default-Start:  2 3 4 5
# Default-Stop:   0 1 6
# Short-Description: Stop/Start VMs before/after System shutdown
### END INIT INFO

# Updated 04/27/2012

# Add this script to /etc/init.d/
# Run "update-rc.d vmboot defaults 99 01" as root

# Written to work with VirtualBox 4.x
# This script will save the state of any running virtual machines.

# User who is running the VMs (Change this!)
VBOXUSER=vboxuser

# Environmental Variables (Do Not Modify!)
SU="sudo -H -u $VBOXUSER"
VBOXMANAGE="/usr/bin/VBoxManage --nologo"
# Get UUID of All Running VMs
# UUID looks like this: a02b5b54-a84d-48fa-8dac-2a3fad55717e
RUNNINGVMS=$($SU $VBOXMANAGE list runningvms | sed -e 's/^".*".*{\(.*\)}/\1/')
# Get UUID of All VMs
ALLVMS=$($SU $VBOXMANAGE list vms | sed -e 's/^".*".*{\(.*\)}/\1/')

# Functions
function getVMName()
{ echo $($SU $VBOXMANAGE list vms | grep "$1" | awk -F\" '{print $(NF -1)}'); }

# Check to ensure $ALLVMS is not null and exit if it is.
if [[ $ALLVMS = "" ]]; then
        echo "No VMs are detected on this host! Did you configure the VBOXUSER variable?"; exit 1
fi

case $1 in
stop)
if [[ -n $RUNNINGVMS ]]; then
        for v in $RUNNINGVMS; do
        echo -e "Saving state of \"$(getVMName $v)\"..." && $SU $VBOXMANAGE controlvm $v savestate
        done; else
        echo "No running VMs to save!"
fi
;;
start)
for v in $ALLVMS; do
        if [[ -n $($SU $VBOXMANAGE showvminfo $v | grep saved) ]]; then
                echo -e "Waiting for VM \"$(getVMName $v)\" to power on..." && $SU $VBOXMANAGE startvm $v --type headless 1> /dev/null && echo "VM \"$(getVMName $v)\" started successfully!"
        fi
# If the previous loop has an error, the loops exits and returns an error.
        if [[ $? -ne 0 ]]; then
                echo "There was an error starting $(getVMName $v)! Try starting it manually to see what the problem is."; break
        fi
done
if [[ -z $($SU $VBOXMANAGE showvminfo $v | grep saved) ]]; then
        echo "No Saved VMs to Start!"
fi
;;
status)
if [[ -n $RUNNINGVMS ]]; then
        echo "List of Running VMs:" && $SU $VBOXMANAGE list runningvms; else
                echo "No VMs Currently Running!"
fi
;;
list)
echo "List of All VMs:" && $SU $VBOXMANAGE list vms
;;
*)
echo "Usage: /etc/init.d/vmboot start | stop | status | list"; exit 1
;;
esac
exit 0
# eof