 Okay, ich glaube, wir können anfangen. Herzlich willkommen zu meinem zweiten Vortrag auf dieser netten Veranstaltung. Mein Name ist Michael Stapelberg und das Thema dieses Vortrags ist man pages.debian.org oder im vollen Titel die Modernisierung von man pages.debian.org. Der Untertitel war die mir bekannte modernste Web 1.0-Anwendung. Ich kann gleich noch erklären, warum das als Web 1.0 gilt, meiner Meinung nach zumindest zum größten Teil. Zunächst mal möchte ich darauf eingehen, was wir in dem Vortrag so auf uns zukommen haben. Zunächst möchte ich motivieren, warum ich denn eine man pages.de-Seite angefangen habe. Es gibt doch schon 50 verschiedene im Internet. Jeder kennt sicherlich die eine oder andere. Linux.die.net zum Beispiel ist sehr bekannt. Dann werde ich eine Übersicht geben über das Problem. Manche von euch werden sich sicherlich fragen, man pages.de-Seit steckt doch nicht viel dahinter, oder? Man hat diese Dateien und dann wandelt man den HTML um und dann ist man schon fertig. Warum gebe ich dafür einen Vortrag auf so eine Nerdveranstaltung? Das Problem lässt sich in drei Unterbereiche aufgliedern in das Extrahieren von man pages, das Umwandeln von man pages nach HTML und das letztendliche Ausliefern dieser man pages. Nachdem wir dann also etabliert haben, wie das Problem generell anzugehen ist oder wie ich denke, dass die sinnvolle Variante ist, um das Problem anzugehen, werden wir auf die Laufzeitumgebung eingehen, in der letztendlich die Software läuft und dann ziehe ich einen Fazit, wie sich das Projekt so entwickelt hat und wir haben noch Zeit für Fragen. Wenn irgendjemand Fragen hat, während des Vortrags, die unfassbar wichtig sind, damit ihr den weiteren Vortrag versteht, könnt ihr auch gerne die Hand heben, dann versuche ich die direkt zu beantworten, ansonsten bitte bis zum Ende warten. Zunächst zur Motivation. Das Lesen von man pages ist im Browser oft bequem. Das hat verschiedene Gründe. Das mag sein, dass man gerade auf Reisen ist und man sitzt in der Straßenbahn und man diskutiert über irgendein Thema und dann denkt man sich, da muss ich kurz nachschlagen, ob das mit dem Tool wirklich geht und dann hat man aber nur seinen Smartphone und möchte nicht den Rechner rausholen, dann kann man sich dort vielleicht die Manpage anschauen oder der eigene Rechner ist gerade gestorben und man ist gerade in der Rescue Shell und muss irgendwie die Manpage zu einem Befehl sich anschauen oder man sitzt gerade im Rechenzentrum und hat nur eine schmalbandige serielle Konsole vor sich. Es gibt viele Leitgründe, warum man die Manpage im Terminal vielleicht lesen möchte, sondern auch im Browser. Andere Gründe wären, dass man vielleicht die Schriften schöner findet oder das Wrapping oder was auch immer. Könnt ihr euch Gründe für ausdenken. Allerdings ist mir dann aufgefallen. Ich mache das gelegentlich, dass ich Manpages im Browser eben lese und nachschlage und auch daraus kopiere und anderen Leuten Sachen schicke und mir ist dann dabei aufgefallen, dass die existierenden Manpage-Archive, die man so findet, wenn man einfach einen griffigen Suchbegriff bei Google eingibt, sind alt und oftmals sind sie auch voll mit Werbung. Das heißt, die sind general einfach nicht so angenehm zu benutzen und ich dachte, das könnten wir vielleicht besser machen. Wie wäre es eigentlich mit einem Manpage-Archiv, welches immer alle aktuellen Manpages beinhaltet, die man in aktuellen Linux-Distributionen so findet? Wie wäre es, wenn einfach mal alle Manpages im Netz verfügbar wären und nicht nur einen Subset von denen, die man vielleicht erwarten würde? Werbung haben wir im DBM Projekt grundsätzlich nicht. Das wäre auch noch mal ein netter Vorteil. Während der Entwicklung des Projekts habe ich dann irgendwann realisiert, dass Debian ja schon eine Manpage-Seite hat. Also ich habe am Anfang probiert, eine neue zu bauen und dann wurde mir irgendwann gesagt, im Moment, da gibt es doch schon manpages.debian.org und dann dachte ich so, Moment, warum kenne ich das nicht? Ich bin jetzt seit ein paar Jahren in dem Projekt aktiv und ich habe noch nie von der Seite gehört. Es stellte sich raus, dass die Seite zu dem Zeitpunkt, wo ich auf sie aufmerksam geworden bin, gelastet war und deswegen absichtlich aus den Suchmaschinen-Indizes entfernt wurde. Was nämlich passiert ist, ist, dass die Seite war früher einfach ein CGI Script. Das heißt, für jeden Request, den ihr gemacht habt, für jede Manpage, die ihr abgerufen habt, wurde in ein Programm gestartet, welches die Manpage umgewandelt hat. Später wurde dann auch ein Cache eingeführt, aber das war offenbar nicht ausreichend. Und das per se ist ja jetzt erstmal kein Problem. Und irgendeiner, ich weiß gar nicht mehr, ob das eine Debian-interne Änderung war, wahrscheinlich schon, hat dann die Apache-Startseite so konfiguriert, dass in dieser Startseite, die eben ausgeliefert wird, nachdem man den Apache-Server installiert, einen Link war auf die Mann-Page für A2n-Site und A2dis-Site, also diese Tools, mit denen man spezifische VHOS-Konfigurationen im Apache ein- und ausschalten konnte. Und das ist ja per se auch erstmal noch kein Problem, weil ich meine, so viele Leute installieren jetzt auch nicht in den Apache, sondern in den Traffic generieren würde. Aber dann hatte irgendwie diese eine Spiele-Seite, die hatten irgendwie ein Problem mit ihrem Hosting und letztendlich haben sie dann irgendwie den Apache wieder installiert bekommen, aber ihren Inhalt nicht. Und die hatten so viele Hits. Und jetzt kommen da diese ganzen Gamer und wollen auf ihre Spiele-Seite und sehen, die sieht auf einmal ganz anders aus. Aber das sind so Links, ich klick mal alle auf die Links und dadurch wurde die Seite hoffnungslos überlastet. Und dann mussten wir eben quasi die Notbremse ziehen und die Seite deswegen aus den Suchmaschinen entfernen, damit nicht noch mehr Traffic da kommt und dann irgendwie haben wir das Problem dann wieder in den Griff bekommen. Jedenfalls, es gab da also schon eine Seite und dann habe ich mich entschlossen, diese Seite zu modernisieren, statt eine neue Seite zu machen. Und das Ziel war also, dass die Seite nicht unter solchen Schwierigkeiten leiden sollte. Also eine komplett andere Architektur musste her. So, jetzt gebe ich erstmal eine kurze Demo, damit diejenigen von euch, die noch keine Gelegenheit hatten, sich die Seite mal anzusehen, wissen, wie es so aussieht und was man da so machen kann. Wenn man einfach auf manpages.debian.org geht im Browser, dann kommt man diese Startseite zugesicht. Man sieht hier, dass es verschiedene Wege gibt, wie man die Seite benutzen kann, die einem hier erklärt werden. Wenn man zum Beispiel kein spezifisches Ziel hat und sich einfach ein bisschen einlesen möchte, kann man sich die Intro-Seiten der verschiedenen Sections anschauen. Wenn man die verschiedenen Pakete brausen möchte, kann man sich je nach Debian-Version das aufschlüsseln lassen und anzeigen. Aber der gebräuchlichste Weg ist wahrscheinlich, dass man schon in etwa weiß, was man dann sucht. Also man möchte die manpage zu einem bestimmten Tool sehen. Und dann kann man hier einfach in das Feld den Namen der manpage eingeben oder den Namen des Programms besser gesagt. Und dann landet man auf der passenden manpage. Selbstverständlich kann man auch über eine Websuchmaschine wie Google zum Beispiel die Seite durchsuchen, wenn man noch nicht genau weiß, was man denn eigentlich sucht. Das ist im Wesentlichen den Inhalt der W3M manpage. Das ist erstmal keine Überraschung. Man kann da so ein bisschen durchscrollen. Sieht okay, es ist so eine manpage, wie man sich das so vorstellt. Aber auf der rechten Seite sieht man dann, da hat man diese verschiedenen Panels. Und in den verschiedenen Panels kann man zunächst auswählen zwischen den verschiedenen Debian-Versionen. Das heißt, die aktuelle old stable, stable, testing und unstable Version von Debian stehen hier zur Verfügung. Wenn ich sage, ich möchte gerne aus testing die manpage lesen, weil mein System auf testing läuft, dann sehe ich hier auch, dass mittlerweile eine neue Sprache dazu gekommen ist. Das heißt, wenn ich nochmal zurückgehe auf die aktuelle stable, da gab es die manpage in englisch und in japanisch. Und in testing gibt es sie jetzt auch auf Deutsch. Wenn ich jetzt hier auf Deutsch klicke, sehe ich sie auf Deutsch. Wenn ich von hier weiter navigieren würde, würde ich immer auf deutschen manpages bleiben. Das heißt, der merkt sich quasi, was man sich gerade anschaut und versucht einen dann der passenden Sprache entlang zu führen. Jetzt können wir noch kurz die japanische aufmachen. Ich weiß nicht, wie viele von euch flüssig sind in japanisch, aber das ist wohl die W3M-Seite. Sie sieht zumindest gut genug aus, was das Encoding angeht. Hier auf der rechten Seite gibt es auch ein Table of contents, was man ausklappen kann und dann zu den einzelnen Sections runter springen kann. Und in dem Panel hier oben gibt es auch noch die raw manpage-Funktionalität. Das heißt, wenn ich zum Beispiel die manpage dann doch irgendwie lokal mir anschauen möchte, aber das Paket nicht installiert habe und das verschiedene Gründen nicht installieren kann, dann könnte ich so einen Befehl hier benutzen und mir dann lokal die gleiche Seite anschauen. Das ist bestimmt manchmal nützlich. So, das also nur als ein kurzer Überblick jetzt und die Details, was da alles so geht und was es sonst noch so gibt folgen jetzt in dem Vortrag. Ich habe vorhin schon angerissen, das Problem wirkt eigentlich nicht so kompliziert. Man muss irgendwie diese manpages aus Debian extrahieren, dann muss man sie nach HTML umwandeln und dann muss man sie an die Endnutzer ausliefern. Soweit so gut. Dann schauen wir uns mal den ersten Schritt genauer an. Zum extrahieren von manpages muss man sich erst mal anschauen, was es in Debian überhaupt für Paketarten gibt. Es gibt sogenannte Source Packages und es gibt binary Packages. Aus den Source Packages werden binary Packages erzeugt, eins oder mehr. Und ein Source Package ist nicht arg viel mehr als ein Taball von der upstream Software, vielleicht noch ein paar Patches, wenn das nötig ist und ein bisschen Meta-Information, wie man in Debian Bildsystem erklären, wie man aus diesem Source Package denn jetzt die entsprechenden binary Packages baut. In anderen Projekten, zum Beispiel in Debian Code Search, wer das kennt, das ist eines meiner weiteren Projekte, werden nur die Source Packages benutzt. Denn in Code Search will man also den Quelltext der Programme durchsuchen, deswegen die Source Packages. Und bei manpages haben wir genau den anderen Fall. Da können wir mit den Source Packages nicht viel anfangen, denn die Software Autos unter euch wissen das wahrscheinlich, viele Projekte haben gar keine Manpages mehr in der Manpage-Quellform in ihren Quellen, sondern generieren diese Manpages. Weil das Format halt nicht so griffig ist und nicht mehr so beliebt ist. Und deswegen benutzen heutzutage Leute irgendwie ASCII-Doc oder DocBook oder was auch immer ihr zum Dokumentieren benutzt und erzeugen daraus dann eine Manpage. Das heißt, wir können nicht die Source Package uns anschauen, sonst müssten wir das ja kompilieren und das ist eine Sache, die wir jetzt nicht anfangen wollen für dieses Projekt, sondern wir nehmen einfach die Binärpakete. Da sind die fertigen Manpages ja schon drin. Beim Runterladen oder beim Durchgehen von diesen Manpages können wir Pakete, die keine Dateien in User-Share-Man enthalten, einfach komplett überspringen. Es gibt auf dem Debian Archiv, also auf jedem Mirror, gibt es eine Dateinnahms-Contents. Und in der Contents-Datei steht eine Liste drin von Dateinnahmen und den Paketen, die diese Dateien enthalten. Die Contents-Datei lädt das Manpage-Programm zuerst runter und es gibt dann einfach alle Pakete, die keine Manpages enthalten. Das ist schön, weil das den Datenverkehr reduziert von 50 Gigabyte auf 10 Gigabyte und dann funktioniert das Programm halt einfach auch viel schneller. Die Binärpakete sind architekturabhängig. Das heißt, wenn ich einen Computer habe mit AMD64 Architektur, dann kriege ich ein anderes Binärpaket vorgesetzt oder installiert als wenn ich einen Computer habe mit i386 Architektur. Die Manpages in dem Paket allerdings befinden sich in User-Share-Man, was ein Architektur unabhängiger Pfad ist. Also der sogenannte File System Hierarchy Standard, der festlegt, wie die Pfadstrukturen auf einem UNIX-Lenungssystem sind. Dieser Standard sagt, in User-Share-Man dürfen nur Dateien sein, die sich zwischen den verschiedenen Architekturen nicht unterscheiden. Da ist jetzt so ein Fußnotenzeichen, weil das natürlich nicht immer der Fall ist. Aber der Punkt ist, wenn es in einem bestimmten Paket nicht der Fall ist, dann ist das ein Bug, eine Policy-Violation und dann kann ich das reporten und dann wird das gefixt. Und das Programm befasst sich also, wo immer es geht mit dem gewünschten Endzustand, wie Pakete eigentlich in Debian sein sollten und versucht so wenig wie möglich Workarounds und Clutches einzubauen. Allerdings kommt erschwerend hinzu. Jetzt könnte man natürlich sagen, okay, vielleicht nehmen wir dann einfach nur eine beliebte Architektur, z.B. AMD64 und ignorieren einfach alle anderen Pakete. Aber das kann man nicht machen, denn es gibt manche Pakete nur für wenige Architekturen. Ein Beispiel dafür ist Zetsnes, ein Super Nintendo-Emulator, den gibt es nur für i386-CPUs. Und deswegen müssen wir also den Zusammenschluss aller Architekturen verarbeiten. Das heißt, wenn das Programm läuft, dann liest es sich tatsächlich alle Architektur-Dateien durch und sagt dann, okay, folgende Pakete kriege ich alle aus AMD64 und dann habe ich hier noch ein paar, die sind aus i386 und hier noch ein paar, die sind von K-Freebills, die i386, was auch immer. Da gibt es ganz viele Kombinationen, aber dadurch ist eben, also das ist eben einer der Schritte, der sicherstellt, dass unser Mainpage-Archiv auch tatsächlich komplett ist. Ich habe am Ende des Vortrags noch eine Übersicht, wo wir vergleichen können, wie andere Mainpage-Seiten das Hand haben und da werdet ihr sehen, dass nicht alle Architekturen berücksichtigen. So, jetzt habe ich schon gesagt, dass sich die Mainpages in User-Share-Main befinden. Jetzt können wir uns mal die Dateistruktur anschauen. Ich habe hier auf die Folie gepackt quasi einen Schema, wie das aufgebaut ist. Man hat unterhalb von User-Share-Main gegebenenfalls einen Unterordner, der die Sprache der Mainpage bezeichnet. Dann hat man einen Mainordner, der die Section beinhaltet, sowas wie Main1 oder Main5. Dann hat man die eigentliche Mainpage, also der Name der eigentlichen Mainpage-Punkt und dann nochmal die Section-Nummer, die ist also zweimal in so einem Pfad encodiert und dann gegebenenfalls am Ende noch Punkt GZ, weil das komprimierte Dateien sein können. Ein paar Beispiele dafür. Die Weget-Mainpage findet sich in User-Share-Main, Main1, Weget.1.GZ. Es gibt aber auch komplizierte Beispiele, zum Beispiel, wenn man französische Mainpages sich ansieht. Die IW-List-Mainpage aus der Section 8 findet sich unter fr.iso8859-1, also das Encoding steckt da auch noch drin. Und dann gibt es noch exotischere Ortsangaben, wie zum Beispiel CA et Valencia. Das muss man also alles berücksichtigen. Jetzt kommt nicht nur hin zu, dass das alleine schon kompliziert genug ist, sondern in Debian, wenn man sich mal anschaut, welche Mainpages es tatsächlich gibt, wird man feststellen, oh, da gibt es ja allerlei unsinnige Pfade. Es gibt zum Beispiel Dateien, die befinden sich in dem Ordner main-slash-pi-slash-main1, aber pi ist kein Code für eine Sprache, sondern pi kommt einfach von der Python-Datei-Erweiterung und die Debian-Package-Helper installieren da fälschlicherweise die Dateien in falschen Ordner. Das ist der Fall, bei dem man in den jeweiligen Paketen fixen muss. Ich habe die alle reported und die werden jetzt so nach und nach gefixt. Es gibt auch Dateien, die das falsche SUFIX haben. Zum Beispiel befinden sich in manchen main-1-Ordnern Dateien, die auf Punkt 3, Punkt GZ enden. Die sollten aber auf Punkt 1, Punkt GZ enden. Das sind alles so Leichzensfehler oder Sachen, die halt nicht aufgefallen sind beim Paketieren. Das muss man dann jeweils in den Paketen fixen. Und da gibt es noch mehr Sachen, aber ich will dir jetzt nicht alle lang und breit durchkauen. Auf der Folie ist der Link. Da könnt ihr euch das selber anschauen, wenn es interessiert. Das Encoding habe ich gerade schon angerissen. In dem Fall von den französischen Main-Pages, da steckte das drin in diesem einen Ordner. Der Default für Main-Pages ist tatsächlich ISO 8859-1. Aber für jedes Sub-Directory gibt es nur einen Default. Das heißt, ungarische Main-Pages nutzen zum Beispiel ISO 8859-2. Natürlich kann man diese dann auch nochmal über die Sub-Directories überschreiben. Das hatten wir ja gerade als Beispiel französisch mit ISO 8859-1. In der Praxis ist es jetzt allerdings so, dass trotz der Tatsache, dass der Default eigentlich feststreibt, dass man ISO 8859-1 benutzen soll, 98,8% aller Main-Pages in UTF-8 encodiert sind. Deswegen haben wir uns entschieden, dass unser Main-Page-Programm, welches DB-Main heißt, beim Einlesen einfach alles in UTF-8 umwandelt. Das heißt, am Anfang hatte ich noch überlegt, so, ah, sollen wir überhaupt nicht UTF-8 unterstützen, aber 98,8% das ist nicht viel genug, als dass man das einfach unter den Teppich kehren könnte. Und die Idee ist also, dass wir später alles irgendwann mal in UTF-8 haben, aber das ist ein anderes Projekt. Also, dass man einfach irgendwann mal sagt, hey, Main-Pages in Debian müssen grundsätzlich UTF-8 encodiert sein, weil sonst muss man halt in jedem Tool wieder diese Logik implementieren, um zu schauen, welches encoding ist das jetzt und dass dann umwandeln und vielleicht gibt es da Fehler beim umwandeln, das ist alles hässlich. Zusätzlich habe ich ein paar Sachen über Main-Pages gelernt. Es gibt zum Beispiel ein Mechanismus, der mir vorher gar nicht so klar war und das ist der sogenannte SO-Mechanismus. Das steht für See Other und das ist quasi einfach ein Include-Mechanismus. Das heißt, Main-Pages können andere Dateien einbinden, das wird gelegentlich genutzt für Header- und Futterfragmente, also Sachen, die in allen Main-Pages gleich sein sollen, wenn ihr zum Beispiel eine umfangreiche AP-Dokumentation habt, für Software, die in C geschrieben ist, das ist häufig so, dass AP-Dokumentation in Form von Main-Pages ausgeliefert wird und dann haben die eigentlichen Beschreibungen von den Funktionen, aber der Anfang und das Ende ist bei manchen Libraries immer gleich und das machen die über diesen Mechanismus, dass man den Content nicht duplizieren muss. Der Main-Page-Viewer, den ihr in eurem Terminal verwendet, benutzt einen Programm namens ZSOElim, das ist ein super griffiger Name, wofür das steht, ist für See Other Elimination und das Programm ist relativ kurz, das macht nichts anderes als zu schauen, ich habe hier eine Punkt SO-Direktive, dann schaue ich, welche Datei da angegeben wurde und lese die ein und gebe die aus. Interessant ist aber zu bemerken, dass im Fehlerfall die Ersetzung nicht eine Fehlermeldung ausgibt, sondern es wird einfach nichts eingesetzt und tatsächlich gibt es mindestens ein Paket mit fehlerhaften SO-Direktiven, das ich gefunden habe, ich glaube noch ein paar andere und wenn man also Fehlermeldungen ausgibt, dann hat man Main-Pages, die gegebenenfalls voll von Fehlermeldungen sind, die man dann nur bei uns sehen würde und den anderen Main-Page-Viewer nicht, das heißt, wir haben uns auch entschieden, okay, den Fehlerfall müssen wir genauso implementieren, muss einfach dann nichts eingesetzt werden, wenn es die Main-Page nicht gibt, oder das Fragment nicht gibt. So, jetzt haben wir also abgedeckt, wie wir aus Debian Binärpaketen die Main-Pages rausbekommen und jetzt müssen wir sie ja irgendwie nach HTML umwandeln. Backend für Groff namens GroHTML, der Link führt zu dem Paper, das Paper ist interessant, sich durchzulesen, ist aber auch schon ein paar Jahre alt und GroHTML hat die Eigenheit oder hatte das Ziel viel besser gesagt, das ist eine vollständige Repräsentation von Main-Pages in HTML erzeugt. Und wenn man sich jetzt anschaut, was Main-Pages für einen Format haben, dann sieht man, dass die halt so Druckerdirektiven haben. Also so Sachen wie, ja, ihr müsst irgendwie hier so eine Eindrückung machen und dann soll da das hingemalt werden und ein paar Pixel auf der linken Seite jetzt zurück und dann nach unten und dann da einen Bullet-Point hinmachen, um Listen zu implementieren. Also da ist halt nicht mehr viel mit Semantik, sondern das ist wirklich nur Anzahl-Gelähe. Die Art und Weise, wie GroHTML das jetzt abgedeckt hat, ist, dass sie gesagt haben, na gut, dann suchen wir uns halt einfach das passende HTML, um genau so eine Positionierung zu ermöglichen. Und wann immer es da kein passendes HTML für gibt, dann werden einfach alle HTML-Tabellen verwendet. Also keine Semantik-Tabellen, sondern Tabellen zum Positionieren oder gar Bilder. Also manchmal ist es so, dass das GroHTML-Programm dann tatsächlich einfach eine Bildartei generiert und die dann einbindet. Das ist natürlich schlecht, weil die Bilder eine spezifische Auflösung haben und dann funktioniert zum Beispiel auf einem Retina-Display die Seite anders als auf einem normalen Display und alles wird blurry oder nicht blurry oder man muss zu viele Daten laden und überhaupt eigentlich Main-Pages es sei denn, da werden Bilder tatsächlich eingebunden. Das war also keine sehr befriedigende Lösung außerdem dauert es recht lang mit GroHTML diese Main-Pages eben umzuwandeln. Der zweite Versuch, als ich dann so ein bisschen weiter recherchiert hab, was man denn so nehmen könnte, war ein Programm namens DocLifter. Was DocLifter macht, ist, es wandelt Main-Pages nach DocBook. Und jetzt könnte man sich fragen, okay, moment, du hast gerade gesagt, dass Main-Pages nicht semantisch sind, dass sie in DocBook wandeln, weil DocBook ist ja nur Semantik und keine Präsentation. Und die Antwort ist, dass DocLifter da einfach versucht, ganz viele Heuristiken anzuwenden und zu sagen, ah, das sieht ungefähr so aus, das wird wohl das gemeint gewesen sein und es hat tatsächlich auch Unterstützung für relativ viele verschiedene beliebte Generatoren von Main-Pages. Ein kleiner Twist an der Sache ist jetzt natürlich, dass wenn wir diese Architektur genommen hätten, dann könnte es sein können, die Main-Pages als DocBook schippen, sie dann in Main wandeln, um sie wieder zurück nach DocBook zu wandeln, um sie dann nach HTML zu wandeln. Zum einen ist das irgendwie ein unschönes Design, zum anderen funktioniert DocLifter auch tatsächlich gar nicht mit so vielen Paketen. Auf der Website von DocLifter wird angegeben, dass die Erfolgsquote irgendwas um die 80% ist oder so, aber die Angabe ist schon ein paar Jahre alt. Und wenn man sich das heutzutage anschaut, dann ist die Erfolgsquote, die ich gemessen habe, gerade so ein bisschen über 50%. DocLifter ist zusätzlich auch noch ziemlich langsam und ist in einem relativ alten Python 2.7 implementiert, wo das mit dem Encoding noch nicht so gut funktioniert hat. Das ist also mit UTF-8 Main-Pages kommt das teilweise auch nicht klar. Das ist also alles nicht so schön. Und letztendlich haben wir dann aber noch ein drittes Programm gefunden, welches man benutzen kann, um Main-Pages umzuwandeln. Und dieses Programm heißt Main-Doc. Main-Doc ist ein Rewrite von einer Main-Implementation von den OpenBSD-Leuten. Also die haben von Grund auf einfach das Ganze noch mal neu implementiert und haben sich gesagt, statt irgendwie die volle Bandbreite von ROF zu unterstützen, unterstützen wir jetzt die Direktiven, die Leute tatsächlich auch in Main-Pages verwenden. Die haben auch ein eigenes Macroset sich definiert für Main-Pages und die allermeisten Main-Pages in OpenBSD selbst benutzen, dieses moderne Macroset. Main-Doc kommt aber auch mit alten Main-Pages klar. Und das Schöne ist, dass Main-Doc super schnell funktioniert. Es ist in C geschrieben eine moderne Implementation vor allem. Es produziert semantisches HTML5 und die Kompatibilität ist ziemlich hoch. Also ich will nicht behaupten, dass alle Main-Pages einwandfrei damit umgewandelt werden können, aber die allermeisten können damit super umgewandelt werden. Jetzt hatten wir allerdings ein interessantes Problem. Für Main-Doc wollten wir einen Batch-Modus implementieren, denn die Art und Weise, wie man Main-Doc benutzt ist, wie man viele andere Programme benutzt. Das heißt, man gibt über Standard-Input Engabereien. Wenn es Fehler produziert, dann wirft es die nach Standard-Error und ansonsten wirft es die fertige Seite nach Standard-Out. So weit so gut. Das Modell kennt ja jeder. Wenn man jetzt einmal komplett Debian extrahiert und umwandeln möchte, dann hat man dabei 470.000 Main-Pages und das Ganze dauert 2 Stunden, das umzuwandeln. 2 Stunden auf einem relativ modernen Computer. Wenn wir das tatsächlich auf der VM laufen lassen würden, die wir letztendlich benutzen, würde das deutlich länger dauern. Wenn man sich jetzt anschaut, was das System macht, wird man feststellen, dass der Prozessor größtenteils eigentlich nichts zu tun hat. Der ist irgendwie 1 oder 2% Nutzertzeit CPUs-Lastung. Größtenteils ist hier einfach Forekondexec Overhead. Also das Modell, das man für jede Main-Page in einem eigenen Prozess startet, der dann über Standard-In, Standard-Out und Standard-Error kommuniziert, funktioniert einfach nicht sonderlich performant. Und dann habe ich mich gefragt, was ist die eleganteste Art und Weise, Main-Doc'enden Batch-Modus zu verpassen. Wenn ich mir den Vortrag bis hierhin langweilig finde, dann ist das okay. Aber der Trick, den ich jetzt zeige, auf den bin ich relativ stolz und ich glaube, den kann man in ziemlich vielen Programmen verwenden. Also wenn ihr sonst nichts lernt, dann nehmt den Trick mit. Was ich letztendlich implementiert habe, ist, dass man ein zusätzliches Programm hat, nicht mehr Main-Doc an sich, sondern Main-Doc D, aber das ist egal, ob man das jetzt in das gleiche Programm implementiert oder sagt, ich will das sauber getrennt haben. Jedenfalls, was das Programm anders macht, als die Standard-Main-Doc-Implementation, ist, dass man die Daten erwartet, einen Socket vererbt zu bekommen. Das heißt, im Elternprozess, also in unserem debimaren Umwandlungsprogramm, erstellen wir mit der Socket-Pair-Funktion einen Socket-Pair, also einen, der im Parent bleibt und einen, der an Main-Doc weitervererbt wird. Und über diesen Socket schicken wir dann File-Descriptors. Das heißt, man kann über einen Socket nicht nur Bytes schicken, nicht nur Text oder Binaire-Daten, sondern man kann auch File-Descriptors und das wissen manche Leute auch gar nicht. Aber das ist ein cooler Trick. Was wir damit machen können, ist, dass wir Standard-In, Standard-Out und Standard-Error aus dem Parent in den Child stecken können, der schon gestartet ist, also der nicht noch mal forken und exhecken muss, sondern der dann einfach sagen kann, ah, da kam eine neue Nachricht, ich packe mal die totalen File-Descriptors aus, ich verarbeitete die Main-Page und dann warte ich auf die nächsten File-Descriptors. Und ich habe hier die Main-Pages referenziert, mit denen man das machen kann, um das C-Message, also Control-Messages, für die Sockets, damit man die File-Descriptoren vererben kann und Dub 2, also Duplicate, um die File-Descriptoren mit den passenden Descriptornummern zu ersetzen. Die Implementation davon habe ich sowohl in Debimann, also die Elternseite, als auch in Mandrock selbst, also die Kindseite, verlinkt auf den Folien und ihr werdet sehen, dass das irgendwie zwei Bildschirm-Seitencode ist. Also wenn ihr ein altes Programm habt, könnt ihr diesen Trick verwenden, um es quasi in einem lang laufenden Modus relativ schön einfach schneller zu machen. So, jetzt zurück zum eigentlichen Umwandeln von Main-Pages nach HTML. Es gibt Cross-References in Main-Pages, das hat sicherlich jeder schon mal gesehen, dass man irgendwie eine Main-Page liest und dann wird dann der Name von einer anderen Main-Page erwähnt und das Format dafür ist üblicherweise, dass man eben in Klammern die Section packt, also sowas wie in W3M, dann sieht man irgendwie eine Referenz auf sagen, wer Grund hat, Klammer auf fünf Klammer zu. Allerdings gibt es dafür kein verbreitetes Markup. Wie vorhin auch wieder, die Idee hinter Rhoff ist eben Präsentations-Layer und nicht Semantik-Layer, d.h. es gibt verschiedene Arten und Weisen, wie man eben so eine Cross-Reference ausdrücken kann und Verlinkungen gibt es nicht. Wir wollten das aber natürlich verlinken, weil wenn man das schon in einem Browser liest, dann wäre es doch schön, wenn man einfach draufklickt was man machen muss, ist, dass man die Formatierungs-Direktiven ignorieren muss. Also wenn manche Leute z.B. den Section-Namen in Italik machen oder andere Sachen in Bold oder so, einfach alles komplett wegwerfen und dann schauen, ob man quasi Name-Klammer auf, Section-Klammer zu Sachen findet in der Main-Page und dann kann man die als Cross-Reference direktiven betrachten und entsprechend verlinken. Das erfordert natürlich auch, dass die Namen von allen Main-Pages vor dem Umwandeln schon bekannt sind, das ist jetzt eine Cross-Reference oder das ist keine Cross-Reference, weil es die Seite gar nicht gibt, sondern das sieht nur zufällig so aus wie eine Cross-Reference. Das heißt, dass das Debimann-Programm vorher sich quasi eine komplette Sicht über die Welt erarbeiten muss und erst dann anfangen kann, alles umzuwandeln. Den selben Mechanismus benutzen wir übrigens auch für URLs und es gibt einen interessanten Edge-Case, es gibt nämlich URLs, die wiederum Cross-References enthalten und das passiert nämlich dann, wenn die Autoren von Main-Pages auf einen Online-Main-Page-Viewer reinpacken, was irgendwie total quasi unnötig kompliziert ist. Sie hätten einfach direkt die Cross-Reference reinpacken können, aber das gibt es tatsächlich in Main-Pages und das soll natürlich auch funktionieren. Für die Table of Contents, die ich schon demonstriert hatte, an der rechten Seite gab es ja dieses Menü, wo man dann auswählen konnte, suchen wir einfach nach H1 bis H6-HTML-Elementen, also alle Arten von Überschriften und generieren dann eine passende ID dafür. Das, was ich regelärmt habe, ist, dass HTML5-IDs tatsächlich sehr wenig Restriktionen haben. Die Regeln dafür sind at least one character, no spaces, das ist einfach genug, das heißt, alle Spaces ersetzen wir durch Anderscores und dann encodieren wir das als URL-Fragment und dann ist man auch schon fertig, also so kann man HTML5-IDs erzeugen. Jetzt kommen wir dazu, wie wir diese Main-Pages, die wir jetzt aus den Binärpaketen rausgeholt haben und die Endnutzer ausliefern und ein wichtiger Teil davon ist, wie die URLs strukturiert sind. Bei Main-Pages.debieren.org ist es so, dass man jeden Teil von dem URL-Schema, das ich jetzt vorstellen werde, weglassen kann, außer natürlich den Namen von der eigentlichen Seite. Das heißt, der Name muss immer da sein, dann kann man mit einem Punkt getrennt die Section angeben und nochmal mit einem Punkt getrennt die Sprache. Man kann zusätzlich das Binärpaket, also die Version von Debian aus der sie extrohiert wurde. Ich habe hier ein paar Beispiele dafür, das ist quasi der einfachste Fall, wenn man nur den Namen angibt, also Main-Pages.debieren.org. Aber man kann das dann quasi immer spezifischer machen. Man kann zum Beispiel sagen, ich möchte verlinken auf die E3-Main-Page, aber auf die E3.1-Main-Page, also die Main-Page für das Programm und nicht für irgendwelche Konfigurationszerteilen und für genau die Version, die aktuell in Debian stable ist. Ich möchte auf die Version verlinken, die in Kürze zu Debian stable gehört, nämlich stretch und die dann auch für die kommenden Jahre gültig bleibt, dann nimmt man diesen dritten Link. Und der vierte Link ist quasi der Vollständigkeit halber, wenn man auch noch angeben muss, aus welchem Binärpaket man diese Main-Page hat. Denn Cronthub ist ein Fall, der in sehr vielen verschiedenen Binärpaketen vorkommt. Da hat man verschiedene Möglichkeiten, welche Cron-Implementation man in Debian benutzen möchte und dann muss man das auch angeben. Wenn man Permalinks benutzen will, also wenn ihr jetzt sagt, ich möchte einen Link auf eine Main-Page setzen, dann solltet ihr am besten die Sprache weglassen. Das macht der Permalink-Button, den ihr auf den Main-Pages findet, auch automatisch für euch. Dann kann nämlich Main-Pages Debian org die richtige Sprache automatisch wählen für die Nutzer, die sich die Seite dann anschauen. Die eigentliche Auslieferung oder der redirect quasi von, wenn ihr eine URL angebt, die nicht vollständig ist, also die nur einen gewissen Teil enthält, ist hier verlinkt auf der Folie, also die Implementation, das ist ein relativ ausführlicher Mechanismus. Was der im Wesentlichen macht, ist, der schaut sich an, welche Teile habe ich schon und für die Teile, die noch fehlen, füllt er sie dann so nach und nach ein und quasi ist quasi wie so ein Tunnel und wird immer schmaler und am Ende bleiben nur noch ein paar Main-Pages übrig und er gibt dann die passende raus. Ich würde sagen, dass Debian im Wesentlichen den großen Corpus an statischen Seiten generiert. Das heißt, um die Seite auszuliefern oder um die Seite zu stützen, braucht man einfach nur einen Web-Server und einen Verzeichnis, in dem diese ganzen Seiten leben. Alle Seiten, die ihr gesehen habt in der Demo, sind einfach statische Websites. Dieser redirect Mechanismus allerdings ist natürlich dynamisch. Man kann da nicht alle Kombinationen, was man im Voraus berechnen könnte, im Voraus berechnen, das wäre unnötig kompliziert. Sondern das ist ein dynamischer Mechanismus, also auch kein Web 1.0 mehr und der lebt deswegen in einem separaten Server-Programm. Die Entscheidung kommt daher, man könnte jetzt natürlich auch sagen, gut, dann macht doch einfach ein großes Server-Programm, welches dann auch die statischen Seiten ausliefert. Aber der Vorteil von so einer zweigeteilten Hierarchie ist eben, dass man eine sogenannte Graceful-Degredation hat. Das funktioniert, wenigstens das Ausliefer der statischen Seiten immer noch. Und wenn zum Beispiel Leute über irgendwelche Links oder irgendwelche Suchmaschinergebnisse auf unsere Seite kommen, dann sehen sie immer noch die passenden Main-Pages. Selbst wenn die Redirects nicht mehr gehen sollten. So, diese Redirector macht auch eine Spracherkennung, wie ich gerade schon angedeutet habe. Und das passiert über den Accept-Language-HRTP-Header. Also euer Browser schickt an jede Seite, die ihr aufruft, einen Header mit und das kann man in den Einstellungen vom Browser einstellen. Und was dann letztendlich generiert wird in diesem Beispiel hier ist, sind so Paare von quasi Qualitätswerten oder Präferenzwerten, würde ich eher sagen. Hier sieht man zum Beispiel Französisch, wie es in der Schweiz gesprochen wird. Oder Französisch hat den Prioritätswert 0,9, ist also ganz oben. Ansonsten Englisch und ansonsten geht Deutsch auch. Und wenn das nicht klappt, dann gibt wenigstens irgendeine Seite aus in irgendeiner Sprache. Da kann der Nutzer ja dann doch noch was damit anfangen. Und das unterstützt eben der DB-Man Aug-Server für den Redirect, also der schaut sich das an und macht dann einen vollständigen Language-Match. Das heißt, auch wenn jemand herkommen würde und sagen würde, ah, ich möchte Französisch haben oder in diesem Fall von unserem Beispiel, wenn jemand in Norwegen mit einem norwegisch eingestellten Browser herkommt und eine Seite anfordert, für die es keine norwegische Übersetzung gibt, dann kann das Programm feststellen, ah, dann kann man das dann auch verstehen und liefert einem dann immerhin noch die dänische Seite aus. Zusätzlich haben wir ein OpenSearch.xml-Datei. Die OpenSearch.xml-Datei ist eine Beschreibungsdatei für Suchmaschinen, aber nicht für Internet-Suchmaschinen, sondern für die Suchmaschinen, die ihr in eurem Browser-Adress fällt habt. Das heißt, wenn ihr Keyword-Search benutzt oder den Namen von der Seite eingebt in Chrome zum Beispiel, also wenn ihr man p und dann tap drückt, dann könnt ihr einfach den Titel von der Seite eingeben, oder aufrufen wollt, z.B. WGED oder W3M und dann Enter und dann kommt ihr direkt auf die passende Seite. So, jetzt haben wir die Features in etwa abgesteckt, jetzt kommen wir zur Laufzeitumgebung. Die manpages.debian.org wird generiert komplett auf Debian-Infrastruktur, deswegen auch der .org-Domainname und nicht der .net-Domainname, das ist der Unterschied, also .net ist was irgendwelche Random-Entwickler da gerne mal ins Internet stellen würden, aber .org ist quasi ordentlich und langzeitmaint. Dafür haben wir eine VM, die heißt Manciali und die läuft auf einem HP-Blade-System bei Bitemark-Costing in den UK. Die CPU, die dort drin steckt, ist ein AMD-Opteron der 23XX-Serie und die kam 2008 bzw. 2009 auf den Markt, ich weiß nicht genau, welches Modell das ist, aber da habt ihr eine Größenordnung für, wie alt diese CPU ist. Wir haben zwei Gigabyte RAM zugewiesen der VM und die Storage ist irgendwie so ein HP-Blade-System, Storage-Ding, die Größenordnungen, um die es hier geht, ist Minuten auf meiner Workstation und Stunden auf dieser VM. Die genauen Messwerte habe ich da auch noch mal verlinkt. Jetzt könnte man sich allerdings fragen, warum erzählst du überhaupt hier von der Geschwindigkeit, das ist eigentlich nicht so wichtig, oder wie oft ändern sich denn die Marnpages? Aber für mich ist das schon wichtig. Zum einen ist mir wichtig, dass wenn neue Marnpages nach Debian kommen, sie schnell zur Verfügung stehen, also dass wenn ihr irgendwie ein Paket hochladet mit einem Fix, dann könnt ihr sich schnell im Web zu sehen sein. Aber zum anderen gibt es auch noch zwei andere interessante Gründe, weswegen Geschwindigkeit hier wichtig ist. Das eine ist Disaster Recovery. Ihr könnt euch vorstellen, wenn wir irgendwie einen Korpus haben von Millionen von kleinen Dateien, die alle irgendwie nur ein paar Kilobytes höchstens groß sind und man einen Backup-Programm auf diesen Korpus loslässt, dann skaliert das nicht unbedingt gut. In Debian benutzen wir Backular und quasi die Zeit, die man bräuchte, um alles zu sichern und wieder zu restoren, ist größer als die Zeit, die man braucht, um es neu zu erzeugen. Das heißt, für Disaster Recovery haben wir keine Backups von diesem Korpus, sondern wenn uns die Kiste stirbt, dann würden wir einfach einen neuen Durchlauf machen. Und der zweite Grund, warum das eine gute Sache ist, dass das alles schnell funktioniert, ist die Developer Velocity. Also wenn jemand von euch jetzt herkommt und sagt, ich möchte daran mitentwickeln, dann wäre das eine große Einstiegshürde, wenn ich jetzt sagen würde, okay, wir laufen und in fünf Tagen reden, wir dann wieder miteinander, sondern das soll so funktionieren, dass ihr relativ schnell loslegen könnt und einfach schnell einen kompletten Debian Unstable oder Experimental oder was auch immer ihr zum Testen verwenden wollt, umwandeln könnt. Der nächste Punkt, auf den ich kurz eingehen möchte, ist das DSA, das Debian System Administrators Team ausschließlich Apache 2 benutzt. Also kein Engine X, kein Lighty, keine anderen Webserver, sondern immer nur Apache 2. Ich hatte ursprünglich ein Debian-Config, und habe dann eine Apache 2-Konfiguration erstellt, damit wir das deployen konnten auf mann-pages-debian.org. Allerdings, die Apache 2-Konfig ist nicht so elegant wie die Engine X-Konfig, und nachdem ich euch jetzt diesen Teil noch erkläre, schauen wir uns auch noch einen Konfig-Auszug an. Wie das letztendlich funktioniert, ist das auf der VM, die ich gerade erwähnt habe, der komplette Corpus generiert wird, aber er wird dort nicht an die Nutzer ausgeliefert, sondern er wird dann erst nochmal verteilt. Und dazu gibt es ein sogenanntes Static Mirroring Setup, das hat Peter Palfrada gebaut für Debian und auch für das Torprojekt, dort wird das auch verwendet. Und das benutzt im Wesentlichen AirSync und verteilt Websites und auch andere Daten auf verschiedene Server. Und das Schöne an der Nutzung dieser Infrastruktur ist, dass für geplante Wartungsarbeiten wir keine Downtime haben, sondern da wird im Vorfeld der DNS-Record angepasst. Das heißt, wenn ihr euch genau anschaut, wohin mann-pages.debian.org zeigt, dass es nicht auf drei verschiedenen Servern zu finden ist, sondern nur auf zwei verschiedenen Servern und der dritte wird gerade gewartet. Das heißt, für Kernel Updates und andere Sachen, die halt häufig passieren, haben wir keine Downtime. Das ist schon mal gut. Das ist schon mal ein deutlicher Fortschritt zu dem vorherigen Setup. Und für dieses Setup haben wir eben Debian angepasst, damit es gut damit funktioniert. Ich habe ja schon erklärt, der eigentliche Teil sind eben diese statischen Websites. Wir haben dann den dynamischen Teil auch hinter den anderen DNS-Namen gepackt. Und wir haben uns aber auch entschlossen, dass wir die redirects nicht nur im dynamischen Teil haben wollen, sondern zumindest zu einem Großteil auch quasi auf allen statischen Servern abhandeln können wollen. Dafür müssten wir also jetzt die Funktionalität, die der Debian Augserver bereitstellt, in Apache 2-Configs neu implementieren, also mit Rewrite Rules und so was. Und wie wir das gemacht haben, ist, dass wir ein Feature von Apache 2 benutzen, das nennt sich Rewrite Maps. Das ist quasi einfach ein Key Value, PERS, also so eine, es ist tatsächlich ein Datenbankformat, also Berkeley DB kann man da verwenden oder auch andere Formate. Und da kann man dann quasi schauen, wenn ich jetzt hier diese Anfrage habe, wohin soll das gehen. Und wir wandeln also den Index, den Debian erstellt in das passende Format um. Wir machen das hier parallelisiert und sortieren das dann und fügen das wieder zusammen. Und dann kommt man an die dritte Instruktion und fragt sich, okay, was passiert dort? Das sieht aus wie Exploit, Shellcode oder so was. Aber was wir hier machen, ist wir erzeugen eine leere Berkeley Datenbank, allerdings mit nem Datenbankformat, welches sich besser eignet für die spezielle Indexdatei, die wir hier haben. Denn der Standard ist irgendwie ein Datenbankformat, welches halt irgendwie gut funktioniert. Man fügt später irgendwie noch neue Paare hinzu und so, und dann funktioniert das gut. Aber wir haben ja einen speziellen Anwendungsfall. Wir haben einmal immer diese Batch-Durchläufe, in der diese Datenbanken komplett neu generiert werden gefasst. Blöderweise kann man in dem HTTX-T2-DBM-Tool, welches das Apache-Paket mitbringt, das nicht angeben. Sondern das macht immer nur das Datenbankformat, welches für uns nicht gut ist. Allerdings ist es so, dass wenn man dem Tool ne Datenbank gibt, die schon existiert, die das gute Format hat, dann nimmt es dir auch. Das heißt, dieser Base64-Block, den ihr da seht, ist quasi ne leere Berkeley Datenbank in dem passenden Format. Damit erzeugen wir ne leere Datei und die Datenbank. Hier kommt jetzt quasi der schrecklichste Teil des ganzen Projekts, nämlich die Redirect-Konfiguration in Apache 2. Und hier habe ich jetzt mehrere Abende stundenlang einfach nur Apache-Doku gelesen zu Mod Rewrite und allen möglichen anderen Apache-Features und dem Web irgendwie Posts durchgelesen. Und ich glaube, zu dem Zeitpunkt, als ich das geschrieben habe, konnte ich wirklich jedes Feature benennen und also hier wird quasi jedes Regular-Expression-Feature einmal benutzt, was Apache zu bieten hat in diesem Modul. Und das ist auch nur der Proof-of-Concept. Die fertige Implementation ist deutlich länger. Ich habe den Link auf die Folien gepackt, wenn sie das jemand geben will. Aber ich würde quasi die These aufstellen, dass Mod Rewrite-Konfiguration Touring vollständig ist. Also wenn ihr einen Compiler bauen wollt, ihr irgendwie Sachen nach Mod Rewrite kompiliert, ich glaube, das wäre machbar. Gut, es muss aber auch alles gar nicht verwendet werden. Ich habe hier jetzt mal auf der linken Seite der Folie die Engine X-Konfiguration gepackt und auf der rechten Seite das System-De-Service-File, wie man den Augserver starten kann. Ihr seht also, man hat im Wesentlichen den Corpus von ganz vielen statischen Websites. Man hat diesen Debut, wie man Augserver den man so betreiben kann. Und einen Engine X-Konfig-File und dann ist man auch schon fertig. Wenn jemand eine Instanz von diesem Anwendungsfall oder irgendwie in der Cloud Deployen oder so, es ist unfassbar einfach, weil es handelt sich wirklich nur um statische Websites und diesen einen zusätzlichen Endpunkt. Als Fazit habe ich hier nochmal den Vergleich. Ich habe mir ein paar Mainpage-Websites auch angeschaut. Wenn man sich also das mal vergleicht und in so einer Tabelle auflistet, ich habe hier ein paar Testfälle rausgesucht, dann sieht man, wie die sich so im Vergleich schlagen. In dieser Tabelle ist quasi eine Datei, die es in ganz vielen verschiedenen Binärpaketen gibt. Wie ihr seht, ist auf allen anderen Mainpage-Seiten, die ich getestet habe, hat man Zugriff auf genau eine dieser Chrontab-Versionen, weil die eben in dem URL-Schema auch gar nicht abgebildet haben, dass man mehrere Binärpakete haben könnte, die die gleiche Mainpage enthalten. Und jetzt kann man sich anschauen, wo die Mainpage sie weil es herkommen. Man sieht zum Beispiel, dass der Ubuntu-Mainpage-Converter die auf der Hurricane Electric-Mainpage-Seite ist aus irgendeinem BSD rausgekommen und man 7.org benutzt irgendwie eine relativ unbekannte Implementation davon. Dann habe ich noch ein paar andere Testfälle. GBP.1 ist die Mainpage für Git-Build-Package, also ein Debian spezifisches Tool. Man sieht, dass die in den allermeisten Mainpage-Archiven halt einfach gar nicht drin ist. Und in dem einzigen Non-Debian-Archiv, in dem sie drin ist, Main.cx, ist sie aus Debian-Stable genommen, also auch schon nicht mehr so aktuell. Java FX-Packager ist ein interessanter Fall deswegen, weil die Mainpage nicht in User-Share-Main lebt. Stattdessen lebt in User-Share-Main ein Sim-Link auf eine Mainpage, die sich woanders befindet. Das ist anscheinend schon so ein Edge-Case, dass denen keine andere Seite abgedeckt hat. Zetsnes war das Paket, was wir vorhin als Beispiel hatten, für i36 spezifisch. Wie ihr seht, die Debian Ubuntu und Main.cx-Seiten enthalten denen, die anderen Mainpages haben den schon gar nicht. Tophead.1 ist das analoge Beispiel von Main.cx und Main.cx haben die 64 only, statt i36 80 only. Dann W3M.jah, das ist die japanische Seite, die japanische Version von W3M im Debian-Archiv ist die ordentlich drin, auf Main.cx auch, auf den meisten anderen fehlt sie und auf Ubuntu ist das in Coding kaputt. Und die deutsche W3M-Website ist die, von der ich gesagt habe, dass sie erst später hinzugekommen ist, also erst in Testing, die haben wir in Debian und auf Ubuntu. Als Fazit möchte ich also ziehen, dass wir es geschafft haben, das vollständigste Mainpage-Archiv, was man derzeit im Internet finden kann, meines Wissens nach zu erstellen. Das heißt, ich würde euch ans Herz legen, das dafür auch zu benutzen, wenn ihr also Mainpages habt, dann setzt doch ein Link da drauf und benutzt die Seite schnell, sie sieht attraktiv aus, sie funktioniert gut auf Smartphones und auf Tablets und wenn es neue Mainpages gibt, dann wandern die Leute ein bisschen über Go-Sprechen. Wir haben nämlich das komplette Projekt in Go implementiert. Das liegt einfach daran, dass Go meine aktuelle absolute Lieblingssprache ist, wer gestern den Vortrag von mir gesehen hat, weiß auch schon, dass das so ist. Das Schöne daran ist, dass die Funktionalität, die wir brauchen, größtenteils implementierbar ist mit der Standard-Library, das einzige zusätzliche oder die signifikanten zusätzlichen Pakete, die wir benutzen, sind das und die Charakter-Maps und Umwandlungen dessen befasst und Netz-Lash-HTML, welches eben HTML-Paser beinhaltet, damit wir diese Überschriften daraus fummeln können und solche Sachen und von Paul Tech, ein anderer Debian- Entwickler, die entsprechenden Debian Support Libraries für Go, damit wir Debian-Pakete aufmachen können und so was. Das Schöne an Go ist insbesondere auch, dass man Nebenläufigkeit einfach umsetzen kann. Das heißt, das Debian-Programm, wenn man das laufen lässt, erreicht man möglicherweise die maximale Ressourcen Ausnutzung in dem jeweiligen Schritt. Das heißt, im ersten Schritt, wenn alle Marnpages runtergeladen werden, also alle Marnpages extrahiert werden sollen aus den Debian-Paketen, ist die Leitung einfach komplett dicht. Also selbst wenn ihr eine Gigabit-Leitung habt, die ist dicht. Anschließend, das Entpacken der Marnpages, ihr habt alle CPU-Kurs in Benutzung und eure Festplatte, so viel wie geht, wird benutzt. Anschließend muss natürlich geschaut werden, gerade auch bei einem Schöne, der sich jetzt eigentlich geändert. Welche muss ich neu generieren? Und das funktioniert für diese Millionen an Dateien in weniger als 3 Sekunden auf einer schnellen SSD, was ein super guter Wert ist, den ihr mit Tools wie Feind oder so auch nicht hinbekommt. Und quasi in diesem Schema so egal, wo man schaut, das Bottleneck ist immer das Bottleneck, was man erwarten würde. Also wenn man sich quasi theoretisch überlegt, so ah, wo müsste jetzt dieser Programmschritt langsam sein, dort ist er auch langsam. Es gibt also keine unnötigen Bottlenecks zu bedenken gibt, ist das auf der Manziale-VMW nur 2 GB Speicher haben, was im Prinzip okay ist, aber heutzutage halt dann doch auch schon ein bisschen wenig, insbesondere wenn man eben einmal alle Marnpages auch irgendwie im Speicher halten muss, damit man das Cross-Referencing machen kann und solche Sachen. Da mussten wir also ein bisschen aufpassen, wir sind mehrfach in die Situation gelaufen, dass wir nicht vorsichtig genug programmiert haben und zu viel Speicher verschwendet haben. Glücklicherweise gibt es gute Profiler und man kann sich dann auch schon schnell anschauen will und damit konnte man dann relativ schnell finden, ah, wo kommt eigentlich der Speicherverbrauch her und das dann eliminieren. So, jetzt bin ich am Ende von dem Inhalt, den ich euch zeigen wollte, wir haben noch ein paar Minuten für Fragen, mehr Informationen zu dem Programm findet ihr hier auf dem folgenden Gitter-Blink. Wenn ihr Feedback zu dem Vortrag habt, würde ich mich sehr freuen, ihr könnt den QR-Code hier scannen oder auf den Feedback Link auf den Folien klicken und die Frage rundein. Dann fange ich gerade mal an. Du hattest in der Beschreibung zu deinem Vortrag auch eine Sache angeteasert, dass teilweise die alias-links erst durch Shellscript bei der Installation gesetzt werden. Wie macht ihr das da beim Entpacken von den Paketen, installiert ihr die alle lokal und sucht dann die Man-Pages raus oder wie funktioniert das? Tada, Bonusfolie. Genau, das ist tatsächlich ein ziemlich hässlicher Edgecase, also um das genauer zu erklären, dass man eine bestimmte Implementation auswählen kann. Das habt ihr vielleicht schon mal gesehen für XWWE Browser oder für VI und andere Editorien. Da ist also nicht nur eine Version in Debian, sondern man kann über so ein Simlink basiertes Verfahren auswählen, welchen man denn eigentlich haben will. Der Clue ist, dass dieses Simlinks nicht nur für die eigentlichen Binarys von dem Programm verwendet werden, sondern auch für die passenden Man-Pages, weil wenn man jetzt gerade installiert hat. Und das funktioniert intern, also in dem Debian-Paket über ein Tool namens Update Alternatives. Das heißt, das Tool wird nicht nur von Benutzern benutzt, um eben die Alternativen auszuwählen zu konfigurieren, sondern auch um diese Alternativen Datenbank überhaupt auch erst einzurichten. Und in dem Post Script, also in dem Shell-Script, welches nach der Installation, nach dem Entpacken von dem Debian-Paket bei der Installation gestartet wird, einfach der maintainer beliebigen Code reinschreiben und Update Alternatives aufrufen. Das ist jetzt schwierig für uns, weil wir ja als Modell haben, dass wir die Debian-Pakete runterladen und einfach alle Man-Pages raus extrohieren. Aber wir installieren die ja nicht. Wir können auch nicht einfach den Shell-Code pasen, weil da sind komplizierte Konstrukte drin irgendwie vorschleifen und so. Ich habe mir das mal angeschaut. Es ist nicht so, als wären die Aufrufe einfach zu verstehen. Und Pakete installieren wollen wir nicht. Wir haben jetzt einen kleinen Patch der Update Alternatives austauscht durch ein kleines Programm, welches nicht nur Update Alternatives aufruft, sondern auch eine Log-Meldung ausgibt mit dem Befehlsaufruf. Den Aufruf können wir dann wieder umpasen. Und das ist das, was wir haben. Und das ist das, was wir haben. Das ist das, was wir haben. Das ist das, was wir haben. Das ist das, was wir haben. Das ist das, was wir haben. Das ist das, was wir haben. Im kleinen Aufruf können wir dann wieder umpasen und dann feststellen, was passiert jetzt hier eigentlich und dann entsprechend die Verknüpfung setzen. Beantwortet das die Frage? Super. Alles klar, weitere Fragen ? Hier vorne? Ich nehme an, du hast etwas Interessantes zu erzählen, zu cross-references und Paketen, die Man-Pages mit dem gleichen Namen installieren. Ja, das ist natürlich ein bisschen schwierig. überlegt, wie sollen wir das eigentlich lösen? Zum Beispiel, wenn man sich die Kronman-Page anschaut und da ist dann eine Referenz auf Grund habt, da muss man natürlich schauen, dass die irgendwie möglichst im gleichen Paket dann aufgelöst werden soll. Für die meisten Cross-References machen wir es einfach so, dass wir einen deterministischen Mechanismus haben, der die Referenz auflöst, wenn sie unklar sein sollte. Und dann muss der Nutzer eben einfach über das Panel, was auf der rechten Seite ist, auswählen, welche Implementation hat jetzt der Nutzer eigentlich gemeint. Das ändert sich ja vielleicht auch im Verlauf der Zeit einfach. Deswegen ist es besser, denke ich, wenn man dem Nutzer die Wahl überlässt. Aber für Referenzen innerhalb des gleichen Pakets geben wir natürlich einen kleinen Boost zu Cross-References, die quasi im gleichen Paket aufgelöst werden können, dass man, wenn man gerade am Lesen ist, nicht in die IRE geführt wird. Weitere Fragen. Okay, ansonsten bin ich auch noch den ganzen Tag über hier. Wenn irgendwas ist, könnt ihr mich auch gerne noch ansprechen. Und dann bleibt mir nur zu sagen viel Spaß mit der neuen Manpage-Seite und setzt fleißig links.