 Gut, fangen wir an. Herzlich willkommen zu meinem Vortrag. In diesem Vortrag geht es um mainpages.debian.org. Hoffentlich stimmt mir nach dem Vortrag spätestens zu, dass das die sinnvollste Mainpage-Seite ist, die es derzeit so gibt. Ich werde versuchen, euch näher zu bringen, warum ich die Seite gemacht habe. Mein Name ist Michael Stapelberg und ich bin im Debian-Projekt aktiv. Zunächst skizziere ich mal, was euch erwartet. Wie gesagt, ich werde motivieren, warum das Projekt entstanden ist. Ich werde eine Übersicht geben, wie man eigentlich mainpages aus Debian-Paketen extrahiert, wie genau wir die nach HTML wandeln und wie wir sie letztendlich ausliefern. Das sind die drei großen Bestandteile des Vortrags. Dann werde ich auf die Laufzeitumgebung eingehen, in der das Ganze läuft, an den Fazit ziehen und dann haben wir noch Zeit für Fragen und Antworten. Sofern ihr Fragen habt, die für das unmittelbare Verständnis des Vortrages super wichtig sind, könnt ihr euch gerne melden und dann nehme ich euch dran. Ansonsten machen wir es einfach am Ende. Zur Motivation. Mainpages im Browser zur Verfügung zu haben, ist oft einfach bequem. Es gibt viele Szenarien. Angenommen, ihr sitzt irgendwie in der Straßenbahn und unterhaltet euch über irgendwas und wollt schnell mal nachschauen, wie war das eigentlich, kann, wie geht diese eine Option, den neuen Header oder was weiß ich was. Und dann hat man eben nicht gerade einen Terminal zur Hand oder es wäre ziemlich unbequem, einen Terminal zur Hand zu haben. Oder man ist gerade in einem Rescue System, weil der Computer nicht mehr läuft oder der Server nicht mehr läuft und man hat gerade sein Smartphone. Es gibt viele Anwendungsfälle, wo das einfach sehr nützlich ist. Außerdem ist das Text-Rendering besser. Man kann angenehmer zoom und so weiter und so weiter. Ich glaube, ich brauche euch nicht davon überzeugen, dass man das gelinglich machen möchte. Leider ist es so, dass die existierenden Mainpage-Archive generell mehrere Schwächen haben. Zum einen sind sie unvollständig. Häufig war es also so, dass wenn ich nach einer Mainpage geschaut habe, ich die in den verschiedenen Mainpage-Seiten nicht finden konnte. Ich habe später auch noch mal eine Übersichtstabelle, wo ich ein paar Beispiele rausgegriffen habe, stellvertretend für ganze Klassen an Mainpages, die aus den bestehenden Seiten einfach fehlen. Dann sind diese Mainpage-Archive oftmals alt. Also bei manchen ist es so, dass sich jemand hingesetzt hat, irgendwann mal die aktuelle Version von Debian da reingeworfen hat und das seither nie wieder aktualisiert hat. Andere sind besser, aber sagen zum Beispiel in der aller Regel auch nicht, welche Versionen von der Software sie dokumentieren oder woher diese Mainpages eigentlich kommen. Also wer das noch nicht genug ist, ist es auch so, dass einige dieser Seiten vollgestoppt sind mit Werbung, also generell einfach keine gute User-Experience bieten. Und ich dachte mir, das können wir doch eigentlich alles besser. Im Verlauf des Projekts, also nachdem ich gesagt habe, ah, ich muss jetzt meine eigene Software dafür bauen und eine eigene Seite dafür hochziehen, habe ich festgestellt, moment, da gibt es im Debian-Projekt ja schon eine Seite. Das ist eben mainpages.debian.org. Die kannte ich zu dem Zeitpunkt noch nicht. Ich hatte nämlich ausprobiert main.debian.org und das ging eben nicht. Und mainpages.debian.org konnte man auch nicht finden. Die war nämlich zeitweise aus den Suchmaschinenindexes rausgeflogen. Das lag daran, dass die Seite implementiert war über einen CGI-Skript. Einige von euch kennen das sicher, wenn man sich zum Beispiel die FreeBSD-Mainpages anschaut, dann kriegt man quasi einfach, wie wenn man mahen und dann den Begriff eingeben würde im Terminal, kriegt man genau die gleiche Ausgabe ist, einfach so Blogsatz und Text und so was. Und dieses CGI-Skript hat auch einen Caching-Layer und so, also sollte eigentlich ganz gut funktionieren. Aber was passiert ist, ist, dass eine andere Webseite kaputt gegangen ist. Irgendwann ist so eine Gamer-Webseite. Ich weiß nicht genau, was da vorher drauf war. Aber aus irgendwelchen Gründen hatten die Serverprobleme oder was weiß ich. Und irgendwann kamen die wieder und hat einfach die Apache-Standard-Seite ausgeliefert. Soweit so gut sollte man meinen. Allerdings ist es so, dass in der Debian-Apache-Version die Standardseite einen Link enthält auf die Mainpages für die A2N-Seite und A2DIS-Seite-Programme, sodass die verwirrten Besucher von dieser Spiele-Webseite nicht wussten, so was läuft ja, wie komme ich auf meine Seite und klicken einfach alle diese Links an. Und dann hat man tausende Leute, die sich auf einmal diese Mainpages anschauen wollen und die arme Seite war hoffnungslos überlastet. Deswegen mussten wir sie also abschalten und für Crawler sperren, was der andere große Faktor war, der Load auf die Seite gebracht hat. Und deswegen kannte sogar ich die nicht. Mittlerweile funktioniert sie aber wieder und mehr Details gleich. Jetzt schieben wir erst mal eine kurze Demo ein, weil ich kann euch eine Stunde lang von dem Projekt erzählen, aber schöner ist es eigentlich, wenn ihr euch das mal kurz anschauen könnt. Ich habe hier ein paar interessante Seiten rausgegriffen. Die W3M-Seite ist ein ganz guter Einstieg. Wir können aber mal von Anfang an fangen. Also wenn man auf Mainpages-Debian-Ork geht, dann landet man auf dieser Übersichtseite. Da sagt er, man kann hier den Namen von der Mainpage eingeben, wenn man schon weiß, was man sucht. Man kann sich ansonsten aber auch die Einleitungen in die verschiedenen Sections, die es in den Mainpages gibt, anschauen oder das ganze Repository einfach browsing. Das ist hauptsächlich nützlich für Suchmaschinen, wenn man mal ehrlich ist. Gehen wir also nochmal zurück auf die W3M-Seite. Man sieht hier, es gibt die Überschriften und so, alles ist hübsch in HTML dargestellt, ist also nicht einfach so ein Textdump, ist also optisch ansprechend und auch alles gut verknüpft. Also URLs und Referenzen auf andere Mainpages sind auch dabei. Zusätzlich ist es so, dass man an der rechten Seite diese Navigationspanels hat. Man sieht hier also in ein paar Funktionen, permanenten Link ist oftmals praktisch in Internet-Diskussionen oder wenn man auf die Seite einfach verlinken will, von der eigenen Webseite aus oder so. Man kann sich die RAW-Mainpage runterladen. Das ist hauptsächlich dafür praktisch, dass wenn man sie in einem anderen Mainpage-Viewer sich anschauen will, kann man sie einfach, also ich kann es hier, ich mache das mal kurz, ich sage Copy Link Address und dann sage ich Curl auf das. Man auf, ich glaube Dev Standard In muss man da benutzen, genau. Und dann sehe ich die W3M-Webseite Mainpage, egal ob ich sie jetzt auf meinem System verfügbar hab oder nicht, könnte manchmal ganz praktisch sein. Es gibt auch tatsächlich einen Script, wo jemand gesagt hat, ah, wenn man D-Main eingibt, dann soll man die Mainpage bekommen, egal ob sie lokal installiert ist oder nicht. Also der holt sie dann automatisch von dem Service ab. Das nur als Tipp an Rande. Auf der rechten Seite gehen wir mal weiter durch, sieht man dann die Table of Contents. Da kann man direkt in eine bestimmte Section springen, zum Beispiel Examples. Man sieht auch, dass sich das hier in der URL reflektiert. Das kann man also einfach Copy, Paste und verwenden. Wenn man während dem Scrollen auf eine bestimmte Section gehen will, gibt es hier auch dieses Paragraphzeichen, da kann man auch sagen Copy Link Address und dann kann ich das im Chat an irgendjemanden schicken. So, Table of Contents haben wir. Die anderen Versionen sollten relativ selbst erklären sein. Alle Debian-Versionen, die aktuell supportet sind, sind unterstützt. Man hat also Stable per Default, All Stable, Testing und Unstable. Experimental ist auch beinhaltet, aber in Experimental gibt es eben derzeit kein neueres WDRM-Paket. Die anderen Sprachen deuten an und sieht man hier auch, dass die Seite vollständig lokalisiert und internationalisiert ist. Das heißt, man kann Mainpages in jeder Sprache Browsen. Und das funktioniert auch korrekt mit den Cross-References. Das heißt, wenn ich jetzt hier zum Beispiel dem TTY Link folge, dann sehe ich dann auch die TTY Mainpage auf japanisch eben. Und dann kann ich sagen, Moment, das spreche ich ja gar nicht. Ich will sie lieber auf Deutsch sehen oder dann wieder auf Englisch gehen und so weiter. Und ich kann zwischen den Versionen hin und her springen. Also so wie man das eigentlich erwartet, aber die Navigation ist eben sehr vollständig. Es gibt recht viele Features und das Ganze ist relativ aufgeräumt. Zwei Sachen, der noch der Vollständigkeit halber und dann sind wir aber auch durch, was die Features angeht. Man kann sich die anderen Sections auch anschauen. Zum Beispiel Krontup ist sowohl ein Dateiformat, ein dokumentiertes als auch eine Neutility, um diese Dateien eben zu verwalten. Das heißt, hier in Section 5 sehen wir, das ist das Format an sich. Und in Section 1 sieht man executable programs or shell commands. Und dann sieht man hier auch noch ein besonderes Merkmal, nämlich, dass Krontup in mehreren Binärpaketen enthalten ist. Und auf Mainpages sind wir vollständig. Das heißt, wir indexieren alle diese und stellen alle diese zur Verfügung. Egal, welche der verschiedenen Kroneimplementationen man benutzt, man kann die Mannpage dafür finden. So, jetzt habt ihr einen Eindruck bekommen, was auf der Seite zu sehen ist und wie sich das so bedient. Und jetzt machen wir mal weiter mit, wie das eigentlich funktioniert. Als Übersicht, ich habe es ja in der Agenda schon angedeutet, die drei großen Städte sind, man extrahiert die Mannpages aus den Debian-Paketen, man wandelt sie nach HTML um, damit man sie ausliefern kann und den Browser anschauen kann und dann liefert man sie eben an die Endnutze aus, soweit kein Hexenwerk. Mannpages extrahieren funktioniert folgendermaßen. Man muss die binary Packages nehmen in Debian, denn die Source Packages enthalten den Quelltext. Im Quelltext sind in aller Regel die Mannpages nicht als solche vorhanden, sondern die sind in anderen Formaten vorhanden, zum Beispiel ASCII-Doc oder DocBook oder sonstige Dokumentationsformate, die eben idiomatisch für die jeweilige Sprache sind, in der das Projekt gehalten ist und dann wird in aller Regel eine Mannpage daraus erzeugt. Es gibt natürlich auch welche, die von Hand geschrieben und gepflegt werden, aber in aller Regel ist es eben nicht der Fall. Deswegen im Gegensatz zu zum Beispiel Debian Code Search und ein anderes Projekt von mir sind wir in diesem Fall nicht an den Source Paketen interessiert in Debian, sondern an den resultierenden Binary-Paketen. So, wir können hier auch schon eine Optimierung anwenden, denn wenn wir für jeden Durchlauf von einem Mannpages-Debian-Org-Lauf alle BNR-Pakete runterladen müssten, dann müssten wir relativ viel Bandbreite aufbringen. Das sind 50 Gigabyte üblicherweise, aber man kann das auf 10 Gigabyte reduzieren, was eine signifikante Reduktion ist. Wenn man sich vorher die Contents-Datei anschaut, in der steht nämlich drin, welche Dateien in welchem Paket beinhaltet sind. Das benutzt auch das Upt-File-Programm, wenn ihr das benutzt, wenn nicht als Tipp vielleicht mal anschauen. Das heißt, wir können direkt sehen, ah, es gibt BNR-Pakete, zum Beispiel Datenpakete für Spiele oder so, die gar keine Mannpages enthalten und das sind üblicherweise auch die, die relativ groß sind. Die skippen wir also sofort und dann schauen wir uns die BNR-Pakete an. Ein erschwerend hinzukommender Faktor ist, dass BNR-Pakete architekturabhängig sind. Es gibt zum Beispiel also BNR-Pakete für AMD64 und andere für i3680. In Debian werden derzeit, ich glaube, Größenordnung 8 oder so Architekturen unterstützt. Das heißt, das sind einige. Die Mannpages befinden sich glücklicherweise in dem Ordner User Shareman, der dokumentierter Maßen Architektur unabhängig ist. Die Fußnoten auf den Folien bedeuten, dass das natürlich nicht immer der Fall sein muss. Es gibt tatsächlich auch BNR-Pakete, die Mannpages beinhalten, die nicht in User Shareman liegen, die dann zum Beispiel nur einen Summling auf die eigentliche Mannpage in User Shareman platzieren oder die noch schlimme Referenz, also einen Include auf diese Mannpage machen, zeige ich auch gleich noch, wie das funktioniert. Und das zum einen und das Architektur unabhängig ist auch manchmal nicht wahr. Also manchmal gibt es Pakete, bei denen sich die Mannpages unterscheiden, je nachdem, welche Architektur man schaut. Das liegt nicht notwendigerweise daran, dass die tatsächlich unterschiedlich sind, je nach Architektur, sondern vielmehr daran, dass die nicht reproduzierbar gebaut werden in manchen Fällen, zum Beispiel weil ein Timestamp mit drin ist oder sowas von dem aktuellen Datum, wenn die übersetzt wird, aus dem Quellformat ins Mannpageformat und die Architekturen werden zu unterschiedlichen Zeiten gebaut. Deswegen kommen da manchmal Unterschiede. Das ist aber ganz klar ein Bug und da kann man dann einen Debian Bug feilen, das ist eine Policy Violation, das muss dann der Maintainer fixen. So, jetzt gibt es aber manche Pakete, die es nur für wenige Architekturen gibt. Das heißt, wir können uns es nicht so einfach machen und sagen, wir schauen uns einfach nur die AMD64 Binary Pakete an, weil es gibt zum Beispiel sowas wie Zetsnes, das ist nur auf i36 vorhanden. Das funktioniert einfach nicht auf anderen Architekturen, das wurde noch nicht portiert. Und deswegen müssen wir also den Zusammenschluss aller Architekturen verarbeiten und dann deduplizieren. So, schauen wir uns mal an, was in UserShermahn eigentlich gespeichert ist. Ich habe hier oben mal das Namensschema draufgepackt. Man hat unterhalb von UserShermahn gegebenenfalls einen Unterordner für die Sprache, um die es geht, also sagen wir französisch oder japanisch, wie wir vorhin gesehen haben, dann hat man einen Ordner Mahn und dann die SectionNummer, also Mahn1 oder Mahn5, für wie vorhin die Formate oder das Tool. Dann hat man den Namen, sagen wir Krontap, Punkt und dann nochmal die SectionNummer, die wir ja eigentlich schon haben. Beispiele, Mahn1 slash Weget.1 soweit so gut. Andres Beispiel, fr.iso8859-1. Da sieht man schon, dass da auch Encodings in eine Rolle spielen und dann als letztes Beispiel CAA Valencia, was vielleicht ein bisschen unüblicher ist, was man nicht sofort so kennt. Also die Locale sind da auch spielen da auch eine Rolle. In Debian gibt es, wie ich gelernt habe, bei dem Projekt allerlei unsinnige Pfade auch in verschiedenen Paketen. Man findet zum Beispiel gelegentlich Dateien in Mahn slash Pi und jetzt fragt man sich welche Sprache ist eigentlich Pi und die Antwort ist, naja, das ist die Python-Datei-Erweiterung, die irrtümlicher Weise in den Pfad mit reingenommen wurde, weil es einen Debian Packaging Helper Tool gibt, welches als Format quasi für die Mahn-Dateien schaut und nach der Erweiterung sie in die entsprechende Sprache einsortiert. Das heißt, wenn man sowas hat wie Weget.1.fr, dann sagt er, klar französisch, aber wenn man irgendwie sowas hat wie Weget.pi, weil es in Python implementiert wurde, dann sagt er, ah, Pi ist die Sprache, stimmt aber gar nicht. Das muss man also fixen und da habe ich auch entsprechende Bug-Reports gefeilt. Das ist aber davon auszugehen, dass das immer mal wieder passiert. Also manchmal leidet die Qualität unseres Mahn-Patch- Archivs darunter, dass die Quellpakete schon in den Bug haben. Ein anderer häufiger Fehler ist, dass die Dateien einfach eine falsche Suffix haben. Das ist eine Konsequenz davon, dass man die Section-Nummer wiederholt. Man hat sie sowohl in dem Ordner-Namen als auch im Datein-Namen noch mal und dann kann man es natürlich auch falsch machen und das passiert dann natürlich auch. Es gibt noch einige andere Klassen von Fehlern, für diejenigen, die es genauer interessiert, auf den Folien, die nachher auch online gestellt werden, ist der Link und da seht ihr dann eine schöne Auflistung, was da alles derzeit kaputt ist. Encoding habe ich gerade schon angerissen. Der Default für Mahn-Pages ist tatsächlich auch heute noch ISO 8859-1 und nicht etwa UTF-8. Allerdings ist der Default für jedes Sub-Directory anders. Jede Sprache hat quasi ihren eigenen Default. Ungarisch zum Beispiel hat ISO 8859-2 und natürlich kann man das auch überschreiben für jedes Sub-Directory, wie wir vorhin gesehen haben, als Beispiel noch mal das Fr. ISO 8859-1. Es ist in der Praxis allerdings so, dass trotz der Tatsache, dass das Mahn-Programm davon ausgeht, dass alles erst mal ISO 8859-1 sein sollte, die meisten Pakete einfach UTF-8 verwenden und das auch aber nicht besonders kennzeichnen. Das heißt, in einem Ordner, in dem eigentlich ISO 8859-1 Dateien erwartet werden, sind in der Praxis eigentlich immer nur UTF-8 Dateien. Allerdings zu 89,8 Prozent nur und deswegen für das verbleibende 1,2 Prozent müssen wir halt auch die verschiedenen Characters jetzt implementieren. Das heißt, wir haben tatsächlich auch Code, der schaut, ist es gültiges UTF-8? Wenn ja, wird es einfach akzeptiert, wie es ist und wenn nein, dann schauen wir uns die Defaults für die jeweiligen Sub-Directories an oder nehmen das encoding, was im Ordner spezifiziert wurde. Wir wandeln dann einfach alles nach UTF-8 mit der Hoffnung, dass irgendwann mal einfach alles UTF-8 ist in Debian. Da könnte man vielleicht einen Release-Goal starten und dann entsprechende Quality Assurance Checks einbauen, dass man da mal in die richtige Richtung kommt. Und dann haben wir es einfach und können den Code rausschmeißen und nehmen einfach alles als UTF-8. So, dann habe ich vorhin auch schon kurz gesagt, es gibt einen Include-Mechanismus. Das ist das sogenannte Punkt SO, das ist so eine Manpage-Direktive, die steht für See Other und das ist nichts anderes als ein Include. Das wird häufig genutzt für Header- oder Futterfragmente, die man in vielen Manpages gemein hat. Also, wenn man zum Beispiel eine AP-Dokumentation sich anschaut, ich habe jetzt kein griffiges Beispiel Parade, aber einige umfangreiche C-Libraries haben eben hunderte von Funktionen und damit dienen ich den kompletten Header und Futter, jeweils duplizieren müssen sagen, okay, den lagern wir aus in ein kleines Include-Fragment und dann werden die einfach dazu gepackt. Das normale Mann-Programm fürs Terminal benutzt ein Programm namens ZSO-Elim, um diese SO-Direktiven zu ersetzen. Das Programm heißt ein bisschen komisch. Wofür es steht ist SO-Elimination, also das Eliminieren von diesen Punkt SO-Anweisungen durch eben das Einbinden der Dateien, um die es da geht. Das Zett am Anfang steht dafür, dass es auch komprimierte Dateien unterstützt, was nicht immer so war. Als kleine Randnotiz im Fehlerfall ist das korrekte Verhalten oder das Verhalten, was eben alle Mann-Viewer machen und wir deswegen auch so machen müssen, dass man einfach nichts einsetzt, nicht etwa dass man eine Fehlermeldung ausgeben würde. Tatsächlich gibt es auch mindestens ein Paket, ich glaube deutlich mehr, mit fehlerhaften SO-Direktiven, in denen man dann also, wenn wir Fehlermeldungen korrekt implementieren würden, lauter Fehlermeldungen über die eigentliche Mann-Page-Seite hat, aber nur in unserem Viewer und nicht in allen anderen, deswegen haben wir uns entschlossen, okay, dann machen wir es eben genauso und unterdrücken diese Fehlermeldungen. Wie wandelt man jetzt die Mann-Pages nach HTML? Also wir haben jetzt gesagt, Benärpakete nehmen wir und extrahin die daraus, aber jetzt muss man sie ja umwandeln. Der erste Versuch, den wir gestartet haben, waren, wir benutzen Gro-HTML. Das ist ein Groff-Backend und Groff ist wiederum das die Groff-Implimentation von GNU und die wiederum wird verwendet von dem Mann-Viewer im Terminal. Das heißt, da dachten wir na ja gut, wenn man den gleichen Viewer-Code nehmen kann und einfach einen Anthos-Backend haben kann, dann ist das die beste Option, weil es maximal kompatibel ist, quasi genau so, wie wenn man sich den Terminal anschauen würde. Aber das Problem ist, ich habe hier das, der Gro-HTML-Link führt auch auf das Paper, in welchem Gro-HTML dokumentiert wurde. Das ist also quasi im Rahmen einer wissenschaftlichen Arbeit entstanden. Und was Gro-HTML versucht oder was das erklärte Ziel ist, ist möglichst nahe an die original Mann-Page heranzukommen. Dazu muss man jetzt erwähnen, dass Mann-Pages ursprünglich quasi als so eine Art Druckersprache gedacht waren, ähnlich wie Post-Script. Das heißt, man hat da laute Anweisungen drin, nicht semantische Anweisungen, so was wie, ah, hier fängt jetzt eine Liste an und hier habe ich jetzt Unterpunkte, sondern man hat da Anweisungen drin wie, ja, bewegt jetzt mal den Cursor um irgendwie 92 Punkt nach rechts und macht da jetzt einen Punkt hin, um eine Liste, einen Liste-Element zu denotieren. Und das Problem ist also, dass Gro-HTML sagt, na ja, dann mache ich eben quasi maximale Kompatibilität mit wie ein Drucker arbeiten würde. Das machen Sie, indem Sie Gro-HTML Tabellen benutzen, um Sachen zu positionieren, das heißt, man hat überall Tabellen und gar nicht semantisch. Und noch schlimmer ist, dass wenn Gro-HTML an seine Grenzen stößt, dann hat es quasi diesen Fallback, das ist einfach sagt, na ja, dann renne ich das halt als Post-Script oder was auch immer, in ein Bild und binde das Bild ein. Das ist deswegen ganz schlecht, weil das Bild dann natürlich nicht ordentlich skaliert auf den verschiedenen Arten von Bildschirmen, die wir heutzutage haben, sondern eben einfach eine Raster-Grafik ist und keine Vektor-Grafik. Das sieht also schlecht aus, je nach Bildschirmen und ist auch ein bisschen umständlich zu handeln in unserem Archiv. Wir haben uns dann also entschlossen, Gro-HTML ist vielleicht nicht der Weisheit letzter Schluss für unser konkretes Projekt und haben dann ein anderes Tool probiert, nämlich Doglifter. Doglifter hat als Ansatz, dass es Manpages nach Dogbook wandelt, also, dass es aus diesem Drucker-Format quasi wieder was Semantisches macht. Auf der Website von Doglifter steht, dass es mit, ich glaube, 70 oder 80 Prozent an Manpages kompatibel ist. In meinen Tests war das leider nicht so, da hat sich allerdings mittlerweile auch einiges getan. Also, damals mag das vielleicht wahr gewesen sein, aber heutzutage in einem aktuellen Debian werden gerade mal noch ein bisschen weniger als 50 Prozent der Manpages erfolgreich nach Dogbook konvertiert. Außerdem ist das Tool leider sehr langsam und es hat verschiedene Encoding-Probleme. Es wurde in Python 2.7 noch geschrieben und nie irgendwie ordentlich auf Python 3 und oder Unicode-Handling konvertiert. Ich habe das dann probiert zu fixen, aber stellt sich draußen, na ja, wenn das eh die meisten Manpages gar nicht kann, dann ist das ein bisschen unsinnig. Letztendlich haben wir das Tool gefunden, bei dem wir dann auch geblieben sind und das ist Mandock. Mandock ist ein Rewrite von so einem Mannverarbeitungsstack, sozusagen, von den OpenBSD-Leuten. Das Tool ist besonders schnell. Es ist das mit Abstand das schnellste, was wir uns angeschaut haben und vor allem es produziert semantisches HTML5. Und das ist echt schön. Es ist ziemlich kompatibel. Ich sage nicht, dass es kompatibel mit allen Manpages ist. Bei Mancm gibt es so kleinere Darstellungsprobleme, so Sachen wie A. Die Liste ist jetzt nicht ganz richtig eingerückt. Es ist irgendwie nur ein Tab statt 2 in sozusagen aber im Großen und Ganzen hat das ganz ordentliches Output. Jetzt hatten wir ein interessantes Problem. Nämlich, wenn man Mandock benutzt, dann ist das ganz normale Interface quasi für Mandock. Man füttert eben den Dokument auf StandardIn und es schreibt nach StandardOut beziehungsweise StandardR auf, sofern es Fehlermeldungen gibt. Das kann man jetzt machen. Aber wenn wir eben die 470.000 Manpages, die wir in Debian extrahieren und dann umwandeln wollen, dann dauert das zwei Stunden auf einem annehmbar schnellen Rechner. Wenn man aber schaut, was die CPU eigentlich macht, ist die gar nicht ausgelastet. Der komplette Overhead geht eigentlich drauf für Fork und Exec. Die Frage ist jetzt also, wie könnte man Mandock in ein Batch-Modus verpassen, damit man also nicht dauernd diesen Prozess aufsetzen und Laden-Overhead halt so einfach sagen kann, kommt konzentriertlich aufs Umwandeln und dann kann man auch die CPU ausnutzen. Und die Antwort ist, wir erstellen ein Socket-Paar mit der Socket-Pair-Funktion und dann haben wir also zwei Sockets, den einen Socket behalten wir in unserem Prozess, den anderen Socket vererben wir an Mandock D, was ein Mandock-Batch-Demon ist, den wir starten. Der Mandock-Batch-Demon erkennt dann, okay, ich hab jetzt hier einen Socket bekommen und liest über den File-Deskriptoren. Das funktioniert über die sogenannten Control-Messages. Ich hab hier auch einen Link auf die Folie gepackt. C-Message ist der passende Begriff, um sich das anzuschauen. Und wir schicken also quasi drei File-Deskriptoren als Ersatz für StandardIn, StandardOut und StandardError. In dem Mandock-D werden die dann mithilfe von Dub 2 auf die richtige Nummer gepackt, sodass der Rest von Mandock nach wie vor denkt, er liest von StandardIn und schreibt nach StandardOut und StandardError. Aber tatsächlich schreibt er eben in einen Socket von uns und wir wiederum lesen das dann einfach im Speicher ein und packen das dann letztendlich in der Datei. Das heißt, dadurch sparen wir uns komplett dieses, wir müssen neue Prozesse andauernd starten und tatsächlich bringt das die Zeit für das Umwandeln von Mandpages massiv nach unten. Also statt, dass wir über zwei Stunden warten müssen, sind es nur noch 20 Minuten für die komplette Umwandlung. Das ist also signifikant und das Schöne ist, dass es recht wenig Code ist. Ich habe hier die Links auch auf die Folie gepackt. Der erste Link führt zu der Implementation der Server-Seite, also quasi der der Parent-Seite, sag ich mal, besser. Und Mandock ist der Patch, den ich eben upstream geschickt habe. Der ist jetzt also auch auch in der normalen Mandock-Distribution drin, mit dem man den Mandock-Demon bekommt, der dann eben diesen Socket versteht und davon die Falldeskriptoren lesen kann. Das ist eine recht schöne Technik, finde ich, weil man mit der mit ganz wenigen Änderungen ein bestehendes Programm von einem Single-Mode auf einem Batch-Mode kann quasi. Also ich denke, da gibt es viele Anwendungsfälle und man kann das auch in anderen Programmen gut einsetzen. So, jetzt haben wir also Mandock benutzt, um eine Mandpage nach HTML zu wandeln. Was kommt als Nächstes? Wir brauchen Cross-Referencing und Cross-Referencing funktioniert bei Mandpages so, dass man nach allem sucht, was in etwa wie eine Cross-Referenz aussieht. Es gibt dafür keinen Markup. Es gibt streng genommen Markup, aber kein verbreitetes Markup. Deswegen muss man sich sowieso anschauen. Beim Suchen muss man als kleine Spitzwindigkeit von Matierungsdirektiven ignorieren. Denn einige Mandpages haben Sachen drin wie Name und dann in Kursiv-Section oder Name in dem Link und dann Section nochmal hinten drinnen. Solche Sachen muss man natürlich strippen. Das heißt, wir müssen quasi in einer Plaintextansicht nach Cross-Referencing suchen. Das erfordert allerdings auch, dass die Namen aller Mandpages vor dem Umwandeln bekannt sind. Das heißt, wenn wir so was finden, was wie eine Cross-Referenz aussieht, dann wollen wir auch noch mal überprüfen, dass das wirklich auch eine Cross-Referenz ist und wird es nicht irgendwie falsch interpretieren. Und deswegen machen wir quasi eine Plausibilitäts-Check. Das impliziert aber auch, dass wir während dem kompletten Umwandlungsprozess quasi eine globale Ansicht von allen Mandpages in allen Suites von Debian haben, damit wir wirklich auch quasi sagen können, ist das jetzt eine Cross-Referenz oder nicht. Der selbe Mechanismus wird auch für UALs eingesetzt. Und hier gibt es einen schönen Edgecase, nämlich UALs, die Cross-Referenz enthalten. Das kommt dadurch zustande, dass manche Autoren von Mandpages nicht etwa eine Cross-Referenz textuell eingebaut haben, sondern auf einen anderen Online-Mandpage-Viewer verlinken, in dem dann wiederum die der Name und die Section der Mandpage drinsteckt. Das handeln wir also auch korrekt, aber idealerweise wäre das eigentlich nicht nötig. Die Table of Contents wird so erzeugt, dass wir einfach nach Heading, also Überschriftselementen in dem HTML suchen, also h1 bis h6 und dann generieren wir eine ID daraus. Was ich dabei gelernt habe, ist, dass in HTML5 die IDs sehr freigebig sind. Die einzigen Regeln dafür sind at least oneCharacter and no spaces. Das heißt, mit folgenden drei Zeilen Go kann man die Spaces ersetzen durch Anderscores und sofern man mindestens einen Charakter drin hat, hat man dann eine gültige URL. Also hier kann man dann mit dem fragment sagt man, das soll als fragment encodiert werden. Und wenn man dann dieses URL-Objekt in den String umwandelt, dann kriegt man eine gültige Cross-Referenz. So, jetzt haben wir also diese Mandpages umgewandelt und Cross-References haben wir gemacht und wir wissen, wie das Table of Contents aussehen muss und so weiter. Jetzt ist die Frage, OK, wie bauen wir unser URL-Schema auf? Wohin packen wir die resultierenden Mandpages? Und das Schema, für das wir uns entschieden haben, ist, dass wir als ersten Bestandteil die Debian Suite haben, also sowas wie Testing, Unstable beziehungsweise die entsprechenden Namen dafür, sowas wie Jesse und Stretch. Dann haben wir das Binearpaket, aus dem wir die Mandpage rausgeholt haben, damit wir mehrere Mandpages mit dem gleichen Namen aus konfliktierenden Binearpaketen auch abbilden können. Dann kommt der Name der Mandpage, Section und die Sprache. Damit haben wir also alles abgedeckt. Und das Schöne an dem URL-Format ist, dass man jeden Teil außer dem Namen natürlich, man muss ja wissen, was man anspricht, auch weglassen kann. Das heißt, die URLs, die ich hier draufgepackt haben, sind alle Valide. Man kann zum Beispiel sagen, ah, ich möchte mit die Mandpage für i3 anschauen. Dann sagt er, OK, du willst wahrscheinlich die Mandpage aus Debian Stable. Das benutzen die meisten Leute und schaut nach, was der Browser schickt an entsprechenden Language-Headern. Da gibt es diesen Accept-Language-Header. Und dann sagt er, ah, du sprichst Deutsch am besten und Englisch als Zweitbestes. Die Mandpage gibt es nur in Englisch. Ich gebe dir die Englische. Oder die Mandpage gibt es in Deutsch. Du kriegst dir die Deutsche. Wenn man dann genauer werden will, dann kann man sagen, OK, ich möchte die Mandpage aus Stable oder Unstable-Testing und so weiter. Oder man kann sagen, ich möchte die Mandpage aus Stretch. Dann kriegt man einen Link, der länger funktioniert, weil Stretch eben den Zyklus durchmacht. Im Moment ist es Testing. Bald wird es Stable. Dann wird es irgendwann Old Stable und irgendwann gibt es dann nicht mehr. Aber da kriegt man quasi den Link, der am längsten funktioniert oder besser gesagt, der am längsten auf das gleiche Dokument zeigt, wenn man wirklich irgendwas Spezifisches für diese Mandpage-Version dokumentieren möchte. Und zu guter Letzt hier einen voll ausgestatteter Link. Da würde man auf die Kront-Up.5-Mandpage verweisen in Jesse aus dem Kront-Paket. Permalinks macht man allerdings am besten ohne Sprache. Also der Link, den man jetzt hier quasi als vollen Link sieht, ist nicht ideal als Permalink. Einfach, weil der auf die Englische Version zeigt und idealerweise würde man das dem Browser überlassen. Deswegen der Permalink-Button, den ich vorhin gezeigt habe, in den Panels an der Seite, der macht das Richtige. Den sollte man dafür verwenden. Wie diese ganze Mechanismus funktioniert, um von der verkürzten URL auf die komplette URL zu redirecten, ist hier in dem Link erklärt. Das ist einfach, der Mechanismus schaut halt einfach, welche Kandidaten habe ich. Und dann nach deterministischen Regeln narrowed down, auf halt letztendlich einen Kandidat und liefert den dann aus. Da will ich jetzt nicht näher darauf eingehen. Aber ein Punkt, den ich erklären möchte, ist, dass der als separatast Server implementiert ist. Denn alles, was ich bislang erklärt habe, kann man komplett statisch abhändeln. Und so ist es tatsächlich auch implementiert. Das heißt, Debiman, das Programm, mit dem diese Manpage-Seite eben erzeugt wird, ist ein Batch-Programm. Das kann man periode schlaufen lassen. Und das wandelt einfach aus einem Debian-Archiv Manpages in eine statische Seite um. Also ein statisches Archiv an Manpages. Zusätzlich zu diesem statischen Corpus, den es ausspuckt, generiert es einen Index-File. Dieses Index-File wird von dem separaten Server geladen und der weiß dann okay, wenn Requests auf diese URLs kommen, dann schicke ich die dorthin. Das Konzept nennt sich Graceful Degradation, so dass, wenn, also in dem Server nen Bug ist oder wenn der Server abstürzt oder wenn er irgendwie überlastet ist oder so, dann klappen also die Redirects nicht mehr, aber alle Links, die Leute auf unsere Seite gepackt haben, die also nicht sich auf nen Redirect verlassen, sondern schon vollständig qualifiziert sind, wie es üblicherweise auch in Suchmaschinen- Resultaten der Fall ist, funktionieren dann immer noch. Das heißt, die wichtigste Trafficquelle, also Suchmaschinen-Links, funktionieren noch, selbst wenn quasi bei uns alles schiefläuft. Zur Spracherkennung, ich hab ja schon erwähnt, dass es diesen Accept Language-Header gibt. Hier ist noch mal, wie das aussehen kann. Man hat hier diese Sprachen, zum Beispiel FRCH, also französisch, wie es in der Schweiz gesprochen wird und französisch egal wo, dann hat man hier nen Wert. Also der Browser sagt quasi, französisch ist die erste Wahl, das ist über den Quality Score 09, dann geht es weiter mit Englisch, Deutsch und ansonsten gibt mir einfach irgende Seite, das passt schon, irgende Seite ist besser als keine Seite und die Server implementieren tatsächlich auch, ich geb keine Seite aus, wenn kein Header matcht, also das muss man tatsächlich so machen. Und wir machen nicht nur an dieser Stelle, sondern generell überall, wo es um Transitions geht, also wo man von einer Manpage zu anderen kommt, zum Beispiel bei den Cross-References, wie ich es vorhin gezeigt hab, nen vollständigen Language-Match. Das heißt, solche Sachen wie das Norwegespracher auch dänische Seiten verstehen können, sind abgebildet, sodass also man immer eine hohe Chance hat, dass wenn es eine Manpage gibt, die man verstehen könnte, man auch auf diese geleitet wird. Das finde ich eine relativ angenehme Experience für Leute, die eben Manpages in Nicht-Englisch lesen möchten. Zusätzlich haben wir eine Open-Search.xml-Datei, das ist so eine Beschreibungsdatei für Submaschinen, die macht, dass man in der Adresszeile beziehungsweise im Suchfeld, je nachdem, ob man Chrome oder Firefox verwendet, den Anfang der Seite einfach eingeben kann, also nachdem man Manp oder wie viel auch immer Buchstaben ihr braucht, um das eindeutig zu machen, gedrückt hat, kann man tap drücken und dann den Namen eingeben, auf die man möchte, mit Enter bestätigen und dann kommt man direkt auf diese Seite. Implementiert ist das über diesen Jump-Händler, der dann einfach einen Redirect macht. So, gehen wir mal auf die Laufzeitumgebung ein. Es gibt vom Debian-Sysadmin-Team eine VM für das Manpage-Projekt, die sie uns zur Verfügung gestellt haben. Da lief auch schon das alte System drauf, deswegen haben wir die einfach weiter übernommen. Die heißt Manziali und die läuft auf einem HP Play-System bei Bitemark-Housting. An dieser Stelle also danke sowohl an Bitemark als auch an das DSR-Team für die Hardware-Spende und das Betreiben dieser Hardware. Als CPU steckt dazu in ein AMD Optaron-System der 2.3er-Serie. Mehr kriege ich aus dem Prog-CPU-Info nicht rausgelesen. Wenn man aber auf Wikipedia schaut, dann sieht man, dass diese Serie aktuell war 2008-2009. Es ist also bald eine 10 Jahre alte CPU, nur um mal quasi ein Bild zu schaffen, auf welcher Umgebung wir da laufen. An Arbeitsspeicher haben wir 2 GB zur Verfügung und die Storage ist so was auch immer an Spinning-Disk damals in dieses HP Play-System eingebaut wurde, also keine SSD oder so. Die größten Ordnungen, über die wir hier sprechen sind, man kann einen kompletten Durchlauf von Debiman über alle Debian-Sweets, alle Manpages machen in Minuten auf meiner Workstation und in Stunden auf dieser Feuer. Die genauen Messwerte habe ich hier auch verlinkt. Jetzt könnte man sich vielleicht fragen, warum rede ich hier überhaupt Geschwindigkeit? Aber ich finde, dass Geschwindigkeit durchaus wichtig ist, auch wenn es um solche Batch-Systeme geht. Man könnte sagen, na gut, dann kommt halt eine Manpage, wenn sie nach Debian wandert und aktualisiert wird, erst irgendwie morgen in manpagesdebian.org und nicht schon heute. Aber es gibt noch zwei weitere Punkte, bei denen das wichtig ist. Das eine ist Disaster Recovery. Wenn ihr mal versucht habt, einen Ordner zu sichern mit quasi egal, welchem Backup-Programm im konkreten Fall von diesem Setup nutzt, das DSR-Theme Baccular, dann werdet ihr feststellen, wenn ihr Orten habt mit Millionen von Dateien drinnen, dann skaliert das nicht besonders gut. Also die Dateien sind alle sehr klein, sind irgendwie nur ein paar Kilobyte. Und deswegen ist quasi der Overhead die Metadaten, die man dafür braucht, um das zu verwalten, massiv. Und wenn man jetzt also quasi sagen würde, ah, wir möchten den Datenbestand sichern, um ihn nachher wiederherzustellen, dann ist es tatsächlich so, dass es schneller geht, ihn komplett neu zu erzeugen, als ihn wiederherzustellen. Das heißt aber auch, dass je schneller wir das komplett erzeugen können, desto schneller sind wir wieder online, wenn tatsächlich irgendwas passiert. Die Geschwindigkeit von diesem Batch-Prozess ist also Teil unserer Disaster Recovery Story. Weiterhin ist es wichtig für die Developer Velocity. Das heißt, ich persönlich mag nicht lange warten auf Programme, wenn sie laufen. Das heißt, von Anfang an habe ich darauf geachtet, dass das möglichst schnell läuft, weil je langsamer es läuft, desto demotivierter bin ich, desto weniger kann ich das entwickeln. Und ich denke, es geht auch anderen Leuten so. Wenn ich sagen kann, hey, wenn du einen Patch beistern willst zu mannpatchesdebian.org, das Einzige, was du machen musst, ist irgendwie kurz das Programm laufen lassen, fünf Minuten kommst du wieder, und dann kannst du schon loslegen und deine Änderungen testen und dann einen inkrementellen Lauf starten. Das ist deutlich attraktiver, als wenn ich sagen muss, ah, du musst jetzt erst mal irgendwie Sachen installieren und dann vielleicht übermorgen kannst du es testen, die Veranstaltung ist längst vorbei und dann hat man die Motivation verloren. Für mich persönlich ist es also sehr wichtig. Das DSA-Team benutzt ausschließlich Apache 2. Ursprünglich hatte ich einfach eine Engine-X-Konfiguration, die relativ schmal ist. Ich zeig das auch nachher noch, wie das genau funktioniert. Aber ich musste das dann eben umstellen auf Apache 2. Wie wir die Seite tatsächlich ausliefern, ist über ein Setup, welches sich Static Mirrorring nennt. Das wird im Debian-Projekt genutzt, nicht nur für mannpatchesdebian.org, sondern auch für andere Seiten. Es wird auch im Tor-Projekt benutzt, weil Peter Palfrada, der das geschrieben hat, in beiden Projekten aktiv ist. Im Wesentlichen ist das Ersync mit ein paar Konfigurationsdateien, damit man weiß, was von wohin geschoben wird. Aber was eben passiert ist, dass auf der Manziale vor allem wir nicht die Seiten tatsächlich auch ausliefern, sondern dort erzeugen wir sie nur und dann erzeugen wir sie auf ein paar statische Mirrors, die dann eben näher an unseren Endnutzern sind, also verteilt auf mehrere Kontinente und die vor allem eine höhere Verfügbarkeit haben, weil in diesem Setup DNS-Anpassungen gemacht werden, wenn immer es geplante Wartungsarbeitungen gibt. Zum Beispiel bei Kernel-Updates, die regelmäßig passieren sollten und auch im Debian-Projekt regelmäßig passieren für DSA-gewartete Systeme. Wird vorher der DNS-Record rausgenommen für das System, welches aktualisiert wird, dann wird das Update gemacht, dann der DNS-Record wieder rein und dann geht es weiter. Daher haben wir also keinen Single-Point-of-Failure in unserer Infrastruktur, wie das früher der Fall war. Also früher war die Manpatch-Seite quasi mit Single-Point-of-Failure nur mit dieser einen VM, die dann komplett überlastet war, wie er am Anfang erklärt. Das ist mittlerweile nicht mehr so. Wir haben die Debian-Software angepasst, damit das in diesem Setup auch gut funktioniert. Und was ich damit meine, ist, dass wir die Redirects, die ich gerade eben beschrieben habe, als in einem separaten Server laufend in Apache 2-Config reimplementiert haben. Das sieht dann folgendermaßen aus. Wir erzeugen eine sogenannte Rewrite-Map. Das ist ein Apache-Feature, in dem man quasi so einen Key-Value-File hat. Intern ist das eine Berkeley-Datenbank. Und was wir hier also haben, ist, wir haben einen Tool, welches den erzeugten Index umwandelt in eine Rewrite-Map. Wir machen das parallelisiert, damit wir alle CPU-Kenne ausnutzen können. Dann sortieren wir das Ganze und merchen es in eine große Datei. Anschließend kommt hier dieser Base64-Fluch. Und was sich hier hinter verbirgt, ist eine leere Datenbank-Datei, die ich mit einem Tool erstellt habe auf meinem Computer, weil ich in diesem Tool eben angeben kann, welches Datenbank-Format genutzt werden soll. Und in dem HTTXT2-DBM-Tool kann ich das eben nicht machen. Blöderweise ist der Default für die Berkeley-Data-Bases nämlich auf einem Format eingestellt, welches unvorteilhaft ist für uns, wo also das Einfügen von den ganzen Einträgen über diesen HTText2-DBM-Befil und auch das tatsächliche Lookup deutlich länger dauert, als es eigentlich laufen müsste. Also das ist ein massiver Speed-Up und deswegen lohnt es sich auch, diesen unwartbaren Fluch an leere Datenbank-Datei hier drin zu haben. Das Gute ist nämlich das HTTXT2-DBM, wenn die Datenbank schon existiert, die einfach weiterverwendet. Das heißt, wir können einfach einmal sagen, hier nehmt ihr richtigen Parameter und dann müssen wir uns nicht mit dem Tool drum schlagen. So, das liest also diese Rewrite-Map, die wir erzeugt haben im textualen Format ein, erstellt eine schnelle Lookup-Table draus und der Apache benutzt die dann. Dadurch sind die allermeisten Redirects in die ihr lauft von dem Static Mirroring Setup schon abgehandelt. Die Alternative dazu ist, dass das Static Mirroring Setup erst, wenn ihr es anspricht, erkennen müsst, oh, ich muss hier einen Redirect machen, euch dann auf einen komplett anderen V-House redirected, wodurch ihr eine neuen DNS Lookup, einen neuen TLS Handshake und so weiter braucht, der dann wiederum, auf dem läuft dann der Augserver, der den dynamischen Redirect macht und der schickt euch dann wieder zurück. Und das Setup hat eine furchtbare Latents. Deswegen haben wir uns dafür entschlossen, wir machen das nochmal, so dass der Apache die Redirects in den meisten Fällen schon abhandeln kann. Die einzigen Edge Cases sind, wenn ihr eine 404 Seite ansteuert, wenn also der Apache denkt, oh, da ist vielleicht ein Edge Case, den ich noch nicht abgedeckt habe, dann leitet er euch immer noch an den dynamischen Redirector weiter. So, hier ist das entsprechende Pondant zu der Apache Config. Also, das ist jetzt, wie man diese Redirect-Map tatsächlich auch benutzt. Ich habe das erzeugt, in mehreren Abenden die komplette Dokumentation des Mod-Rewrite-Modules von vorne bis hinten zu lesen. Also, kein Scherz, ich habe dir wirklich von Anfang bis Ende gelesen. Und ich glaube, dass diese Config alle Features, die signifikant sind in dem Modul, mindestens einmal verwendet. Ich bin auch überzeugt, dass Rewrite das Mod-Rewrite quasi Touring-Vorständig ist. Also, ihr könnt da sicherlich irgendwie einen Brainfuck-Interpreter einbauen oder sowas. Was hier funktioniert ist, was hier passiert ist im Wesentlichen einfach, dass er den Accept-Language-Header nimmt und den verarbeitet. Aber es gibt allerlei Edge Cases, weswegen man komische Statements nehmen muss, z.B. hier ist Set-Enf-If, weil das an der richtigen Stelle in der Apache Processing Toolchain quasi passiert. Und lauter Sachen braucht man, irgendwie Rack-Ex-Matches und so weiter und so weiter. Und das ist auch nur ein Auszug. Die vollständige Version habe ich auf der Folie verlinkt, wenn ihr euch das wirklich antun wollt. So, jetzt habe ich vorhin schon gesagt, ich hatte eigentlich mit dem Engine-X angefangen und da ist es ganz deutlich einfacher, wenn man sich also überlegt, ah, vielleicht will ich auch so einen Set-Up haben, lokal, für was auch immer, wenn ihr z.B. in der Firma irgendwie einen Debian-Derivat erzeugt und betreut und auch so einen Index haben wollt, könnt ihr das deutlich einfacher aufsetzen, heißt irgendwie mit kompliziertem Apache-Config, die kein Mensch versteht. Auf der linken Seite habe ich eine Engine-X-Config hingepackt. Die sagt einfach, in Surfmahn befinden sich alle Dateien, setzen einen passenden Caching-Header. Das G-SIP-Static always bedeutet, bzw. das in Kombination mit dem G-Unsip bedeutet, dass wir auf der Festplatte nur die G-SIP-Komponenten-Dateien vorhalten und nicht beide Datei-Typen vorhalten. Und für Browser, die kein G-SIP unterstützen, packt es dann der Server aus. Im Apache haben wir das auch, aber das ist dort deutlich komplizierter. Und dann sagen wir, dass alle URLs, die nicht gefunden werden, also die nicht vom Engine-X direkt auf der Platte abgehandelt werden, an den Aug-Server gehen, der läuft dann hier auf Localhost auf einem Port. Und wie man den startet mit einer System-D-Unit, habe ich hier auf der rechten Seite gezeigt, ist auch kein Hexenwerk dabei. Man startet einfach diesen Server und kann ihn auch noch ein bisschen einstrengen, damit er nicht unnötige Rechte hat, auf dem System alles Mögliche zu lesen, kann man sagen, der soll nur Read-Only-Zugriff haben und überhaupt eine eigene Stamp, die uns weiter unter schön abgetrenntem User-Account laufen und dann soll er auch wieder neu gestartet werden, wenn der Crashing sollte, aber der ist bislang stabil. Und mit diesen zwei Config-Files und Engine-X und System-D kann man das Ganze dann eigentlich bauen. Funktioniert relativ schnell. So, einen Edgecase möchte ich noch kurz erklären, weil er auch in der Beschreibung für den Vortrag angekündigt war und ich finde, dass er hier enttäuscht rausgeht, das sind nämlich die Slave-Alternative-Man-Pages. Die längste Zeit und auch, nachdem ich das Man-Pages-Remake gelauncht hatte, waren die nicht implementiert, aber mittlerweile sind sie implementiert. Worum es dabei geht, ist, dass verschiedene Implementationen auf einem Debian-System gleichzeitig vorhanden sein können. Das sind Kandidaten, die sicherlich jeder kennt, wie zum Beispiel XWW-Browser, also wenn ihr verschiedene Browser installiert habt, klar, oder VI, ihr könnt verschiedene Versionen von dem VI-Editor installiert haben. Es gibt sowas wie Elvis oder VI Tiny oder der Fuller Wim oder sowas, oder auch Postgres, was oftmals in verschiedenen Versionen gleichzeitig in Debian vorhanden ist. Und wie das funktioniert, ist, dass die nicht nur Sim-Links für die Binaries haben, sondern eben auch für die Man-Pages. Damit man, wenn man sowas macht wie Man-PG-Dump, man auch auf die PG-Dump-Version kommt, die man gerade benutzt und nicht auf irgendeine oder die falsche. Wie das technisch funktioniert, ist, dass in dem Post-Inscript, also einfach so ein Shell-Script, welches nach der Installation von dem Paket ausgeführt wird auf dem Zielsystem, einen Aufruf drin ist auf ein Tool namens Update Alternatives. Dieses Tool wird also das Richter zur Laufzeit, die Alternatives-Datenbank ein, und das ist im Wesentlichen eine Sim-Link-Farm und hat aber keine formelle API oder ist auch nicht maschinenlesbar irgendwie beschrieben in den Man-Pages, sorry, in den Debian-Binary-Paketen, die die Man-Pages enthalten, sodass wir die Pakete irgendwo installieren müssen. Also wir können das nicht von außen sehen, dass die da, wir können schon sehen, dass die Update Alternatives aufrufen, aber nicht wie genau. Man könnte sagen, ja, man könnte ja auf gut Glück probieren, irgendwie dieses Post-Inscript zu pasen und zu schauen, was die dafür Aufrufe machen. Aber tatsächlich, ich habe es mir ein bisschen angeschaut, es gibt genug Debian-Pakete, die da wirklich komplizierte Schellanweisungen drin haben. Da müsste man also quasi eine komplette Schell nachimplementieren. Damit ist das raus. Wir müssen also tatsächlich die Pakete irgendwo installieren und ab dann wird es schon wieder ein deutlich komplizierteres Programm und Setup, weil bislang ist es recht einfach. Man sagt dem einfach, hier ist irgendwie diese Debian-Version will ich haben und dann lädt er die von dem Mirror und dann entpackt er die aus. Aber jetzt müsste er auch tatsächlich Sachen installieren. Das macht das Ganze teurer und komplizierter und umständlicher. Deswegen haben wir uns entschlossen, das in einem anderen Teil der Debian-Infrastruktur abzuhandeln, nämlich in PO Parts. Das ist ein Tool, welches die Installation und das Entfernen von Paketen durchspielt. Und dann schaut, ob auf dem System Pakete oder Dateien hinterbleiben, die eigentlich von dem Paket wieder hätten gelöscht werden sollen. Und dort installiert, also wären also ohnehin schon alle Pakete installiert. Und dann haben wir gesagt, okay, wenn wir das dort eh schon machen, dann können wir dort auch einen Logfile erzeugen, welches diese ganzen Update-Alternatives-Aufrufe in ihrer vollständig expandierten Form einfach mit schreibt. Und dann können wir die von dort aus pasen, weil dann ist es nur noch der Aufruf und die Parameter für das Tool. Das kann man dann wiederum interpretieren. Und damit wird es dann möglich. Das haben wir dann auch so gemacht. Und nachdem PO Parts alle Pakete nochmal durchinstalliert hatte, haben wir jetzt einfach so ein paar kleine Daten-Dateien, die lädt das Debian-Programm beim Start einfach mit ein und erzeugt dann die entsprechenden Simulinks, wie als wären die in dem Debian-Paket schon drin. So, ich möchte jetzt noch mal einen Fazit ziehen. Wir haben eine attraktive Manpage-Seite implementiert, auch mit einem Mobile-Layout für Smartphones, Tablets und so weiter. Es ist sehr modern und sie ist vor allem sehr vollständig. In dieser Tabelle habe ich das mal übersichtsweise aufgeführt. Die Manpage ist Debian-Org-Seite, enthält alle Versionen von der Kronto-Manpage. Sie enthält die Git-Build-Paget-Manpage. Die ist deswegen speziell, weil sie Debian-spezifisch ist. Also da sieht man dann quasi welche anderen Manpage-Seiten in ihren Korpus auf Debian basieren. Die Manpage ist Ubuntu-Seite. Nicht überraschenderweise hat natürlich auch das Git-Build-Packet-Tool, weil das quasi aus Debian nach Ubuntu überschwappt. Aber man.cx, zum Beispiel sieht man, die sind auch Debian basiert, aber die ganzen anderen Manpage-Seiten sind zum Beispiel nicht Debian basiert. Dann JavaFX-Packet-Jer ist ein anderes interessantes Beispiel, weil die eben so einen Simulink verwenden und ihre Manpage in einem ganz anderen Ordner haben. Das bricht schon einige andere Manpage-Archive. Bei uns funktioniert das. Das ist deswegen interessant, weil es nur in i36 ist. Und Top-Hat ist deswegen interessant, weil es nur in AMD64 ist. Da kann man also sehen, welche Architekturen nutzen die Manpage-Seiten. Man.cx ist, wie wir jetzt also deduziert haben, eine i36 Version von einem alten Debian-Stable. Dann haben wir W3M als Beispiel. Und hier sehen wir, dass das in den meisten Archiven gar nicht drin ist, was super überraschend ist, weil W3M ist schon wirklich kein exotisches Tool. Auf Man.cx ist es drin und auf der Ubuntu-Manpage-Seite ist das Inkroning kaputt. Dann haben wir W3M.1.de. Das ist deswegen ein interessantes Beispiel, weil es neuer ist. Also das wurde erst kürzlich in W3M hinzugefügt, die deutsche Übersetzung. Und da sieht man dann, wie aktuell die Archive jeweils sind. Hier sieht man also Man.cx ist damit raus. Und Ubuntu und Debian bleiben übrig. Der gravierende Vorteil, also mal abgesehen von dem Encoding und der Vollständigkeit, die Debian-Manpage-Seite gegenüber der Ubuntu-Manpage-Seite hat, die tatsächlich ziemlich brauchbar ist, muss man sagen, ist, dass eben alle Pakete, also alle konfliktierenden Pakete auch ordentlich gehandelt werden, wie eben am Beispiel von der Grundabseite gezeigt. So, eins möchte ich auch noch erwähnen, das komplette Projekt wurde in Go implementiert. Im Nachhinein muss ich sagen, das war eine gute Wahl, nicht nur weil ich Go sehr gerne mag und standardmäßig meine Projekte damit implementiere, sondern auch, weil, wie sich herausstellt, die Funktionalität größtenteils von der Standard-Library abgedeckt wurde. Wir brauchen ganz wenige externe Packages. Pakete, die wir hier brauchen, sind die experimentellen Text- und Netflix-HTML-Pakete, mit denen wir also das HTML verarbeiten, um die Headings wieder rauszuholen und Text eben für dieses ganze Characterset- Handling und Lokalisierung und so was. Und dann brauchen wir von Paul Tech die Debian-Packages, die uns erlauben, Debian-Paket-Listen einzulesen und Debian-Pakete aufzumachen und solche Sachen. Vor allem aber war interessant zu sehen, dass Nebenläufigkeit sehr einfach umzusetzen ist. Das heißt an verschiedenen Stellen parallelisiert Debian-Massiv. Das führt dazu, dass wir maximale Ressourcen-Ausnussungen tatsächlich recht einfach erreichen können. Also ich habe immer geschaut, mit D-Stab zum Beispiel oder anderen Tools, mit denen man Systemaktivität visualisieren kann, wo ist gerade der Flaschenhals? Und dann habe ich geschaut, ist das ein Flaschenhals, den ich erwarten würde oder nicht? Zum Beispiel, wenn man Debian zum ersten Mal startet, dann muss er natürlich erstmal alle Debian-Pakete einlesen. Das muss er also übers Netz machen, wenn man die nicht lokal vorhält dann lasse der die vollständig aus. Danach muss er das Ganze also auspacken, da würde man dann erwarten, okay, Festplattenaktivität würde man erwarten und CPU-Aktivität. Wenn es ein Inkrementellerlauf ist, muss er schauen, welche Seiten oder welche Pakete haben sich mittlerweile geändert. Da würde man also auch erwarten, okay, das blockiert auf die Festplatte und oder aufs Dateisystem, weil er halt alle Einträge quasi einmal durchstatten muss. Tatsächlich können wir das als kleine Randnotiz innerhalb von Bewerkstelligen, also Millionen von Dateien auf einer SSD kann man einfach, wenn man es effizient macht, in zwei Sekunden komplett durchstatten. Was signifikant schneller ist als find oder andere Tools das können. Und so habe ich also quasi bei jedem Schritt geschaut, so ist hier das bottleneck das Richtige und solange den Code entsprechend optimiert, bis es das Richtige war. Das heißt, ich bin relativ zuversichtlich, dass Debian nicht nur heute gut funktioniert auf den Rechnern, die wir aktuell haben, also sowohl den alten Rechnern, diese alte v.a. auf der es läuft, sondern wie meine Workstation zu Hause, sondern das auch in Zukunft, wenn die Rechner noch mehr parallel werden und noch schneller werden, das Programm sich gut anpassen kann und quasi maximal schnell bleibt. Das Einzige, was man erwähnen muss, als negativer Punkt ist, dass wir auf der VM, auf der wir laufen, nur relativ wenig Speicher haben, zwei Gigabyte RAM nur, und da sind wir am Anfang relativ oft angeeckt, weil quasi der ursprüngliche oder der erste Instinkt, den man eben hat, als Programmierer ist okay, ich mache es, dann verschwendet man gegebenenfalls Speicher, das ist am Anfang passiert, und dann muss man eben schauen, wo geht der Speicher hin und wie kann man das effizienter gestalten. Da gibt es glücklicherweise einen Profiler, der heißt P-Prof, ich habe hier den Blog-Eintrag verlinkt, wo man sehen kann, wie das funktioniert, und damit konnte man das Problem dann wunderbar lösen. So, jetzt sind wir am Ende der Folien angekommen. Ich bin jetzt gerne noch bereit für eine kleine Q&A-Session. Mehr Infos zu dem Projekt an sich, findet ihr auf dem GitHub Repository. Die Seite an sich, seid ihr natürlich auch herzlich eingeladen zu benutzen, also einfach manpages.debian.org, wenn ihr nicht ohnehin schon dorthin geschickt seid, wenn ihr irgendwie auf Google nach einer Manpage sucht. Wenn ihr Interesse daran habt, eine Debian Instance auch für eure Lieblingsdistro aufzuziehen, sei sie jetzt debianbasiert oder nicht debianbasiert. Wer ich auch interessiert daran, einfach mich mal ansprechen, dann können wir schauen, wie wir das machen können. Und zu guter Letzt würde ich mich auch über Feedback zu dem Vortrag freuen, ob es euch gefallen hat oder was ich verbessern könnte. Ich habe hier den Link auf dem Folien oder auch der QR-Code, wenn ihr das schnell scannen wollt. So, dann sage ich erstmal, danke und jetzt können wir fragen. Bitte schön. Mikrofon? Wie handelt ihr Updates von Paketen? Wird das irgendwie krank gepusht oder läuft da ein CronJob jeden Tag und dann baut es neu? Ursprünglich hatten wir einen CronJob, aber tatsächlich ist mittlerweile dadurch, dass das auch auf offizieller Debian Infrastruktur läuft, das Programm in den sogenannten Paketen aktiviert. Das heißt, es gibt in Debian, wie du vielleicht weißt, 4-mal am Tag einen Update in dem Pakete, die bereits nach Debian akzeptiert wurden, auch tatsächlich so genannt installiert werden und dann auf den Mirror auch aktualisiert werden. Das heißt, immer wenn das passiert und nachdem der Mirror, den wir benutzen, gerade aktualisiert wurde, kriegen wir sofort eine Push Notification, neuer Run läuft los. Wir verarbeiten die Pakete, das bewegt sich in der Größe von Minuten und dann dauert es eigentlich nur noch bis nachdem, wie es geprägt hat und verteilt hat. Das bewegt sich noch mal in Minuten bis Stunden Bereich, je nachdem, ob da gerade alles rund läuft und wie viel Daten dazu verarbeiten sind. Das heißt, üblicherweise, wenn du jetzt ein neues Paket nach Debian hochladen würdest oder eine neue Version von einem Paket, was du betreust, dann, wenn du das am Morgen machst, solltest du am Nachmittag spätestens deine Änderungen schon live begutachten können. Weitere Fragen. Wenn es keine weiteren Fragen gibt, dann machen wir an der Stelle Schluss und wir sehen uns im nächsten Video. Tschüss.