Wie ich schon in einigen Beiträgen hier im Blog berichtet habe, verwende ich in meinen Programmierprojekten Jenkins zum Zweck der Continuous Integration (CI). Diese Woche habe ich mal versucht einen Schritt weiter zu gehen und habe mich mit Continous Delivery (CD) mit Jenkins beschäftigt.
Continuous Delivery (CD) soll durch eine möglichst weitgehende Automatisierung die time-to-market verkürzen. Mag das für manchen schon genug der (Marketing-) Argumente sein, um sich mit CD zu beschäftigen, so bringt es aber auch weitere Vorteile mit sich. Durch geschickte Integration mehrere Komponenten wird die Continuous Integration (CI) – Kette ausgebaut und umfasst neben „Commit, Build, Test, Package“ nun etwas mehr.
Keine Angst… CI ist Teil von CD. So untergliedert sich CD in verschiedene Stages, wobei die erste Stage – die so gernannte „Commit Stage“ mit dem bisher eingesetzten CI identisch ist.
Die darauffolgenden Stages machen den Unterschied. So wie ich das bisher verstehe sind die folgenden Stages nicht rigide definiert, sondern richten sich nach dem jeweiligen Umfeld. Das Ziel ist aber immer das selbe, nämlich das Deployment der gebauten Version auf einem (Kunden)System. Alle Stages zusammen bezeichnet man als Deployment-Pipeline. Eine typische Deployment-Pipeline kann beispielsweise so aussehen:

Eine Umsetzung einer solchen Pipeline ist in Jenkins mit Hilfe unterschiedlicher Jobs möglich. Durch die Abhängigkeiten der Jobs untereinander wird so eine implizite Reihenfolge festgelegt. Eine Visualisierung der Pipeline ist dann etwa mit dem Plugin „Build Pipeline Plugin“ machbar.
Es können Manual-Steps, sowie Automatic-Steps in der Build-Pipeline umgesetzt werden. Besteht die komplette Pipeline aus automatisch ausgeführten Schritten, spricht man im Rahmen von CD auch von „Continuous Deployment“. Wie genau die nachfolgenden Builds ausgelöst werden, kann man mit Hilfe des Plugins „Parameterized Trigger Plugin“ in Jenkins festlegen.
Neben diesen beiden Jenkins-Plugins bieten sich zum Umsetzen einer CD-Pipeline aber auch weitere Tools an. Zu diesen Tools zählt neben Buildtools, wie zum Beispiel Gradle oder Repositories, wie etwa Nexus der Firma Sonatype, auch Hilfswerkzeuge wie Vagrant an. Letzteres hilft beim Erstellen, Verwalten und Verwenden von ganzen Testumgebungen. In den Testumgebungen kann dann etwa die zuletzt gebaute Version der zu testenden Software aus dem Nexus Repository herunterladen, dann installieren und zu guter Letzt testen.
Dazu nutzt Vagrant virtuelle Maschinen (derzeit werden virtualbox und vmware unterstützt), welche dann bei jedem Testdurchlauf einen definierten, immer gleichbleibenden Zustand haben. Den gewünschten Zustand kann man per Provisioners herstellen. Das kann entweder ein Shell-Provisioner (in Form eines Shell Scripts) oder ein Chef- oder Puppet-Provisioner sein. Mit Gradle kann man dann etwa eine Vagrant-Machine starten (per Gradle Vagrant Plugin), um dort Integrationstests, Akzeptanztests und/oder Performancetests durchzuführen. Ein paar Testmaschinen kann man etwa von Vagrantbox.es herunterladen.
Der Vorteil bei der Verwendung von Vagrant liegt dabei nicht nur in definierten (Ausgangs)zuständen für reproduzierbares Testen, sondern auch darin, dass die beteiligten Virtual-Machines einfach von einem System auf ein anderes kopiert werden können. Dazu muss man nicht die gesamte Maschine kopieren. Es ist ausreichend, wenn man die Beschreibungsdatei (das so genannte Vagrantfile) kopiert wird. Ein Vorteil ist das etwa immer dann, wenn man die Testmaschine nicht nur am Testserver, sondern auch auf Entwicklungsrechnern zur Verfügung haben will. Auch kann man so die gesamte Testumgebung in Form einer Beschreibungsdatei (welches aus wenigen KByte besteht) in das Versionskontrollsystem einchecken.
Vagrant kann in der Funktionalität erweitert werden. Dazu verwendet es Plugins. Ein sinnvolles Plugin ist das Plugin „vagrant-cachier“. Es kümmert sich darum, dass beim Starten der Vagrant-Maschine das Downloadvolumen verringert wird. So speichert es etwa per yum (oder auch apt-get) installierte Dateien in einem Cache zwischen. Dieser Cache wird beim Zurücksetzen des VM-Zustandes nicht zurückgesetzt und verhindert so den mehrfachen Download. Selbst maven-repositories kann man mit Hilfe des Plugins und ein wenig Arbeit zur Datei-Zwischenspeicherung überreden.
Sollte es beim Starten einer Vagrantbox Probleme geben, so kann man im Vagrantfile eine GUI aktivieren. Damit wird dann beim Start etwa die Virtualbox-Umgebung angezeigt:
Beispielsweise kann man damit Probleme finden, die sich ergeben, wenn man im BIOS des Host-Systems die Virtualisierung nicht korrekt aktiviert hat (Intel VT muss eingeschaltet sein)