Redmine 5.1 auf FreeBSD

Obwohl es bereits Redmine 6.0.1 zum jetzigen Zeitpunkt gibt, haben wir unter FreeBSD bisher leider „nur“ Version 5.1 zur Verfügung. Allerdings gab es auch eine ganze Weile lang keine lauffähige Redmine-Version für FreeBSD in den Packages und Ports.

Ich habe Version 5.1 testweise in einer VM installiert und es funktionierte problemlos. Letztlich kann man nach dieser Anleitung vorgehen:

Ich freue mich darüber, dass es funktioniert und wir Redmine weiterhin unter FreeBSD nutzen können und hoffe, dass es bald auch eine aktuellere Version gibt.

Sprechende Namen oder: Code-Qualität

Da es in einem meiner letzten Projekte vorkam und sich jetzt auch öfter wiederholt hat, möchte ich einmal dazu etwas schreiben. Das Thema ist „Programmieren“.

Beim Programmieren in einer der meisten gängigen Programmier- oder Scriptsprachen schreibt man Quellcode. Dieser Quellcode ruft oftmals Prozeduren oder Funktionen auf, die mit den Bibliotheken beim Compiler mitkommen. Der Programmierer schreibt aber auch eigene. Dabei geht es mir um diese Themen:

  • Verzeichnis- und Dateihierarchie
  • Benamung von Dateien
  • Benamung von Codebestandteilen
    • Funktionen
    • Prozeduren
    • Klassen/Interfaces
    • Variablen
    • Konstanten

Mir ist oft aufgefallen, dass diesen Themen oftmals nur ungenügend Aufmerksamkeit geschenkt wird, dabei ist das, meiner Meinung nach, unglaublich wichtig, wenn

  • Der Code gewartet werden soll über Jahre oder Dekaden
  • Andere den Code verstehen sollen
  • Andere den Code ändern oder erweitern sollen
  • Andere den Code portieren sollen
  • Es keine ausreichende Dokumentation gibt

Ein Beispiel. Wir haben eine Funktion, die sieht selbst so aus und hat folgenden Inhalt:

int ab_ad_nmb_re(int pab, int p_ab, bool ab) { 
    int pab_list; 
    char *pa; 
    … 
}

Da gibt es mehrere Probleme:

  1. Der Funktionsname besteht aus etlichen Abkürzungen, die ein anderer nicht kennt, nachschlagen und sich merken muss. Oder immer wieder nachschlagen muss. Dementsprechend nichtssagend ist der Name
  2. Die Variablen heißen alle fast gleich, sind nichtssagend und unglaublich verwirrend

Oftmals, von mehreren unterschiedlichen Leuten, höre ich dann folgende Argumente:

  • Ich weiß ja, was das alles heißt
  • Du kommst da schon irgendwann rein
  • Wir können doch keine aussagekräftigen Namen nehmen, da das dann zu lang ist und dann bringt das auch keinem was

Ehrlicherweise muss ich da sagen: Nein. Ich nehme (s. GitHub) halbwegs aussagekräftige Namen (manchmal, selten, auch mal nicht, das sollte so aber nicht sein). Sie sagen aus, was sie machen, man braucht keine oder wenig Dokumentation und auch andere sind schnell eingearbeitet und können Änderungen vornehmen.

Bezüglich langer Namen: Jeder halbwegs taugliche Editor zum Programmieren bietet Autovervollständigung. Selbst VIM bringt im Standard bereits eine kontextlose Autovervollständigung mit, die ich gerne benutze: [Strg]+[p/n]. Damit sind längere Namen kein Problem mehr, da nur der oder ein paar Anfangsbuchstaben getippt werden müssen.

Das hat viele Vorteile:

  • Der Code wird lesbarer
  • Andere können sich viel schneller einarbeiten
  • Der Code selbst ist Dokumentation

Mein altes Projekte Warehouse nutzt solche Namen an den meisten Stellen. Das Projekt ist von 2009 und wurde mit VIM umgesetzt. Aber schaut euch auch Frameworks an, die Methodennamen mit vernünftiger Benamung haben wie Qt, wxWidgets, Java-SDK, uvm.

Ich kann nur empfehlen, lieber den Code etwas aussagekräftiger zu gestalten, denn meiner Meinung nach zahlt sich das schnell aus. Speicher ist günstig, da machen die paar Bytes den Kohl auch nicht fett.

Bald neue Videos

Viele haben mir geschrieben, dass ich doch weitere Videos bzw. Tutorials machen soll. Das freut mich sehr.

Zur Zeit nimmt mich die neue Arbeitstelle und meine Familie gut ein, ich habe aber schon die nächsten Videos geplant (Themen: wxWidgets, Qt und auch FreeBSD) und freue mich, sie bald machen und veröffentlichen zu können. Es dauert allerdings noch ein paar Tage. Aber: Es wird mit den Tutorials weiter gehen.

Wenn ihr Vorschläge für bestimmte Themen habt, gerne her damit.

Die Sache mit Recruitern

Ich werde, teils mehrmals pro Woche, von Recruitern, z.B. auf LinkedIn, angeschrieben. Das genaue Vorgehen ist mir meist völlig schleierhaft. Sie hätten eine super Stelle zu prima Konditionen, die perfekt auf mich passen würde. Oftmals passt die Stelle nicht zu meiner Vita. Ich kann das nicht nachvollziehen.

Auf LinkedIn und den anderen Plattformen steht, was ich bisher gemacht habe und meine Website verrät auch meine Gebiete. Dennoch kommen meist, nicht immer, von Recruitern irgendwelche Standardtexte und dass sie mit mir telefonieren wollen. Gehalt, ob remote gearbeitet werden kann weitere Infos über die Stelle bekomme ich oft nur auf Nachfrage. Mittlerweile schreibe ich zumeist, einfach, weil es mich interessiert: „Wie sind denn die Konditionen und ist die Stelle zu 100% remote?“ Zurück kommt häufig ein ziemlich für die Branche unterdurchschnittliches Gehalt und „Ja, remote geht, einmal pro Woche.“.

Was mir nicht ganz klar ist: Unternehmen zahlen doch für diese Recruiter und wenn die Leute, wie ich, auch noch eine Website haben, worauf steht, was sie so machen, ist es dann zu viel verlangt, einfach mal fünf Minuten Zeit darein zu investieren? Dann könnten die sich auch den Spruch sparen „Wir wissen, dass du sicher immer wieder angeschrieben wirst, aber wir haben was ganz ganz besonderes.“

compow als Privatprojekt in Form einer Referenz wieder online

Eines meiner Projekte, dass ich vor wenigen Jahren gemacht hatte, lag noch auf meiner Festplatte und war bereits lange nicht mehr aktiv. Ich dachte mir allerdings, dass ich das noch einmal gerne als Referenz von mir online stellen wollte: compow.

Bei compow handelt es sich um eine Website, auf der sich Firmen vorstellen können und Stellenanzeigen schalten können. Ursprünglich war das mal kostenpflichtig, was ich aber herausgenommen habe, da ich nicht selbständig bin und damit kein Geld verdiene, es ist lediglich eine meiner Referenzen.

Das Interessante an der Website ist der Tech-Stack, denn anstelle einer der üblichen Webprogrammiersprachen wie Ruby, PHP, Python, Go, ASP.NET (keine Sprache, aber ihr wisst, was ich meine), basiert diese Website auf folgenden Technologien:

Wie gesagt, die Seite dient einfach nur als Referenz, womit ich mich in den letzten Jahren beschäftigte. Die Website ist nicht weiterentwickelt und wird es mitunter auch nicht.

Ein interessanter Fehler beim Testen von Software

In der Firma, in der ich arbeite, ist mir ein Malheur passiert, und zwar beim Testen der von mir geschriebenen Software. Ich will (vielleicht darf) ich keine Details verraten, aber es geht um ein Programm, welches ein anderes Programm startet, überwacht und beendet. Nichts Großes, nichts Kompliziertes. Eine Sache muss man aber wissen: das Programm, an dem ich arbeite und das Programm, dass von meinem gestartet wird, soll auf macOS arm64 und macOS amd64 laufen und ist keine Fat-Binary, was bedeutet, dass es für die jeweilige Plattform immer ein Bundle gibt.

Jetzt ging es zum Glück nur um eine Testversion, die ich meinen Kollegen zum Ausprobieren geben wollte. Ich packte mein Programm also, zusammen mit dem Fremdprogramm. Einmal für macOS amd64, einmal für macOS arm64 (und noch weitere Plattformen). Faul, wie ich bin, hatte ich dafür ein Script geschrieben. Leider habe ich nicht weit genug automatisiert, denn hier passierte das Problem: Ich packte mein Programm für amd64 und das Fremdprogramm für arm64. Bevor ich meine Software zum Testen herausgebe, probiere ich diese immer einmal aus, zumindest im kleinen Rahmen. Eine CI-CD-Pipeline gab es in dem frühen Entwicklungsstadium leider noch nicht (Das ist ein Fehler! Kümmert euch direkt darum!). Jetzt hätte das Problem beim Testen auffallen müssen, aber hier beging ich den entscheidenden großen Fehler in der gesamten, sehr suboptimalen Kette: Ich probierte die arm64 und die amd64 meine Software und der Fremdsoftware nur auf meiner arm64-macOS-VM aus.

Wer aufgepasst hat, kann sich sicher denken, was jetzt passiert ist: Da Rosetta 2 lief, startete sie natürlich mein amd64-Programm und mein amd64-Programm startete das arm64-Fremdprogramm, ohne, dass ich was von einem Fehler mitbekam.

Ich lieferte natürlich die amd64-Version aus und es kam, wie es kommen musste: bei den Kollegen mit amd64 macOS funktionierte zwar mein Programm, das Fremdprogramm aber natürlich nicht, da es kein Rosetta-Äquivalent auf macOS amd64 gibt.

Dabei hatte ich den Fehler die ganze Zeit auf dem Schirm, denn mein Paketierungsscript lieferte Hinweise, wenn die Architektur der Fremdsoftware mit der Architektur meines Programms nicht zusammenpasst. Aber ein Hinweis lässt sich im Stress leicht übersehen. Hier hätte ich doch besser einen Abbruch eingebaut.

Was lernen wir daraus? Am Besten vollständig automatisierte Tests implementieren, aber wenn man für verschiedene Architekturen händisch testet, das dann auch direkt auf der jeweiligen Architektur durchführen und nicht in einer Emulation.

Ich bin wieder in Lohn und Brot – Meine neue Festanstellung und wie es hier weitergeht

Ich bin wieder unter Dach und Fach und freue mich unendlich. Ich habe eine neue Festanstellung gefunden und befinde mich gerade in der Einarbeitung.

Da ich jetzt erstmal, zumindest während der Einarbeitung, in Vollzeit arbeite, habe ich leider keine Zeit mehr für Videos, da ich vollständig mit Job und Familie ausgelastet bin. Damit bleiben die ganzen Serien zuerst einmal stehen.

Wie es da in Zukunft weitergeht, weiß ich noch nicht. Ich danke aber schon einmal bis hierhin und hoffe, den ein oder anderen Blogartikel in den nächsten Wochen schreiben zu können.

Umstellung eines ganzen Netzwerks von Windows 2000 auf Ubuntu 6.04

Es muss 2005 gewesen sein, als wir überlegten, gut 60 Arbeitsplätze auf ein neues Betriebssystem zu heben. Im Einsatz war noch Windows 2000 inklusive Domäneninfrastruktur. Das System machte immer wieder Probleme, sei es bei Updates oder sogar beim Drucken. Hier und da nervte vieles und Windows 2000 war mit seinen fünf Jahren auch nicht mehr das Jüngste. Mittlerweile ging auch der Supportzeitraum zu Ende, zumindest der Mainstream-Support, und was keiner von uns wusste war, dass es noch den Extended Support gab. Aber abgesehen davon: Es musste was Moderneres her.

Natürlich diskutierten wir über Windows XP, was aber auch schon ein wenig in die Jahre gekommen war und mir so absolut überhaupt nicht gefiel und natürlich dachten wir bereits an den Nachfolger, Windows Vista, der aber noch auf sich warten lies. Zuerst dachten wir, dass wir zwei Möglichkeiten hätten: Wir bleiben bei dem, was wir haben, also Windows 2000 und wechseln dann auf den Nachfolger von XP, wann auch immer dieser erscheinen würde oder wir wechseln auf XP und dann später auf den Nachfolger.

Die Entscheidung

Da wir bereits, neben FreeBSD, Linux auf einigen unserer Server nutzten, fragte die Geschäftsleitung, ob das auch im Clientbereich eine Idee wäre, denn es liefe ja gut. Ich sagte, dass das durchaus eine Option sein könnte, dachte aber eher daran, dass große Probleme kommen könnten. Ich sagte, wir evaluieren das mal. Ich hatte schon einige Jahre Erfahrung mit Linux, war dem Projekt also alles andere als abgeneigt und dachte mir auch, dass die Plattform stabil genug sei, um produktiv damit zu arbeiten.

Linux ist ja nicht gleich Linux und nur ein Kernel, aber selbst wenn wir von GNU/Linux sprechen: eine Distribution musste her. Ich hatte ewig lange Gentoo genutzt, aber nur privat und war sehr überzeugt davon. Wenn ich bedenke, wie viel Zeit ich in Kompilationen vergeudet habe … aber das ist ein anderes Thema. Mir war klar: wir können Gentoo keinesfalls für unser Netzwerk einsetzen. SuSE mochte ich nicht wirklich, RedHat auch nicht, Mandrake … naja … und ich weiß gar nicht mehr, was es um 2005/2006 so alles gab. Aber eine kleine Distribution begann, groß zu werden: Ubuntu. Debian war mir von jeher ein Begriff, und da Ubuntu darauf basierte, schauten wir uns das an und ich begann, längere Zeit damit zu arbeiten. Es war ok, lief stabil und ich konnte das Meiste damit erledigen. Allerdings war ich auch kein Kaufmann, Designer oder Redakteur. Mir war direkt klar: für unsere Produktion ist es nichts, darüber müssen wir nicht weiter nachdenken. Aber Texte damit verfassen: Das ging. Und so beschäftigten wir uns tiefer mit der Materie.

Die Automatisierung

Mein Vorgänger war der absolute Turnschuhadmin. Nichts war automatisiert, er bevorzugte das sinnlose Herumlaufen. Das wollten wir mit der Umstellung ebenfalls erschlagen. Wir wollten aber auch eine Art Domäne haben, zumindest mal globale Homeverzeichnisse und zentrale Anmeldungen. Die Installation sollte von selbst gehen, oder wenigstens, halbwegs von selbst.

Für die Installation entschieden wir uns, da ja Debian-basiert, für Kickstart und ein selbstentwickeltes Script. Mit Kickstart war es problemfrei möglich, eine generische Betriebssysteminstallation durchzuführen. Wir hatten zu dem Zeitpunkt die IP-Adressen noch manuell vergeben und keinen DHCP-Server mit MAC-Matching genutzt, so dass wir am Bootprompt die IP-Adresse für den jeweiligen Rechner mit angeben mussten. Anhand der IP-Adresse wurde entschieden, welche Software und Konfigurationen der Rechner bekam. Alles haben wir selbst gescriptet und entwickelt. Es lief recht reibungslos. Ich erinnere mich noch an den Tag der Umstellung. Wir liefen mit mehreren Personen durch die Abteilungen und starteten die Installationen an. CD rein, davon booten, IP eingeben, der Rest passierte letztlich automatisch. So ganz wahr ist das nicht. Der Installationsprozess war in zwei Bereiche aufgesplittet: den mit Kickstart zur Betriebssysteminstallation und dann der eigentliche Konfigurationsvorgang, der nach der Installation einmal händisch gestartet werden musste. Ich weiß nicht mehr, warum wir das nicht auch automatisierten, aber es hatte irgendeinen Grund. Ein Problem, das wir allerdings bis zum Schluss nicht wegbekamen, waren ein oder zwei Dialoge, die man tatsächlich selbst mit OK bestätigen musste. Sie ließen sich nicht wegoptimieren. Damit war eine unbeaufsichtigte Installation zwar nicht möglich, aber zu der Zeit konnten wir ein komplett installiertes und konfiguriertes System in gut dreißig Minuten mit wenig Aufwand bereitstellen. Das Optimum war damit noch nicht erreicht, aber der Komfort im Gegenzug zu früher war für uns weltbewegend.

Globalitäten

Zusätzlich wollten wir noch zwei weitere Dinge: eine zentrale Anmeldung und globale Home-Verzeichnisse.

Bei der zentralen Anmeldung entschieden wir uns gegen LDAP und Kerberos, da es einfach für uns in dem Zeitraum zu komplex war und wir ja auch noch das Tagesgeschäft zu betreuen hatten. Es gab eine sehr viel einfachere Lösung, die natürlich auch wesentlich limitierter war und letztlich kaum Sicherheit bot: NIS. Doch wir fuhren damit gut. Neben den Linux-Clients hatten wir daran auch die Macs und die FreeBSD-Maschinen angebunden und es lief. Wir arbeiteten später noch an LDAP, aber erstmal war das so in Ordnung.

Die Konstellation lief fast zehn Jahre und es gab unglaublich wenige Probleme. Aus Kompatibilitätsgründen (Kombination Word und InDesign) haben wir uns dann aber entschlossen, die Redaktion aus Linux herauszunehmen und Macs zu geben, damit der Austausch mit der Produktion besser lief.

Würde ich es wieder tun?

Technisch war das Projekt, meiner Meinung nach, ein voller Erfolg. Die Administration machte, zumeist, Spaß und lief, bis auf wenige Probleme, super. Aber würde ich es wieder tun? Nein. Denn was Computer vereinfachen, verkomplizieren die Menschen. Einige waren begeistert, aber viele eben nicht und es gab hier und da guten Gegenwind. Ich empfand es als sehr anstrengend. Was ich bei der Administration sparte, musste ich in sinnlosen Diskussionen ausbaden.

Das Interessante aber war, dass eine solche Umstellung möglich war. Es waren dann zwar keine sechzig Computer, aber immerhin um die fünfundreißig, die mit Linux liefen und das sehr gut. Aber die Leute müssen sich darauf einlassen.

Videoreihe: Entwicklung einer Desktopsoftware für compow mit C++, Qt und SQLite Teil 8

Der Benutzer soll die Datensätze exportieren können, und zwar als CSV, JSON und XML. Dazu treffen wir in diesem Video die Vorbereitungen, indem wir die Daten des CompanyTypes in einer Hashmap (QHash) speichern, um sie später einfach auszulesen.

Eine Desktopanwendung für compow mit C++, Qt und SQLite - Teil 8
Eine Desktopanwendung für compow mit C++, Qt und SQLite – Teil 8

Und so sieht es aus:

QtCreator mit CSV-Export in der Debug-Übersicht
QtCreator mit CSV-Export in der Debug-Übersicht

Hier geht es zum Video.