Site Logo

IzzySoft


{itemlist}
 
Software Liste Dokumentationen Demos Artikel

IzzySoft Release Framework: Software Release einfach gemacht

Um was es geht

Wer ein oder mehrere Software-Projekte verwaltet und überdies auch für die "File Releases" verantwortlich zeichnet, weiß, was mit dieser Aufgabe verbunden ist – und genau für sie/ihn ist dieses Framework gedacht. Bei jedem Release muss der/die Verantwortliche …

relman in Aktion (zum Vergrößern anklicken)

Und dann immer im Blick haben, was sich wo befindet: Lokale Verzeichnisse, Verzeichnisse auf den Servern. Nicht vergessen, die Links für die Downloads bzw. die Versionsnummern zu aktualisieren, usw. usf.. Wäre es da nicht praktisch, einen "Release Manager" zur Hand zu haben - dem man einfach sagt: relman MeinProg NeueVersion, und er erledigt alles nötige automatisch? Nachdem das hier beschriebene "Release Framework" einmal installiert und richtig konfiguriert ist, hat man genau das! Alle *.tar.gz Archive und Debian bzw. RPM Pakete sind nach diesem Kommando nicht nur erstellt, sondern auch bereits auf den jeweiligen Servern abgelegt. Auch das "ChangeLog" liegt dann schon dort vor, und stellt auf magische Weise die gerade fertiggestellten Pakete zum Download an. Nur das "Announcement" in den entsprechenden Foren o.ä. steht noch offen. …

Dies sind die drei Programme, die an diesem Framework beteiligt sind:

Feuer gefangen? Auf den folgenden Seiten gibt es die Einzelheiten:

Inhalt

relman

Als diejenige Komponente, die die Verteilung der Software auf die verschiedenen Server übernimmt, kann man relman sicher als "Verteilerzentrum" ansprechen. Aber es ist mehr – es ist die "Schaltzentrale" des gesamten Frameworks: Hier werden alle relevanten Details zu den Projekten gespeichert, nur dieses Programm wird direkt aufgerufen und kümmert sich um alles nötige.

Auch wenn relman selbst nur ein "einfaches Shell Skript" ist, welches die Daten einer Konfigurationsdatei ausliest, sie interpretiert, und darauf basierend die entsprechenden Tools aufruft – es ist ein leistungsfähiges Werkzeug. Dank seiner flexiblen Konfiguration erlaubt es u.a. auch die Definition von Skripten, die in den verschiedenen Stadien des Prozesses (zu Anfang, vor der Paketerstellung, vor der Verteilung bzw. zum Abschluss), verschiedene Arten des Bezugs der Sources (vom einfachen Kopieren bis zum Export aus CVS bzw. SVN), sowie das Kopieren des entsprechend formatierten "ChangeLogs" zum Einsatz mit HistView. Nur Kaffeekochen kann es leider noch nicht …

Dokumentation

Die eigentliche Dokumentation (abgesehen von diesem Artikel) kommt in Form von "Man pages" – eine unter Unix/Linux durchaus verbreitete Form. Durch Eingabe von man relman an der Kommandozeile (gefolgt von "Enter" ;) erhält der Anwender eine Übersicht über die passenden Parameter und deren Einsatz. Gleiches gilt für man relman.conf hinsichtlich des Aufbaus und der verfügbaren Optionen in der Konfigurationsdatei. Da an diesen beiden Stellen alle Details beschrieben sind, konzentriert sich dieser Artikel auf das Wesentliche – um in überschaubarem Rahmen einen Einblick zu ermöglichen.

Konfiguration

Allgemein

Die Konfiguration – eine einfache "ASCII" Textdatei – lässt sich grob in zwei Sektionen einteilen: Die "globalen", sowie die projektspezifischen Einstellungen. In vielen Fällen gilt es hier lediglich, die Werte 0 (für ein deaktiviertes Feature) bzw. 1 (aktivierte Funktion) zuzuweisen. Die verbleibenden Einstellungen Extract from config file (click to enlarge) betreffen überwiegend Verzeichnis- und Serverangaben. Da die meisten "globalen Einstellungen" gleichzeit als "Defaults" für projektspezifische Settings dienen, kann die Erstellung eines Projektes im Minimalfall mit zwei Zeilen auskommen: Dem Namen des Projektes sowie dem Verzeichnis, in welchem sich der zugehörige Sourcecode befindet. Selbstverständlich lassen sich jedoch einige oder gar alle "Defaults" hier durch spezifische Einstellungen "überschreiben". Auf diese Weise bleiben die Angaben für "einfache Projekte" überschaubar – während für "spezielle Projekte" die volle Flexibilität gewahrt bleibt.

Die einzigen ausschließlich "globalen" Einstellungen sind das Verzeichnis des "Build Environments" (gewöhnlich /usr/src/debian, sofern bereits pkgmake installiert ist – was der Fall sein sollte, und zwar automatisch sofern die Installation von relman über ein *.deb/*.rpm Paket erfolgte, da relman auf pkgmake aufsetzt), sowie das zu verwendende pkgmake "Executable". Bei Installation basierend auf einem *.deb/*.rpm Paket sind hier keine Anpassungen nötig.

Alle anderen Einstellungen sind die bereits genannten "Defaults" (Voreinstellungen) für die später zu definierenden Projekte. Konkret bedeutet dies, dass man z.B. generell die Erstellung von RPM Paketen aktivieren, sie aber für einzelne Projekte gezielt abschalten kann – oder auch umgekehrt. Je besser diese Voreinstellungen auf den Großteil der Projekte passen, desto weniger ist für jene später explizit zu definieren. Die Beispiel-Konfiguration, welche mit relman ausgeliefert wird, demonstriert dies anhand der Projekte "small" und "medium" – sowie die "volle Flexibilität" anhand des Projektes "LongJohn".

Sind die "globalen Einstellungen" festgelegt, kann man zur Definition der Projekte fortschreiten. Projekteinstellungen sind zweifelsfrei an ihrem Präfix zu erkennen (und dem jeweiligen Projekt zuzuordnen). Diese lassen sich für jedes Projekt möglichst kurz halten, um Tipparbeit zu sparen. Um ein "dummes" Beispiel zu geben, nehmen wir uns ein Projekt und nennen es "verylongprojectname". Alle "Releases" sollen natürlich den vollen Namen verwenden (also z. B. verylongprojectname-0.1.2.tar.gz) – aber wir wollen das natürlich nicht jedes Mal eingeben müssen. Also nehmen wir uns stattdessen als Kürzel vlpn_ her:

vlpn_name=verylongprojectname
vlpn_srcdir=/usr/local/source/vlpn

usw.. Für eine Release können wir uns auf das Projekt unter dem Kürzel "vlpn" beziehen: relman vlpn 0.1.2.

Für jedes Projekt lassen sich separate "Distribution Targets" (also Ziele, zu denen die erstellten Archive/Pakete transferriert werden sollen) definieren, sowie welche Pakete (nicht) erstellt werden sollen, und, und, und. Sobald die nötigen Einstellungen jedoch mit den "Defaults" übereinstimmen, brauchen wir sie hier jedoch nicht explizit aufzuführen.

Pakete

Mit einfachen "booleschen" Variablen lässt sich festlegen, welche Pakete erstellt werden sollen. Während der "Tarball" generell dazu gehören sollte (mktar=1), sofern man etwas aus den Sourcen erstellen will (da dieser sowohl für RPM als auch Debian Pakete als Grundlage genommen wird), kann die Entscheidung hinsichtlich Debian (mkdeb) und RPM (mkrpm) Paketen differenzierter ausfallen. Die Variablen group und section legen hier die von pkgmake zu verwendende RPM Paketgruppe bzw. Debian Sektion fest. Und soll pkgmake noch etwas mitgeteilt werden, für dass relman (noch?) kein Keyword bereit hält, kann dies über pkgmakeparms geschehen.

Weiter oben wurden einige Variablen bereits im Rahmen der "globalen" Einstellungen und "Defaults" angesprochen. Bis auf die beiden genannten Spezialfälle gilt: Stellt man den Projekt-Präfix (in unserem Beispiel "vlpn_") voran, wird daraus eine projektspezifische Einstellung. Beispiel: mkdeb=1 - generell sollen Debian Pakete erstellt werden, vlpn_mkdeb=0 - für unser verylongprojectname jedoch nicht.

Paketdienst

Die Verteilung der Software erfolgt über FTP und SCP (je nachdem, was konfiguriert wurde). Die Ziele können für jedes Projekt separat definiert werden, aber selbstverständlich sind auch hier globale Werte möglich. Ein klassisches Beispiel wäre ein Upload der Software in den "incoming" Ordner bei Sourceforge:

tarftp=upload.sourceforge.net
tarftpdir=incoming

In diesem Fall haben wir das global für alle *.tar.gz Archive mit zwei Zeilen für FTP definiert: Den Server sowie das Verzeichnis separat. Für SCP wäre dies nur eine Zeile: [user[/password]@]server:/path/to[/filename.ext]. Wird der Dateiname nicht extra angegeben, heißt die Datei auf dem Zielsystem exakt so wie nach der Paketerstellung lokal (das gilt übrigens generell für FTP). Lässt man das Passwort weg, wird ggf. danach gefragt. Den Usernamen ebenfalls entfallen lassen kann man, wenn auf der Gegenseite der selbe Verwendung findet. Bei FTP erfolgt die Authentifizierung übrigens anhand einer netrc Datei – näheres bringt man netrc zum Vorschein.

Diese *ftp[dir] und/oder *scp Einstellungen sind für jeden Dateityp separat vorzunehmen (kann ja auch alles zu ganz verschiedenen Zielen kopiert werden [müssen]) – d. h. für deb, rpm, tar, und - ein spezieller Fall - hist, welches das "History File" für Histview bezeichnet.

Skripte Bereits in der genannt wurden diverse Skripte, die zu

verschiedenen Stadien des Prozesses "laufen gelassen" werden können. Also sollen an dieser Stelle auch gleich ein paar mögliche Einsatzgebiete her, um deren Einsatz zu veranschaulichen:

Bevor wir irgend etwas "releasen", wollen wir die aktuelle Arbeit noch in das entsprechende Repository einchecken. Dafür eignet sich das prerun Skript, da dies zu allererst läuft: vlpn_prerun="cd /usr/local/source/vlpn && cvs ci". Dann wollen wir sicherstellen, dass die Versionsnummer in einer speziellen Datei auch die richtige ist - ohne dass wir dieser Datei eine neue CVS-Version verpassen: vlpn_prebuild="echo \"version=%v\" >%b/version". So, diese beiden Dinge können wir jetzt nie mehr vergessen. Damit nach dem Hochladen des aktuellen Debian Paketes auch das Repository aktualisiert wird, gleich noch ein postrun="ssh unser.server ~/bin/update-repo" – jawollja, global, damit es immer passiert.

Quellen

Wer mehr über relman erfahren will, kann sich noch an folgenden Stellen umsehen:

pkgmake

Haben wir relman als "Schaltzentrale" und "Verteilerzentrum" kennengelernt, so ist pkgmake eigentlich nur ein "Backend" dazu – aber immerhin ein wichtiges: Ohne das, was der "Packager" erstellt, hätte relman nichts zu tun: pkgmake zeichnet verantwortlich für das Erstellen der Tar Archive sowie Debian und RPM Pakete – je nachdem, was konfiguriert wurde.

Anders als relman, der hauptsächlich über seine Konfigurationsdatei gesteuert wird und im Allgemeinen mit zwei Kommandozeilen- Parametern ausreichend bedient ist, verlangt ein Aufruf von pkgmake gleich eine ganze Kette von Parametern. Daher bietet sich auch die Verwendung von relman als "Frontend" an, sodass wir uns darüber nicht wirklich Sorgen machen müssen. Aber wir dürfen es natürlich, wenn wir darauf bestehen: pkgmake kann durchaus auch "Stand-Alone" verwendet werden.

Dokumentation

Wie bereits bezüglich relman erwähnt, kommt auch hier die Dokumentation wieder hauptsächlich in Form von "Man Pages" daher. Nur ist es hier gleich eine mehr: man pkgmake gibt Auskunft über die zahlreichen Kommandozeilen-Parameter, man pkgmake.conf hinsichtlich der Optionen in der Konfigurationsdatei, und "man pkgmake.tpl" ist zuständig für die Details in den Template Dateien.

Konfiguration

Die Konfigurationsdatei

Konfigurationsdatei (zum Vergrößern anklicken) Wie bereits gesagt, kann pkgmake durchaus auch (sinnvoll) "Stand-Alone" eingesetzt werden – also verfügt es auch über eine eigene Konfigurationsdatei. Wie auch bereits bei relman, handelt es sich hier um eine einfache (ASCII) Textdatei nach Konventionen der Unix Shell "Bash", sodass die Einstellungen aus "Variable=Wert" Paaren bestehen. Alle hier getroffenen Einstellungen stellen "Defaults" dar, welche mittels Kommandozeilen-Parametern überschrieben werden können. Dies heißt wiederum: Je genauer diese Einstellungen mit denen eines Projektes übereinstimmen, desto weniger Parameter braucht man für selbiges anzugeben. Doch genaugenommen interessiert uns das ja eigentlich gar nicht, da sich ja relman um diese Dinge kümmert …

Doch selbst wenn relman zum Einsatz kommt, sollten einige Einstellungen in der Konfiguration von pkgman getroffen sein. Dies betrifft in erster Linie die Angabe des Packers (also desjenigen, der für die Erstellung der Pakete verantwortlich zeichnet), sowie des Vendors (also des "Herstellers" der Software). Zumindest ersterer ist i. d. R. konstant, auch wenn "Fremdsoftware" verarbeitet wird – was sicher eher die Ausnahme ist, sodass auch der "Vendor" überwiegend gleich bleibt. Die Lizenzen der Software können voneinander abweichen, aber auch hier gibt es meist einen Schwerpunkt, der an dieser Stelle konfiguriert werden sollte. Auf jeden Fall stellen die verwendeten "Executables" (ausführbaren Programme) zur Erstellung von Debian (DEBBUILD) und RPM (RPMBUILD) Pakete eine Konstante dar, sowie das "Build Environment" (Verzeichnis, in welchem die Pakete und Tar-Archive abgelegt werden). Für zumindest diese Dinge sollten hier Voreinstellungen getroffen werden.

Nebenbei: Wie auch bei relman, werden bei pkgmake zwei Verzeichnisse auf Konfigurationsdateien geprüft, und selbige dann sequentiell eingelesen: Globale Einstellungen aus der Datei /etc/pkgmake.conf werden mit denen aus der "persönlichen" Datei ~/.pkgmake/pkgmake.conf überschrieben – in letzterer lassen sich also von ersterer abweichende Einstellungen treffen, während man alle anderen hier auskommentiert. So ergänzen sich beide wunderbar, wenn sich z. B. mehrere Entwickler einen Server zur Paketerstellung teilen.

Die Template Datei(en)

Template-Datei (zum Vergrößern anklicken) pkgmake benutzt RPM .spec Dateien als Konfiguration zur Erstellung von RPM und Debian Paketen. Dabei können im Grunde genommen beide Pakettypen aus der gleichen .spec Datei generiert werden. Der "kleine Unterschied" liegt hier in der Definition der Paketgruppe: Die bei RPM verwendeten Gruppen stimmen nämlich mit den bei Debian zum einsatz kommenden "Sektionen" ganz und gar nicht überein. Dennoch käme es deshalb nicht zu einem Installationsfehler – obwohl es zwei gute Gründe gibt, diesen Konflikt zu beheben: 1) Ein Debian-Paket mit einer RPM Gruppe ist einfach nicht 100% konform, und 2) sorgt es beim Anwender dafür, dass dieser in seiner Paketverwaltung letztendlich zahlreiche zusätzliche "Gruppen" hat, die jeweils nur ein oder zwei Pakete enthalten. Um dieses Problem zu umgehen, lassen sich bei pkgmake eine Gruppe und eine Sektion definieren, wobei letztere dann speziell für die Debian Pakete zum Einsatz kommt. Solange niemand die Gruppe im Template "hardcoded" hat, sondern brav der Platzhalter Verwendung findet.

Wie (üppig) Platzhalter in der Template-Datei zum einsatz kommen (können), zeigt die Abbildung (links): Fas die ganze Datei kann sich aus solchen zusammensetzen. Je weniger man ohne Platzhalter auskommt, desto flexibler wird die Handhabung der Template-Datei: Im Idealfall ließe sich ein solches Template gleich für mehrere Projekte nutzen - woran oftmals nur die %files Sektion hinderlich ist …

Niemand ist dazu gezwungen, Platzhalter zu verwenden - jedoch macht pkgmake ohne diese einfach weniger Sinn. In der Praxis gilt es daher nicht abzuwägen, ob, sondern welche Platzhalter zum Einsatz kommen sollen. Nicht alles kann mit ihnen abgedeckt werden, und nicht immer macht jeder Platzhalter auch wirklich Sinn. Die Flexibilität ist jedoch gegeben, und der Einsatz mag bei verschiedenen Projekten halt unterschiedlich ausfallen. Wie obiges Beispiel zeigt, sollte jedoch zumindest die "Group:" als Platzhalter realisiert sein, damit sowohl konforme RPM als auch Debian-Pakete erstellt werden können.

Quellen

Mehr Informationen zu pkgmake finden sich:

HistView

Das Release ist gemacht, das Projekt hat seine "Website", die Dateien sind hochgeladen, und (potentielle) Benutzer sollen über die neue Version sowie die gemachten Änderungen informiert werden – hier kommt Histview ins Spiel. Die PHP Klasse lässt sich nutzen, um das "ChangeLog" des Projekts auf benutzerfreundliche Weise anzuzeigen – und dabei für jedes Release auch die zugehörigen Dateien zum Download anzubieten.

Dokumentation

Histview in Aktion (zum Vergrößern anklicken) Anders als bei den Kommandozeilen-Tools relman pkgmake, kommt die Dokumentation hier im HTML-Format daher. Die Pakete (und auch der "Tarball") enthalten eine Api Referenz in Form einzelner HTML Dateien, die sich im Verzeichnis doc/ (Tar-Archiv) bzw. /usr/share/doc/histview (RPM/Debian Paket) befinden. Beispiele für die Anwendung finden sich im Programmverzeichnis (/usr/share/histview bei Installation aus Paketquellen).

Damit Histview ein ChangeLog analysieren kann, muss dieses in einem bestimmten Format vorliegen – wobei dies in den meisten Fällen "von Natur aus" so ist, da das Format sich recht intuitiv darstellt:

Eine mit v0.0.0 beginnende Zeile wird als "Version" interpretiert – wobei die "0.0.0" natürlich durch die entsprechende Versionsnummer zu ersetzen ist. Dieser Zeile folgt meist eine "Unterstreichung" (-----). Alles vor der ersten Versionsnummer wird genau so ignoriert, wie leere oder mit einem Hash (#) beginnende Zeilen. Für neue Features beginnt die Zeile mit einem +, gefolgt von mindestens einem Leerzeichen (braucht man mehrere Zeilen für die Beschreibung, sind die Folgezeilen entsprechend einzurücken). Ein * bezeichnet eine Änderung, ! einen Bugfix und - den Wegfall einer "Sache".

Für die meisten Projekte sollte also entweder keine oder nur geringe Änderungen am Format des ChangeLog nötig sein, damit Histview dieses verarbeiten kann.

Konfiguration

Histview

Skript-Datei (zum Vergrößern anklicken) Die Konfiguration findet hier in der aufrufenden PHP Skript Datei statt. Da Histview als PHP Klasse bereit gestellt wird, lässt sich das "Drum herum" auf diese Weise frei gestalten – wobei die bereitgestellten Beispieldateien durchaus als Grundlage dienen können.

Im Grunde genommen gibt es da auch nicht viel zu tun: Es muss eine Instanz der Klasse angelegt werden, wobei der Name der zu analysierenden ChangeLog Datei und, optional, der "Basisname" für die zum Download zu verlinkenden Dateien (für gewöhnlich der Projektname in Kleinbuchstaben –z.B. "histview" für histview-0.1.4.tar.gz, histview_0.1.4-izzy1_all.deb, etc.pp.) als Parameter übergeben werden. Dann lässt sich – wiederum optional – durch den Aufruf der Methode use_dlclass() die Benutzung der Download-Klasse aktivieren (siehe Beispielskript). Auf jeden Fall sollten wir Histview mitteilen, wo es die Download-Dateien für die jeweiligen Typen (tar, rpm, deb) finden kann – hierfür steht die Methode set_basedir(). Sollen Debian/RPM Pakete angezeigt werden, sollte auch mittels der Methode set_relname() der Release-Prefix angegeben werden, sofern einer zum einsatz kommt (im obigen "histview" Beispiel wäre das "izzy"). Das war's im Wesentlichen (wie immer, gibt es noch mehr, was man machen kann, aber nicht muss) – und Histview kann mit der process() Methode angewiesen werden, das angegebene ChangeLog zu analysieren – um dann mittels der Methode out() den resultierenden HTML-Code zurück zu liefern, damit er im aufrufenden Skript verarbeitet (ausgegeben) werden kann.

Als weitere "Nice-to-Have" Dinge, die man noch tun kann, steht z.B. die Angabe anderer Icons für die Download-Dateien zur Verfügung, um nur eine Sache beim Namen zu nennen. Doch diese Details lassen sich alle der bereits weiter oben genannten Api Referenz entnehmen.

Die Download-Klasse

Weiter oben wurde sie bereits erwähnt, da die Histview-Klasse sie optional verwenden kann. Wozu man dies tun sollte, war dort jedoch nicht beschrieben. Nun, die Download-Klasse bietet – auch über die Einbindung in Histview selbst – einige nette Funktionen: In Histview eingebunden, lassen sich damit die Download Verzeichnisse selbst verstecken (es taucht nur noch der Dateiname auf). Darüber hinaus können auch (im Zusammenspiel mit einer MySQL Datenbank) Download-Statistiken erstellt werden. Eine weitere Möglichkeit ist das Erstellen von Verzeichnislisten für den Download.

Weitaus interessanter dürfte jedoch die Möglichkeit sein, sich mittels der Download-Klasse einen "Alias" zum Herunterladen der jeweils aktuellsten Version zu erstellen. Man kann dann für den Download einfach eine feste URL, z. B. "project_release.php", angeben – und wer diese URL ansteuert, erhält immer die jeweils neueste Version, ohne dass wir erneut Hand angelegt hätten. Die Methode send_latest() stellt dazu den Schlüssel dar. Anhand dreier Parameter (Basisname der Datei, Typ ["tar","deb","rpm"], sowie Verzeichnis) ermittelt sie die so spezifizierte Datei mit der höchsten Versionsnummer, und schickt diese an den "Anforderer".

Quellen

Wer mehr über Histview erfahren möchte, schaut bitte hier:

2018-12-16