Eine VirtualBox-Installation fährt Schnappschüsse virtueller Maschinen in Sekundenschnelle von der Kommandozeile hoch und hilft, beim Browsen die Privatsphäre zu wahren und Perl-Module durch einen Smoke-Test zu schicken.
Wer ständig neue Linux-Distributionen ausprobiert, der bedient Virtualisierer wie VMWare, KVM, Xen, oder VirtualBox wahrscheinlich schon im Schlaf. Aber auch Programmierer, die Code für unterschiedliche Linux-Versionen oder, Gott bewahre, Windows-Versionen entwickeln, wissen lokal verfügbare virtuelle Maschinen für schnelle Tests zu schätzen.
Das Virtualisierungspaket Virtualbox ([2]) ist einfach mittels einer ansprechenden GUI zu bedienen (Abbildung 1) und bequem als Ubuntu-Paket unter der GPLv2-Lizenz verfügbar (Abbildung 2).
Abbildung 1: VirtualBox mit einigen Ubuntu- und Windows-Versionen als Gastsystemen. |
Abbildung 2: Synaptik-Listing von Ubuntu-Paketen, die VirtualBox installieren. |
Mit Hilfe von Installations-CD/DVDs oder .iso-Dateien legt der User im Virtualisierer schnell eine Handvoll Gastsysteme an, die anschließend auf Knopfdruck in eigenen Fenstern hochfahren. Die Maussteuerung im Gastsystem bedarf einer kurzen Gewöhnungsphase, denn hat das Gastsystem einmal den Maus-Fokus, gibt es ihn nicht mehr her. Der Mauszeiger eckt nun an den Grenzen des Gastsystemfensters an. Um den Fokus des virtuellen Systems zu verlassen, drückt der User eine vordefinierte Taste (voreingestellt ist die rechte (!) ALT-Taste), worauf der Mauszeiger wieder auf dem heimischen Desktop weilt.
Dank effizient implementierter Schnappschusstechnik frieren VMs Zustände rasch ein und stellen sie später in wenigen Sekunden wieder her. So können Websurfer eine frisch erzeugte Ubuntu-Installation mit geöffnetem Browser für peinliche Webrecherchen nutzen.
Was Google über seine Nutzer weiß, kommt immer dann erschreckend zutage, wenn der User einen Suchbegriff eingibt und die Autocomplete-Funktion peinliche Vervollständigungen vornimmt. Niemand möchte schließlich daran erinnert werden, dass vor einigen Tagen nach "Hämorrhidencreme" oder "Fußpilz" gesucht wurde, ganz zu schweigen vom Einfluss dieser Suchbegriffe auf das Langzeittargeting von Googles personifizierter Werbemaschine.
Der paranoide Pinguinfreund möchte weder die ausgestellten Cookies länger als notwendig behalten noch irgendwelche Spuren in der Browser-History hinterlassen. Da er nicht genau weiß, was der Browser hinter seinem Rücken alles an Caching und sonstiger Datenspeicherei betreibt, liegt es nahe, für sensitive Suchanfragen blitzschnell eine virtuelle Maschine mit eingabebereitem Browser hochzufahren, die Suche durchzuführen und gleich darauf die VM wieder in ihren Ausgangszustand zurückzuversetzen.
Abbildung 3: Diesen peinlichen Suchbegriff wird der Browser beim nächsten Hochfahren der VM vergessen haben. |
Das Verfahren ist zwar nicht ganz hundertprozentig wasserdicht, ein James Bond als Gegenspieler könnte auf der virtuellen Festplatte vielleicht noch Datenschnipsel finden, und auch die IP-Addresse des verwendeten Routers taucht in den Google-Logs auf, aber legt die Latte schon merklich höher. Wer mehr Privatsphäre braucht, sollte Tor bemühen und die in einer Einzeldatei liegende VM-Festplatte nach Gebrauch mit dban zerstören.
Kurz nach der Linux-Installation von der DVD öffnet der auf seine Privatsphäre bedachte User also im nagelneuen Gastsystem den Firefox-Browser und zieht vom aktuellen Zustand der VM einen Snapshot (Abbildungen 2 und 3).
Abbildung 4: Der User zieht vom aktuellen Zustand der VM einen Snapshot ... |
Abbildung 5: ... der in wenigen Sekunden abgespeichert ist. |
Nach Abschluss der geheimen Mission fährt der User die VM herunter und stellt über die "Restore"-Funktion des VirtualBox-Snapshot-Menüs den ursprünglichen Zustand wieder her. Beim nächsten Hochfahren der VM steht wieder ein offener Browser bereit, der sich allerdings an nichts mehr erinnert, ganz so, als wäre ein Zeitsprung in die Vergangenheit erfolgt.
Statt sich bei jeder Recherche erst die VirtualBox-GUI hochzufahren und
in dessen Menüs herumzuklicken, bietet sich ein Perl-Skript an, das die
VM selbständig auswählt und hochfährt. Nach getaner Arbeit drückt der
User im Skript die Enter-Taste und die VM fährt herunter und der
Startzustand wird wieder hergestellt.
Mit dem Programm VBoxManage
bietet VirtualBox dankenswerterweise eine
Komplettstuerung von der Kommandozeile. Listing 1 zeigt das Perl-Skript,
das die VM mit dem Namen "Ubuntu 10.04" und deren vorher manuell
angelegten Snapshot "Browse" auswählt (siehe Abbildung 1). Mittels
des tap
-Kommandos aus dem CPAN-Modul Sysadm::Install setzt es die
Shell-Befehle ab. Man könnte das Skript natürlich einfacher als Shell-Skript
implementieren, aber erfahrene Perl-Programmierer wissen, dass es nur
eine Frage der Zeit ist, bis ein Shell-Skript im Funktionsumfang so weit
wächst, bis man es in Perl reimplementiert, weil es sonst nicht mehr
zu warten ist.
Das Skript nutzt die Unterkommandos startvm
und ctrlvm poweroff
, um
die VM herauf- und später wieder herunter zu fahren. Den Snapshot restauriert
es sowohl am Anfang als auch am Ende des Skripts, um sicher zu stellen, dass
die VM auch dann in den Initialzustand hochfährt, falls jemand zwischenzeitlich
in im Snapshot-Menü der VirtualBox-GUI herumgefuhrwerkt hat.
01 #!/usr/local/bin/perl -w 02 use strict; 03 use Sysadm::Install qw(:all); 04 use Log::Log4perl qw(:easy); 05 06 Log::Log4perl->easy_init($DEBUG); 07 08 my $vbm = "VBoxManage"; 09 my $vm = "Ubuntu 10.04"; 10 11 tap $vbm, "snapshot", $vm, "restore", "Browse"; 12 tap $vbm, "startvm", $vm; 13 14 print "Press Enter for shutdown"; 15 <STDIN>; 16 17 tap $vbm, "controlvm", $vm, "poweroff"; 18 tap $vbm, "snapshot", $vm, "restore", "Browse";
VirtualBox-VMs lassen sich aber auch im Headless-Modus völlig ohne Bildschirmausgabe steuern. Ein im unsichtbar laufenden Gastsystem installierter sshd-Dämon erlaubt dem Hostsystem, dort Kommandos auszuführen oder mit dem Gastsystem Dateien auszutauschen.
VirtualBox fährt Gastsysteme allerdings von Haus aus im NAT-(Network Address-Translation)-Modus hoch, weist ihnen eine Adresse im virtuellen 10.x.x.x-Netz zu und kommuniziert mit dem lokalen Netz des Hosts über eine Adressumwandlung, ähnlich wie die meisten Router in Privathaushalten die lokalen Geräte mit ihren 192.168.x.x-Adressen mit dem Internet kommunizieren lassen. Dies funktioniert aus der VM ins lokale Netz ohne Probleme, allerdings dürfen der Host oder Geräte im lokalen Netz keine Verbindung mit der VM aufnehmen. Dies lässt sich über den Dialog "Network Adapters" ändern, der sich hinter dem Symbol mit den zwei Terminals am rechten unteren Rand einer laufenden VM verbirgt (Abbildungen 6 und 7).
Abbildung 6: Ein Rechtsklick auf das Symbol mit den zwei Terminals öffnet den Dialog zum Einstellen des Netzwerk-Adapters. |
Abbildung 7: Der Bridged-Adapter im Netzwerk-Dialog erlaubt die Kommunikation zwischen VM und dem Rest der Welt. |
Ändert man die Einstellung "NAT" in "Bridged Mode"
um, holt sich die VM eine IP-Adresse im lokalen Netz vom dort laufenden
DCHP-Server ab (z.B. 192.168.0.135) und wird somit zum gleichberechtigten
Kommunikationspartner. Ein in der VM installierter sshd-Dämon
("sudo apt-get install openssh-server") gewährt dann Clients auf dem
Host oder im lokalen Netz, die sich mit "ssh 192.168.0.135" in der VM
mit ihrer Userid anmelden, anstandslos Zugriff. Kopiert der User auch noch
seinen SSH-Public-Key (z.B. .ssh/id_rsa.pub
) in die Datei
~/.ssh/authorized_keys
in der VM, geht es sogar ohne Passwort, was
für automatisch ablaufende Skripts wichtig ist.
Allerdings ist es gar nicht so einfach, herauszufinden, welche IP sich eine bestimmte VM beim Hochfahren zugelegt hat. VirtualBox bietet eine Methode über die sogenannten "Guestproperties", einer Erweiterung, die der User erst durch Anwahl des Menüeintrags "Devices/Install Guest Additions" einer laufenden VM installieren muss (Abbildung 8). Anschließend lädt die VM eine .iso-Datei vom Internet, mounted sie als CD-Drive in der VM und führt ein auf der CD liegendes Shell-Skript aus, das dort wild anfängt, Kernelmodule zu kompilieren.
Abbildung 8: Wer die "Guest Additions" installiert, bekommt nützliche Utilities für VirtualBox-VMs. |
Bei der von mir verwendeten VirtualBox-Version 3.1.6 funktionierte das
Verfahren allerdings nicht, ich musste VBoxGuestAdditions_3.1.6.iso
manuell in die VM herunterladen, über ein "mount -o loop" mounten,
das Ubuntu-Paket dkms
installieren, und dann
das Shell-Skript VBoxLinuxAdditions-x86.run
ausführen (Abbildung 9).
Hierbei ist zu beachten, dass dies nicht mit Ubuntu-11 als Gastsystem
funktioniert, wenn das Hostsystem noch Ubuntu-10.04 fährt.
Abbildung 9: Die Installation der "Guest Additions" erfordert einige Handarbeit. |
Nach einem Neustart der VM kann dann der Host das Kommando
VBoxManage guestproperty enumerate "Ubuntu 10.04"
absetzen und erhält in
einem Wust von weiteren Informationen die Zeile
"Name: /VirtualBox/GuestInfo/Net/0/V4/IP, value: 192.168.0.135"
, was
ihm die von der VM verwendete IP anzeigt. Wer statt "enumerate" ein
"get" auf den oben gezeigten GuestInfo-Pfad absetzt, bekommt die IP der
laufenden VM direkt übermittelt (Abbildung 10).
Abbildung 10: Die "Guest Properties" zeigen an, welche IP sich eine bestimmte VM vom DHCP-Server geholt hat. |
Falls CPAN-Module ihre Abhängigkeiten zu weiteren Modulen ordnungsgemäß angeben, erledigt eine CPAN-Shell die Installation ohne viel Federlesens. Leider vergessen Autoren allerdings manchmal, Module anzugeben, die sich auf ihrem Entwicklungsrechner befinden, aber blanken Perl-Installationen noch nicht beiliegen. Anwenderfrust ist die Folge.
Abhilfe schafft hier eine
als VM-Snapshot festgehaltene frische Perl-Installation, die der
Modul-Autor mit Hilfe des Skripts cpan-smoke
in Listing 2 hochfährt,
ihr einen
gerade erzeugten CPAN-Distributions-Tarball übergibt und dort eine
CPAN-Shell testen lässt, ob sich die neue Version auf einem jungfräulichen
System mit CPAN-Anschluss installieren lässt. Läuft die dem
Modul beiliegende Testsuite ohne Fehler durch? Dann gilt der sogenannte
"Smoke Test" als bestanden und die Chancen stehen gut, dass das Modul
sich gut auf ähnlichen Systemen installieren lässt.
Abbildung 11: Ein neuer Snapshot "CPAN Smoke" baut auf den "Guest Additions" auf und verfügt über eine konfigurierte CPAN-Shell. |
Hierzu konfiguriert der Entwickler in einer VM mit den "Guest Additions" eine CPAN-Shell, zieht davon einen Snapshot und nennt ihn "CPAN Smoke". Abbildung 11 zeigt, dass im Snapshot-Baum der VM "Ubuntu 10.04" nun zwei Zweige existieren, der anfangs erzeugten Snapshot "Browse" baut auf einer frischen Installation auf und existiert unabhängig von eventuell weiteren auf "CPAN Smoke" aufbauenden Snapshots.
Damit die Installation auch mit der Mini-CPAN-Shell cpanm
im lokalen
Verzeichnis klappt, hat der Snapshot "CPAN Smoke" das CPAN-Modul
local::lib installiert, das in einem Ubuntu-System am besten durch
das Kommando
$ sudo apt-get install liblocal-lib-perl
durch den Package-Manager in die VM gelangt. Das Kommando
$ eval $(/usr/bin/perl -Mlocal::lib)
in der Shell setzt dann die notwendigen Shell-Variablen für die Installation weiterer Module im lokalen Verzeichnis. So installiert sich auch die Mini-Shell lokal:
$ cpan App::cpanminus
und anschließend steht das Kommando cpanm
zur Installation weiterer
Module im $PATH zur Verfügung:
$ cpanm --version cpanm (App::cpanminus) version 1.4008
Wer genau mitverfolgen möchte, wie die Installation von App::cpanminus in einer frisch angelegten Ubuntu-Installation vonstatten geht, kann sich den Durchlauf im Screencast zum September-Perlsnapshot ansehen.
An dieser Stelle wird dann der Snapshot gezogen und "CPAN Smoke" benannt.
Ruft man auf dem Host dann cpan-smoke
mit einem Tarball eines
mit "make tardist" erzeugten CPAN-Tarballs als Argument auf, restauriert
das Skript den Snapshot, fährt die VM hoch und wartet bis dessen
Netzwerkkonfiguration abgeschlossen ist und es auf ein "ping" reagiert.
Das Kommando VBoxHeadless --startvm
in Zeile 28 startet die
VM ohne jegliche GUI-Ausgabe und wartet im Vordergrund, bis der
User das Programm mit CTRL-C abschießt. Das CPAN-Modul Proc::Simple
schickt es deshalb in den Hintergrund und merkt sich die PID, damit
das am Ende des Skripts ausgelöste END-Snippet ab Zeile 29 seinen
kill()-Befehl an das richtige Programm schickt und die kopflose
VM herunterfährt.
Dann kopiert Zeile 55 den tarball ins /tmp-Verzeichnis der VM und
Zeile 56 startet dort das Kommando cpanm tarball
, das sich den
Tarball schnappt, entpackt, und "make"-Kommandos zum Testen und zur
Installation ausführt. Stößt cpanm
auf CPAN-Module, von denen das
Modul abhängt, lädt es diese selbständig vom CPAN und installiert diese
ebenfalls.
01 #!/usr/local/bin/perl -w 02 use strict; 03 use Sysadm::Install qw(:all); 04 use Proc::Simple; 05 use Net::Ping; 06 use Log::Log4perl qw(:easy); 07 08 my( $tarball) = @ARGV; 09 10 die "usage: $0 tarball" if 11 !defined $tarball; 12 13 Log::Log4perl->easy_init($ERROR); 14 15 my $vbm = "VBoxManage"; 16 my $vbh = "VBoxHeadless"; 17 my $vm = "Ubuntu 10.04"; 18 my $ippath = 19 "/VirtualBox/GuestInfo/Net/0/V4/IP"; 20 my $snap = "CPAN Smoke"; 21 22 # in case it's up in foreground 23 tap $vbm, "controlvm", $vm, "poweroff"; 24 tap $vbm, "snapshot", 25 $vm, "restore", $snap; 26 27 my $proc = Proc::Simple->new(); 28 $proc->start("$vbh --startvm '$vm'"); 29 END { 30 $proc->kill(); 31 } 32 33 INFO "Waiting for VM to come up"; 34 35 while( !$proc->poll() ) { 36 DEBUG "Waiting for VM process"; 37 sleep 1; 38 } 39 40 my $ip; 41 42 while( !defined($ip = ip()) ) { 43 DEBUG "Waiting for IP"; 44 sleep 1; 45 } 46 47 my $ping = Net::Ping->new(); 48 while( !$ping->ping($ip) ) { 49 DEBUG "Waiting for Ping"; 50 sleep 1; 51 } 52 53 INFO "VM is up: $ip"; 54 55 tap "scp", $tarball, "$ip:/tmp/$tarball"; 56 sysrun "ssh", $ip, 57 qq{eval \$(/usr/bin/perl -Mlocal::lib); 58 cpanm /tmp/$tarball}; 59 60 tap $vbm, "controlvm", $vm, "poweroff"; 61 tap $vbm, "snapshot", 62 $vm, "restore", $snap; 63 64 ########################################### 65 sub ip { 66 ########################################### 67 my($stdout) = tap $vbm, "guestproperty", 68 "get", $vm, $ippath; 69 70 if( $stdout =~ /Value: (.*)/ ) { 71 return $1; 72 } 73 74 return undef; 75 }
Damit die Shell in der VM das Kommando cpanm
findet, nach
installierten Modulen im lokalen Pfad ~/perl5
sucht und dort
neue Module ebenfalls installiert, setzt der ssh
-Befehl in Zeile
56 vor dem eigentlichen cpanm
-Kommando noch den weiter oben
gezeigten eval-Befehl ab, der die erforderlichen Shell-Variablen setzt.
Die Ausgabe des Installationsskripts cpanm
landet dank der
sysrun
-Funktion des Moduls Sysadm::Install auf der Standardausgabe
des rufenden Skripts cpan-smoke
, wo der sorgfältige Entwickler ablesen,
kann wie seine neueste Kreation sich in einer fremden Umgebung schlägt.
Falls Rauch aufsteigt, müssen wohl die definierte Abhängigkeiten zu
anderen CPAN-Modulen untersucht werden.
Auch im Cloud-Zeitalter, in der VMs wie Amazons EC2 auf dem Internet zur Verfügung stehen, ist eine lokale Virtualisierungslösung wie VirtualBox noch attraktiv. Eine detaillierte Bedienungsanweisung für Neulinge bietet [3], allerdings beschreibt es die fast schon veraltete Version VirtualBox 3.1. Schnell mal 32 Dollar gezahlt und in Minuten auf den Kindle heruntergeladen spart das sauber redigierte Buch gegenüber weniger strukturierten Internetinhalten enorm Zeit.
Listings zu diesem Artikel: ftp://www.linux-magazin.de/pub/listings/magazin/2011/10/Perl
VirtualBox Project Page, http://www.virtualbox.org
"VirtualBox 3.1: Beginner's Guide", Alfonso V. Romero, Packt Publishing (April 15, 2010), Kindle Edition
Michael Schilliarbeitet als Software-Engineer bei Yahoo! in Sunnyvale, Kalifornien. Er hat "Goto Perl 5" (deutsch) und "Perl Power" (englisch) für Addison-Wesley geschrieben und ist unter mschilli@perlmeister.com zu erreichen. Seine Homepage: http://perlmeister.com. |