Tag Archives: virtualbox

paedML auf Virtualbox

Hier hatte ich schon einmal kurz beschrieben, wie man sich eine paedML unter VirtualBox einrichtet. Die aktuelle 5.0.4er paedML brauchte ich neulich (zum Zwecke der Bugsuche auf dem Schulserver) mal wieder und deswegen hier eine Aktualisierung der Hinweise.

Zuerst den IPCop einrichten.

Das erste Interface, das dessen Setup-Prozess findet, wird die grüne Schnittstelle. Deswegen wird die erste Netzwerkkarte in VBox gleich auf inet gesetzt.

Dies gilt selbstverständlich nur, wenn man die Server+IPCop Installation für Testzwecke auf dem heimischen Rechner haben will. Virtualisiert man sich die Installation in der Schule mit Hilfe von VBox (was durchaus so performant ist wie unter Xen oder KVM),  dann würde man in diesem Schritt eine der physikalischen NICs des Wirtsrechners im promiscuous Modus wählen – aber hierzu an anderer Stelle mehr.

Die zweite Schnittstelle im IPCop wird später dann das rote Interface und deswegen steht dieses hier und für den geschilderten Zweck (Spielwiese für zu Hause) auf NAT.

Um die beiden Netzwerkkarten im IPCop-Setup leichter unterscheiden zu können, wählt man sich hier einen anderen NIC Typ aus, als für die erste Schnittstelle. Wer sich total vertut, kann aber auch auf dem IPCop selbst die Kartenzuordnungen ändern, ohne ins Setup zu gehen – hier steht wie.

Im Setup des IPCop dann für GREEN den gewünschten Adressbereich auswählen (10.16.1.1 etc.) – für RED wird DHCP ausgewählt, was einem die restliche Konfiguration erspart (DNS usw). Ist der Cop mal an Bord, dann diesen booten und mit ping überprüfen, ob er ins Netz kommt. Erst weitermachen, wenn auch die Namensauflösung klappt.

Dann den 5.0.4er Server aufsetzen, der bei mir nur mit PAE/NX = aktiv booten wollte:

Dessen Netzwerkkonfiguration ist nun die folgende:

Über die VirtualBox Bridge intnet kommunizieren die beiden miteinander – und auch alle Client-Rechner, die man sich testweise und ebenfalls unter VBox dazu installiert.

Virtualbox saved state recovery

(C) leonlai @ sxc

Für den Wirtsrechner kam ein neuer Kernel, ein Reboot wurde notwendig. Auf mein Virtualbox Start-Stop-Skript vertrauend startete ich den Wirt neu, ohne vorher die virtuellen Maschinen einzeln anzuhalten oder einzufrieren – was auch bei den meisten reibungslos funktionierte, nicht jedoch bei der virtualisierten paedML. Die warf mir nach dem Reboot die folgende Meldung entgegen:

The VM is missing a block device. Please make sure the source and target VMs have compatible storage configurations

Ein Beitrag im Forum bei Virtualbox lies vermuten, dass die Lösung nah ist. Hier wird empfohlen, in der .vbox Datei den stateFile=”{xxxxxxxxxx-xxxx-xxxx-xxxxxxxx}.sav” Eintrag zu löschen. Leider half das bei mir nicht.

Dafür half es, den saved state zu verwerfen. In der grafischen Oberfläche ist das lediglich ein Klick auf den Knopf Discard. VBox warnt dann, dass dies dem Ziehen des Netzsteckers gleichkomme … was auch nicht weiter schlimm ist. Im dümmsten Fall bekommt fsck Arbeit.

Es geht aber auch auf der Shell mit

vboxmanage discardstate name_der_vm

wie das Handbuch zu VBox ausführt.

VirtualBox Start Stop Script

(C) asifthebes @ sxc

Um auf einem Wirtsrechner mehrere Instanzen von unter Virtualbox laufenden VMs mit dem Wirt selbst zu starten und zu stoppen, brauchten wir entsprechende start-stop-Skripte. Fündig wurden wir im Forum von Virtualbox:

http://forums.virtualbox.org/viewtopic.php?f=7&t=34790

Eine Alternative sahen wir uns ebenfalls noch an, entschieden dann aber für das Skript von Nicolas Tessore. Trotzdem – wenigstens noch der Link: http://www.glump.net/howto/virtualbox_as_a_service

Das Skript von N.Tessore passten wir ein klein wenig bei Require-Start an und dokumentieren dies nun hier. Es läuft reibungslos auf einem Ubuntu Server 10.04 LTS 64 bit und Virtualbox 4.1 – für andere VBox- und Ubuntu-Versionen sollte es anpassbar sein:

#! /bin/sh
### BEGIN INIT INFO
# Provides: vbox-headless
# Required-Start: $syslog $vboxdrv $network
# Required-Stop:
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start VMs in headless mode.
# Description: This script runs VMs for the default VirtualBox
# user in headless mode. Make sure all VMs are using different
#  RDP ports.
### END INIT INFO

# Author: Nicolas Tessore <n.tessore@gmail.com>

####
# VirtualBox settings
####

# The user which owns the VMs
VBOX_USER=username

# The list of VMs to run. Leave empty to run all registered VMs.
VBOX_LIST=”"

# VirtualBox executables
VBOX_MANAGE=/usr/bin/vboxmanage
VBOX_HEADLESS=/usr/bin/vboxheadless

####
# End VirtualBox settings
####

# Do NOT “set -e”

# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC=”VirtualBox daemon”
NAME=vbox-headless
DAEMON=$VBOX_HEADLESS
DAEMON_ARGS=”"
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME

# Exit if the package is not installed
[ -x "$DAEMON" ] || exit 0

# Read configuration variable file if it is present
[ -r /etc/default/$NAME ] && . /etc/default/$NAME

# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh

# Define LSB log_* functions.
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
. /lib/lsb/init-functions

vm_init_list()
{
# get registered VMs
LIST_VMS=`sudo -H -u $VBOX_USER $VBOX_MANAGE –nologo list vms | cut -d ‘ ‘ -f 1 | tr -d ‘”‘`

# check for list of VMs
if [ -z "$VBOX_LIST" ]
then
# all registered VMs for user
VBOX_LIST=$LIST_VMS
else
# check that VMs exist
for VM in $VBOX_LIST
do
case $LIST_VMS in
“$VM”)
continue
;;
*)
log_failure_msg “ERROR: VM ‘$VM’ is not registered!”
exit 1
;;
esac
done
fi
}

# get uuid for vm
vm_get_uuid()
{
vm=$1
hwuuid=`sudo -H -u $VBOX_USER $VBOX_MANAGE –nologo showvminfo –machinereadable “$vm” | grep ‘hardwareuuid=’`
echo $hwuuid | cut -d ‘=’ -f 2 | tr -d ‘”‘
}

# control running vm
vm_ctrl()
{
sudo -H -u $VBOX_USER $VBOX_MANAGE –nologo controlvm $1 $2 > /dev/null 2>&1
}

#
# Function that starts the daemon/service
#
do_start()
{
vm_init_list

# Return
#   0 if daemon has been started
#   1 if daemon was already running
#   2 if daemon could not be started
RETVAL=0

# Start all VMs
for VM in $VBOX_LIST
do
VM_UUID=`vm_get_uuid $VM`
VM_PIDFILE=”$PIDFILE.$VM_UUID”
VM_DAEMON=”$DAEMON”
VM_DAEMON_ARGS=”$DAEMON_ARGS –startvm $VM_UUID”

log_action_begin_msg “Starting VM ‘$VM’”

# test for running VM
USER=$VBOX_USER LOGNAME=$VBOX_USER start-stop-daemon \
–start \
–quiet \
–pidfile $VM_PIDFILE \
–startas $VM_DAEMON \
–test \
> /dev/null

# VM already running
if [ "$?" != 0 ]
then
# report VM is running
log_warning_msg “VM ‘$VM’ already running”
[ "$RETVAL" = 0 ] && RETVAL=1
continue
fi

# start VM
USER=$VBOX_USER LOGNAME=$VBOX_USER start-stop-daemon \
–start \
–quiet \
–pidfile $VM_PIDFILE \
–make-pidfile \
–background \
–chuid $VBOX_USER \
–startas $VM_DAEMON \
– $VM_DAEMON_ARGS

log_action_end_msg “$?”

# check if start failed
if [ "$?" != 0 ]
then
# report error
log_failure_msg “Error starting VM ‘$VM’”
RETVAL=2
fi
done

if [ "$RETVAL" -lt 2 ]
then
log_daemon_msg “VirtualBox daemon started successfully”
else
log_daemon_msg “VirtualBox daemon started with errors”
fi

return “$RETVAL”
}

#
# Function that stops the daemon/service
#
do_stop()
{
vm_init_list

# Return
#   0 if daemon has been stopped
#   1 if daemon was already stopped
#   2 if daemon could not be stopped
#   other if a failure occurred
RETVAL=0

for VM in $VBOX_LIST
do
VM_UUID=`vm_get_uuid $VM`
VM_PIDFILE=”$PIDFILE.$VM_UUID”

log_action_begin_msg “Stopping VM ‘$VM’”

# try savestate halt
vm_ctrl $VM savestate

# stop daemon
USER=$VBOX_USER LOGNAME=$VBOX_USER start-stop-daemon \
–stop \
–quiet \
–retry=TERM/30/KILL/5 \
–pidfile $VM_PIDFILE

case “$?” in
0)
log_action_end_msg 0
;;
1)
log_warning_msg “VM ‘$VM’ already stopped”
[ "$RETVAL" = 0 ] && RETVAL=1
;;
2)
log_action_end_msg 1
log_failure_msg “ERROR: Could not stop VM ‘$VM’”
RETVAL=2
continue
;;
esac

rm -f $VM_PIDFILE
done

if [ "$RETVAL" -lt 2 ]
then
log_daemon_msg “VirtualBox daemon stopped successfully”
else
log_daemon_msg “VirtualBox daemon stopped with errors”
fi

return “$RETVAL”
}

#
# Function that sends a SIGHUP to the daemon/service
#
do_reload() {
#
# If the daemon can reload its configuration without
# restarting (for example, when it is sent a SIGHUP),
# then implement that here.
#
start-stop-daemon –stop –signal 1 –quiet –pidfile $PIDFILE –name $NAME
return 0
}

case “$1″ in
start)
log_daemon_msg “Starting $DESC” “$NAME”
do_start
case “$?” in
0|1) log_end_msg 0 ;;
2) log_end_msg 1 ;;
esac
;;
stop)
log_daemon_msg “Stopping $DESC” “$NAME”
do_stop
case “$?” in
0|1) log_end_msg 0 ;;
2) log_end_msg 1 ;;
esac
;;
status)
status_of_proc “$DAEMON” “$NAME” && exit 0 || exit $?
;;
#reload|force-reload)
#
# If do_reload() is not implemented then leave this commented out
# and leave ‘force-reload’ as an alias for ‘restart’.
#
#log_daemon_msg “Reloading $DESC” “$NAME”
#do_reload
#log_end_msg $?
#;;
restart|force-reload)
#
# If the “reload” option is implemented then remove the
# ‘force-reload’ alias
#
log_daemon_msg “Restarting $DESC” “$NAME”
do_stop
case “$?” in
0|1)
do_start
case “$?” in
0) log_end_msg 0 ;;
1) log_end_msg 1 ;; # Old process is still running
*) log_end_msg 1 ;; # Failed to start
esac
;;
*)
# Failed to stop
log_end_msg 1
;;
esac
;;
*)
#echo “Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}” >&2
echo “Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}” >&2
exit 3
;;
esac

:

In diesem Pastebin liegt es auch noch rum, sollte Copy and Paste aus WordPress mal wieder zickig sein:

http://pastebin.com/4i8W0FB2

Mit Hilfe von

update-rc.d  vbox-headless start 99 2 3 4 5 . stop 99 0 1 6 .

konnte das Skript dann zwar in die richtigen Ordner

/etc/rc2.d/S99vbox-headless
/etc/rc3.d/S99vbox-headless
/etc/rc4.d/S99vbox-headless
/etc/rc5.d/S99vbox-headless

eingefügt werden, aber – komisch, komisch – nicht an der 99. Stelle, sondern immer nur an der 20. Diese Anpassung musste also von Hand vorgenommen werden.

Das wirklich coole an N.Tessores Skript ist, dass es die VMs nicht herunterfährt, sondern bei einem Serverreboot schlicht pausieren lässt. So sind die VMs nach dem Start des Wirtsrechners sofort wieder da.

VirtualBox VDI verkleinern

(C) leonlai @ sxc

Ich backe gerade eben für meine Schule eine virtuelle Maschine mit Ubuntu Lucid und ksociograma für die Erstellung von Soziogrammen. Leider wächst der VDI Container aber immer stärker, als er eigentlich müsste, weil Ubuntu ja zuerst die Pakete herunterlädt und dann installiert. Ich kann die Pakete dann in der VM zwar mit

sudo apt-get clean

sudo apt-get autoremove

wieder rauswerfen und damit die VM putzen – das ändert aber an der Größe der VM nichts mehr. Die bleibt auf der Wirtsplatte so dick, wie sie war.

Einige Anleitungen im Netz beschreiben nun, wie man die VDI Datei wieder verkleinert – aber leider stimmt keine der von mir gefundenen zu 100%. Deswegen hier eine Beschreibung des Vorgangs, der bei mir für einen Linux-Gast funktioniert hat:

Zu beachten: Die VM (der Linux-Gast) ist mit EXT3 als Dateisystem anzulegen – sonst klappen die folgenden Schritte nicht!

Nachdem alle Programm installiert sind und die VM geputzt wurde (siehe oben), wird diese herunter gefahren. Dann wird die VM mit einer Ubuntu Desktop-CD gebootet. In dieser wechselt man auf eine Root-Shell

sudo su -

und installiert sich das Programm zerofree, das nur mit EXT3 als Dateisystem klar kommt

apt-get install zerofree

Exkurs: Wenn man sich Platte des Gastes einmal kurz einhängt (mount -t ext3 /dev/sda1 /mnt), dann zeigt ein df -h in der VM an, wie viel Platz noch vorhanden ist und liefert einem außerdem alle Gerätenamen – in meinem Fall ist die Platte des Gastes /dev/sda1. Nicht vergessen: Die Platte muss nach diesem Schritt wieder ausgehängt werden, damit die folgenden Schritte funktionieren: umount /mnt

Dann wird die Platte der VM read-only in die Desktop-Umgebung gemountet

mount -o ro -t ext3 /dev/sda1 /mnt

und zerofree drauf losgelassen

zerofree /dev/sda1

Nachdem das Progrämmchen fertig ist, kann die VM herunter gefahren und die VDI Datei vom Wirt aus geschrumpft werden:

VBoxManage modifyvdi /pfad/zur/vm.vdi compact

Endlich keine device busy Meldungen mehr, wenn man versucht, zerofree aus der VM heraus auf die eigene Platte los zulassen.