GitLab – Webhooks

gitlab-webhooks
Da ich vor kurzem für einen unserer namhaften Kunden ein GitLab Setup aufsetzten durfte und dieser sich nun auch Automatische Checkouts seiner Live Branches auf seinen Produktiv Systemen wünschte, habe ich mich dazu entschlossen euch ein bisschen an der Einrichtung dieser Mechaniken teilhaben zu lassen, natürlich nicht im vollem Umfang des Projektes für unseren Kunden, das eine oder andere habe ich für diesen Artikel verständlicherweise leicht abwandeln müssen, das hier gezeigte funktioniert trotzdem, ich habe es selber ausprobiert.
Dann legen wir mal los…
In einem klassischen Git Setup werden die Hooks direkt im Repository im Unterordner hooks abgelegt, hier mal ein Beispiel wie das aussehen kann…

$ MyAwesomeProject/hooks $ ll
-rwxrwxr-x 1 enzo enzo  452 Jun 28 11:46 applypatch-msg.sample*
-rwxrwxr-x 1 enzo enzo  896 Jun 28 11:46 commit-msg.sample*
-rwxrwxr-x 1 enzo enzo  189 Jun 28 11:46 post-update.sample*
-rwxrwxr-x 1 enzo enzo  398 Jun 28 11:46 pre-applypatch.sample*
-rwxrwxr-x 1 enzo enzo 1642 Jun 28 11:46 pre-commit.sample*
-rwxrwxr-x 1 enzo enzo 1239 Jun 28 11:46 prepare-commit-msg.sample*
-rwxrwxr-x 1 enzo enzo 1352 Jun 28 11:46 pre-push.sample*
-rwxrwxr-x 1 enzo enzo 4898 Jun 28 11:46 pre-rebase.sample*
-rwxrwxr-x 1 enzo enzo 3611 Jun 28 11:46 update.sample*

GitLab geht hier allerdings einen anderen Weg, da dieses das hooks Verzeichnis durch einen Symbolischen Link auf System eigene Hooks umlenkt (wie hier Beispielhaft zu sehen ist)…
gitlab-webhooks-art2
…nun sollte man hier auch besser die Finger heraus lassen, da GitLab dieses Verzeichnis für allerlei anderen Mechaniken benötigt, der Weg über die Webhooks ist meiner Meinung nach aber auch flexibler (allein schon wegen der einfachen Anbindung an Web Dienste wie GitHub, Bitbucket, Heroku, etc.).
Nun direkt zum spaßigen Teil, im GitLab benötigen wir einen neuen User ohne irgendwelche besonderen Rechte incl. SSH Public Key, fangen wir mit dem Key selbst an, da der Checkout User keinen besonderen Rechte benötigt außer einen Pull/Fetch zu tätigen, reicht es uns den Key also entsprechend Unprivilegiert zu preparieren (bei der Passwortabfrage bitte nichts angeben, einfach mit Enter bestätigen)…

$ ssh-keygen -t rsa -b 2048 -O clear -O no-agent-forwarding -O no-port-forwarding -O no-pty -O no-user-rc -O no-x11-forwarding -f gitlab.key
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in gitlab.key.
Your public key has been saved in gitlab.key.pub.
The key fingerprint is:
4b:f3:ae:60:d4:5d:5e:02:75:64:4c:7f:ce:09:ec:8a enzo@ebony
The key's randomart image is:
+--[ RSA 2048]----+
|          ...+=  |
|           ..o.. |
|            oo. o|
|       . . o.o.oo|
|      . S . .. .o|
|     . . +. .    |
|      o .E..     |
|     . . .       |
|        ...      |
+-----------------+
$ ll
insgesamt 8
-rw------- 1 enzo enzo 1675 Jun 28 11:52 gitlab.key
-rw-r--r-- 1 enzo enzo  392 Jun 28 11:52 gitlab.key.pub

…nun benötigen wir lediglich noch einen User im GitLab, das sollte keine große Herausforderung darstellen, bitte stellt auch sicher das ihr den SSH PublicKey in unserem Beispiel gitlab.key.pub dem User, lasst ihn uns hier der Einfachheit halber checkout nennen zuweist, da die Webhooks mit den Berechtigungen des Standard Apache User www-data läuft (das ist zumindest unter Debian/Ubuntu der Fall, unter Redhat Systemen heißt dieser wwwrun) solltet ihr dem Key als Identifier so etwas wie www-data to gitlab oder ähnliches benennen, damit ihr später ganz einfach den Überblick behalten könnt…
gitlab-webhooks-art4
gitlab-webhooks-art5
…nun müssen wir unserem User checkout lediglich noch in unser Projekt aufnehmen, die Rechte eines Reporter sollten dafür ausreichend sein um Fetch/Pull oder auch Clone zu können, mehr benötigen wir an dieser Stelle nicht…
gitlab-webhooks-art9
…somit sind wir auf schon fast fertig, zumindest was das GitLab Setup selbst betrifft, nun müssen wir lediglich noch die URL unseres Webhook konfigurieren und schon können wir uns dem Hook selber widmen…
gitlab-webhooks-art7
gitlab-webhooks-art8…bitte beachtet auch, das es beim Entwickeln eines Webhooks sehr hilfreich sein kann wenn ihr über den Button [Test Hook] den Push Event einfach mal Manuell triggert, ansonsten würde euer Webhook erst aufgerufen werden wenn ihr wirklich in das Repository Pusht (das geht natürlich auch, legt euch hierzu einfach ein neues Repository zum spielen an).
So nun geht es an den Server der unseren Webhook ausführen soll, ihr benötigt lediglich einen simplen Apache/NginX vHost mit Standard Rechten, man kann selbstverständlich auch ein komplizierteres Deployment bauen aber darum geht es in diesem Artikel nicht (ich nutzte hier den Apache2 mit PHP5, da dieser bereits auf dem Kunden System vorhanden wahr und zusätzliche Scriptsprachen installieren ist meist schlechte Praxis sowie auch unnötiger Aufwand).
Ich habe mich hier für den Standard Pfad des Apache Setups entschieden da der Standard vHost bereits auf diesen zeigt und dieser auch nur aus dem internen Netz bedienbar ist, somit ist sichergestellt das Niemand von außerhalb Unfug treiben kann.
Dort habe ich im DocumentRoot des Apache ein Verzeichnis api erstellt, der volle Pfad lautet hier /var/www/html/api, dort habe ich mein Webhook mit Namen on-push.php abgelegt, dieser hat nun folgenden Inhalt…

object_kind == 'push' ) {
                if( $obj->ref == 'refs/heads/'.BRANCH ) {
                    $allowed = false;
                    foreach( $USERS as $user ) {
                        msg( "permission test ( ".$obj->user_name ." == ". $user." ) ..." );
                        if( preg_match( "/$user/i", $obj->user_name ) ) {
                            msg( $user . " allowed to do updates on refs/heads/".BRANCH." branch" );
                            $allowed = true;
                            break;
                        }
                    }
                    if( $allowed ) {
                        if( $obj->before != "0000000000000000000000000000000000000000" ) {
                            msg( "changing directory to ".PROJECTROOT );
                            chdir( PROJECTROOT );
                            msg( "executing: ". COMMAND );
                            $fh = popen( COMMAND." 2>&1", "r" );
                            $result = fread( $fh );
                            while( !feof( $fh ) ) {
                                msg( rtrim(fgets( $fh, 4096 )) );
                            }
                            pclose( $fh );
                        } else {
                            msg( "it's a empty repository, we'll do nothing at this point" );
                        }
                    } else {
                        msg( "permission denied for ". $obj->user_name );
                    }
                } else {
                    msg( "everybody can push to ". $obj->ref.", but we'll do nothing, please check your project settings" );
                }
            } else {
                msg( "[ ". $obj->object_kind ." ] event handler not yet implemented" );
            }
        } else {
            msg( strtoupper($_SERVER['REQUEST_METHOD'])." from [ ".$_SERVER['REMOTE_ADDR'] ." ] is not allowed, please check your server settings" );
            return_status( ERR );
        }
    } catch( Exception $e ) {
        msg( "======= EXCEPTION BEGIN ========" );
        msg( $e->getMessage() );
        msg( "======= EXCEPTION END ==========" );
        return_status( ERR );
    }
    return_status( OK );
    // ================================ FUNCTIONS ===========================================
    function return_status( $status = ERR ) { header( $status ); }
    function getRequestBody() { return json_decode( file_get_contents('php://input') ); }
    function msg( $message ) { if( $message != null ) file_put_contents( LOGFILE, $message."\n", FILE_APPEND ); }
?>


..damit das nun funktionieren kann, müssen wir nun noch das Projekt Klonen und die SSH Settings anlegen, fangen wir daher direkt mit den SSH Settings an…

# (beginne mit Root Login)
su - -s /bin/bash www-data
mkdir -p .ssh && chmod 0600 .ssh
exit
cp gitlab.key /var/www/.ssh/ && chown www-data. /var/www/.ssh/gitlab.key && chmod 0400 /var/www/.ssh/gitlab.key
su - -s /bin/bash www-data
vi .ssh/config

…die .ssh/config sieht dabei wie folgt aus…

Host gitlab.example.org
    UserKnownHostsFile /dev/null
    StrictHostKeyChecking no
    IdentityFile ~/.ssh/gitlab.key
    User git
    LogLevel VERBOSE

…speichert nun das ganze und Klont eurer Projekt nach /var/www/project1/htdocs

# (beginne mit Root Login)
su - -s /bin/bash www-data
cd /var/www/project1
git clone git@gitlab.example.org:test/number1.git htdocs

…wenn ihr nun Lokal mit eurer Arbeitskopie arbeitet und an dem Punkt seit das ihr alles fertig zuhaben scheint und dann einen Push in euren staging Branch macht, wird GitLab jedesmal den Webhook on-push.php Aufrufen und auf dem Projekt/Web -Server einen Fetch/Pull ausführen lassen, um das Projekt auf den selben Stand wie eure Arbeitskopie zu bringen.
Zugegeben der PHP Handler oben ist keinesfalls perfekt, ich bin auch kein guter PHP Programmierer, genau genommen eigentlich gar keiner ;). Der Hook für das Kunden Projekt umfasst zudem noch mehr Fähigkeiten und würde mit seine zu diesem Zeitpunt ca. 800 Zeilen diesen Artikel in jedem Fall sprengen, aber ich denke das der gezeigte Webhook oben bereits eine gute Ausgangsbasis darstellt, sodass ich euch hoffentlich dazu Animieren konnte, das ganze doch einmal selber nachzubauen.
Zum zweck des Debugging, loggt dieser zur Kontrolle nach /var/www/html/api/on-push.log , hier lohnt also ein Blick.
Noch ein kleiner Hinweis meinerseits, der eine oder andere von euch wird schnell feststellen, das GitLab selber im Admin Panel auch einen Menü Eintrag mit der Bezeichnung [Deploy Keys] bereitstellt, womit sich das oben gezeigte auch umsetzten lässt, aufgrund einiger bedenken bzgl. Sicherheit dieses allerdings nicht immer gewünscht ist, da alle Keys die dort hinterlegt werden automatisch, für allen Projekte (auch für zukünftige) direkt verwendet werden können.
Nützliche Links:

Weekly Snap: Puppet project, Jasmine tests and VM alternatives

30 May – 3 June slipped into summer with a peek into a Puppet consulting project and tips for JavaScript testing and virtualisation.
To begin, Thomas explained his preference against large VMs. With their high overheads, he sought alternatives to hypervisors such as KVM, Xen and VMware. Instead of virtualised kernels with virtualised hardware, Thomas referred to Jails (BSD) and Zones (Solaris), or Linux-vServer and OpenVZ for Linux. Where the required patched kernels are inappropriate, he offered Linux Containers (LXC) as substitutes. In the upstream since 2.6.29 and progressing slowly, Thomas liked them as they do not need direct hardware access, do not block devices, network or memory. But most of all he liked the fact such a virtual server can perform just as well as processes on the host itself, where one single kernel manages virtual memory enabling more virtual servers to be run than on a mature VMware.
Jannis followed with his JavaSript testing tip – Jasmine. The successor to JSUnit, he recommended this test unit suite for its lack of dependencies and ability to describe tests, and even gave a user login test example to boot.
Last but not least, Birger gave us a peek into the consulting team’s latest escapades: A Puppet project at Continental, the automotive supplier. Used to help manage their heterogeneous server environment, Puppet oversees Linux and HPUX systems. Though the first is far simpler than the latter, thanks to spirit of open source the automation project was nonetheless a success.

Puppet bei Continental

Unser Projekt zur Automatisierung beim Automotiv Automobilzulieferer Continental ist inzwischen 2 Jahre alt. Es hat nicht an Reiz verloren.
Wir haben bei Planung und Einsatz von Puppet als Mittel zum Management der heterogenen Serverlandschaft unterstützt.
Linux Systeme mit Puppet zu managen ist inzwischen Alltagsgeschäft, HPUX ist aber nach wie vor kein Spaziergang. Leider gibt es für HPUX auch keinen Support von Puppetlabs. Aber möglich ist dank offener Quellen alles. Leider darf ich hier nicht weiter ins Detail gehen.
Vielen Dank für die gute Zusammenarbeit.

Weekly Snap: Training Dates, Siemens CEP CT3, an OTRS Project and a SQL Developer Release

11 – 15 October was packed with news from all sides of the office, from hardware and training course announcements, to a consulting project and a SQL Developer release.
From the consulting team, Birger shared his most recent project at the German Federal Bureau of Water and Shipping – an OTRS implementation to cover multiple locations with differing domains and user groups from one single ticketing system.
Hardware man Martin then bid his last Siemens TC35i goodbye and introduced its successor, CEP CT3. Running under the current Linux kernel, Windows (see shop for drivers) and Solaris, the modem tops its predecessor by offering a USB port and relevant accessories. With an external antenna, it is ideal for server racks with poor reception and thus a perfect USB GSM modem for sending SMS alerts from your monitoring system. Martin recommended teaming CEP CT63 GSM Terminal with Moxa NPort 6150 for smooth network integration.
Following on, Bernd forwarded news of the SQL Developer Early Adopter version release and its new features. Though he recommended MySQL Workbench for straight MySQL users, Bernd praised SQL Developer for its greater flexibility in enabling access to various databases such as Oracle, MySQL, Microsoft SQL Server and DB2. In the Oracle realm new features included new profiling and tuning functions, a migration assistant, a data modeller for graphical ER models, as well as reverse engineering that also works with MySQL. For SQL beginners, a new visual query builder simplifies the process of creating SQL statements too. All in all after his tests, Bernd found no major bugs and gave the Early Adopter version the thumbs up.
From the events team, Manuela announced the upcoming training calendar to end 2010 and start 2011. Ending 2010 with ‘Puppet Configuration Management’ for beginners on 7 – 9 December, and kick starting 2011 with ‘Nagios SLA Reporting with Jasper’ on 29 – 30 February, ‘Nagios – Availability Monitoring’ rounds it all off on 21 – 24 March for the coming months. She guaranteed all interested participants restricted class sizes for greater individual attention and accommodation at the course hotel to allow for discussion and idea exchange, consolidating all that is learnt in and out of the class. For more information, visit our training centre: www.netways.de/training

Clever Elements GmbH

Wir freuen uns, mit der Clever Elements GmbH unseren neuesten Kunden im Bereich Managed Service begrüßen zu dürfen. Clever Elements ist ein kleines Unternehmen unweit vom Moritzplatz direkt im Herzen Berlins. Namhaften Kunden wie z.B. Siemens, BMW und IBM bietet es eine Online-Software für E-Mail-Marketing, welche die Erstellung und Versendung von Newslettern so einfach und intuitiv wie nur möglich macht.
In den letzen Tagen haben wir die bestehenden Services auf ein neues HA-Cluster in unserem Rechenzentrum umgezogen. Ab sofort profitieren die Kunden von Clever Elements  von der damit verbunden Leistungssteigerung und können sich auf die hochverfügbare Umgebung 24×7 verlassen. Die vorhandene Architektur erlaubt zudem ein flexibles Wachstum in der Zukunft ohne Downtime.
Die Arbeit von Clever Elements kann man im Social Media-Zeitalter natürlich auch auf Facebook verfolgen.
Wir freuen uns auf eine weiterhin gute Zusammenarbeit mit der Clever Elements GmbH.

Project of the Month: NoMa up a notch

June 2010: In a large and distributed environment, multi channel alerts for hundreds of users can get complicated. Indeed that’s where NoMa came in handy for one of our longstanding clients. With no less than 60 alert definitions, NoMa had been managing Nagios alerts for the corporation’s 1000+ users dependent on central services, across their 80+ remote sites worldwide.
All was working well, but as always things can work better. One pesky characteristic was that if a highly interconnected component were to fail, not only would the admins receive that alert, but they would also receive individual alerts for all the other services and components that were subsequently affected. This domino effect inundated the admins with messages that ultimately stemmed from the same issue. So the proposal was put forward – how about bundling all related errors into one summary message, but still be able to individually (de)activate each alert?
Consultant William took on the challenge, thereby setting the foundations of NoMa’s latest release, version 1.0.5. By transferring the persistence coded in Perl memory to a database NoMa had improved stability and failover precaution built in. This enabled the new feature of central outage correlations and alert summaries. Further improving the user friendliness, the team also simplified the (de)activation of alerts to be executable on the web interface, without the need for restarts.
All in all, thanks to their sponsorship and close cooperation, NoMa will soon be available as v 1.0.5 equipped with greater flexibility. As the biggest contributor to NoMa, a company representative even presented the project at the OSMC 2009. Check out the presentation for more info and keep an eye on netways.org for the official release coming soon!

Weekly Snap: CSS2 floats to AKCP converters, OSDC & NETWAYS Jobs

29 Mar – 3 Apr: sprang over Easter with CSS floating style, industrial sensor converters, OSDC early bird reminders, NETWAYS jobs and an April special for Nagios/Icinga voice notification services.
The development team kicked off with Marius’ CSS2 tip for floating page layouts. First in ‘clearfix’, inserting a ‘clear’ after a float, second with ‘overflow:hidden|auto’ for a new display context. This ensures that the ‘clear’ doesn’t creep into the entire page, staying in the desired area automatically without needing to create strange margins.
On the monitoring front we reflected on the March project of the month, while Martin showed us how to integrate third-party sensors for those tricky industrial monitoring needs. From temperature sensors for pipelines or outdoors, to absolute pressure measurement and CO ² sensors – all these industrial sensors can be converted into electricity or voltage so their results can be transmitted over long distances to an AKCP sensorProbe2 which then forwards them on via SNMP to any monitoring software such as Nagios and Icinga.
Following on, Manuela reminded early birds to snap up the last ticket specials for the OSDC coming up on 23 – 24 June, while Karo announced our search for 3 new enthusiastic professionals to join the NETWAYS team. Project managers, Linux consultants and bookkeepers are welcome to apply, as are any would-be apprentices for software development.
Of course, no April could begin without a fool on the 1st day of the month – check out the newest voice notification services we’re offering through our partner call center in India and enjoy!

Project of the Month: Mule for Enhanced Distributed Monitoring

March 2010: When our customer needed to centrally monitor the latency of IT services across their 3 offices in Germany, America and Sweden, they were looking for a speedier alternative to their existing solution. Remote monitoring was not meeting their standards, as relying on an international link was all but efficient.
So Bernd came in with an ESB idea. Implementing Mule in their 3 locations, the set up included a server based in Germany and satellites in America and Sweden. The satellites read status and performance data from their file systems to send to the server, which in turn stored the data in an external command file. In processing commands, the server then read from NDO/IDO-DB, reviewed the content and sent the commands to the corresponding satellites. These satellites then also stored the data in an external command file.
Supported by Mule ESB, the satellites could be connected far more tightly and information could flow smoother. Moreover, transforming their makeshift bundle of scripts into a centralised system also meant the entire process itself could be more easily monitored with the handy check_jmx4perl. All in all, a more dynamic and flexible solution thanks to Mule.

Gesunde Datenbanküberwachung mit Nagios

Gesundheit Nordhessen Logo
In vielen öffentlichen Einrichtungen wird die kostengünstige Monitoring Lösung Nagios geschätzt. So auch bei unserem Kunden der Gesundheit Nordhessen Holding AG. Besonders positiv fällt immer wieder die Möglichkeit ins Gewicht eigene Erweiterungen oder Anpassungen vorzunehmen und so auch auf spezielle Anforderungen einzugehen. In diesem Fall ging es besonders um einige Eigenheiten bei der Überwachung von verschiedenen Datenbanksystemen (MySQL, Oracle und MSSQL).
Wir haben in Kassel schon im letzten Jahr geholfen, und möchten uns hier noch ein mal für die gute Zusammenarbeit bedanken.

RT-Hosting für das Europäische Patentamt

Vor einiger Zeit hatten wir das Europäische Patentamt schon einmal mit Consulting zum Request Tracker vor Ort in Wien unterstützt. Das Tool hat sich für die interne und externe Kommunikation bewährt, jedoch wurde mittlerweile entschieden, dass es sinnvoller ist den Betrieb auszulagern um sich nicht um dessen Details kümmern zu müssen.
Das Setup wird in unserem Rechenzentrum auf einer virtuellen Maschine betrieben und der Speicherplatz wird auf einem NetApp SAN zur Verfügung gestellt. Durch diesen Aufbau können bei Bedarf die Ressourcen flexibel erweitert werden.
Durch die eingesetzte SSL Verschlüsselung ist auch der Zugriff von externen Quellen sicher. Wir freuen uns über das gewährte Vertrauen und eine weiterhin gute Zusammenarbeit.