Das Paket Vagrant verwaltet mit VirtualBox als Virtualisierer VMs einfach von der Kommandozeile aus. Der Kunde kann so ohne große Installationssprünge einfach mal in ein Produkt hineinschnuppern.
Die alte Ausrede "also bei mir funktionierts" bei defekten Produkten hat unter Softwareentwicklern spätestens mit der Erfindung von virtuellen Maschinen ausgedient. Auf einer nackten Distro lassen sich ganze Softwaresuiten reproduzierbar installieren und Tests verifizieren dann, ob das Gesamtsystem auch tatsächlich funktioniert oder nicht.
Um diese Tests zu automatisieren, benötigt der Entwickler ein Kommandozeilen-Tool zum Hochfahren der Virtuellen Maschine, ein Einrichtungs-Tool zum Installieren der Applikationspakete und deren Abhängigkeiten, und ein Skript zum Anwerfen der Testsuite. Oft erstrecken sich Applikationen auch über mehrere Instanzen, wie bei einem Client, der zu einem Webserver Kontakt aufnimmt, der wiederum eine Datenbankinstanz nutzt.
Das Tool Vagrant [2] (übersetzt: "Vagabund") definiert die in einem Softwareprojekt genutzten virtuellen Maschinen einfach per Konfigurationsdatei, die das Entwicklungsteam versioniert und neben dem Source-Code im Projekt-Repository mitführt. Vagrant nutzt als Virtualisierer das kostenlose VirtualBox von Oracle ([3]), das auf Linux, OSX und Windows läuft und alle möglichen Betriebssysteme wie auch Linux virtualisiert. Vagrant richtet die VMs in sogenannten "Boxes" so her, dass in ihnen ein ssh-Daemon läuft und ein User namens "vagrant" sudo-Rechte besitzt.
Abbildung 1: Vagrant und VirtualBox: Wer wollte nicht schon einmal auf einem Macbook mit einem Aufruf von der Kommandozeile in ein 64-bit-Ubuntu wechseln? |
Abbildung 2: Vagrant läuft auf Debian, Red Hat Linux, dem Mac, und Windows. |
Abbildung 3: Auf vagrantbox.es stehen alle gängingen Linux-Distributionen als Vagrant-Boxes zum Download bereit. |
So startet die Sequenz "vagrant up" und "vagrant ssh" eine vorher von einem Distributionsserver wie zum Beispiel http://vagrantbox.es heruntergeladene Box als VM und wechselt auf der Kommandozeile in sie hinein. Zum automatischen Einrichten von Softwarepaketen und Anpassen von Konfigurationsdateien stehen Software-Provision-Tools wie Puppet, Chef und Saltstack bereit. Diese sorgen dafür, dass Distro-Pakete vom Repo-Server geladen und installiert, Abhängigkeiten aufgelöst, rollenspezifische Konfigurationen eingestellt und Services gestartet und am Laufen gehalten werden.
1 Vagrant::Config.run do |config| 2 3 # 32-bit Ubuntu Box 4 config.vm.box = "precise32" 5 6 # provision with Puppet 7 config.vm.provision :puppet 8 end
Das Kommando "vagrant init" in einem frisch angelegten Verzeichnis im Hostsystem legt eine Datei namens "VagrantFile" an, die außer einer langen Liste von auskommentierten Optionen nur den Ruby-Code
Vagrant::Config.run do |config| config.vm.box = "base" end
enthält. Das anschließend abgesetzte Kommando vagrant box add ...
ersetzt den Wert für "base" in der Datei
mit dem angegebenen Namen für die neu angelegte
Box ("precise64" in Abbildung 4) und lädt die Box vom Webserver
an dem angegebenen URL. Unterstützt die heruntergeladene VM-Box
ein Einrichtungstool wie Puppet, Chef oder Saltstack, darf das
Vagrantfile die Konfiguration der VM diesem überlassen. Listing 1
verweist zum Beispiel auf
config.vm.provision :puppet
Damit erwartet Vagrant in der Datei manifests/default.pp
unter dem Vagrant-Verzeichnis eine Puppet-Konfigurationsdatei nach
Listing 2. Abbildung 4 zeigt das Datei-Layout im Hostsystem, das im
Source-Control-Repo des Entwicklungsteams liegt.
Abbildung 4: Diese Dateien in der Sourcecode-Verwaltung bestimmen Parameter und Inventar der Vagrant-VM. |
01 # Basic Puppet Mojo manifest 02 03 class mojo { 04 exec { 'apt-get update': 05 command => '/usr/bin/apt-get update' 06 } 07 08 package { "libmojolicious-perl": 09 ensure => present 10 } 11 12 file { '/usr/bin/mymojo': 13 ensure => link, 14 target => "/vagrant/mymojo", 15 force => true 16 } 17 } 18 19 include mojo
Ein vagrant up
fährt dann nicht nur die VM der Box hoch, sondern
wirft auch den Puppet-Client an. Dessen Konfigurationsdatei in
Listing 2 definiert eine Klasse mojo
, die als erstes den Index des
unter Ubuntu verwendeten Package-Managers mit apt-get update
aktualisiert.
Die package
-Anweisung in Zeile 8 zieht das CPAN-Modul Mojolicious
herein, das unter Debian-ähnlichen Systemen als Paket
libmojolicious-perl
vorliegt. Die ensure
-Anweisung stellt sicher,
dass das Paket installiert ist und löst ein apt-get install
aus,
falls es noch fehlt. Das ebenfalls benötigte Perl-Core-Paket
ist glücklicherweise
schon von Haus aus auf der Ubuntu-Distro vorhanden.
Die Anweisung file
in Zeile 12 legt in der VM
einen Link unter /usr/bin/mymojo
an, der auf das gleichnamige
Perlskript unter /vagrant/mymojo
zeigt. Das Verzeichnis /vagrant
bindet Vagrant praktischerweise an das Vagrant-Verzeichnis im Hostsystem,
also kann der User in seinem Source-Control-Repository einfach Skripts
einchecken, die dann in hochgefahrenen VMs erscheinen. Statt die VM mit
reload
neu zu starten, um neue Puppet-Parameter auszuprobieren, kann
der User während der Testphase in der VM auch einfach das Kommando
puppet apply /vagrant/manifests/defaut.pp
aufrufen und Puppet damit
zum Einrichten der VM bewegen.
Listing 3 definiert einen simplen Webserver Marke Eigenbau, der auf dem
CPAN-Modul Mojolicious::Lite aufbaut. Auf jeden eintrudelnden GET-Request
antwortet er mit dem Namen des Users, der ihn hochgefahren hat.
Die Funktion c<getpwuid> nimmt die effektive UID des Skripts ($>) entgegen
und liefert in skalarem Kontext den Usernamen zurück.
Die Methode render()
gibt den ihr überreichten Text an den anfragenden
Webclient zurück.
Der Entwickler legt das Skript im Vagrant-Verzeichnis auf dem Hostsystem
ab und startet dann in einer mit vagrant ssh
neu geöffneten VM-Session
die Applikation mit /usr/bin/mymojo daemon
. Der Webserver in Listing
3 reagiert dann auf alle GET-Anfragen mit der Ausgabe des Unix-Users, der
das Skript gestartet hat. In der Vagrant-Session ist dies vagrant
:
$ vagrant ssh vagrant@precise64:~$ curl http://localhost:3000 I am vagrant
Zu beachten ist, dass der Webserver sich an einen lokalen Port innerhalb der VM bindet, vom Hostsystem und dem angrenzenden Netzwerk aus ist er nicht erreichbar. Um dies zu erlauben, benötigt VirtualBox die sogenannten Guest-Additions, die etwas mehr Installationsaufwand erfordern.
01 #!/usr/bin/perl -w 02 use strict; 03 use Mojolicious::Lite; 04 05 get '/' => sub { 06 my $self = shift; 07 08 my $user = getpwuid( $> ); 09 10 $self->render( text => 11 "I am $user\n" ); 12 }; 13 14 app->start;
Einrichtungs-Tools (Provision Tools) können weit mehr als hier gezeigt, und übernehmen mittels auf Community-Ebene austauschter Module gängige Sysadmin-Aufgaben, wie den Webserver Apache mit SSL hochzufahren und am Leben zu erhalten oder MySQL zu konfigurieren und zu starten. So muss nicht jeder Sysadmin das Rad neu erfinden und kann getestete und in der Produktion bewährte Bausteine zusammenklicken. Wer viele solcher Nodes in Server-Farmen verwaltet, überträgt die Verantwortung einem Master-Server der so Heerscharen von End-Nodes verwaltet. Ein Blick in die Manualseiten von Puppet, Chef, und dem vielversprechenden Newcomer Saltstack [4] lohnt sich.
Auf [3] ist zur Installation der Kombination aus Vagrant und VirtualBox zunächst das passende VirtualBox-Paket abzuholen und gemäß den Instruktionen für die verwendete Linux-Distro zu installieren. Auch für das Ruby-basierte Vagrant stehen fertige Pakete für eine ganze Reihe gängiger Linux-Distros auf [2] bereit, deren Installation ein Klacks ist. Sucht man dann auf http://vagrantbox.es die URL für eine Vagrant-Box des gewünschten zu simulierenden Linux-Distro heraus, führen die Schritte in Abbildung 5 (zum Beispiel für Ubuntu Precise 32-bit) zum Ziel.
Abbildung 5: Alle notwendigen Schritte zur Installation einer VM mit Ubuntu Precise 32-bit mit Vagrant und VirtualBox. |
Die plattformübergreifende Definition von virtuellen Maschinen mit ebenfalls poliglotten Anweisungen für Einrichtungstools versetzt Entwickler in die Lage, ihre Testumgebungen auf Knopfdruck hochzufahren, allein basierend Informationen, die in der versionierten Source-Code-Verwaltung stecken. Da sich modifizierte Vagrant-Boxen ohne viel Aufwand auch wieder in neue Boxen eintüten lassen, kann man ein fast fertiges Produkt auch schnell zum Kunden schicken, der es nach dem standartisierten Verfahren auf einer Vielzahl von Host-Plattformen einfach mal ausprobieren kann.
Listings zu diesem Artikel: ftp://www.linux-magazin.de/pub/listings/magazin/2013/05/Perl
Vagrant Homepage: http://www.vagrantup.com
Virtualbox: https://www.virtualbox.org/wiki/Downloads
Saltstack: http://saltstack.com