Automatisch starten en stoppen van virtuele machines

Met het gebruiken van virtuele machines op een enkele systeem is het handig dat, wanneer het systeem wordt geboot of juist wordt uitgeschakeld, ook de virtuele machines automatisch mee opstarten en down gaan. VirtualBox geeft geen mogelijkheid voor deze functionaliteit. Charles Auer (http://charlesa.net) schreef een systeem service die precies dat doet. Bij het opstarten van hover starten alle VM’s netjes achter elkaar. Binnen Ubuntu is de functionaliteit van acpibutton functioneel. Dit betekent dat de virtuele machine zal afsluiten nadat dit signaal is ontvangen. Deze methode is gekozen voor Hover. Dit werkt ook voor Hover zelf als op de power button, op de kast, wordt gedrukt.

Wanneer Hover wordt afgesloten, door de power button een keer in te drukken of door het shutdown commando, worden eerst de virtuele machines afgesloten. Hover wacht met afsluiten tot alle virtuele machines down zijn. 

Om dit te installeren open een nieuw bestand:
sudo nano /etc/init.d/controlvms

Voeg het script, zoals dat weergegeven onderaan de pagina, toe aan het bestand. Het script kan ook worden gedownload van http://charlesa.net/scripts/linux/vboxscript.php.

Pas de volgende waarden in het bestand aan:
VBOXUSER Vul hier de gebruikers naam in van de gebruiker die de virtuele machines heeft aangemaakt. Dit is belangrijk omdat in deze gebruikers directory de configuratie van de virtuele machines kan worden gevonden (home/$VBOXUSER/VirtualBox VMs).
SHUTDOWNMODE Pas dit aan zoals je dat wilt. Mogelijkheden zijn “acpipowerbutton”, “savestate”, “reset”. Als je niet weet laat dit dan op acpipowerbutton staan. Gebruik reset niet!
ENABLELOGGING om het loggen van berichten in of uit te schakelen.

Sla het bestand op. Maak het mogelijk uit te voeren:

sudo chmod +x /etc/init.d/controlvms

Installeer de System-V style initialisatie verbindingen:

sudo update-rc.d controlvms defaults 99 01

Dat is alles! Reboot het system, alle vm’s zullen na reboot automatisch worden gestart.

The VirtualBox Start en Stop Script

#!/bin/bash
### BEGIN INIT INFO
# Provides:       controlvms
# Required-Start: vboxdrv $local_fs $syslog
# Required-Stop:  vboxdrv $local_fs $syslog
# Default-Start:  2 3 4 5
# Default-Stop:   0 1 6
# Short-Description: Stop/Start VMs before/after System shutdown
### END INIT INFO
#---------- VMBoot (controlvms)------------------------------------------#
# An LSB-Compliant Init script for VirtualBox 4.x guests on Ubuntu systems.
#
# Valid Parameter values:
#  start            Starts all VMs owned by VBOXUSER.
#  stop                Stops all VMs owned by VOXUSER. Stop behavoir is controled by SHUTDOWNMODE.
#  status            Prints a status message indicating running VMs.
#  restart            Stops and then starts all VMs. Stop behavoir is controled by SHUTDOWNMODE.
#  force-reload            Stops and then starts all VMs, resetting any that do not stop gracefully. 
#
# To Install:
#  Add this script to /etc/init.d/
#  Make the script executable with 'chmod +x /path/to/this/script' as root
#  Run update-rc.d vmboot defaults 99 01 as root
#
# To Configure:
#  Set VBOXUSER below adding the username of the user who created the
#        VM. This is important because the VM config will
#        reside in /home/$VBOXUSER/VirtualBox VMs/<Virtual
#        Machine Name>/
#  Set SHUTDOWNMODE to your preference. valid values are:
#        "acpipowerbutton", "savestate", "reset". reset can
#        damage your virtual disks so don't use it.
#  Set ENABLELOGGING to enable or disable logging to the systemlog.
#        when logging is enabled messages will be written to
#        the syslog using the pattern contained in LOGGERMSG
#
# To Use:
# Once Installed and configured, VMBoot works automatically on system boot and shutdown, like any other service. 
# You may manually control controlvms, by calling the init script itself (as root), or by using the Service interface.
#        ex.     sudo /etc/init.d/controlvms start
#    OR
#        ex.     sudo service controlvms stop
#
#---------- User Settings ---------------------------------------------#
VBOXUSER=xxxxxx;        #User who owns the VMs.
SHUTDOWNMODE="acpipowerbutton";    #shutdown or save state. acpipowerbutton|savestate
ENABLELOGGING="1";        #en/disable syslogging. 1|0
#---------- Environment settings --------------------------------------# 
#Do not modify these values unless absolutely necessary.
VBOXMANAGE="/usr/bin/VBoxManage --nologo";
SU="sudo -H -u $VBOXUSER";
ECHOCMD="echo -e";
LOGGERMSG="$(echo -e `date "+%b %d %H:%M:%S"` `hostname` "$0": %s)n";
#---------- Script -------------#
RUNNINGVMS=$($SU $VBOXMANAGE list runningvms | sed -e 's/^".*".*{(.*)}/1/'); #UUID of All Running VMs. UUID looks like this: a02b5b54-a84d-48fa-8dac-2a3fad55717e
ALLVMS=$($SU $VBOXMANAGE list vms | sed -e 's/^".*".*{(.*)}/1/');        #UUID of All VMs

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

#outputs messages to the screen and log if logging is enabled
function output(){
    if [[ "$ENABLELOGGING" -eq "1" ]]; then
        $ECHOCMD "$(printf "$LOGGERMSG" "$1")" >> /var/log/syslog;
        echo "$1"
    else
        $ECHOCMD "$1";
    fi
}
#return a given machines human readable name by UUID
function getVMName(){
    echo $($SU $VBOXMANAGE list vms | grep "$1" | awk -F" '{print $(NF -1)}');
}
#return the list of currently running VMs. never gets stale.
function getRunningVMs(){
    echo $($SU $VBOXMANAGE list runningvms | sed -e 's/^".*".*{(.*)}/1/');
}
function stopService(){
    if [[ -n $RUNNINGVMS ]]; then
        #set message based on SHUTDOWNMODE
        modemsg="Shutting Down";
        if [[ $SHUTDOWNMODE == "savestate" ]]; then
            modemsg="Saving state of";
        elif [[ $SHUTDOWNMODE == "reset" ]]; then
            modemsg="Aborting"
        fi
        #shutdown or save all running vms
        for v in $RUNNINGVMS; do
            name=$(getVMName $v)
            output "$modemsg $name...";
            $SU $VBOXMANAGE controlvm $v $SHUTDOWNMODE;
            # If this loop has an error, the loops exits and returns an error.
            if [[ $? -ne 0 ]]; then
                output  "There was an error $modemsg $name."; 
            else
                output "VMBoot has stopped $name.";
            fi
        done;
    #wait for VMs to shutdown, if they haven't already.
        c=60;
        while [[ (-n $(getRunningVMs)) && ("$c" -gt "0") ]]; do
            sleep 1;
            c=$(($c - 1));
        done
        #if waited for specified number of seconds, log and exit.
        if [[ "$c" -eq "0" ]]; then
            output "Warning: One or more VMs failed to stop!";
        else
            output "VMBoot stopped all running VMs."
        fi
    else
        output "No running VMs to save!";
    fi
}

function startService(){
    name=""
    for v in $ALLVMS; do
        if [[ -n $($SU $VBOXMANAGE showvminfo $v) ]]; then
            name=$(getVMName $v)
            output "Waiting for VM "$name" to power on..." 
            $SU $VBOXMANAGE startvm $v --type headless 1> /dev/null;
        else
            output  "No Saved VMs to start!";
        fi
        # If the previous loop has an error, the loops exits and returns an error.
        if [[ $? -ne 0 ]]; then
            output  "There was an error starting "$name"! Try starting it manually to see what the problem is."; 
            break;
        else
            output "VM "$name" has been successfully started.";
        fi
    done
}

function restartService(){
    stopService;
    startService;
}

function force-reloadService(){
    stopService  #attempt to gracefully shutdown guests.
    #if any VMs are still up, forcibly reset them.
    if [[ !(-n getRunningVMs) ]]; then
        sdm=$SHUTDOWNMODE
        SHUTDOWNMODE="reset"
        stopService
        SHUTDOWNMODE=$sdm
    fi
    restartService
}

function serviceStatus(){
    logging=$ENABLELOGGING
    ENABLELOGGING="0" #disable logging if it is on
    if [[ -n $RUNNINGVMS ]]; then
        output "List of Running VMs:n $(getRunningVMs)" ;
    else
        $ECHOCMD "No VMs Currently Running!";
    fi
    ENABLELOGGING=$logging
}

case $1 in
stop)
    stopService
;;
start)
    startService
;;
restart)
    restartService
;;
force-reload)
    force-reloadService
;;
status)
    serviceStatus
;;
*)
echo "Usage: /etc/init.d/vmboot start | stop | status | restart | force-reload"; exit 1
;;
esac
exit 0
# eof

Laatst bijgewerkt op 24 mei 2014

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Verplichte velden zijn gemarkeerd met *