Wie man einen eigenen Collabora Server für Nextcloud in Docker und hinter einem Nginx Reverse Proxy korrekt startet

Um innerhalb von Nextcloud so eine Art Google-Docs betreiben zu können, benötigt man zum einen die Nextcloud-Office-App, aber auch einen extra Server (Collabora), der quasi als Backend für das Office dient. Letztendlich handelt es sich da um eine Headless Open-Office Instanz, wenn ich das richtig verstanden habe.

Im besten Fall betreibt man Nextcloud ohnehin auf dem eigenen Server innerhalb von Docker, dann sollte die Kommunikation mit dem Collabora Server kein Problem sein.

Da in meinem Beispiel die Nextcloud Instanz von Hetzner gehosted wird, war es notwendig, dass der Collabora Server über das Internet kontaktiert wird und eben nicht im gleichen Netzwerk hängt. Und da ist die Dokumentation etwas schwammig bzw. einfach falsch. Denn in der Dokumentation, die man so im Netz finden kann, wird gesagt, dass man eine Environment-Variable namens “domain” definieren muss, die dann ein Regex der Nextcloud Domain enthält (damit nur Requests von dieser Domain bearbeitet werden).

Der entsprechende Code wurde aber geändert, sodass mehrere Nextcloud Server auf Collabora zugreifen können. Statt “domain” muss die Environmentvariable “aliasgroup1” heißen und sie enthält die komplette Domain inkl Portangabe (Durch Komma getrennt kann man mehrere URLs übergeben).

Beispiel:

aliasgroup1=https://meine.domain.com:443

In meinem konkreten Beispiel habe ich die Konfiguration, dass auf dem Server für Colabora Docker mit dem allseits bekannten Lets Encrypt Nginx Companion läuft. Das nette an diesem Setup ist, dass man allen weiteren Docker Containern auf diesem Server nur drei Env-Variablen mitgeben muss und schon erstellt und verwaltet das System automatisiert die Lets Encrypt Zertifikate.

In dieser Kombination ist es wichtig, Collabora mitzuteilen, dass es sich nicht um SSL kümmern soll, was man mit der Env-Variable

extra_params=--o:ssl.enable=false --o:ssl.termination=true

erreicht. Ausserdem muss der Collabora Container im privileged Modus laufen!

Mein Setup in Ansible sieht dann letztenlich so aus:

- docker_container:
    name: collabora
    image: collabora/code
    state: started
    detach: yes
    restart_policy: always
    privileged: yes
    expose:
      - 9980
    env:
      aliasgroup1: https://nextcloud.domain.com:443
      VIRTUAL_HOST: office.domain.com
      LETSENCRYPT_HOST: office.domain.com
      VIRTUAL_PORT: "9980"
      LETSENCRYPT_EMAIL: ich@meins.de
      extra_params: "--o:ssl.enable=false --o:ssl.termination=true"

Das Equivalent auf der Console sollte dann so aussehen:

docker run --name=collabora --env=aliasgroup1=https://nextcloud.domain.com:443 --env=VIRTUAL_HOST=office.domain.com --env=LETSENCRYPT_HOST=office.domain.com --env=VIRTUAL_PORT=9980 --env=LETSENCRYPT_EMAIL=ich@meins.de --env='extra_params=--o:ssl.enable=false --o:ssl.termination=true' --privileged --expose=9980 --restart=always --detach=true collabora

Wenn das erledigt ist und der Server läuft, kann man in Nextcloud den Admin Bereich öffnen und dort auf den Punkt “Office” gehen. Hier stellt man den Collabora Server ein und klickt auf Speichern:

Anschließend geht man in Nextcloud auf den “Dateien” Tab und klickt dann oben auf das Plus, um eine neue Datei zu erzeugen:

Anschließend öffnet man das Dokument und sollte nun die Office Oberfläche sehen. Falls eine Fehlermeldung kommt, und man es “später nochmal versuchen soll”, geht auf den Server wo Collabora läuft und schaut in die Logs des Containers.

Wenn ihr da irgendwas von

Terminating connection. Error: No acceptable WOPI hosts found matching the target host [nextcloud.domain.com] in config.

seht, dann habt ihr die Domain in der Environment Variable nicht korrekt übergeben. Überprüft vor allem, ob es sich überhaupt um die gleiche Domain wie in der Fehlermeldung handelt. Diese ist in jedem Fall die korrekte Domain und sollte so auch in der “aliasgroup1” drin stehen!

Confluence HSQLDB auf mysql migieren

Folgende Problematik: ihr habt Confluence testweise auf einem Server installiert und nutzt für die Evaluation erstmal die hsqldb – also die integrierte in-Memory Datenbank, die NICHT für den produktiven Einsatz gedacht ist, da sie im Falle eines Absturzes zu Datenverlust führt. Die gestützter sehen das jedoch anders und nutzen das System umgehend produktiv und nun müsst ihr schnell auf eine richtige Datenbank wie MySQL, Oracle usw. umsteigen. Und genau für diesen Punkt ist dieses kleine Tutorial gedacht:

Im Confluence Admin in den Bereich Administration und dort “Sichern und Wiederherstellen” wechseln. “In Sicherungsordner archivieren” sowie “Anhänge sichern” aktivieren und auf sichern klicken.

Das nun erstellte Backup befindet sich (standardmäßig) unter

/var/atlassian/application-data/confluence/backups

Ladet die Datei xmlexport-xxxxxxxx-xxxx.zip herunter – die richtige Datei erkennt ihr am jeweiligen Timestamp.

Anschließen Confluence herunterfahren und die Datei

/var/atlassian/application-data/confluence/confluence.cfg.xml

löschen (auch hier ist der Pfad wieder standardmäßig und kann bei euch evtl. abweichen).

Unter

https://confluence.atlassian.com/display/DOC/Database+JDBC+Drivers

den entsprechenden Treiber für eure zu verwendende DB herunterladen (ist für MySQL und Oracle notwendig), entpacken und die jeweilige .jar Datei in den Pfad (standardmäßig)

/opt/atlassian/confluence/confluence/WEB-INF/lib/

legen.

Mysql my.cnf (/etc/mysql) einstellen:

[mysqld]
character-set-server=utf8
collation-server=utf8_bin
default-storage-engine=INNODB
max_allowed_packet=32M

Mysql neu starten.

Datenbank einrichten:
CREATE DATABASE confluence;
GRANT ALL PRIVILEGES ON confluence.* TO ‘confluenceuser’@’localhost’ IDENTIFIED BY ‘confluencepass’;
FLUSH PRIVILEGES;

Nun müsst ihr Confluence wieder starten und im Browser unter der ursprünglichen URL aufrufen – der Setup Wizard beginnt erneut. Sprache einstellen und dann “Kundenspezifische” Installation wählen. Dort die externe Datenbank Mysql auswählen und auf der nächsten Seite die Zugangsdaten zur Datenbank eintragen:

URL: jdbc:mysql://[db-host]/[db-name]?sessionVariables=storage_engine%3DInnoDB
Benutzer: [db-username]
Kennwort: [passwort]

Anschließend wird die Datenbank erzeugt.

Im nächsten Schritt ganz unten “Wiederherstellen aus Backup” wählen und im folgenden Upload Dialog die vorhin gesicherte

xmlexport-xxxxxxxx-xxxx.zip

wählen. Nun wird die ursprüngliche Datenbank wieder hergestellt und ihr könnt confluence wieder wie gewohnt nutzen.

[Quicktip] Sonos mit Soundcloud Unterstützung

Leider gibt es von Sonos bisher noch keinen Support für eine der größten Audio Plattformen im Netz: Soundcloud.com. Zufällig bin ich heute über folgenden Artikel gestolpert, der schön einfach erklärt, wie man – derzeit noch inoffiziell – Soundcloud auf seinem Sonos Audio System zum Laufen bekommt.

unofficial SoundCloud Sonos application

Großartig!

via c-jay.net

Ein schönerer Desktop

Und hier mal wieder ein Artikel von meinem ehemaligen Kollegen Alberto, dieses mal zum Thema Desktop Verschönerung auf dem Mac…

Die meisten Mac Desktops sehen eher langweilig aus und weichen kaum vom Standard ab. Wer nicht ganz im Einheitsgrau versinken will, hat immerhin ein spannendes Hintergrundbild. Eine Vielfalt wie gemodete Desktops unter Windows vermisst man jedoch auf den meisten Macs. Dabei gibt es mit dem GeekTool im AppStore durchaus ein mächtiges, zudem kostenloses Werkzeug, um den eigenen Hintergrund zum Leben zu erwecken. Am Beispiel meines eigenen Desktops möchte ich euch demonstrieren, was möglich ist – mit ein paar Zeilen Bash und dem GeekTool.

Der richtige Hintergrund

Alles steht und fällt mit dem richtigem Hintergrundbild, dieses bildet die Basis für unseren lebendigen Desktop. Ich habe mich hierbei für Vaporware 2.0 von http://browse.deviantart.com/?q=aurahack#/d1kj7zb entschieden, da ich ein großer Fan der 8Bit Kunst und ebenso Musikliebhaber bin. Kleiner Bonus: das Bild gibt es auch in einer hohen Auflösung und eignet sich damit Perfekt für mein Retinadisplay.

Typhographie

Die Magie dieses Desktops ist vor allem den Ausgaben der verschiedenen Shellscripte geschuldet. So ist eine entsprechend passende Schrift unerlässlich, wenn man sich die Wirkung nicht durch eine 08/15 Standardschrift zerstören will. Aufgrund des 8Bit Themas des Hintergrundbildes sollte die Schrift auch ein wenig pixelig, eben 8Bit Style sein. Fündig geworden bin ich hier mit dem 8Bit Wonder, welches für alle Ausgaben verwendet wird. Die Farbwahl für die Ausgaben fiehl dabei auf weiß, da dies beim gewählten Hintergrund den besten Kontrast ergibt.

Die Magie

Bis hierher haben wir nur ein gut aussehendes Hintergrundbild – aber das haben viele. Wir wollen mehr. Wir wollen den ultimativen Hintergrund. Um das zu ermöglichen, brauchen wir ein paar Scripte, die wir mittels GeekTool ausführen und richtig auf dem Desktop platzieren.

CPU- und Arbeitsspeicherverbrauch

Beginnen wir in der rechten, oberen Ecke. Wäre es nicht toll, hier den aktuellen Arbeitsspeicherverbrauch und die genutzte CPU im Blick behalten zu können? Hierfür müssen wir einfach ein Shell geeklet aus dem gestarteten GeekTool auf die richtige Stelle auf dem Desktop ziehen und in den Einstellungen das Command Feld mit dem unten stehenden Script befüllen. Dieses liest die CPU Load mithilfe von top aus und formatiert diese als Balkendiagramm mit entsprechender Prozentanzeige. Selbiges wird für den Arbeitsspeicher durchgeführt, nur, dass sowohl Werte für den genutzten und ungenutzten Speicher ausgelesen werden. Damit wir immer aktuell bleiben, sollte die refresh time auf 0.1 Sekunden gesetzt werden. (Anm. Bytelude: bei solch kurzen Refresh-Zyklen immer die CPU und den Akkuverbrauch im Auge behalten – im Zweifel lieber längere Refresh-Raten verwenden)

myCPU=`top -l 1 | awk '/CPU usage/ {print $3}' | sed s/%//`
myCPU=`echo "tmp=$myCPU; tmp /= 1; tmp" | bc`
typeset -i b=9
echo "CPU Usage      \c"
while [ $b -lt $myCPU ]
do
    echo "33[1;37m▇33[0m\c"
    b=`expr $b + 10`
done
#echo "33[1;39m█33[0m\c"
while [ $b -lt 99 ]
do
    echo "33[2;30m▇33[0m\c"
    b=`expr $b + 10`
done
echo "  $myCPU%\c"
echo "\r"
unset myCPU
unset b
myUsedMem=`top -l 1 | awk '/PhysMem/ {print $8}' | sed s/M// `
myFreeMem=`top -l 1 | awk '/PhysMem/ {print $10}' | sed s/M// `
myActiveMem=`top -l 1 | awk '/PhysMem/ {print $4}' | sed s/M// `
myTotalMem=` expr $myUsedMem + $myFreeMem`
myUsedPer=`echo |awk '{print f / t * 100}' f=$myActiveMem t=$myTotalMem`
myUsedPer=`echo "tmp=$myUsedPer; tmp /= 1; tmp" | bc`
typeset -i c=9
echo "Memory Usage   \c"
while [ $c -lt $myUsedPer ]
do
        echo "33[1;37m▇33[0m\c"
        c=`expr $c + 10`
done
#echo "33[1;39m█33[0m\c"
while [ $c -lt 99 ]
do
        echo "33[2;30m▇33[0m\c"
        c=`expr $c + 10`
done
echo "  $myUsedPer%\c"
echo "\r"
unset myUsedMem
unset myFreeMem
unset myTotalMem
unset myUsedPer
unset c
unset count
unset i
unset currname
unset currp
unset a

Dienste im Blick behalten

Als Webentwickler kann man nicht ohne seinen Apache und seine MySQL Datenbank entwickeln. Warum also nicht den Status dieser beiden Dienste im Blick behalten und sofort sehen, ob diese laufen oder gerade offline sind? Selbstverständlich kann hiermit auch jeder andere Dienst im Auge behalten werden, solange dessen Prozessname bekannt ist. Hierfür wird, wie im vorherigen Beispiel, ebenfalls ein Shell geeklet benötigt, welches unten stehendes Script als Command mit bekommt. Dieses durchsucht den Prozessbaum, angezeigt durch ps, nach dem gewünschten Prozess. Wenn dieser gefunden wird, so wird in grün running ausgegeben, ansonsten in rot gestaltet ein offline. Gekapselt ist das ganze in eine Bashfunktion, welche mit echo ausgegeben wird. Auch hierbei sollte die refresh time des geeklets nicht außer acht gelassen werden, jedoch reichen hier auch größere Sekundenwerte.

 typeset -i show=0 function service() { echo $1 | tr '[:lower:]' '[:upper:]' if ["$(ps -Ac | grep $1)" != "" ] then echo "33[1;32m running 33[0m else echo "33[1;31m offline 33[0m fi }
echo $(service httpd) echo $(service mysqld) 

Wer bin ich?

Manchmal gibt es diesen Moment, da fragt man sich: wer bin ich, woher komm ich, wohin gehe ich. Als ITler folgt darauf meist die Frage nach der eigenen IP als zentraler Lebenspunkt – also warum diese nicht ebenfalls immer in Sicht haben? Auch dafür können wir wieder ein Shell geeklet nutzen, welches per curl die eigene externe IP beim DNS-Provider dyndns.org erfragt und aus der Rückgabe per sed alle Zeichen außer Zahlen und Punkten entfernt, da um die eigentliche IP herum etliche HTML-Tags liegen. Das fertige Script sollte danach wie folgt aussehen:

echo External IP: `curl -s http://checkip.dyndns.org/ | sed 's/[a-zA-Z/ :]//g'`

Hier spielt die Musik!

Da die letzten paar Scripts alle technischer Natur waren und wohl nicht für jeden Nutzer das richtige bieten, sollen nun auch ein paar Informationen angezeigt werden, die nicht nur technikaffinen Menschen etwas bringen. Und da (fast) jeder Musik mag: warum nicht einfach den aktuellen Titel mit Interpreten und zugehörigem Album anzeigen, sofern iTunes gerade läuft? Passt ja auch ganz gut zum gewählten Hintergrund. Glücklicherweise hat iTunes seit einiger Zeit eine Script Schnittstelle, welche per AppleScript abgefragt werden kann und entsprechende Informationen bereit stellt. Da GeekTool aber AppleScripts nicht direkt ausführen kann, lohnt es sich einen Blick auf das Kommando osascript zu werfen, welches nichts anderes tut, als ein übergebenes AppleScript auszuführen und die Rückgabe auszugeben. Mithilfe des Parameters -e kann hier auch eine Zeichenkette als Script übergeben werden und es muss kein zusätzliches Script auf einer nie wieder auffindbaren Stelle im System hinterlassen werden. Unten stehendes Script tut dann nichts weiter als sich alle Prozesse mit ihrem Namen vom System zu holen, diese nach iTunes zu durchsuchen und im Fehlerfall, wenn iTunes also nicht läuft, die Ausgabe auf Stopped zu setzten. Wenn iTunes jedoch gerade läuft holt das Script sich Titel, Album und Interpret des gespielten Lieds und schreibt diese auf den Outputstream. Ein kleiner Trick hierbei sind die new_line Tags, welche als Trennzeichen genutzt werden, um die drei Attribute später untereinander ausgeben zu können. Die Ausgabe geschieht dabei mit einem echo, welches nach awk gepipet wird. Awk kümmert sich darum, dass anhand des new_line Tags die Ausgabe zerlegt und nur der gerade relevante Teil ausgegeben wird. Das fertige Script sieht dann wie folgt aus und kann direkt in einem Shell geeklet laufen gelassen werden:

DATA=$(osascript -e 'tell application "System Events"
    set myList to (name of every process)
end tell
if myList contains "iTunes" then
    tell application "iTunes"
        if player state is stopped then
            set output to "Stopped"
        else
            set trackname to name of current track
            set artistname to artist of current track
            set albumname to album of current track
            set output to trackname & "new_line" & artistname & "new_line" & albumname
        end if
    end tell
else
    set output to "Enjoy the silence"
end if')
echo $DATA | awk -F new_line '{print $1}'
echo $DATA | awk -F new_line '{print $2}'
echo $DATA | awk -F new_line '{print $3}'

Mehr Text

Viel Musik lebt von ihren Lyrics, also zeigen wir diese auch gleich noch mit an. Zumal auf dem Hintergrundbild noch einiges an Platz frei ist, der sonst so leer wirkt. Das folgende Script ist im Grunde genommen nicht viel anders als das vorherige, jedoch wird diesmal nur per AppleScript der Liedtext zum aktuellen Song abgefragt. Sollte iTunes nicht laufen, so wird hier nur ein leerer String zurück gegeben. In der Ausgabe werden alle Vorkommen von “\r” durch “\n” ersetzt, damit diese Umbrüche korrekt umgesetzt werden.

echo "\n\n"
osascript -e 'tell application "iTunes" to lyrics of current track' | tr '\r' '\n'

Zeit ist Geld

Als nächstes sollten wir einen Blick auf den Gameboy in der rechten, unteren Ecke werfen, welcher bisher nichts anzeigt. Das soll sich ändern. Um auch mal ein einfaches Script zu nutzen soll hier nur mit Hilfe des date Kommandos das aktuelle Datum, sowie die Uhrzeit angezeigt werden. Hierzu gibt es nicht viel zu sagen, dem date Kommando wird als Argument mitgegeben, wie das Datum, respektive die Zeit aussehen soll, weitere Optionen hierzu sind in der entsprechenden Manpage nach zu lesen.

date +%d.%m.%y
date +%H:%M

Alle Farben sind schön

Um auch mal eine aufwändigere Kombination von mehreren geeklets zu zeigen und ein wenig Farbe ins Spiel zu bringen, soll unser aktueller Speicherverbrauch in einem Tortendiagramm visualisiert werden, welches die Kopfhörer des Hintergrundbildes überlagert. Dafür brauchen wir zwei geeklets: ein Shell geeklet zum Sammeln der Daten und Generieren der Grafik sowie ein Bild geeklet zum Anzeigen der generierten Grafik. Das Sammeln der Daten geschiet im Grunde genommen durch das Auslesen der Prozessliste mit ps und umformartieren dieser Informationen per cut, sed, awk und anderen UNIX Tools. Hier in die Tiefe zu gehen würde nur unnötig ausarten. Die gesammelten Daten werden danach mit Hilfe der Google Chart API zu einer ansehnlichen Grafik aufbereitet, welche per curl im temporären Ordner abgelegt wird.

SIZE="450x650"
TYPE="pc"
COLOR="E5707070|C5606050|C5A5A050|AAAAFF50|AAAAFF30,E5AB77|F5CB97"
BG="bg,s,00000000"
ps Amo pmem,comm | grep -v % | sed 's/\/.*\///; s/^ //; s/,/\./' > /tmp/memusage.log
grep -v "0\." /tmp/memusage.log > /tmp/memusage2.log
(grep "0\." /tmp/memusage.log | cut -d\  -f1 | paste -sd+ - | bc; echo others) | xargs >> /tmp/memusage2.log
data=`cut -d\  -f1 /tmp/memusage2.log | paste -sd, -`
unused=`echo $data -100 | sed 's/,/\+/g' | bc`
legend=`cut -d\  -f2,3,4,5 /tmp/memusage2.log | sed 's/ /%20/g' | paste -sd\| -`
sum=`vm_stat | head -6 | tail -5 | awk 'BEGIN{sum = 0;} {sub(/\.*$/,""); sum+=$NF} END{print sum}'`
vm_stat | head -6 | tail -5 | awk -F: '//{print $1, 100*$2/'$sum'}' | sed 's/down //; s/,/\./' | cut -d\  -f2,3 > /tmp/memusage3.log
pfree=`grep free /tmp/memusage3.log | cut -d\  -f2`
pinactive=`grep inactive /tmp/memusage3.log | cut -d\  -f2`
pactive=`grep "^active" /tmp/memusage3.log | cut -d\  -f2`
pspeculative=`grep speculative /tmp/memusage3.log | cut -d\  -f2`
pwired=`grep wired /tmp/memusage3.log | cut -d\  -f2`
pmem="$pwired,$pactive,$pinactive,$pspeculative,$pfree"
plab="wired|active|inactive|cache|free"
rm /tmp/memusage.log
rm /tmp/memusage2.log
rm /tmp/memusage3.log
link="http://chart.apis.google.com/chart?cht=$TYPE&chs=$SIZE&chd=t:$pmem|$data,$unused&chco=$COLOR&chf=$BG&chl=$plab|$legend|"
echo $link

So viel zum schwierigen Teil, denn sobald das Bild generiert wurde, muss es nur noch mit Hilfe eines Bild-geeklets angezeigt werden. Mit 230 Pixeln Höhe und Länge ist das geeklet optimal dimensioniert und überdeckt genau die Kopfhörer. Als weitere Eigenschaften müssen neben der schon bekannten refresh time, denn dieses Bild soll alle paar Sekunden neu generiert werden, auch die Bildurl angegeben werden. Hierbei kann per file:///tmp/memusage.png auf das eben generierte Bild zruück gegriffen werden. Um die Infos aktuell zu halten, sollten beide geeklets eine kurze refresh time bekommen.

Wenn auch diese beiden geeklets funktionieren, ist die Arbeit erstmal getan. Jedoch gibt es noch viel zu entdecken und mit Hilfe des MacOSX Unix Unterbaus gibt es noch viele weitere Möglichkeiten, verschiedenste Informationen abzurufen und diese auf dem Desktop darzustellen. Hier kann sich ruhig ausgetobt werden, um die perfekte Balance zwischen nützlicher Datenvisualisierung und optisch ansprechendem Desktop zu finden.

Eine kleine Einführung in die Technik des Pair Programming

Meinem Arbeitgeber ist Fortbildung und Wissenserweiterung/-auffrischung sehr wichtig. Und deshalb gab es vor einigen Wochen einen Workshop zum Thema Pair Programming, einer Teilmenge von XP, also dem Extreme Programming.

Die Thematik Pair Programming war mir schon länger geläufig, allerdings hatte ich zum Teil völlig falsche Vorstellungen davon und mir waren die Konzepte dahinter völlig fremd. Pair Programming ist eben nicht nur der Zustand, dass ein Programmierer am Rechner sitzt und ein zweiter ihm ständig über die Schulter schaut und kommentiert. Es geht viel mehr darum, dass der Code wirklich gemeinschaftlich entsteht und vor allem nicht ein Entwickler arbeitet und der Partner sich langweilt.

Grundlagen

Die Idee des Pair Programmings basiert auf dem Driver-Navigator Prinzip, welches man aus dem Rally Sport kennt. Der Fahrer ist vom Beifahrer abhängig, der Beifahrer wiederrum vom Fahrer. Und: dadurch, dass beide zusammen arbeiten, sind sie effizienter. Der Fahrer kann sich voll und ganz auf die aktuelle Situation einstellen und seine komplette Energie in die optimalste, derzeit angebrachte Fahrweise stecken. Der Beifahrer hingegen hat den Überblick über das große Ganze. Er kennt die ganze Strecke in- und auswendig. Da er sich nicht primär um die aktuelle Situation kümmern muss, kann er ruhig Ansagen für kommende Ereignisse machen.

Das gleiche Prinzip kommt im Pair Programming zum Einsatz: der Programmierer an Tastatur und Maus ist der Driver, der Programmierer neben ihm der Navigator. Der “Driver” kümmert sich um die aktuelle Problematik, der “Navigator” behält die Überblick über die komplette oder aber zumindest die übergeordnete Problematik. Außerdem führt er nicht den gleichen Gedankengang wie der Driver aus, was ihm ermöglicht, evtl. Fehler eher zu erkennen oder auf kommende Fehler hinzuweisen.

Die 7 Säulen des Pair Programmings

Man kann die Grundsätze des Pair Programmings auf 7 Säulen aufteilen. Die Säulen verdeutlichen, welche Vorteile Pair Programming gegenüber anderen Konzepten hat:

pair pressure – sich gegenseitig fokussieren und andere wegschicken bzw. Ablenkungen aus der Welt schaffen.

pair negotiation – das gegenseitige Sparring bzw. die gegenseitige Verbesserung durch ständiges direktes Feedback.

pair courage – den Mut, Dinge und vor allem Code zu ändern. Stichwort Refactoring.

pair review – Das ständige Reviewen des Codes.

pair debugging – Vier Augen sehen mehr als zwei – vor allem beim Debugging!

pair learning – das voneinander Lernen und der somit entstehende Wissenstransfer.

pair trust – das Vertrauen zum partner und auch in seine Methoden.

Wissensstufen

Ein wichtiger Aspekt des Pairings ist die Zusammenstellung des Paares. Diese ist abhängig von den verfügbaren Programmierern (und ihren Charaktereigenschaften), aber auch von der zu lösenden Aufgabe. Man kann den Erfahrungsgrad hierzu in 3 Gruppen, die sich aus dem Japanischen Kampfsport ableiten, unterteilen:

Shu, Ha und Ri

Wenn man die 3 Worte bzw. Silben von vorn nach hinten liest, hat man schon die Klassifizierung. Wichtig hierbei ist: JEDER Programmierer wechselt im Laufe seiner Karriere zwischen diesen Gruppen immer wieder hin und her.

Die “Shu” sind Einsteiger bzw. Juniors. Hierbei geht es nicht unbedingt nur um die allgemeinen Programmierskills – auch wenn ein “Ha” oder “Ri” eine komplett neue Sprache oder ein neues Framework kennen lernt, dann ist er zunächst wieder ein “Shu”.

Die nächste Stufe, “Ha” genannt, umschreibt den Zustand, dass man sich mittlerweile schon gut zurecht findet, die neue Sprache oder das Framework oder was auch immer bereits sehr gut beherrscht und die ersten Regeln in Frage stellt. In diesem Stadium baut man stark an Wissen auf.

Wenn man die Stufe “Ri” erreicht hat – und dafür braucht man mindestens ca. 10.000 Stunden Arbeit im jeweiligen Themengebiet – dann ist man an der Spitze angekommen. Auf diesem Level gelten so gut wie keine direkten Regeln mehr – denn diese sind bereits in das Unterbewusstsein übergegangen. Für zu bewältigende Aufgaben findet man so gut wie immer die eleganteste Lösung – nicht zwangsweise auf Basis von Patterns – sondern wirklich die optimale Lösung. Daher: Losgelöst von den Regeln, aber indirekt doch basierend auf ihnen.

Paar-Kombinationen

Nachdem nun die Grundlagen soweit verstanden sind, kommt es zur Anwendung. Ein wichtiger Faktor des Pair Programmings ist die Kombination der Partner – basierend auf ihrer Klassifizierung.

In der Regel sollte man darauf achten, dass zwischen den Partnern eine Wissens-Stufe liegt – das hat den Effekt, dass der Entwickler mit dem geringeren Wissensstand besser Wissen aufbauen kann. Für den Partner in der höheren Klasse dient diese Konstellation als weitere Festigung des Wissens.

Sollte man an eine wirklich brenzlige Stelle mit großem Impact für das Projekt oder die Firma kommen, kann man auch auf die Kombination “Ri” – “Ri” setzen. Diese wird aller Wahrscheinlichkeit nach zu einer sinnvollen und schnellen Lösung des Problems führen, jedoch sollte hier beachtet werden, dass Leute dieses Kaliebers nicht zu lange im Paar arbeiten. Gurus arbeiten im Allgemeinen auch eher allein 😉

Sprünge über 2 Klassen, also die Kombination “Shu” – “Ri”, machen nur selten Sinn. Der Unterschied ist sehr enorm und es besteht die Gefahr, dass der “Shu” den “Ha” Level mehr oder weniger überspringen und sich direkt über bestimmte Grenzen hinweg setzen möchte. Für kürzere Zeiträume kann man diese Kombination allerdings für die komprimierte Wissensweitergabe verwenden.

Sind alle 3 Klassen in einem Team vertreten, so kann evtl. auch ein “Shu” – “Shu” Paar Sinn machen. Der Wissenstransfer ist sicher nicht so hoch wie in anderen Konstellationen, allerdings lernt es sich zusammen immerhin leichter als allein und diese Kombination führt dazu, dass man die Nerven der erfahreneren Entwickler schonen kann.

Feedbackschleifen

Ein wichtiges Element in der Entwicklung sind sogn. Feedbackschleifen – also die Zeit, in der ein Entwickler mehr oder weniger das tut, was er für richtig hält, ohne dass es der Kunde oder jemand anderer sieht und beurteilt. Bleibt man im Feld der agilen Entwicklung, dann gibt es dort 2 Feedbackschleifen: Den Sprint (7-14 Tage) und das Daily Standup (1 Tag). Je kleiner die Feedbackschleife wird, desto weniger Fehlentwicklungen können auftreten, da schnell interveniert werden kann.

Wenn man nun ins Pair Programming einsteigt, dann kommt eine weitere Feedbackschleife hinzu, die jedoch im Minutenbereich liegt. Egal, was man gerade codet – der Partner sieht es und kann und wird es umgehend beurteilen sowie kommentieren. Diese extrem verkürzte Feedbackschleife vermindert sehr stark Fehlentwicklungen, zumindest auf Codeebene. Auch werden so sehr schnell Verständnisprobleme der Aufgabenstellung sichtbar.

Zusammenfassend kann man sagen: je mehr Feedback man bekommt, desto besser kann man sich entwickeln – je länger der Zeitraum bis zum nächsten Feedback ist, desto länger kann man auf dem falschen Weg unterwegs sein.

Vorgehensweise

Kommen wir abschließend zum eigentlichen Vorgehen – denn darum liest du diesen Artikel ja 😉

Um jegliche Ablenkung zu minimieren, setzen sich beide Entwickler an EINEN Rechner. Um die Zusammenarbeit zu optimieren, sollte man das System mit 2 Monitoren betreiben, die beide das gleiche anzeigen. So hat jeder Entwickler den bestmöglichen Blick auf das Geschehen. Wichtig hierbei ist: es gibt nur eine Maus und eine Tastatur, die zu einem Zeitpunkt bedient wird! Für einen einfacheren Wechsel zwischen den Rollen des Drivers und des Navigators kann man gern eine zweite Maus und eine zweite Tastatur anschließen.

Für unser Beispiel haben wir den Driver “Tom” und den Navigator “Paul”.

Der Driver Tom beginnt nun damit, einen Unit Test zu schreiben, der natürlich gleich brechen wird. Nun übernimmt Paul (er wird zum Driver) und schreibt die zu bearbeitende Funktion oder Klasse so, dass der Test nicht mehr bricht. Dies geschieht auf einem extrem simplen Niveau! Beispiel:

Test:

function testMethod() {
	assertTrue(method());
}

Der ausgeführte Test wird brechen, weil es die aufzurufende Methode noch gar nicht gibt – und wenn es sie doch geben sollte, dann ist sie leer und liefert keinen Rückgabewert.

Hier nun die zugehörige Funktion, die Paul darauf hin geschrieben hat:

function method() {
	return true;
}

Der Test läuft nun erfolgreich durch. In der nächsten Iteration wechseln beide wieder und Tom muss nun den Test so umbauen, dass er dem gewünschten Ergebnis wieder näher kommt. Er baut den Test so lange um, bis er wieder bricht. Dann wird wieder gewechselt und Paul muss dafür sorgen, dass seine “method” das vom Test gewünschte Ergebnis liefert.

Diese Vorgehensweise wird auch Test Driven Development genannt. Man macht sich erst Gedanken über den Test, der beweisen soll, dass die Funktion so läuft wie erwartet. Und erst anschließend wird die eigentliche Funktionalität implementiert.

Im Bezug auf das Pair Programming nennt man diese Vorgehensweise “ping pong pair programming”. Der Vorteil dieser Methode ist, dass man sich langsam an das Ziel herantastet. Jeder Entwickler kennt den Zustand, in dem man eine Implementierung gleich im ersten Zug baut, sich völlig verzettelt und von vorn beginnen muss. Genau diese Entwicklung soll an dieser Stelle verhindert werden. Man beschäftigt sich eben nicht mit dem großen ganzen, sondern tastet sich über kleine Iterationen immer näher an eine bessere Implementierung. Durch immer wieder einsetzendes Refactoring wird der Code somit immer weiter verbessert und optimiert.

Fazit
Ich möchte den Artikel an dieser Stelle erstmal beenden, weil im Prinzip auch schon alles gesagt ist. Die Hauptaufgabe, nach erlernen der Grundlagen, liegt nämlich in der Übung. Hierbei sollte man darauf achten, dass man den Partner ab und zu mal wechselt, um konstant neue Einflüsse auf die eigenen Skills zuzulassen.

Eine Problematik bleibt allerdings noch offen: wie verkaufe ich das meinen Kunden? Dabei handelt es sich in der Tat um einen der schwierigsten Aspekte. Man darf beim Pair Programming keinesfalls davon ausgehen, dass zwei Entwickler an einer Aufgabe auch doppelt so schnell entwickeln – wobei man diese Denkweise in der Programmierung allgemein unterbinden sollte, denn: 9 Frauen bringen ja auch nicht ein Baby in nur einem Monat zur Welt 🙂

Was man dem Kunden allerdings verkaufen kann, ist die effektivere Problemlösung und die bessere Verteilung von Wissen. Dies ist besonders interessant, wenn man mit Entwicklern des Kunden zusammen arbeitet. Ein weiteres, sehr wichtiges Argument, ist die bessere Code Qualität und geringere Bug-Anfälligkeit. Durch das ständige Code-Review können Flüchtigkeitsfehler stark vermindert werden, was für weniger Frust auf Seiten des Kunden als auch der Entwickler sorgt.

Abschließend sei gesagt: Probiert es aus! Pair Programming bringt euch als Entwickler deutlich weiter und es macht auch noch extrem Spaß.

Mac USB Festplatte mit Filevault 2 (OSX Lion) nachträglich verschlüsseln

Seit Samstag habe ich auf meinem Arbeits-Macbook die Komplettverschlüsselung mittels Filevault 2 aktiviert. Wenn das Gerät mal abhanden kommen sollte, ist es so für den Finder wertlos – es sei denn, er baut die Festplatte aus. ABER: Diebe und anderes Gesindel kommen nicht an die sensitiven Daten ran. Das ganze Prozedere ist idiotensicher in den Systemeinstellungen im Punkt “Sicherheit” hinterlegt und schnell erledigt. Zumindest, wenn man eine SSD hat. OSX Lion schiebt die Umwandlung des Laufwerks aber bequem in den Hintergrund und man kann nach einem kurzen Neustart wie gewohnt weiter arbeiten.

Jetzt kommt das “aber”: wie oben erwähnt, habe ich eine SSD verbaut. Und wie ich bereits genug gejammert habe, ist die natürlich für meine Bedürfnisse zu klein, weshalb die ursprünglich verbaute 500Gb Platte als USB Laufwerk zum Einsatz kommt. So. Nun ist meine Systemplatte verschlüsselt und gesichert, aber die Platte mit den eigentlichen Daten ist für jeden verfügbar. Und blöderweise auch einfacher zu klauen. Also habe ich mich mal umgesehen, wie ich diese auch verschlüsseln kann.

Die Optionen sind:

  • einen Verschlüsselten Filevault Container mit dem Festplattendienstprogramm erstellen
  • Truecrypt Container
  • Komplettverschlüsselung der Partition mit Truecrypt
  • Verschlüsselung mit Filevault

Der verschlüsselte Filevault Container wäre sicher die einfachste Möglichkeit, jedoch ist er auch etwas umständlich. Er hat eine fixe Größe und muss auch immer extra gemounted werden – das gleiche gilt für den Truecrypt Container und die Truecrypt Partition. Bleibt noch die Verschlüsselung mit Filevault 2 – mit einem kleinen Haken: man muss die Platte dafür neu formatieren. Zumindest ist das der offizielle Weg. Das Internet hat mir aber noch einen anderen Weg gezeigt:

  • Terminal öffnen
  • diskutil cs convert /Volumes/[Name des Laufwerks] -passphrase
  • Nun werdet ihr nach einem Passwort für die Festplatte gefragt, welches ihr dann nochmals bestätigen müsst
  • anschließend wird die Partitionstabelle leicht modifiziert und dann beginnt die Umwandlung im Hintergrund
  • mittels folgendem Befehlt könnt ihr euch den Fortschritt ansehen (“Size (Converted)”):
  • diskutil cs list

Wenn ihr die Platte nun das nächste Mal wieder an den Rechner steckt, werdet ihr nach dem eingegebenen Passwort gefragt, anschließend ist die Platte dann normal verfügbar. Auch in Kombination mit Timemachine gibt es keine Probleme, da die Verschlüsselung transparent abläuft.

Solltet ihr die Verschlüsselung wieder rückgängig machen wollen, ist folgender Befehl nötig:

diskutil cs revert /Volumes/[Name des Laufwerks] -passphrase

Gebt das Verschlüsselungs-Passwort ein und schon wird die Verschlüsselung rückgängig gemacht.

via forums.macworld.com

SSD Trim Support unter Mac OSX Lion aktivieren

Ich konnte bisher nicht viel mit dem “Trim” Befehl für SSDs anfangen – bis ich den Grund für diesen Befehl nun selbst erfahren durfte. Nachdem sich meine SSD langsam aber sicher gefüllt hat, wurden kurzerhand die iPhoto und iTunes Librarys auf eine externe USB Festplatte verlagert. Dumm nur: ich hatte danach genauso viel freien Speicher wie vorher. Und dass, obwohl ich an die 10.000 Bilder entfernt hatte.

Das Problem an SSDs ist nämlich: löscht man eine Datei, dann wird, wie bei normalen magnetischen Festplatten auch, nur die Referenz auf diese Datei gelöscht. Die Nullen und Einsen, aus denen die Datei mal bestanden hat, bleiben erstmal auf der Platte liegen. Erst wenn dieser frei gewordene Platz für andere Dateien benötigt wird, so wird er mit den neuen Daten überschrieben. Funktioniert dies bei magnetischen Speichern problemlos, ist es bei Flash Speicher nicht ganz so leicht. Hier muss nämlich der zu schreibende Datenbereich wirklich gelöscht werden.

Normalerweise sollte dies der Controller der Festplatte übernehmen – z.B. in Zeiten geringer Belastung, also wenn die Festplatte gerade nichts anderes zu tun hat. In meinem Fall hat er es offensichtlich nicht getan. Und dafür gibt es nun den sogn. Trim Befehl, den das Betriebssystem an die Platte schicken kann und somit veranlasst, dass frei gewordener Speicher auch gelöscht wird.

Gütigerweise hat Apple den Support dafür auch unter OSX Lion eingebaut – aber nur für die original von Apple verbauten SSDs. Selbst eingebaute SSDs kommen nicht in den Genuss. Da mein Gerät von Gravis zusammengestellt wurde, ist offensichtlich keine original Hardware verwendet worden. Was nicht schlimm ist, aber eben die von mir beobachtete fehlerhafte Speicherplatzanzeige brachte.

Glücklicherweise kann man dieses Verhalten ändern – indem man Trim für ALLE SSDs freischaltet. Und das geht so:

Bevor ihr loslegt: ich übernehme keinerlei Haftung oder Verantwortung, falls ihr eure Hardware oder euer System beschädigt. Alle Aktionen werden auf eigene Gefahr durchgeführt. Sicherheitshalber sollte man vorher nochmal Timemachine laufen lassen, um ein valides Backup vom kompletten System zu haben!

  • Terminal öffnen
  • Backup des zuständigen Treibers erstellen:
  • sudo cp /System/Library/Extensions/IOAHCIFamily.kext/Contents/PlugIns/IOAHCIBlockStorage.kext/Contents/MacOS/IOAHCIBlockStorage /System/Library/Extensions/IOAHCIFamily.kext/Contents/PlugIns/IOAHCIBlockStorage.kext/Contents/MacOS/IOAHCIBlockStorage.original

  • Treiber patchen:
  • sudo perl -pi -e 's|(\x52\x6F\x74\x61\x74\x69\x6F\x6E\x61\x6C\x00{1,20})[^\x00]{9}(\x00{1,20}\x51)|$1\x00\x00\x00\x00\x00\x00\x00\x00\x00$2|sg' /System/Library/Extensions/IOAHCIFamily.kext/Contents/PlugIns/IOAHCIBlockStorage.kext/Contents/MacOS/IOAHCIBlockStorage

  • Caches löschen:
  • sudo kextcache -system-prelinked-kernel
    sudo kextcache -system-caches

  • Reboot!

Überprüfung: links oben auf den Apfel -> über diesen Mac -> weitere Informationen -> Systembericht -> Serial-ATA anklicken.
Unter “Trim Unterstützung” sollte nun “Ja” stehen.

Will man den Patch wieder rückgängig machen:

  • Patch rückgängig machen:
  • sudo perl -pi -e 's|(\x52\x6F\x74\x61\x74\x69\x6F\x6E\x61\x6C\x00).{9}(\x00\x51)|$1\x41\x50\x50\x4C\x45\x20\x53\x53\x44$2|sg' /System/Library/Extensions/IOAHCIFamily.kext/Contents/PlugIns/IOAHCIBlockStorage.kext/Contents/MacOS/IOAHCIBlockStorage

  • Caches löschen:
  • sudo kextcache -system-prelinked-kernel
    sudo kextcache -system-caches

  • Reboot!

und sollten alle Stricke reißen, dann kann man immer noch das zuvor erstellte Backup wieder einspielen:

sudo cp /System/Library/Extensions/IOAHCIFamily.kext/Contents/PlugIns/IOAHCIBlockStorage.kext/Contents/MacOS/IOAHCIBlockStorage.original /System/Library/Extensions/IOAHCIFamily.kext/Contents/PlugIns/IOAHCIBlockStorage.kext/Contents/MacOS/IOAHCIBlockStorage
reboot

via digitaldj.net

Ein WordPress Blog still legen und archivieren

Der Bytelude ist nun bereits mein dritter Blog. Zuerst war da mein selbst geschriebenes CMS mit integriertem Blog, und anschließend kam eine WordPress Variante. Irgendwann war die Situation etwas fest gefahren und so beschloss ich, nochmal einen dritten Anlauf zu wagen. Dabei herausgekommen ist bytelude.de. Und da ich es selbst nicht leiden kann, dass Google Suchergebnisse ins Leere führen, sind die anderen beiden natürlich weiterhin aktiv. Bei der selbstgeschriebenen Variante ist das nicht weiter tragisch, da ich das CMS trotzdem aktiv pflege und es extrem wenig Ressourcen benötigt. Bei WordPress sieht das schon anders aus. Zum einen muss man es immer auf dem aktuellsten Stand halten und zum anderen frisst es bei jedem Aufruf ziemlich viele Ressourcen. Nach ein paar Google Suchanfragen bin ich dann auf die Idee gekommen, dass man WordPress ja auch einfach in eine statische Seite konvertieren kann.

Gesagt getan, und ich bin auf folgende zwei Tutorials gestoßen:

Convert WP to static html

How to retire a wordpress blog

Die erste Anleitung hat bei mir leider nicht richtig funktioniert, enthält aber den wichtigen Teil der Vorbereitung. Kurz gesagt: man sollte die Seite auf Permalinks umstellen. Das sinnvollste Format ist “/jahr/monat/post-name/”. Die Permalinks sind notwendig, da sonst immer nur Dateien wie “index.php?parameter=value…” abgespeichert werden. Der Aufruf im Browser funktioniert dann natürlich nicht korrekt und man bekommt eine Menge Fehler.

Und hier der Code in Kurzform:
Permalinkstruktur folgendermaßen einstellen:

"/%year%/%monthnum%/%day%/%postname%/"

Anschließend müsst ihr, falls noch nicht vorhanden, die entsprechende .htaccess Datei mit folgendem Inhalt anlegen:

RewriteEngine On
RewriteBase /pfad/zum/wordpress/blog/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /pfad/zum/wordpress/blog/index.php [L]

Und schon kommen wir zum 2. Tutorial. Dort wird dann der entscheidende wget Befehl erklärt. Vorher wird noch darauf hingewiesen, dass man die Trackback und xmlrpc.php links aus dem gewählten Theme entfernen sollte. Andere Blogs versuchen sonst Trackbacks zu senden, da diese ja im HTML Code hinterlegt sind.

Nachdem das erledigt ist, hier nun der finale wget Befehl:

wget -r -E -T 2 -np -R xmlrpc.php,trackback -k http://[BLOG URL]

Führt diesen Code in einem extra Ordner aus. Es wird automatisch ein Ordner mit eurer Blog-URL angelegt, darin ist dann die komplette Seite enthalten.

Wget fängt nun auf eurer Hauptseite an, diese in Form einer index.html abzuspeichern. Evtl. verlinkte CSS Dateien und Javascript Files werden in der gleichen Ordnerstruktur wie auf eurem Server heruntergeladen und abgespeichert. Dieser Vorgang wird nun für alle auf der Seite gefundenen Links wiederholt. Durch die Permalink Struktur werden nun die einzelnen Blog-Beiträge in der Form /Jahr/Monat/Titel/index.html abgespeichert.

Wenn der Vorgang abgeschlossen ist, könnt ihr euren WordPress Ordner löschen und an dessen Stelle den heruntergeladenen Ordner (natürlich ohne den Ordner mit eurem Domainnamen) kopieren. Nun sollte eure Seite weiterhin wie gewohnt geladen werden und alle Links funktionieren auch – außer den dynamischen Funktionen wie Kommentare oder dem Admin-Panel. Ihr werdet auch bemerken, dass die Seite nun deutlich schneller lädt und euer Server deutlich weniger belastet wird. Und man muss sich nicht mehr um Updates kümmern 😉

[Video Tutorial] manuelle Blende im Videomodus der Canon EOS 500d einstellen

Hier kommt nun mein zweites Videotutorial mit dem oben genannten Thema. Ich möchte euch zeigen, wie man mit einfachen Schritten die Automatik der Kamera überlisten kann, um im Videomodus zumindest die Blende manuell einstellen zu können. Da die EOS 500d ein Einsteigermodell ist, hat Canon hier absichtlich die Möglichkeit entfernt, Werte wie Belichtung, ISO oder eben auch die Blende manuell einstellen zu können. Für Hobbyfilmer ist auch dieser Automatikmodus völlig ausreichend, eine professionelle Aufnahme kann man so aber nicht durchführen. Ich hoffe, dass euch das Tutorial weiter hilft – bei mir hat es das getan 😉

Weiterhin freue ich mich natürlich über jede Art von Feedback und vor allem auch über Vorschläge für weitere Video Tutorials.