Last Update:
$Id: packagedevelopment.tex 27326 2011-01-17 08:31:52Z starwarsfan $
Inhalt:
Es wird _nicht_ explizit eine Build-Umgebung vorausgesetzt. Das Kompilieren hat mit dem eigentlichen Paketbau nichts zu tun. Natürlich ist es sehr wahrscheinlich, dass auf der Entwickler-Maschine auch Kompiler etc. vorhanden sind, zwingend notwendig ist das jedoch nicht. Bspw. wird für die Entwicklung von php-Paketen wie 'phpmyadmin' kein Kompiler benötigt.
Für die Anwendung der Scripte werden _nicht_ zwingend root-Rechte benötigt! Somit kann man die Paketentwicklung als normaler User durchführen. Es ist jedoch darauf zu achten, dass dieser User die notwendigen Rechte hat, um die Pakete in die entsprechenden Deployment-Folder zu kopieren. Dazu später mehr.
Im Vorfeld muss also sichergestellt werden, dass der ssh-Zugriff auf den Repository-Server mit Keyfile-Authentifizierung funktioniert.
Das ssh-Konfigurationsfile kann dann bspw. so aussehen:
eis # cat /home/starwarsfan/.ssh/config
Host repoeis
Hostname repoeis.foobar.org
User starwarsfan
IdentityFile /home/starwarsfan/.ssh/id_rsa_repoeis
Der beim Schlüsselwort 'User' angegebene User muss also dem Usernamen auf dem Repository-Server entsprechen und beim Schlüsselwort 'IdentityFile' wird der zu verwendende Private-Key angegeben.
Wichtig ist ausserdem, dass dieses File nur der entsprechende User lesen bzw. schreiben darf!
eis # ls -l /home/alice/.ssh/config -rw------- 1 alice users 164 Nov 4 22:15 /home/starwarsfan/.ssh/config
Repository
+ trunk
| + _ADMIN
| + backup
| + base
| + chat
| + communication
| + contrib
| + database
| + devel
| + driver
| + game
| + kernel
| + lib
| + libdev
| + mail
| + misc
| + multimedia
| + netservices
| + netutils
| + news
| + plang
| + printer-file
| + security
| + system
| + utils
| + web
|
+ branches
| + backup
| + base
...
| + utils
| + web
|
+ tags
| + backup
| + base
...
+ utils
+ web
Der Ordner '_ADMIN' ist nur im Trunk vorhanden. Dort liegen die mit diesem Paket gelieferten Build-Scripte. Die restlichen Ordner sind in allen drei Basis-Ordnern identisch.
Die Sektion-Ordner werden anhand der Einträge aus dem File 'sections-new.txt' erzeugt. Darauf bauen im weiteren Verlauf auch die Build-Scripte auf. Je nachdem in welcher Sektion später Pakete entwickelt werden, werden sich die entsprechenden Ordner nach und nach mit Inhalt füllen.
In den folgenden Abschnitten eine kurze Erläuterung, wofür die Sektionen zu verwenden sind.
Einfach gesagt: In der Sektion 'lib' werden sowohl die 'lib-' als auch die 'libdev-'Pakete entwickelt. Damit liegt alles was zusammen gehört in einem Basisordner.
Die Pakete dieser Sektionen sollen zum jeweils nächsten Release nach Möglichkeit in der nun gültigen Sektion erscheinen.
Jedes den Build-Scripten bekannte Paket wird einmalig in der Datei 'folder-list-new.txt' eingetragen. In dieser Datei wird die Sektion-Struktur erneut abgebildet und durch den Eintrag eines Paketes an entsprechender Stelle dessen Platzierung im Repository definiert. Für die beiden Pakete 'phpmyadmin' und 'phpldapadmin' würde das wie folgt aussehen:
backup:#---------------BACKUP--------------------- base:#---------------BASE----------------------- chat:#---------------CHAT----------------------- communication:#---------------COMMUNICATION-------------- contrib:#---------------CONTRIB-------------------- database:#---------------DATABASE------------------- database:phpmyadmin <-- devel:#---------------DEVEL---------------------- drivers:#---------------DRIVERS-------------------- game:#---------------GAME----------------------- kernel:#---------------KERNEL--------------------- lib:#---------------LIB------------------------ libdev:#---------------LIBDEV--------------------- mail:#---------------MAIL----------------------- misc:#---------------MISC----------------------- multimedia:#---------------MULTIMEDIA----------------- netservices:#---------------NETSERVICES---------------- netutils:#---------------NETUTILS------------------- netutils:phpldapadmin <-- news:#---------------NEWS----------------------- plang:#---------------PLANG---------------------- printer-file:#---------------PRINTER-FILE--------------- security:#---------------SECURITY------------------- system:#---------------SYSTEM--------------------- utils:#---------------UTILS---------------------- web:#---------------WEB------------------------
(Die beiden Pfeile am Zeilenende dienen nur der Illustration!)
Es gibt für jede Sektion eine Zeile als Separator-Eintrag nach obigem Schema. Nach der Sektion folgt getrennt durch ':#' ein einfacher Kommentar, welcher im TextGUI der Scripte zur optischen Trennung der Sektionen verwendet wird.
Nach diesem Eintrag werden die Pakete der jeweiligen Sektion aufgelistet. Ein Eintrag für ein Paket hat zwingend den folgenden Aufbau:
<section>:<package>
Die Sektion muss dabei einem Eintrag aus 'sections-new.txt' entsprechen.
Hinweis: Eine Sonderstellung bei der Einordnung nehmen libdev-Pakete ein. Diese Pakete haben zwar eine eigene Sektion, werden jedoch physikalisch zusammen mit der zugehörigen Library in der Sektion 'lib' vorgehalten. Damit wird eine einfache Wartung und Entwicklung der entsprechenden Pakete gewährleistet, da somit sämtliche Bestandteile beeinander sind und nicht zwei Ordner aus verschiedenen Sektionen ausgecheckt werden müssen. Für das Handling von Library-Paketen folgt später noch ein eigenes Kapitel.
Entsprechend dem Eintrag in 'folder-list-new.txt' existiert für das Paket im tatsächlichen Sektion-Ordner unterhalb von 'trunk' der eigentliche Paket-Ordner, in welchem das Paket entwickelt und gepflegt wird:
Repository + trunk ... | + contrib | + database | | + phpmyadmin | | | + devel | + dns-dhcp ...
Repository
+ trunk ... | + contrib | + database | | + phpmyadmin | | + _ADMIN | | | - phpmyadmin-global-settings.txt | | | | | + common | | | + _ADMIN | | | | - phpmyadmin-files.txt | | | | - phpmyadmin-settings.txt | | | | - phpmyadmin-state.txt | | | | - phpmyadmin-version.txt | | | | | | | + tmp | | | + usr | | | + var | | | | | + eisfair-1 | | | + _ADMIN | | | + var | | | | | + eisfair-2 | | + _ADMIN | | + var | | | | | + devel | + dns-dhcp ...
Hier die Kurzform: In den Ordnern _unterhalb_ eines Paket-Ordners gibt es immer gültige Bestandteile eines Paketes mit allem was dazu gehört. Also auch eine FileList für den Inhalt _dieses_ Ordners. Im globalen Settingsfile wird angegeben, welche dieser Ordner zusammengepackt werden, um ein komplettes eisfair-Paket zu erzeugen. So lassen sich die Bestandteile eines Paketes aufteilen: Unterhalb von common liegt das, was bei allen Paketen gleich ist. In den anderen Ordnern dann der 'Rest', welcher für ein komplettes Paket fehlt, jedoch von Zielsystem zu Zielsystem unterschiedlich ist.
Neben dem Ordner '_ADMIN' wird noch 'common' sowie bei Bedarf 'eisfair-1' und 'eisfair-2' angelegt. Das ist davon abhängig, für welches Zielsystem das Paket entwickelt werden soll.
Ein Vorgriff auf das Script zum Anlegen eines neuen Paketes: Soll das Paket für nur ein Zielsystem entwickelt werden (bspw. nur für eisfair-2), dann werden nur die Ordner '_ADMIN' und 'common' angelegt. Werden jedoch mehrere Zielsysteme gewünscht, dann werden für jedes dieser Zielsysteme separate Ordner erzeugt. Der Sinn und Zweck dieser Übung wird in den folgenden Abschnitten erklärt.
Im Ordner '<package>/common/' sowie jedem weiteren Ordner parallel dazu gibt es ebenfalls einen Ordner '_ADMIN/', welcher die folgenden vier Dateien enthält:
Weiterhin befindet sich unterhalb von '<package>/common/' die minimal notwendige Verzeichnis-Struktur, welche für ein eisfair-Paket benötigt wird. Es ist kein Problem, hier bei Bedarf weitere Verzeichnisse anzulegen.
Sind neben '<package>/_ADMIN/' und '<package>/common/' weitere Ordner vorhanden (wie bspw. '<package>/eisfair-1' und '<package>/eisfair-2'), so enthalten diese jeweils mindestens wieder einen Ordner '_ADMIN' sowie 'var/install/packages/' mit einem minimalen Package-Info-File.
Die Idee hinter dieser Strukturierung ist die: Wird ein Paket nur für ein Zielsystem gebaut (bspw. eisfair-1) oder es ist für mehrere Zielsysteme identisch (wie bspw. phpmyadmin), dann wird nur der Ordner 'common' benötigt und darin das gesamte Paket entwickelt.
Unterscheiden sich jedoch Teile des Paketes wie bspw. unterschiedliche Binaries für eisfair-1 und eisfair-2, so werden diese Teile unterhalb von '<package>/eisfair-1/...' bzw. '<package>/eisfair-2/...' gepflegt. Damit ist es möglich, die identischen Teile wie bspw. die Doku oder Install-Scripte in '<package>/common/...' einmalig für beide Pakete zu pflegen, während die unterschiedlichen Bestandteile separat abgelegt werden.
An dieser Stelle kommt die Datei '<package>-global-settings.txt' ins Spiel. Darin werden die Bestandteile der verschiedenen Build-Targets definiert. Das sieht für das eben beschriebene Beispiel so aus:
packageComment[0]='Package for eisfair-1'
packageToBuild[0]='common
eisfair-1'
packageComment[1]='Package for eisfair-2'
packageToBuild[1]='common
eisfair-2'
Wenn nun das Paket für eisfair-1 gebaut werden soll, so wird dem Build-Script mitgeteilt, dass es das Build-Target '0' bauen soll, welches sich aus den Ordnern 'common' und 'eisfair-1' zusammensetzt. Für eisfair-2 ist das demzufolge Build-Target '1', welches die Ordner 'common' und 'eisfair-2' verwendet.
In diesem Settings-File sind vorbereitete Einträge für zehn Build-Targets vorhanden, welche ihrerseits beliebig viele Ordner enthalten können. Somit ist Folgendes kein Problem:
...
packageComment[1]='Package for eisfair-2'
packageToBuild[1]='common
eisfair-2
special-content
more-content'
...
Damit werden die vier aufgelisteten Ordner in das Paket verpackt.
Wurden in den ersten beiden Ordnern keine Konfig-Files gefunden, dann werden alle weiteren Ordner durchsucht. Werden keine Konfigurationen gefunden, wird der Build abgebrochen.
Wenn sich ein Paket für verschiedene Zielsysteme unterscheidet, gibt es immer separate Ordner je Zielsystem. Somit sollte die Reihenfolge der Ordner in den Build-Targets in '<package>-global-settings.txt' immer so gewählt werden, dass an zweiter Stelle der Ordner steht, in welchem sich die jeweiligen Paket-Settings sowie das zu verwendende Package-Info-File befindet. Damit wird ermöglicht, dass die Pakete je nach Zielsystem eigenständig gepflegt werden können, was sich durch separate Versionsnummern je nach Zielsystem wiederspiegelt.
Es werden also die im Build-Target angegebenen Ordner von oben nach unten nach den Konfigurationsfiles durchsucht. Im Anschluss daran werden die enthaltenen Dateien in umgekehrter Reihenfolge, also von unten nach oben, zum Paket-Archiv hinzugefügt. Wird dabei eine Datei gefunden, welche bereits zum Archiv hinzugefügt wurde, wird der Build mit der Meldung auf eine doppelt vorhandene Datei abgebrochen. Dies kann explizit vermieden werden, indem eine (aus welchen Gründen auch immer) doppelt vorhandene Datei in der entsprechenden Filelist mit dem Flag 'i' (ignore) versehen wird.
Um dies nochmals zu verdeutlichen hier die Ordnerstruktur des fiktiven Paketes 'dbtool':
Repository + trunk ... | + database | | + dbtool | | + _ADMIN | | | - dbtool-global-settings.txt | | | | | + common | | | + _ADMIN | | | | - dbtool-files.txt | | | | - dbtool-settings.txt | | | | - dbtool-state.txt | | | | - dbtool-version.txt | | | | | | | + tmp | | | + usr | | | + var | | | | | + binaries-eisfair-1 | | | + _ADMIN | | | + usr | | | + sbin | | | | | + binaries-eisfair-2 | | | + _ADMIN | | | + usr | | | + sbin | | | | | + eisfair-1 | | | + _ADMIN | | | + var | | | | | + eisfair-2 | | + _ADMIN | | + var | | ...
Für diese Ordnerstruktur seien die folgenden Build-Targets definiert:
packageComment[0]='Package for eisfair-1'
packageToBuild[0]='common
eisfair-1
binaries-eisfair-1'
packageComment[1]='Package for eisfair-2'
packageToBuild[1]='common
eisfair-2
binaries-eisfair-2'
Wird nun das Paket für eisfair-1 gebaut, dann werden die Konfig-Dateien aus 'trunk/database/dbtool/eisfair-1/_ADMIN/' verwendet. Im weiteren Verlauf werden zunächst die Binaries aus 'trunk/database/dbtool/binaries-eisfair-1/' in das Archiv gepackt, dann die Dateien aus 'trunk/database/dbtool/eisfair-1/' und zuletzt die Dateien aus 'trunk/database/dbtool/common/'.
Alle weiteren Tags werden automatisch beim Build des Paketes aktualisiert.
Das folgende Kapitel widmet sich einer ausführlichere Betrachtung der Versionsnummer eines Paketes und deren Berechnung sowie dem daraus resultierenden Paket-Status.
<major>.<minor>.<bugfix>
Die drei Blöcke repräsentieren somit die Major-, Minor- und Bugfix-Version des Paketes. Ausserdem wird an Hand des Typs der Minor-Nummer der Status des Paketes bestimmt:
Damit lassen sich alle möglichen Varianten abbilden und zudem ist allein aus der Versionsnummer heraus der Paket-Status einheitlich definiert.
Ein Paket würde sein Dasein also mit der Version 0.1.0 beginnen, einem 'testing'-Release. Auf den Status 'unstable' wurde ganz verzichtet, da damit eine genaue Definition dessen, wann denn nun ein Paket 'unstabil' und wann 'zum testen geeignet' ist, auch nicht vereinfacht wird. Es ist lediglich so, dass ein Paket mit der Version 0.x.x immer 'testing' ist, die anderen Status kommen erst ab Version 1.0.0 zum tragen.
Somit ergibt sich bspw. folgender Ablauf:
1. Release 1.0.0 <-- Stable 2. Bugfix 1.0.1 <-- ebenfalls Stable 3. Bugfix 1.0.2 <-- nochmal Stable 4. Vorabversion 1.1.0 <-- Testing 5. Bugfix 1.0.3 <-- wieder Stable 6. Vorabversion 1.1.1 <-- Testing 7. Release 1.2.0 <-- Stable 8. Bugfix 1.2.1 <-- Bugfix der neuesten Stable-Version 9. Bugfix 1.0.4 <-- Bugfix einer älteren Version
Nun stellt sich höchstwahrscheinlich die Frage, wie die Version 1.0.3 an Position fünf dort hineinpasst und wie die Version 1.0.4 in der letzten Zeile 'gemacht' werden soll.
Die Scripte in diesem Paket unterstützen konsequent das bewährte Subversion-Konzept von 'Trunk', 'Tags' und 'Branches'. Damit wird eine solch flexible Paketpflege erst ermöglicht. Konkret lauft das wie folgt ab:
Das Paket wird im Trunk entwickelt. Das von dort veröffentlichte Paket erhält die Version 1.0.0. Aus dieser Version wird ein Bugfix-Branch angelegt, auf welchem die Bugfixes (und nur die Bugfixes!) zu dieser stabilen Version implementiert werden. Da hier nur Bugfixes und keine Features implementiert werden, sind die aus dem Bugfix-Branch generierten Pakete ebenfalls 'stable'.
Da bei dieser Vorgehensweise die weitere Entwicklung eines Paketes von den Bugfixes losgelöst ist, können also die einzelnen stabilen Releases unabhängig voneinander gepflegt werden. Damit werden die Features des Pakets im Trunk weiterentwickelt und können als 'testing' herausgegeben werden, während im Bugfix-Branch bzw. in den Bugfix-Branches die stabilen Versionen 'stabil bleiben'. Je nach Umfang der änderungen werden die relevanten Teile aus dem Bugfix-Branch in den Trunk gemerged, so dass diese dort ebenfalls enthalten sind.
Hier sei auf die Dokumentation von Subversion [1] verwiesen, insbesondere auf die Kapitel zum mergen von Bugfixes in den Release-Branch.
Damit sollte klar sein, dass in obigem Beispiel die Einträge 1., 4., 6. und 7. aus dem 'trunk' kommen, 2., 3., 5., 8. und 9. jedoch aus 'branches'.
Wichtig: Die Scripte des Paketes 'packagedevelopment' kümmern sich um alle notwendigen Schritte bei der Erzeugung und dem Checkout sowohl des Bugfix-Branches als auch der entsprechenden Tags! Der Entwickler muss also lediglich an den 'richtigen' Stellen arbeiten, der Rest wird ihm abgenommen.
<major>.<minor>.<bugfix>\_<target-no>[\_<destination-system>]*
Bugfix-Branches sehen prinzipiell genauso aus, nur werden diese bei '<bugfix>' durch ein 'x' kenntlich gemacht.
Bsp.:
- 1.0.0\_0\_eisfair-1 Release 1.0.0 für eisfair-1, hieraus entsteht
der Bugfix-Branch 1.0.x\_0\_eisfair-1
- 1.0.0\_1\_eisfair-2 Release 1.0.0 für eisfair-2, hieraus entsteht
der Bugfix-Branch 1.0.x\_1\_eisfair-2
- 1.2.3\_0\_eisfair-1 Dritter Bugfix für Release 1.2.0 für eisfair-1
- 2.0.2\_1\_eisfair-2 Zweiter Bugfix für Release 2.0.0 für eisfair-2
Diese Ordner sowie die dazugehörenden Bugfix-Branches gliedern sich wie folgt in die Repository-Struktur ein:
Repository
+ trunk
...
|
+ tags
| + database
| | + dbtool
| | + 1.0.0\_0\_eisfair-1
| | + 1.0.0\_1\_eisfair-2
| | + 1.2.3\_0\_eisfair-1
| | + 2.0.2\_1\_eisfair-2
...
+ branches
...
+ database
| + dbtool
| + 1.0.x\_0\_eisfair-1
| + 1.0.x\_1\_eisfair-2
| + 1.2.x\_0\_eisfair-1
| + 2.0.x\_1\_eisfair-2
...
An dieser Stelle ein sehr wichtiger Hinweis: Unterhalb dieser Ordner befindet sich zwar jeweils der gesamte Paket-Inhalt, dieser ist aber _nur_ für das im Ordnernamen aufgeführte Build-Target wirklich valid! Das hat seinen Grund unter anderem darin, dass die Pakete für die verschiedenen Zielsysteme eigenständige Versionsnummern haben, welche sich sonst nicht sauber in Tags bzw. Branches auflösen lassen würden. Da in diesen Ordnern aber keinerlei Weiterentwicklung der Pakete erfolgt sondern lediglich die Bugfixes bearbeitet werden, stellt diese Einschränkung keine allzu grosse Hürde dar. Zudem hat der Entwickler dank Subversion jederzeit die Möglichkeit, die Inhalte der Ordner zu mergen.
Bei allen Operationen bietet das GUI die Möglichkeit an, die aktuelle Operation abzubrechen und wieder ins Hauptmenü zurück zu gelangen.
Die folgenden Menüpunkte stehen zur Verfügung:
#======================================================================== # eisfair - the easy internet server No package selected #======================================================================== # # Please choose your next step by entering one of the following numbers: # (You will be asked for additional information if necessary) # 1 - List known packages out of folder list # 2 - Create empty structure for a new package # 3 - Check out existing package or update a existing working copy (tag' # version, bugfix branch by base version number or main development) # 4 - (Re)Create file list for a folder on a package # 5 - Create a release of a package (testing (odd minor number), stable # (even minor) or bugfix (even minor and upcounting bugfix number)) # 6 - Create a tag of the actual state of the trunk (for a stable or # testing release) or the actual state of a bugfix branch # 7 - Show released versions of a package # 8 - Eislist administration (show/search/add/remove/re-create) # # C - Choose package # H - Command history Any other key will end up this script #========================================================================
Bei allen Operationen welche sich auf ein vorhandenes Paket beziehen, wird zunächst das zu bearbeitenden Paket ausgewählt. Das selektierte Paket wird daraufhin in der Titelleiste eingeblendet:
#======================================================================== # eisfair - the easy internet server Working on foobar #========================================================================
Solange das GUI nicht beendet wird, bleibt diese Auswahl erhalten. Um sie zu ändern kann der Menüpunkt 'C - Choose package' verwendet werden. Siehe dazu den Abschnitt 'Choose package'.
Die folgenden Dinge werden abgefragt:
Nachdem diese Angaben erfolgt sind, werden einige Checks ausgeführt und wenn keine Probleme aufgetreten sind, wird das Paket angelegt.
Dabei kann das Paket aus der Liste aller Pakete oder aus der Liste der Pakete einer Sektion ausgewählt bzw. Sektion und Paketname von Hand eingegeben werden.
Danach wird erfragt, von wo ausgecheckt bzw. updated werden soll. Bedingt durch die Subversion Repository Struktur stehen hier drei Möglichkeiten zur Wahl:
Bei Auswahl von Branch oder Tag wird eine weitere Angabe benötigt und zwar die gewünschte Version in der Form <major.minor> für Bugfix-Branches bzw. <major.minor.bugfix> für Tags. Wird hier keine Angabe gemacht, so wird die aktuellste Version (also die Version mit der höchsten Versionsnummer) ermittelt und diese ausgecheckt bzw. aktualisiert.
Es wird das Paket erfragt und für welchen Ordner unterhalb des Paketes die FileList erzeugt werden soll. Damit ist es möglich, die FileList für jeden der Ordner unterhalb von .../<section>/<package>/ separat zu erzeugen. Eine bereits vorhandene FileList wird vorher im gleichen Ordner als '<package>-files.txt.bak' gesichert und zu svn:ignore hinzugefügt. Somit können von dieser 'alten' FileList die Dateirechte der einzelnen Files übernommen werden, falls diese nicht den bei der Erstellung der FileList vorgefundenen Rechten entsprechen.
Der Aufbau der FileList wird in der Entwickler-Dokumentation beschrieben und aus diesem Grund hier nicht nochmals dargelegt.
Dabei kann das Paket aus der Liste aller Pakete oder aus der Liste der Pakete einer Sektion ausgewählt bzw. Sektion und Paketname von Hand eingegeben werden.
Danach wird erfragt, von wo aus ein Tag erzeugt werden soll. Bedingt durch die Subversion Repository Struktur stehen hier zwei Möglichkeiten zur Wahl:
Bei der Auswahl von Trunk wird daraufhin erfragt, für welches Build-Target ein Tag angelegt werden soll.
Bei der Auswahl von Branch wird erfragt, für welchen der gefundenen Bugfix-Branches ein Tag erzeugt werden soll. Hier entfällt die Frage nach dem Build-Target, das dieses durch den Branch selbst bereits vorgegeben ist.
Hier können nun die Eislists administriert werden. Dabei wird zunächst die gewünschte Eislist erfragt und daraufhin ein Menü mit den möglichen Operationen angezeigt. Die Operationen im Einzelnen:
Bei einer einfachen Eislist werden alle Pakete in einer Liste aufgeführt. Bei einer strukturierten Eislist hingegen werden zunächst die Sektionen der gefundenen Pakete aufgeführt und erst nach Auswahl einer dieser Sektionen die dort befindlichen Pakete. Das entspricht dem Aufbau der Eislist, welche bei der normalen Paketinstallation via PackEis zu sehen ist.
Auch hier muss zunächst das gewünschte Paket ausgewählt werden. Danach wird erfragt, welchen Release-Typ man erzeugen möchte. Damit wird automatisch festgelegt, woher die zu verpackenden Daten kommen. Die folgenden Möglichkeiten stehen zur Wahl:
1) Abort operation 4) A bugfix release 2) A testing release 5) A package from an existing tag 3) A stable release
Auswahl 1) bricht die Operation ab, 2) und 3) legen 'trunk' als Quelle fest. Bei Auswahl von 4) wird 'branches' bzw. bei 5) 'tags' verwendet. Bei 4) und 5) folgt darauf noch eine zusätzliche Frage nach dem zu verwendenden Branch bzw. dem zu verwendenden Tag, da bei Branches bzw. Tags jeweils ein zusätzlicher Ordner vorhanden ist (siehe '6.5 Erzeugung von Tags und Branches').
Im nächsten Schritt wird erfragt, ob das Paket erneut mit der aktuellen Versionsnummer gebaut werden soll. Per default wird die Versionsnummer _nicht_ modifiziert. Aus diesem Grund wird die folgende Vorgehensweise empfohlen: Wurde eine Version released und die Entwicklung geht weiter, dann sollte der erste Paketbau als 'testing' _mit_ Modifizierung der Versionsnummer erfolgen. Damit wird die gültige Versionsnummer nach dem bereits erfolgten Release in <package>-version.txt eingetragen und solange an dem Paket entwickelt wird, kann es beliebig oft mit dieser Versionsnummer gebaut werden. Nachdem es released wurde, wird ein entsprechendes Tag erzeugt und der Zyklus beginnt von vorn.
Wichtiger Hinweise: Es ist _nicht_ möglich ein 'trunk'- bzw. ein 'bugfix'-Paket ohne Veränderung der Versionsnummer zu bauen, wenn für diese Version bereits ein Tag existiert! Genau für diesen Fall existiert ein Tag und kann bzw. muss für den Bau exakt dieser Version verwendet werden. Somit ist es im Fall der Paketweiterentwicklung bei ge'tag'ten Versionen zwingend erforderlich, dass der erste Build _mit_ Modifizierung der Versionsnummer erfolgt.
Im nächsten Schritt wird das gewünschte Build-Target erfragt. Hier werden die in der Datei '<package>-global-settings.txt' angegebenen Kommentare zu den einzelnen Build-Targets zur Auswahl aufgelistet. Wurden keine Kommentare eingetragen, so werden die Ordnernamen aufgelistet.
Nun folgt die Frage nach dem im <date>-Tag zu setzenden Datum. Dabei stehen die folgenden Auswahlmöglichkeiten zur Verfügung:
1) Abort operation 2) Now (with extension 'svn2008-07-11' right after the version number) 3) Now 4) Keep 5) Enter by hand
zu 1) Abbruch der aktuellen Operation. zu 2) Diese Variante baut sog. 'svn-Versionen' eines Paketes. Dabei wird die Versionsangabe im <version>-Tag um die Angabe 'svn<datum>' erweitert, was bspw. so aussehen kann: '<version>1.2.3svn2008-05-02<version>'. Auf diese Art und Weise können Pakete gleicher Versionsnummer aber unterschiedlicher Entwicklungsstände bspw. auf der Tester-Eislist für Tests zur Verfügung gestellt werden, ohne für kleinere Änderungen immer neue Versionsnummern generieren zu müssen. Somit dient diese Variante lediglich der Entwicklung und ist für echte Releases nicht anwendbar. Pakete mit einem solchen Tag können auch nicht auf PackEis veröffentlicht werden. zu 3) Es wird das aktuelle Datum verwendet. zu 4) Das Datum wird nicht verändert. zu 5) Das einzutragende Datum kann in der Form YYYY-MM-DD vorgegeben werden.
Nun folgen drei Fragen zur Veröffentlichung des Paketes, sprich dem Eintragen des Paketes in die drei möglichen Eislists. Per default wird das Paket in die Entwickler-Eislist eingetragen, in die TestTeam- und die Release-Eislist jedoch nicht.
Die letzte Frage vor dem Bau des Paketes ist die Frage, ob die modifizierten Dateien ins Repository commited werden sollen. Per default werden _keine_ Dateien commited, so dass das Paket beliebig oft gebaut werden kann.
An dieser Stelle ist die 'Fragerunde' beendet und der Bau des Paketes beginnt. Dabei werden zunächst eine Reihe Checks durchgeführt und der Paketbau ggf. abgebrochen. So ist es bspw. nicht möglich, eine testing-Version ohne Modifikation der Versionsnummer zu bauen, wenn die aktuelle Versionsnummer einer stable-Version entspricht. Weiterhin wird der Build abgebrochen, wenn die FileLists nicht korrekt sind. Dabei gibt es prinzipiell zwei Fälle zu unterscheiden: Einerseits können Dateien vorhanden sein, welche nicht in der jeweiligen FileList eingetragen sind und andererseits können Dateien in der FileList eingetragen sein, welche es aber im Dateisystem nicht (mehr) gibt.
Sollte der Build mit einer entsprechenden Fehlermeldung abgebrochen worden sein bzw. man weiss, dass Dateien hinzugefügt oder entfernt worden sind, dann muss die FileList des entsprechenden Ordners aktualisiert werden. Siehe dazu das Kapitel '(Re)Create file list for a folder on a package'.
Das File 'lib<package>-globel-settings.txt' hat damit beispielhaft den folgenden Aufbau:
# Package out of the content of common and eisfair-1
packageComment[0]='Content of common and eisfair-1_bin_4.2.2'
packageToBuild[0]='common
eisfair-1_bin_4.2.2'
devPackage[0]=1
# Dev-package out of the content of common-dev and eisfair-1-dev
packageComment[1]='Content of common-dev and eisfair-1-dev_bin_4.2.2'
packageToBuild[1]='common-dev
eisfair-1-dev_bin_4.2.2'
devPackage[1]=''
# Package out of the content of common and eisfair-2
packageComment[2]='Content of common and eisfair-2_bin_4.2.2'
packageToBuild[2]='common
eisfair-2_bin_4.2.2'
devPackage[2]=3
# Dev-package out of the content of common-dev and eisfair-2-dev
packageComment[3]='Content of common-dev and eisfair-2-dev_bin_4.2.2'
packageToBuild[3]='common-dev
eisfair-2-dev_bin_4.2.2'
devPackage[3]=''
Durch die Angabe von 'devPackage[0]=1' wird festgelegt, dass das libdev-Paket zum BuildTarget 0 das BuildTarget 1 ist. Entsprechend ist BuildTarget 3 das libdev-Paket für BuildTarget 2.
Beim Bau eines lib-Paketes über das Text-GUI wird erfragt, ob das libdev-Paket gleich mit gebaut werden soll. Dementsprechend wird beim Bau eines libdev-Paketes via Text-GUI erfragt, ob der Build an dieser Stelle abgebrochen werden soll, wenn man für das libdev-Paket auch das lib-Paket bauen möchte.
Eine weitere Besonderheit stellt die automatisierte Aktualisierung des Installationsscriptes 'tmp/install.sh' dar. Endet der letzte der im Build-Target angegebenen Ordner auf eine dreistellige, durch '.' separierte und mit '_' angehängte Versionsnummer, so wird install.sh mit dieser Versionsnummer aktualisiert. Damit wird eine automatisierte Erzeugung der benötigten Symlinks für Libraries ermöglicht. Die ermittelte Versionsnummer wird ebenfalls verwendet, um das PackageInfoFile zu aktualisieren.
Um diese Aktualisierungen vorzunehmen, wird in install.sh nach der Zeichenkette 'libVersion=' gesucht und diese mit der ermittelten Lib-Version aktualisiert. Aus diesem Grund gibt es in install.sh den folgenden Abschnitt:
# Don't change the name of the following variable! It is automatically # updated during the package build with mktarball libVersion=<version>
Im PackageInfoFile wird nach 'Internal Program Version:' gesucht und diese Zeile mit dem Namen der Bibliothek sowie deren Version aktualisiert.
Wird diese Funktionalität nicht gewünscht, so gibt es zwei Varianten:
<major>.<minor>.<bugfix>\_<lib-target>\_<libdev-target>[\_<dest-system>]*
Somit sieht das beispielhaft wie folgt aus:
1.2.0\_0\_1\_eisfair-1
Um ein solches Script bei Bedarf zu erzeugen, steht das Script 'create-do-script-new.sh' zur Verfügung. Dazu muss dieses Script lediglich aus dem _ADMIN-Ordner heraus aufgerufen werden, in welchem ein _do_<package>.sh-Script erzeugt werden soll. Als einziger Parameter ist der Paketname erforderlich, da der Ordnername nicht zwingend dem Paketnamen entspricht. Das erzeugte Script enthält Funktionsrümpfe, welche vom Entwickler mit der gewünschten Funktionalität gefüllt werden müssen.
Würde ein solches Script für das weiter oben bereits verwendete fiktive Paket 'dbtool' für spezielle Aufgaben unterhalb des Ordners 'eisfair-1' benötigt werden, sähe die Ordnerstruktur wie folgt aus:
+ trunk ... | + database | | + dbtool | | + _ADMIN | | + common | | + binaries-eisfair-1 | | + binaries-eisfair-2 | | + eisfair-1 | | | + _ADMIN | | | | - _do_dbtool.sh | | | | - dbtool-files.txt | | | | - dbtool-settings.txt | | | | - dbtool-state.txt | | | | - dbtool-version.txt | | | + var | | | | | + eisfair-2 ...
Wird ein solches Script während dem Paketbau gefunden, so wird es zweimal aufgerufen: Einmal vor dem Verpacken der Dateien in das Paketarchiv und einmal danach. Die Unterscheidung dieser Aufrufe erfolgt durch entsprechende Parameter. Innerhalb des Scriptes steht der volle Pfad zum trunk-Ordner für die weitere Verwendung zur Verfügung.
Ein einfaches Beispiel zur Anwendung: Der preBuild-Teil des do-Scriptes holt sich die Sourcen eines Tools von einem öffentlichen Server, entpackt und kompiliert diese und erzeugt mit dem Script 'create-list-new.sh' die FileList. Damit ist der preBuild-Teil beendet und der normale Paketbau läuft ab.
Der postBuild-Teil räumt wieder auf, indem er die Sourcen sowie die erzeugten Binaries löscht.
Mit dieser Vorgehensweise ist es möglich, den eigentlichen Inhalt eines Paketes mit relativ wenig Aufwand aktualisieren zu können.
Dabei ist konfigurierbar, welche Build-Targets der Pakete gebaut werden sollen und welche nicht. Realisiert wird das durch die Variable 'nightlyBuilds' in '<package>-global-settings.txt'. Diese enthält eine durch Spaces separierte Liste der Build-Targets, welche beim Nightly-Build gebaut werden sollen. Sollen also bspw. die Build-Targets 0, 2 und 3 eines Paketes innerhalb des Nightly-Build gebaut werden, so muss folgendes im globalen Settingsfile des Paketes eingetragen werden:
nightlyBuilds='0 2 3'
Für die Nightly-Builds gibt es ein separates Konfigurationsfile, welches vom Aufbau her identisch mit dem normalen Konfigurationsfile ist. Damit besteht die Möglichkeit, im Konfigfile 'settings-nightly-builds.txt' einen anderen Pfad zum Ablegen der erzeugten Pakete zu verwenden.
Die Nightly-Builds werden durch den periodischen Aufruf des Scriptes 'mk-all-tarballs-new.sh' realisiert, welcher in einem Cron-Job untergebracht werden kann. Innerhalb dieses Scriptes wird über die in 'folder-list-new.txt' gefundenen Pakete iteriert und je nach den in 'nightlyBuilds' vorgefundenen Werte der Build des Paketes angestossen. Dabei erfolgt selbstverständlich keine Modifikation der Versionsnummer und auch kein svn-Commit.
Achtung! Besondere Vorsicht muss bei den Schritten innerhalb der _do_-Scripte geboten sein! Führt ein _do_-Script selbständig commit's durch, so wird das auch bei den Nightly-Builds der Fall sein.
Gültige Werte: yes, no
Standard-Einstellung: START_PACKAGEDEVELOPMENT='yes'
Gültige Werte: yes, no
Standard-Einstellung: PKGDEV_SETUP_FOR_NEW_REPO='yes'
Wird 'svn+ssh://' verwendet, so muss im Home-Verzeichnis des in PKGDEV_WORKING_COPY_USER angegebenen Users das File '.ssh/config' vorhanden sein. Darin muss die SSH-Verbindung zum Repository-Server konfiguriert werden. Weitere Informationen siehe Doku im Abschnitt 3.1 SSH-Konfiguration, Repository-Zugriff mit svn+ssh://
Gültige Werte: 'file://', 'http://', 'https://', 'svn://', 'svn+ssh://'
Standard-Einstellung: PKGDEV_REPO_PROTOCOL='file://'
Gültige Werte:
Standard-Einstellung: PKGDEV_REPO_PATH='/data/repo/eisfair'
Dieser Eintrag findet nur bei PKGDEV_REPO_PROTOCOL='http://' oder bei PKGDEV_REPO_PROTOCOL='https://' Anwendung.
Standard-Einstellung: PKGDEV_REPO_USERNAME=''
Dieser Eintrag findet nur bei PKGDEV_REPO_PROTOCOL='http://' oder bei PKGDEV_REPO_PROTOCOL='https://' Anwendung.
Standard-Einstellung: PKGDEV_REPO_PASSWORD=''
Gültige Werte: gültiger absoluter Pfad
Standard-Einstellung: PKGDEV_WORKING_COPY_PATH='/data/development/eisfair'
Gültige Werte: gültiger Username
Standard-Einstellung: PKGDEV_WORKING_COPY_USER='root'
Gültige Werte: vorhandene Gruppe
Standard-Einstellung: PKGDEV_WORKING_COPY_GROUP='root'
Gültige Werte: gültiger absoluter Pfad
Standard-Einstellung: PKGDEV_DEVELOPMENT_PACKAGE_BASE_FOLDER= '/var/www/htdocs/eisfair/development'
Gültige Werte: gültiger absoluter Pfad
Standard-Einstellung: PKGDEV_TESTTEAM_PACKAGE_BASE_FOLDER= '/var/www/htdocs/eisfair/testteam'
Gültige Werte: gültiger absoluter Pfad
Standard-Einstellung: PKGDEV_RELEASE_PACKAGE_BASE_FOLDER= '/var/www/htdocs/eisfair/release'
Gültige Werte: yes, no
Standard-Einstellung: PKGDEV_ADVANCED_SETTINGS='no'
Gültige Werte: oktaler Zahlenwert, siehe Parameter für Befehl 'chmod'
Standard-Einstellung: PKGDEV_DEVELOPMENT_PACKAGE_BASE_FOLDER_PERMISSION='2775'
Gültige Werte: oktaler Zahlenwert, siehe Parameter für Befehl 'chmod'
Standard-Einstellung: PKGDEV_TESTTEAM_PACKAGE_BASE_FOLDER_PERMISSION='2775'
Gültige Werte: oktaler Zahlenwert, siehe Parameter für Befehl 'chmod'
Standard-Einstellung: PKGDEV_RELEASE_PACKAGE_BASE_FOLDER_PERMISSION='2775'
Gültige Werte: oktaler Zahlenwert, siehe Parameter für Befehl 'chmod'
Standard-Einstellung: PKGDEV_DEVELOPMENT_PACKAGE_BASE_FILE_PERMISSION='664'
Gültige Werte: oktaler Zahlenwert, siehe Parameter für Befehl 'chmod'
Standard-Einstellung: PKGDEV_TESTTEAM_PACKAGE_BASE_FILE_PERMISSION='664'
Gültige Werte: oktaler Zahlenwert, siehe Parameter für Befehl 'chmod'
Standard-Einstellung: PKGDEV_RELEASE_PACKAGE_BASE_FILE_PERMISSION='664'
Gültige Werte: gültiger User
Standard-Einstellung: PKGDEV_DEVELOPMENT_PACKAGE_BASE_FOLDER_USER='wwwrun'
Gültige Werte: gültiger User
Standard-Einstellung: PKGDEV_TESTTEAM_PACKAGE_BASE_FOLDER_USER='wwwrun'
Gültige Werte: gültiger User
Standard-Einstellung: PKGDEV_RELEASE_PACKAGE_BASE_FOLDER_USER='wwwrun'
Gültige Werte: gültige Gruppe
Standard-Einstellung: PKGDEV_DEVELOPMENT_PACKAGE_BASE_FOLDER='nogroup'
Gültige Werte: gültige Gruppe
Standard-Einstellung: PKGDEV_TESTTEAM_PACKAGE_BASE_FOLDER_GROUP='nogroup'
Gültige Werte: gültige Gruppe
Standard-Einstellung: PKGDEV_RELEASE_PACKAGE_BASE_FOLDER_GROUP='nogroup'
Gültige Werte: gültiger Ordnername
Standard-Einstellung: PKGDEV_FOLDER_NAME_TRUNK='trunk'
Gültige Werte: gültiger Ordnername
Standard-Einstellung: PKGDEV_FOLDER_NAME_TRUNK='branches'
Gültige Werte: gültiger Ordnername
Standard-Einstellung: PKGDEV_FOLDER_NAME_TRUNK='tags'
Gültige Werte: 'gzip', 'bzip2'
Standard-Einstellung: PKGDEV_ARCHPROG='gzip'
Gültige Werte: String
Standard-Einstellung: PKGDEV_SECTION_FILE='sections-new.txt'
Die Datei wird wie auch das Section-File im Ordner 'trunk/_ADMIN' im Repository gesucht.
Gültige Werte: yes, no
Standard-Einstellung: PKGDEV_FOLDER_LIST_FILE='folder-list-new.txt'
Gültige Werte: http://<pfad> oder file://<pfad>
Standard-Einstellung: PKGDEV_INDEX_SOURCE=http://www.pack-eis.de/index.txt
Gültige Werte: Ziffer
Standard-Einstellung: PKGDEV_COMMAND_HISTORY=5
Gültige Werte: yes, no
Standard-Einstellung: PKGDEV_DEBUG_OUTPUT='no'
Gültige Werte: yes, no
Standard-Einstellung: PKGDEV_SETUP_NIGHTLY_BUILDS='no'
Allowed values and meaning
--------------------------
0-59 .. minute
0-23 .. hour
1-31 .. day of month
1-12 .. month (or names)
0-7 .. day of week (0 or 7 is Sun, or use names)
Gültige Werte: * * * * *
Standard-Einstellung: PKGDEV_NIGHTLY_SCHEDULE='2 3 * * *'
Gültige Werte: Gültige Email-Adresse
Standard-Einstellung: PKGDEV_NIGHTLY_MAIL_TO='root@localhost'
Gültige Werte: gültiger absoluter Pfad
Standard-Einstellung: PKGDEV_NIGHTLY_WORKING_COPY_PATH='/data/development/eisfair'
Gültige Werte: gültiger Username
Standard-Einstellung: PKGDEV_NIGHTLY_WORKING_COPY_USER='root'
Gültige Werte: vorhandene Gruppe
Standard-Einstellung: PKGDEV_NIGHTLY_WORKING_COPY_GROUP='root'
Achtung: Bei Verwendung von Subversion 1.5.x sollte für die Nightly-Builds eine separate Working-Copy verwendet werden, damit ein vollständiges Update durchgeführt werden kann. Anderenfalls kann es zu Schwierigkeiten kommen, da ab Subversion 1.5.x Sparse-Checkouts möglich sind.
Gültige Werte: yes, no
Standard-Einstellung: PKGDEV_NIGHTLY_WORKING_COPY_DO_UPDATE='yes'
Gültige Werte: gültiger absoluter Pfad
Standard-Einstellung: PKGDEV_NIGHTLY_PACKAGE_BASE_FOLDER='/var/www/htdocs/eisfair/development'
Gültige Werte: gültiger Ordnername
Standard-Einstellung: PKGDEV_NIGHTLY_FOLDER_NAME_TRUNK='trunk'
Gültige Werte: yes, no
Standard-Einstellung: PKGDEV_NIGHTLY_BUILD_BUGFIXES='no'
Gültige Werte: gültiger Ordnername
Standard-Einstellung: PKGDEV_NIGHTLY_FOLDER_NAME_BRANCHES='branches'
Gültige Werte: oktaler Zahlenwert, siehe Parameter für Befehl 'chmod'
Standard-Einstellung: PKGDEV_NIGHTLY_PACKAGE_BASE_FOLDER_PERMISSION=775
Gültige Werte: oktaler Zahlenwert, siehe Parameter für Befehl 'chmod'
Standard-Einstellung: PKGDEV_NIGHTLY_PACKAGE_BASE_FILE_PERMISSION=664
Gültige Werte: gültiger User
Standard-Einstellung: PKGDEV_NIGHTLY_PACKAGE_BASE_FOLDER_USER='wwwrun'
Gültige Werte: gültige Gruppe
Standard-Einstellung: PKGDEV_NIGHTLY_PACKAGE_BASE_FOLDER_GROUP='nogroup'
Gültige Werte: 'gzip', 'bzip2'
Standard-Einstellung: PKGDEV_NIGHTLY_ARCHPROG='gzip'
Gültige Werte: String
Standard-Einstellung: PKGDEV_NIGHTLY_SECTION_FILE='sections-new.txt'
Die Datei wird wie auch das Section-File im Ordner 'trunk/_ADMIN/' im Repository gesucht.
Gültige Werte: yes, no
Standard-Einstellung: PKGDEV_NIGHTLY_FOLDER_LIST_FILE='folder-list-new.txt'
Gültige Werte: yes, no
Standard-Einstellung: PKGDEV_NIGHTLY_DEBUG_OUTPUT='no'
Yves Schumann 2012-05-08