Softwareentwickler / Software Developer
Jenkins Build Lampe in Aktion

Bauen einer Jenkins-Lampe zur Anzeige des Build-Status

Nach erfolgreichem Abschluss meiner Ausbildung zum Fachinformatiker für Anwendungsentwicklung habe ich gemeinsam mit einer Arbeitskollegin als Dankeschön für die Betreuung und Unterstützung während der Ausbildung ein kleines Geschenk für meinen Ausbilder gebastelt . Überlegt haben wir uns, angeregt von früheren Ideen aus der Abteilung, eine Lampe zu bauen, die den Build-Status vom Jenkins anzeigt. Wie ich das umgesetzt habe, möchte ich in diesem Beitrag einmal zeigen.

Hintergrund

Beim Jenkins handelt es sich um “ein erweiterbares, webbasiertes Software-System zur kontinuierlichen Integration von Komponenten zu einem Anwendungsprogramm”(Wikipedia). Es wird im Rahmen eines sogenannten Builds der aktuelle Source-Code aus einem Repository ausgecheckt und überprüft, ob die Anwendung kompiliert werden kann, ob alle Tests funktionieren und verschiedene andere Dinge. So kann man schnell sehen, wenn eine Änderung eine ungewollte Folge nach sich gezogen hat. Um dies noch besser visuell darzustellen, war die Idee, eine Lampe zu bauen, die grün leuchtet, wenn der Build erfolgreich durchläuft, gelb leuchtet, wenn der Build-Prozess aktiv läuft und rot wird, sollte der Build fehlschlagen.

Bauen einer solchen Lampe

Da ich in DIY-Projekten noch relativ wenig Erfahrung habe, war ich sehr glücklich eine leicht verständliche Anleitung auf dordnung.de gefunden zu haben, wie eine solche Lampe gebaut werden kann, die durch einen Raspberry gesteuert wird. Wie genau das geht, kann unter dem Link nachgelesen werden. An dieser Stelle möchte ich nur einmal alle verwendeten Bestandteile auflisten und verlinken.

Architektur

Nach dem Befolgen der Anleitung können die LED’s über den Raspberry angesprochen werden. Dieser Raspberry darf aber in diesem Fall nicht direkt in das Unternehmens-Netz gehängt werden, um Sicherheitsrisiken zu vermeiden. Deswegen kann ich nicht direkt den Jenkins ansprechen, der nur im internen Netz erreichbar ist.

Die API vom Jenkins frage ich über ein Skript ab, dass auf einem internen Linux-Server ausgeführt wird. Je nach Build-Status wird eine Webseite aufgerufen, die auf meinem vServer von 1blu läuft. Dort führt ein PHP-Skript ein Kommandozeilenbefehl aus, wodurch der Inhalt einer Text-Datei angepasst wird. Diese Datei kann ebenfalls aus dem Internet erreicht werden. Diese Datei ruft der Raspberry dann nämlich auf und entscheidet je nach Inhalt, wie die LEDs leuchten sollen.

Abfragen der Jenkins API

Glücklicherweise bietet der Jenkins-Server von sich aus schon verschiedene APIs an. Ich habe mich dazu entschieden, die JSON-API zu benutzen. Zuerst bestimme ich an einem Projekt, welche die aktuelle Build-Nummer ist. Sobald ich diese ermittelt habe, frage ich die Informationen zu diesem ab. Je nachdem, was sich in diesem JSON-String nun befindet, rufe ich die oben beschriebene Webseite mit dem jeweiligen Statuscode als Parameter auf.

#!/bin/bash

jenkinsUrl="http://jenkins.intern"
projectName="Test"
branch="master"
website="https://example.com/"

urlJob=$jenkinsUrl"/job/"$projectName"/job/"$branch"/api/json"
jsonJob=$(curl $urlJob)

nextBuildString=$(sed -n 's/.*\("nextBuildNumber":[0-9]*\).*//p' <<< $jsonJob)
nextBuild=${nextBuildString:18}
currentBuild=$(($nextBuild-1))

urlBuild=$jenkinsUrl"/job/"$projectName"/job/"$branch"/"$currentBuild"/api/json?pretty=true"
jsonBuild=$(curl $urlBuild)

# Projekt wird noch gebaut
case "$jsonBuild" in *'"building" : true'*)
    curl $website"/?status=1"
esac

# Projekt kann nicht gebaut werden
case "$jsonBuild" in *'"result" : "FAILURE"'*)
    curl $website"/?status=2"
esac

# Projekt kann gebaut werden
case "$jsonBuild" in *'"result" : "SUCCESS"'*)
    curl $website"/?status=3"
esac

Verarbeiten dieses GET-Requests

Auf meinem Server muss ich diese GET-Anfrage nun verarbeiten und nutze dazu wie oben beschrieben PHP. Dabei lese ich eigentlich nur den übergebenen GET-Parameter status aus und führe dann mittels shell_exec() einen Kommandozeilen-Befehl aus. Dadurch ändert sich der Inhalt der Textdatei, die – wenn wir bei dem Code-Beispiel folgen – unter “https://example.com/status.txt” erreichbar ist. Aufgerufen wird die URL “https://example.com/?status=1”, wobei der Status auch 2 oder 3 sein kann.

<?php
$status = $_GET['status'];

if($status == 1){
    echo shell_exec("/path/to/script/building.sh");
}
if($status == 2){
    echo shell_exec("/path/to/script/failure.sh");
}
if($status == 3){
    echo shell_exec("/path/to/script/success.sh");
}
?>

Das ausgeführte Skript building.sh sieht beispielsweise wie folgt aus.

#!/bin/bash
sed -i "s/.*/1/g" /path/to/file/status.txt

Es wird also der gesamte Inhalt der Datei durch – in diesem Fall – eine “1” ersetzt.

Abfragen dieser Text-Datei

Diese Text-Datei ruft der Raspberry dann auf und muss anhand dessen entscheiden, wie die Lampen leuchten sollen. Im Grunde ist der Code dazu recht simpel. Wichtig dabei ist, dass pigpiod gestartet wurde, um mit dem pigs-Befehl die Pins vom Raspberry ansprechen zu können.

#!/bin/bash

sudo pigpiod
status=$(curl https://example.com/status.txt)

case $status in
    "1")
        # building = yellow light
        pigs p 17 255 # red
        pigs p 22 255 # green
        pigs p 24 0   # blue
        ;;
    "2")
        # failed = red light
        pigs p 17 255
        pigs p 22 0
        pigs p 24 0
        ;;
    "3")
        # succeded = green light
        pigs p 17 0
        pigs p 22 255
        pigs p 24 0
        ;;
    *)
        ;;
esac

Automatisierung

Damit ich nicht jedes Mal, wenn ich den Build-Status abfragen möchte, beide Skripte manuell starten muss, habe ich jeweils einen Cronjob eingerichtet, der jede Minute läuft. So hat das Licht zwar eventuell eine Verzögerung von einer Minute. Da ein Build aber etwa eine Viertelstunde dauert, dürfte das ganz okay sein!

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Ein Gedanke zu “Bauen einer Jenkins-Lampe zur Anzeige des Build-Status”