#! /bin/bash
### BEGIN INIT INFO
# Provides:          MyVM
# Required-Start:    $local_fs $remote_fs vboxdrv vboxnet
# Required-Stop:     $local_fs $remote_fs
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: virtual machine
# Description:       virtual machine hosted by VirtualBox
### END INIT INFO
#
# Author: Francois Lafont

# Pour faire un tracage du script
#set -x

PATH=/usr/sbin:/usr/bin:/sbin:/bin

#!!# NAME sera le nom du fichier de script. Ici, c'est MyVM. Si vous
#!!# souhaitez mettre un nom different, alors il faudra remplacer
#!!# MyVM dans la ligne 3 par le nom que vous avez choisi.
NAME="MyVM"

SCRIPTNAME="/etc/init.d/$NAME"
MANAGE_CMD="VBoxManage"
START_CMD="VBoxHeadless"

#!!# VM_OWNER sera le nom de login du proprietaire de la VM.
VM_OWNER="francois"

#!!# VM_NAME sera le nom exact de la VM tel qu'il apparait
#!!# sur l'interface graphique. Il vaut mieux que ce nom
#!!# ait ni accent ni espace (encore que les espaces, ca
#!!#  devrait passer).
VM_NAME="XPpro" 

#!!# Message envoye a la VM via le reseau avant son shutdown
#!!# (evitez les accents).
MESSAGE="Arret du systeme..."

#!!# Temps en secondes durant lequel le message s'affiche avant
#!!# l'execution du shutdown.
TEMPS="25"

#!!# Login et mot de passe d'un compte administrateur de la VM.
LOGIN="admin"
PWD="local"

#!!# IP de la VM a eteindre via le reseau. Il faut donc une IP fixe.
IP="192.168.0.151"

SHUTDOWN_CMD="net rpc shutdown -t \"$TEMPS\" -C \"$MESSAGE\" -U \"$LOGIN%$PWD\" -I \"$IP\""

#!!# 720 secondes = 12 minutes pour laisser a la VM le temps de s'éteindre
#!!# proprement, au dela la VM est mise sur poweroff brutalement. Vous pouvez
#!!# changer cette valeur comme il vous plait. C'est pour etre sur que le
#!!# demon s'arrete au bout d'un temps fini.
MAX_TEMPS="720"

# Pour lancer le demon
do_start()
{
    # Return
    #   0 --> le demon a demarre
    #   1 --> le demon etait deja demarre
    #   2 --> le demon n'a pas pu demarrer

    # On verifie si la VM est deja en train de tourner
    running=$(su $VM_OWNER -c "$MANAGE_CMD showvminfo \"$VM_NAME\"" | grep "^State:.*running" | wc -l)
    if [ $running -eq 1 ]
    then
        echo " * $VM_NAME is already running .................................... [ OK ]"
        return 1
    fi

    # Si elle n'est pas encore allumee, on la lance.
    su $VM_OWNER -c "nohup $START_CMD --startvm \"$VM_NAME\" --vrdp off > /dev/null 2>&1 &"
    # On verifie que la VM est bien lancee.
    sleep 2
    running=$(su $VM_OWNER -c "$MANAGE_CMD showvminfo \"$VM_NAME\"" | grep "^State:.*running" | wc -l)
    if [ $running -eq 0 ]
    then
        echo " * Failed to start $VM_NAME .................................... [ ERROR ]"
        return 2
    else
        echo " * $VM_NAME started .................................... [ OK ]"
        return 0
    fi
}

# Pour arreter le demon
do_stop()
{
    # Return
    #   0 --> le demon a ete stoppe
    #   1 --> le demon etait deja stoppe
    #   2 --> le demon ne peut pas etre stoppe

    # On teste si la MV est deja stoppee
    running=$(su $VM_OWNER -c "$MANAGE_CMD showvminfo \"$VM_NAME\"" | grep "^State:.*running" | wc -l)
    if [ $running -eq 0 ]
    then
        echo "$VM_NAME is already stopped."
        return 1
    fi

    # Si elle n'est pas stoppee, on lance l'extinction de la MV via le reseau
    su $VM_OWNER -c "$SHUTDOWN_CMD"
    echo "Please wait..."

    compteur=0
    while [ $running -eq 1 ]
    do
        if [ $compteur -gt $MAX_TEMPS ]
        then
            su $VM_OWNER -c "$MANAGE_CMD controlvm \"$VM_NAME\" poweroff"
            echo "Failed to stop correctly $VM_NAME which is directly turned off."
            return 2
        else
            sleep 10
            echo "Please wait..."
            running=$(su $VM_OWNER -c "$MANAGE_CMD showvminfo \"$VM_NAME\"" | grep "^State:.*running" | wc -l)
            compteur=`expr $compteur + 10`
        fi
    done

    echo "$VM_NAME shutdown."
    return 0
}

# Pour obtenir les statuts du demon
do_status()
{
    su $VM_OWNER -c "$MANAGE_CMD showvminfo \"$VM_NAME\"" | grep "^State:"
}

case "$1" in
    start)
        do_start
        ;;
    stop)
        do_stop
        ;;
    status)
        do_status
        ;;
    *)
        echo "Usage: $SCRIPTNAME {start|stop|status}" >&2
        exit 3
        ;;
esac
