Entwicklerhandbuch/PaketverwaltungManuell

Aus Delixs
Version vom 1. Februar 2010, 13:35 Uhr von Hjg (Diskussion | Beiträge) (Fragen und Antworten)
Zur Navigation springen Zur Suche springen

Einführung

In dieser Anleitung soll gezeigt werden, wie man einfache, debiankonforme Pakete erstellt und in das delixs-Repository hochlädt.

Vorarbeiten

Als Entwicklungsumgebung setze ich eine normale delixs aramec 0.10 Installation (bevorzugt als virtuelle Maschine) voraus. Hierauf müssen dann noch ein paar Tool installiert und konfiguriert werden.

Tools installieren

Installiere auf Deinem Rechner/VM die notwendigen Hilfsmittel mit folgendem Befehl:

<source lang="bash">

  aptitude install dpkg-dev debhelper devscripts fakeroot dh-make build-essential 
                   gnupg gnupg-agent dput openssh-client

</source>

Repository konfigurieren

Das offizielle delixs-Repository muß in die apt-Konfiguration übernommen werden.

Erstelle bzw. editiere die Datei /etc/apt/sources.list.d/delixs.list :

<source lang="apt_sources"> deb http://deb.delixs.de/ aramec/all/ deb http://deb.delixs.de/ aramec/$(ARCH)/

deb http://deb.delixs.de/ testing/all/ deb http://deb.delixs.de/ testing/$(ARCH)/ </source>

Danach ein aptitude update und das Repository ist eingebunden.

Nun müssen noch die delixs-Schlüssel installiert werden, damit keine Sicherheitswarnungen entstehen:

aptitude install delixs-archive-keyring

Danach wieder ein aptitude update, und das Repository ist offiziell verfügbar.

eigenen GPG-Schlüssel erzeugen

Da wir unsere Pakete später in das delixs-Repository hochladen wollen, müssen wir uns einen persönlichen GPG-Schlüssel generieren, mit dem die Pakete signiert werden. Unsignierte Pakete werden vom Repository nicht akzeptiert.

<source lang="bash"> $ gpg --gen-key Bitte wählen Sie, welche Art von Schlüssel Sie möchten:

  (1) DSA und Elgamal (voreingestellt)
  (2) DSA (nur unterschreiben/beglaubigen)
  (5) RSA (nur signieren/beglaubigen)

Ihre Auswahl? 1

Der DSA Schlüssel wird 1024 Bits haben. ELG-E-Schlüssel können zwischen 1024 und 4096 Bit lang sein. Welche Schlüssellänge wünschen Sie? (2048)

Bitte wählen Sie, wie lange der Schlüssel gültig bleiben soll.

        0 = Schlüssel verfällt nie
       = Schlüssel verfällt nach n Tagen
     w = Schlüssel verfällt nach n Wochen
     m = Schlüssel verfällt nach n Monaten
     y = Schlüssel verfällt nach n Jahren

Der Schlüssel bleibt wie lange gültig? (0) 5y

Sie benötigen eine User-ID, um Ihren Schlüssel eindeutig zu machen; das Programm baut diese User-ID aus Ihrem echten Namen, einem Kommentar und Ihrer E-Mail-Adresse in dieser Form auf:

   ``Heinrich Heine (Der Dichter) <heinrichh@duesseldorf.de>

Ihr Name ("Vorname Nachname"): Herman Mustermann Email-Adresse: herman.mustermann@delixs.de Kommentar: Sie haben diese User-ID gewählt:

   "Herman Mustermann <herman.mustermann@delixs.de>"

Ändern: (N)ame, (K)ommentar, (E)-Mail oder (F)ertig/(B)eenden? F

Sie benötigen eine Passphrase, um den geheimen Schlüssel zu schützen. Passphrase: <sagichnicht>

Wir müssen eine ganze Menge Zufallswerte erzeugen. Sie können dies unterstützen, indem Sie z.B. in einem anderen Fenster/Konsole irgendetwas tippen, die Maus verwenden oder irgendwelche anderen Programme benutzen. ++++++++++.+++++.+++++.+++++++++++++++.++++++++++.++++++++++++++++++++.++++++ </source>

Es kann noch folgende Meldung erscheinen:

<source lang="bash"> Es sind nicht genügend Zufallswerte vorhanden. Bitte führen Sie andere Arbeiten durch, damit das Betriebssystem weitere Entropie sammeln kann! (Es werden noch 283 Byte benötigt.) </source>

Dann einfach eine weitere ssh-Sitzung bzw. Konsole öffnen und sinnfreie Tasten drücken. Bei genügend Tastendrücken fährt das gpg-Programm automatisch fort.

<source lang="bash"> gpg: /home/mustermann/.gnupg/trustdb.gpg: trust-db erzeugt gpg: Schlüssel 55248F5E ist als uneingeschränkt vertrauenswürdig gekennzeichnet Öffentlichen und geheimen Schlüssel erzeugt und signiert.


gpg: "Trust-DB" wird überprüft gpg: 3 marginal-needed, 1 complete-needed, PGP Vertrauensmodell gpg: Tiefe: 0 gültig: 1 unterschrieben: 0 Vertrauen: 0-, 0q, 0n, 0m, 0f, 1u gpg: nächste "Trust-DB"-Pflichtüberprüfung am 2015-01-19 pub 1024D/D45554A1 2010-01-20 [verfällt: 2015-01-19]

 Schl.-Fingerabdruck = DF97 B5EA 32A4 E53C 8EA5  1310 E230 87B2 D455 54A1

uid Herman Mustermann <herman.mustermann@delixs.de> sub 2048g/B93FC568 2010-01-20 [verfällt: 2015-01-19] </source>

Wir haben uns hiermit nun einen DSA/ElGamal-Schlüssel erzeugt, der 2048 Bits groß ist und 5 Jahre gültig sein wird.

Der öffentliche Teil des Schlüssels muss natürlich irgendwie zugänglich sein, man sollte ihn daher mit folgendem Befehl exportieren:

$ gpg --armor --export herman.mustermann@delixs.de > pgp-mustermann.asc

dput und ssh konfigurieren

Die Pakete werden später mit dem Tool 'dput' hochgeladen. Damit dieses Programm weiß, was es tun soll, erstellen wir in unserem Homeverzeichnis die Datei '.dput.cf':

<source lang="bash"> ~/.dput.cf: [delixs] fqdn = deb.delixs.de method = scp login = dupload incoming = ./incoming run_dinstall = 0 allow_unsigned_uploads = 0 verify_sigs = 1 </source>

dput verwendet für das Login auf dem Server 'deb.delixs.de' den User 'dupload'.
Zur Identifikation werden zwei Schlüsseldateien benötigt, die wir auf Anforderung via PM von Thorsten erhalten.

Die Key-Dateien des Repository-Verwalters 'dupload' werden einkopiert:
Falls noch nicht vorhanden, zuerst das Verzeichnis ~/.ssh erstellen, dann id_dupload.pub und id_dupload nach ~/.ssh kopieren.
Abschließend müssen der Datei id_dupload andere Zugriffsrechte gegeben werden:

<source lang="bash"> chmod 600 id_dupload </source>

Da die Kommunikation mit dem Repository verschlüsselt erfolgt, müssen wir eine entsprechende ssh-Konfiguration erstellen.

<source lang="bash"> ~/.ssh/config: host deb.delixs.de

 User dupload
 Ciphers arcfour
 IdentityFile ~/.ssh/id_dupload
 Compression yes

</source>

Unser Homeverzeichnis sieht nun also ungefähr so aus:

<source lang="bash"> |-- .bash_history |-- .bash_logout |-- .bashrc |-- .dput.cf |-- .gnupg | |-- gpg.conf | |-- pubring.gpg | |-- random_seed | |-- secring.gpg | `-- trustdb.gpg |-- .ssh | |-- config | |-- id_dupload | `-- id_dupload.pub `-- pgp-mustermann.asc </source>

Arbeitsverzeichnis erstellen

Ab jetzt wollen wir fleissig sein und viele Debianpakete veröffentlichen.
Deshalb erstellen wir uns ein Arbeitsverzeichnis für alle neuen Pakete und wechseln dorthin: <source lang="bash"> mkdir ~/debianpakete cd ~/debianpakete </source>

Neues Projekt

Wir beginnen mit einem neuen Projekt, indem wir einen zugehörigen Unterordner erstellen.
In diesem Unterordner werden alle Versionen und Paketdateien gesammelt.

Projektordner erstellen: <source lang="bash"> mkdir ./delixs-test-script cd delixs-test-script </source>

Nun wollen wir die erste Version unseres Projekts angehen und erstellen uns dafür ein entsprechendes Arbeitsverzeichnis.
Die Benennung dieses Verzeichnisses ist nicht ganz unwichtig, da der Name auch gleichzeitig die Versionsnummer beinhalten soll. Generell sollte das Muster 'paketname-version' eingehalten werden, wie z.B. in 'delixs-test-script-0.1'. Bitte nur Buchstaben, Zahlen und Bindestriche verwenden (also keine Unterstriche !).

Arbeitsverzeichnis erstellen: <source lang="bash"> mkdir ./delixs-test-script-0.1 cd delixs-test-script-0.1 </source>

Im nächsten Schritt müssen wir ein Verzeichnis erstellen, dessen Inhalt der Paketmanager für die Verwaltung und die einzelnen Installationsphasen benötigt.
Das machen wir aber nicht manuell, sondern nutzen dafür das Tool 'dh_make'. Es erstellt einen Unterordner 'debian' und füllt ihn mit den notwendigen und bereits auf unser Projekt angepassten Steuerungsdateien.

Paketverzeichnis 'debian' erstellen mit: <source lang="bash"> export DEBFULLNAME="Herman Mustermann"; dh_make -n -s -e herman.mustermann@delixs.de

(wobei -n = native package -s = single binary -e = maintainer email address bedeutet) </source>

Zur Sicherheit habe ich dem Tool über eine Umgebungsvariable meinen vollständigen Namen übergeben (der in den vom Tool zu erzeugenden Dateien eingetragen werden soll). dh_make ist zwar in der Lage, diesen Namen aus meiner Standardumgebung zu extrahieren, aber wenn ich mich mal nicht als 'Mustermann' angemeldet habe, sondern z.B. sträflicherweise als User 'root' arbeite, ist dieser Mechanismus ganz sinnvoll :-)

Das Tool meldet: <source lang="bash"> Maintainer name : Herman Mustermann Email-Address  : herman.mustermann@delixs.de Date  : Tue, 19 Jan 2010 19:40:56 +0100 Package Name  : delixs-test-script Version  : 0.1 License  : gpl Using dpatch  : no Type of Package : Single Hit <enter> to confirm: </source> Mit einem beherzten Druck auf die Enter-Taste bestätigen wir die Rahmendaten unseres Projekts.

dh_make meldet danach den Vollzug:

<source lang="bash"> Currently there is no top level Makefile. This may require additional tuning. Done. Please edit the files in the debian/ subdirectory now. You should also check that the delixs-test-script Makefiles install into $DESTDIR and not in / . </source>

Wir gehen in das neue Verzeichnis und sehen uns um.

<source lang="bash"> cd debian </source>

Wir erkennen schnell, dass unser Tool dort viele Dateien angelegt hat, die wir glücklicherweise zum großen Teil erst mal gar nicht benötigen. Respektive die Beispieldateien mit der Endung '.ex' können wir erst mal zur Seite legen oder auch gleich ganz löschen.

Dateien löschen: <source lang="bash"> rm *.ex *.EX </source>

Unsere Verzeichnisstruktur sieht nun also ungefähr so aus:

<source lang="bash"> |-- debianpakete | `-- delixs-test-script | `-- delixs-test-script-0.1 | `-- debian | |-- README | |-- README.Debian | |-- changelog | |-- compat | |-- control | |-- copyright | |-- dirs | |-- docs | `-- rules </source>

Wir müssen nun noch einige Dateien editieren.

Datei 'control'
Diese Datei enthält einen Überblick über unser Paket, also eine Beschreibung, eventuelle Abhängigkeiten von anderen Paketen etc.
Der Inhalt ist im Wesentlichen selbsterklärend; wir müssen auf jeden Fall folgende Zeilen bearbeiten.

Anpassen 'control': <source lang="bash"> Section: mail

       Homepage: www.delixs.de

Architecture:all

       Description: ...

</source>

Debian-Pakete werden im Standard-Debian-Archiv eingeteilt in 'main', 'contrib' und 'non-free'. Innerhalb dieser Bereiche gibt es noch 'Sections' (also Unterbereiche), in die Pakete einsortiert werden.
Unser neues Paket sollte einer dieser Sections zugeordnet werden. Als 'Section' tragen wir z.B. 'mail', 'misc', 'net' o.ä. ein. Eine vollständige Liste dieser Sections gibt es unter http://www.debian.org/doc/debian-policy/ch-archive.html#s-subsections

Als 'Homepage' setzen wir unsere Projekt-Website ein: www.delixs.de
Als 'Architecture' nehmen wir 'all', da unser Paket (vorerst) keine kompilierten und somit prozessorarchitekturbedingten Dateien enthält.
Die 'Description', also Beschreibung unseres Pakets, ist zweiteilig. Direkt hinter 'Description' setzen wir eine kurze, einzeilige Beschreibung, in die Zeile(n) darunter, mit einem Leerzeichen am Anfang jeder Zeile, verfassen wir eine ausführlichere Beschreibung unseres Projekts.

Im Ergebnis sieht das Ganze dann ungefähr so aus:

<source lang="bash"> Source: delixs-test-script Section: misc Priority: extra Maintainer: Herman Mustermann <herman.mustermann@delixs.de> Build-Depends: debhelper (>= 7) Standards-Version: 3.7.3 Homepage: www.delixs.de

Package: delixs-test-script Architecture: all Depends: ${shlibs:Depends}, ${misc:Depends} Description: Test script for the delixs project.

This is a rather lengthy description of a small package which will serve as
an example of building debian packages for the delixs project.

</source>

Datei 'changelog'
Wie der Name schon vermuten lässt, sollen in dieser Datei die Änderungen an unserem Paket von Version zu Version fortgeschrieben werden.
Unser Tool dh_make hat uns hier schon mal eine Grundstruktur eingetragen, die wir aber noch in einem Punkt anpassen müssen.
In der ersten Zeile steht: <source lang="bash"> delixs-test-script (0.1) unstable; urgency=low </source> Das 'unstable' hinter der Versionsnummer bestimmt, in welchen Debianzweig unser Paket später hochgeladen wird. Für das delixs-Projekt wurden die Zweige 'aramec' und 'testing' eingerichtet, entsprechend müssen wir hier statt 'unstable' also entweder 'testing' oder 'aramec' eintragen.
Da unser neues Paket ja noch nicht für den produktiven Einsatz freigegeben ist, werden wir hier also 'testing' verwenden.

Die Dateien 'README' und 'copyright' sind sicherlich selbsterklärend und können nach Bedarf angepasst werden.

Datei 'rules'
Dies ist die zentrale Steuerungsdatei, die für alle Instalationsarbeiten vom Paketmanager aufgerufen wird.
Es handelt sich hierbei um eine Make-Steuerungsdatei, die auf den ersten Blick etwas unübersichtlich erscheint. Wir müssen uns auch jetzt noch nicht in die Details dieser Datei einarbeiten, aber um unser Paket für einen ersten Build-Lauf formal korrekt aufzustellen, sollten wir zunächst drei Zeilen darin editieren.

In diesen Zeilen befindet sich der Aufruf eines weiteren Makefiles, das wir aber noch gar nicht erstellt haben (und es vielleicht auch nie tun werden).
Deshalb werden wir den Aufruf einfach auskommentieren, indem wir an den Anfang der jeweiligen Zeile eine Raute '#' setzen.

Anpassen 'rules': <source lang="bash"> Zeile 30: #<----->$(MAKE) Zeile 41: #<----->$(MAKE) clean Zeile 53: #<----->$(MAKE) DESTDIR=$(CURDIR)/debian/delixs-test-script install </source>

Der Build-Vorgang

So, nun können wir einmal testweise versuchen, ob die Paketerstellung soweit funktioniert.

Wir geben ein: <source lang="bash"> debuild </source>

Die Ausgabe ist etwas geschwätzig: <source lang="bash"> mustermann@alix:~/debianpakete/delixs-test-script/delixs-test-script-0.1$ debuild dpkg-buildpackage -rfakeroot -D -us -uc dpkg-buildpackage: setze CFLAGS auf Standardwert: -g -O2 dpkg-buildpackage: setze CPPFLAGS auf Standardwert: dpkg-buildpackage: setze LDFLAGS auf Standardwert: dpkg-buildpackage: setze FFLAGS auf Standardwert: -g -O2 dpkg-buildpackage: setze CXXFLAGS auf Standardwert: -g -O2 dpkg-buildpackage: Quellpaket delixs-test-script dpkg-buildpackage: Quellversion 0.1 dpkg-buildpackage: Quellen geändert durch Herman Mustermann <herman.mustermann@delixs.de> dpkg-buildpackage: Host-Architektur i386

fakeroot debian/rules clean

dh_testdir dh_testroot rm -f build-stamp configure-stamp

  1. Add here commands to clean up after the build process.

dh_clean

dpkg-source -b delixs-test-script-0.1

dpkg-source: Information: verwende Quellformat »1.0« dpkg-source: Information: baue delixs-test-script in delixs-test-script_0.1.tar.gz dpkg-source: Information: baue delixs-test-script in delixs-test-script_0.1.dsc

debian/rules build

dh_testdir

  1. Add here commands to configure the package.

touch configure-stamp dh_testdir

  1. Add here commands to compile the package.
  2. docbook-to-man debian/delixs-test-script.sgml > delixs-test-script.1

touch build-stamp

fakeroot debian/rules binary

dh_testdir dh_testroot dh_clean -k dh_installdirs

  1. Add here commands to install the package into debian/delixs-test-script.

dh_testdir dh_testroot dh_installchangelogs dh_installdocs dh_installexamples dh_installman dh_link dh_strip dh_compress dh_fixperms dh_installdeb dh_shlibdeps dh_gencontrol dpkg-gencontrol: Warnung: unbekannte Substitutionsvariable ${shlibs:Depends} dpkg-gencontrol: Warnung: unbekannte Substitutionsvariable ${misc:Depends} dh_md5sums dh_builddeb dpkg-deb: Baue Paket »delixs-test-script« in »../delixs-test-script_0.1_all.deb« .

dpkg-genchanges  >../delixs-test-script_0.1_i386.changes

dpkg-genchanges: füge kompletten Quellcode beim Hochladen hinzu dpkg-buildpackage: Alles hochzuladen; Debian-native-Paket (komplette Quellen enthalten) Now signing changes and any dsc files...

signfile delixs-test-script_0.1.dsc Herman Mustermann <herman.mustermann@delixs.de>

Sie benötigen eine Passphrase, um den geheimen Schlüssel zu entsperren. Benutzer: "Herman Mustermann <herman.mustermann@delixs.de>" 1024-Bit DSA Schlüssel, ID D45554A1, erzeugt 2010-01-20


signfile delixs-test-script_0.1_i386.changes Herman Mustermann <herman.mustermann@delixs.de>

Sie benötigen eine Passphrase, um den geheimen Schlüssel zu entsperren. Benutzer: "Herman Mustermann <herman.mustermann@delixs.de>" 1024-Bit DSA Schlüssel, ID D45554A1, erzeugt 2010-01-20


Successfully signed dsc and changes files </source>

Wie man sieht, wird das Paket zunächst zusammengebaut und dann signiert.
Es wird sowohl das Paket (bzw. seine Beschreibung) als auch die zum Paket gehörende Changes-Datei signiert, weshalb auch zweimal nach dem Password gefragt wird, das wir bei der Erzeugung unseres GPG-Schlüssels definiert hatten.

Schauen wir uns mal kurz an, was der Befehl 'debuild' denn eigentlich gemacht hat. Dazu wechseln wir von unserem debian-Verzeichnis zwei Ebenen weiter nach oben und finden dort folgende Struktur:

<source lang="bash"> |-- delixs-test-script-0.1 | |-- build-stamp | |-- configure-stamp | `-- debian | |-- README | |-- README.Debian | |-- changelog | |-- compat | |-- control | |-- copyright | |-- delixs-test-script | | |-- DEBIAN | | | |-- control | | | `-- md5sums | | `-- usr | | |-- bin | | |-- sbin | | `-- share | | `-- doc | | `-- delixs-test-script | | |-- README.Debian | | |-- changelog.gz | | `-- copyright | |-- delixs-test-script.debhelper.log | |-- dirs | |-- docs | |-- files | `-- rules |-- delixs-test-script_0.1.dsc |-- delixs-test-script_0.1.tar.gz |-- delixs-test-script_0.1_all.deb |-- delixs-test-script_0.1_i386.build `-- delixs-test-script_0.1_i386.changes </source>

In unserem Paketverzeichnis finden wir nun neben dem 'debian'-Ordner auch noch ein paar neue Dateien, u.a. unser erstes Paket 'delixs-test-script_0.1_all.deb'.

Prima, das könnten wir nun einfach direkt installieren (mit 'dpkg -i delixs-test-script_0.1_all.deb', das Entfernen geht mit 'dpkg -P delixs-test-script'), aber das wäre natürlich unnütz, da unser Paket ja noch garnichts beinhaltet.

Trotzdem können wir herausfinden, was bei einer Installation unseres Pakets passieren würde, indem wir einfach mal einen Blick in unser 'debian'-Verzeichnis bzw. das darin entstandene Verzeichnis 'delixs-test-script' werfen.
In dieses Verzeichnis hat der Build-Befehl schon mal die Ordner und Dateien einkopiert, die auch bei einer realen Installation entstehen würden, in unserem Fall also ist das die Paket-Dokumentation in /usr/share/doc/delixs-test-script.
Ist zwar noch nicht weltbewegend, aber immerhin ...

Upload ins Repository

Nachdem wir nun so ein schönes Paket geschnürt haben, wollen wir es in das Projekt-Repository hochladen, damit alle Teammitglieder Freude daran haben.

Wir befinden uns im Ordner 'delixs-test-script-0.1' und sagen: <source lang="bash"> dput delixs delixs-test-script_0.1_i386.changes </source>

Wir sagen damit dput, dass es ins Repository 'delixs' hochladen soll; was und wohin hochgeladen werden soll, erkennt dput am Inhalt der *.changes Datei.

Wenn ein Paket erst einmal ins Repository hochgeladen wurde, ist ein nochmaliges Hochladen nicht mehr möglich, selbst wenn wir viele Änderungen vorgenommen und das Paket neu mit debuild erstellt haben (?). Ein Hochladen ist erst wieder möglich, wenn wir eine neue Version des Paketes erstellt haben.

Es dauert übrigens bis zu 15 Minuten, bis unser Paket vom Server verarbeitet und wirklich in das Repository aufgenommen wird.

Danach reicht ein
aptitude update
und dann ein
aptitude search delixs
um das eigene, neue Paket im Repository zu sehen.

Neue Version

Nachdem wir das Grundpaket erfolgreich erstellt haben, werden wir nun eine neue Version des Paketes angehen, die dann auch mal etwas Sinnvolles tut.

Um eine neue Version zu erzeugen, gehen wir zunächst in das Verzeichnis der aktuellen Version <source lang="bash"> cd ~/debianpakete/delixs-test-script/delixs-test-script-0.1 </source>

Wir initiieren die neue Version mit <source lang="bash"> debchange -im ( wobei -i inkrementiere die Versionsnummer

         -m  behalte die bisherigen Maintainerdaten bei

bedeutet) </source>

Es startet der Editor und zeigt uns die Datei 'changelog', die nun schon durch einen neuen Eintrag 'delixs-test-script (0.2)' erweitert wurde.

Wir können die Datei um einen entsprechenden Kommentar ergänzen und abspeichern/beenden.

debchange meldet uns zum Abschluss: <source lang="bash"> debchange warning: your current directory has been renamed to: ../delixs-test-script-0.2 </source>

Es hat also unser Versionsverzeichnis umbenannt, indem es die Versionsnummer am Ende hochzählt.
Wir wechseln in dieses Verzeichnis.

Paket-Beispiele

Ein PHP-Script-Paket

Wir möchten gerne, dass unser Paket ein PHP-Script installiert, das wir dann über einen Webbrowser aufrufen können.

Wir erstellen das PHP-Script im Verzeichnis 'delixs-test-script-0.2'. <source lang="bash"> mcedit HelloWorld.php </source>


<source lang="php"> <?php

 echo "Hello world !";

?> </source>

Nun müssen wir dem Paketmanager noch sagen, dass dieses Script in den Dokumentenbereich des apache installiert werden soll.
Hierzu wechseln wir in das 'debian'-Verzeichnis und erstellen die Datei 'install'

<source lang="bash"> cd debian mcedit install </source>


<source lang="bash"> HelloWorld.php var/www/htdoc/hwscript </source>

Ein Einzeiler, der bewirkt, dass die Datei 'HelloWorld.php' während der Installation unseres Paketes in das Verzeichnis /var/www/htdocs/hwscript kopiert wird.
(Syntax: quelldatei zielverzeichnis)

Hätten wir mehrere Dateien dorthin zu kopieren, würde der Einzeiler so aussehen:

<source lang="bash"> HelloWorld.php HelloUniverse.php var/www/htdoc/hwscript </source>

(Syntax: quelldatei[ quelldatei] zielverzeichnis)

Wir können auch ein komplettes Verzeichnis (samt evtl. darin liegenden Verzeichnisbaum) installieren:

<source lang="bash"> PHP-scripte/ var/www/htdoc/hwscript </source>

(Syntax: quellverzeichnis/ zielverzeichnis)

Damit der Paketmanager die 'install'-Datei auswertet, müssen wir noch kurz die zentrale Steuerungsdatei 'rules' editieren.

In Zeile 66 entfernen wir das Kommentarzeichen vom Zeilenanfang. <source lang="bash">

  1. <----->dh_install

</source>

und speichern ab. Fertig.

Das wollen wir gleich mal testen. Wir erstellen das Paket mit <source lang="bash"> debuild </source>

und finden nun unterhalb des 'debian'-Verzeichnisses folgende Struktur:

<source lang="bash"> |-- delixs-test-script | |-- DEBIAN | | |-- control | | `-- md5sums | |-- usr | | |-- bin | | |-- sbin | | `-- share | | `-- doc | | `-- delixs-test-script | | |-- README.Debian | | |-- changelog.gz | | `-- copyright | `-- var | `-- www | `-- htdoc | `-- hwscript | `-- HelloWorld.php </source>

Sieht gut aus, aber wir wollen uns an der Realität messen, deshalb installieren wir das Paket mit <source lang="bash"> dpkg -i delixs-test-script_0.2_all.deb </source>

starten einen Webbrowser und geben ein: <source lang="bash"> http://10.100.0.1/hwscript/HelloWorld.php </source>

q.e.d. :-)

Genauso schnell werden wir das Paket auch wieder los: <source lang="bash"> dpkg -P delixs-test-script </source>

Ein Fremd-Paket installieren

Wir wollen ein fremdes, bereits für Debian existierendes Paket installieren und dabei delixs-spezifische Einstellungen bzw. Anpassungen vornehmen.
Als Beispiel nehmen wir das Paket 'cron-apt', das regelmäßig nach neuen Updates für unseren Server sucht und den Systembetreuer über neue Versionen informiert.

Grundgerüst

Hierzu legen wir ein neues Projekt- und Versionsverzeichnis an

<source lang="bash"> cd ~/debianpakete mkdir ./delixs-refresh cd delixs-refresh mkdir ./delixs-refresh-0.1 cd delixs-refresh-0.1 </source>

Paketverzeichnis 'debian' erstellen mit:
export DEBFULLNAME="Herman Mustermann"; dh_make -n -s -e herman.mustermann@delixs.de

Wir gehen in das neue Verzeichnis und löschen die überflüssigen Dateien. Vor dem Löschen benennen wir aber erst noch zwei der Beispieldateien um, die wir später noch benötigen.

<source lang="bash"> cd debian mv postinst.ex postinst mv postrm.ex postrm rm *.ex *.EX </source>

Wir passen wie üblich die wichtigsten Dateien an.

Anpassen 'control':

<source lang="bash"> Section: admin Homepage: www.delixs.de Architecture:all Description: update notifiation of packages for delixs ... </source>

Zusätzlich zu den bekannten Feldern werden wir 'Depends' um das zu installierende Fremdpaket ergänzen.

Info: Das Installationssystem prüft vor der Installation unserer eigenen Dateien, ob unser Paket von anderen Paketen abhängig ist. Falls dem so sein sollte ('Depends: ...'), werden zunächst die aufgeführten anderen Pakete installiert und konfiguriert, bevor unsere eigenen Dateien an die Reihe kommen.
Deshalb müssen wir lediglich definieren, dass unser Paket von 'cron-apt' abhängt, um dieses Paket automatisch installiert zu bekommen.

Im Ergebnis sieht das Ganze dann ungefähr so aus:

<source lang="bash"> Source: delixs-refresh Section: admin Priority: extra Maintainer: Herman Mustermann <herman.mustermann@delixs.de> Build-Depends: debhelper (>= 7) Standards-Version: 3.7.3 Homepage: www.delixs.de

Package: delixs-refresh Architecture: all Depends: ${shlibs:Depends}, ${misc:Depends}, cron-apt Description: update notifiation of packages for delixs

This package installs the tool cron-apt and changes its configuration to gain.
a perfectly everytime up-to-date delixs server.

</source>

Datei 'changelog'

<source lang="bash"> delixs-refresh (0.1) testing; urgency=low </source>

Anpassen 'rules':

<source lang="bash"> Zeile 30: #<----->$(MAKE) Zeile 41: #<----->$(MAKE) clean Zeile 53: #<----->$(MAKE) DESTDIR=$(CURDIR)/debian/delixs-test-script install </source>

Schnell mal testen, ob die Paketerstellung soweit funktioniert.

debuild

Es fragt nach unserem GPG-Password und erstellt das Paket ohne Fehlermeldung - prima.

Paket konfigurieren

Wenn unser Paket später installiert wird, hat ja der Paketmanager durch die 'Depends'-Angabe dafür gesorgt, dass das Fremdpaket 'cron-apt' vor unseren eigenen Dateien installiert wurde. Wir greifen also auf ein fertig installiertes 'cron-apt' zu.
Nun haben wir gar keine eigenen Dateien, die es zu instalieren gäbe (die 'install'-Datei wird nicht benötigt). Statt dessen wollen wir lediglich einige Konfigurationsdateien ändern, und der Ansatzpunkt hierfür ist die Steuerungsdatei 'postinst'. Wie der Name vermuten läßt, wird dieses Programm ausgeführt, nachdem alle Dateien unseres Pakets installiert wurden.

Zunächst markieren wir 'postinst' als executable.
chmod 755 postinst

Und editieren dann die Datei.
Schnell sehen wir, dass sie eigentlich nur aus einer rudimentären case-Abfrage besteht, deren 'configure)'-Zweig für uns wichtig ist. Hier tragen wir die Befehle ein, um Änderungen an der Konfiguration des Fremdpakets vorzunehmen.

Wir erstellen zwei Funktionen, die im Case-Zweig aufgerufen werden.

<source lang="bash">

  1. !/bin/sh
  2. postinst script for delixs-refresh
  3. see: dh_installdeb(1)

set -e

set_config() {

   # cron-apt config anpassen:
   FILE=/etc/cron-apt/config
   echo "  cron-apt default config"
   sed -i -e "s:^# APTCOMMAND=/usr/bin/aptitude:APTCOMMAND=/usr/bin/aptitude:" \
       -e "s/^# MAILTO=\"root\"/MAILTO=\"postmaster\"/" \
       -e "s/^# MAILON=\"error\"/MAILON=\"upgrade\"/" \
       ${FILE}
   if [ $? -gt 0 ] ; then
       echo "  Fehler beim Bearbeiten der Datei ${FILE}"
       exit 2
   fi

}

set_action() {

   # cron-apt action script setzen:
   FILE=/usr/share/doc/cron-apt/examples/9-notify
   echo "  cron-apt action script"
   cp ${FILE} /etc/cron-apt/action.d/9-notify
   if [ $? -gt 0 ] ; then
       echo "  Fehler beim Bearbeiten der Datei ${FILE}"
       exit 2
   fi

}

case "$1" in

   configure)
       set_config
       set_action
   ;;
   abort-upgrade|abort-remove|abort-deconfigure)
   ;;
   *)
       echo "postinst called with unknown argument \`$1'" >&2
       exit 1
   ;;

esac

  1. dh_installdeb will replace this with shell code automatically
  2. generated by other debhelper scripts.

</source>

Das sollte genügen.
Wir erstellen das Paket
debuild

und laden es in das Repository hoch.

cd ~/debianpakete/delixs-refresh dput delixs delixs-refresh_0.1_i386.changes

Ein Test mit 'dpkg -i ...' ist leider nicht möglich, da dpkg im Gegensatz zu aptitude keine Abhängigkeiten auflösen kann. Aptitude hingegen kann nur Pakete aus Repositories installieren.

Wir warten 15 Minuten auf das Update des Repositorys und installieren dann unser Paket
aptitude update
aptitude install delixs-refresh

Ein kurzer Blick in die Konfigurationsdateien unter /etc/cron-apt zeigt uns, dass das Fremdpaket einwandfrei installiert und unsere Anpassungen ebenso übernommen wurden.

Deinstallation verbessern

Im Prinzip sind wir fertig, allerdings sollten wir noch eine Unzulänglichkeit im Zusammenhang mit der Deinstallation abstellen.
Es gibt unter der Debian-Paketverwaltung zwei Stufen der Deinstallation. Wenn 'aptitude remove ...' aufgerufen wird, entfernt der Paketmanager wie erwartet alle Dateien, die er vormals installiert hatte.
Ausnahmen bilden allerdings Dateien, die typischerweise unter '/etc' liegen und als Konfigurationsdateien definiert sind. Die werden nicht gelöscht, denn falls man das Paket später mal wieder installieren möchte, lägen dann schon angepasste Konfigurationen wie beim letzten Lauf bereit.

Um aber auch diese Dateien loszuwerden, gibt es den Befehl 'aptitude purge ...', der dann wirklich alle Reste des Pakets und Eintragungen in der Paketmanagerdatenbank entfernt.

Wenn wir diesen Befehl auf unser 'delixs-refresh'-Paket bzw. das Fremdpaket cron-apt anwenden, sehen wir eine Fehlermeldung:

<source lang="bash"> Lösche Konfigurationsdateien von cron-apt ... dpkg - Warnung: Während Entfernens von cron-apt ist Verzeichnis »/etc/cron-apt/action.d« nicht leer, wird daher nicht gelöscht. </source>

Klar, wir haben ja in der postinst dafür gesorgt, dass eine weitere Action-Datei einkopiert wird, deshalb müssen wir dafür sorgen, dass diese Datei entsprechend entsorgt wird.

Hierzu erhöhen wir zunächst unsere Version

debchange -im

Handelte es sich bei der zu löschenden Datei um ein File, das auch durch unser Paket installiert wurde, genügte es, im 'debian'-Verzeichnis die Datei 'conffiles' anzulegen.

mcedit conffile

<source lang="bash"> /etc/cron-apt/action.d/9-notify </source>

Damit hätten wir '9-notify' als Konfigurationsdatei definiert, und es wäre schon alles erledigt, den Rest übernähme der Paketmanager.

Aber leider stammt diese Datei ja aus dem Fremdpaket 'cron-apt', deshalb können wir diesen leichten Weg nicht gehen, sondern müssen die von uns einkopierte Datei auch selbst wieder löschen.

Wir bedienen uns der Datei 'postrm', die vom Paketmanager aufgerufen wird, nachdem er seine Löscharbeiten erledigt hat.
Zunächst markieren wir 'postrm' als executable.
chmod 755 postrm

Und editieren dann die Datei.

Auch bei dieser Vorlage handelt es sich im wesentlichen nur um eine Case-Abfrage, bei der wir den 'purge'-Fall separieren:

<source lang="bash">

  1. !/bin/sh
  2. postrm script for delixs-refresh
  3. see: dh_installdeb(1)

set -e

case "$1" in

   remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear)
   ;;
   purge)
       rm /etc/cron-apt/action.d/9-notify
   ;;
   *)
       echo "postrm called with unknown argument \`$1'" >&2
       exit 1
   ;;

esac

  1. dh_installdeb will replace this with shell code automatically
  2. generated by other debhelper scripts.
  1. DEBHELPER#

exit 0 </source>

Fertig.


Fragen und Antworten

Manchmal ist es notwendig, zur ordnungsgemäßen Konfiguration eines Paketes zusätzliche Informationen vom Benutzer einzuholen.
Der Paketmanager bringt alle Tools mit, um dem Anwender unabhängig von der gerade verwendeteten (Text- oder Grafik-) Oberfläche die gewünschten Fragen zu präsentieren und dessen Antworten systemweit - und somit auch für den Zugriff durch andere Pakete - in einer Datenbank abzulegen.

Bemerkenswert hierbei ist die Tatsache, dass die Präsentation der Fragen asynchron zur Paketinstallation und Konfiguration erfolgt.
Wenn dem Paketmanager mehrere Pakete zur Installation übergeben werden, durchforstet er sie zunächst auf irgendwelche Fragen, die es zu stellen gilt, fasst diese Fragen aus allen Paketen zusammen und bietet sie dem Anwender zur Beantwortung an.
Die Antworten werden in der Datenbank gespeichert, und erst dann erfolgt die normale Installation der einzelnen Pakete. Während der Installation kann ein Paket dann auf diese Datenbank zurückgreifen und sich die Antworten abholen, die es benötigt.

Diese Ansynchronität zwischen Fragestellung und Installation/Konfiguration wird auch in der Art der Implementierung bei der Paketerstellung deutlich.

Das sehen wir uns am Beispiel unseres Pakets 'delixs-refresh' an.
In dem Paket 'cron-apt' wird u.a. ein cron-Job eingerichtet, der einmal täglich nach Updates sucht. Wir möchten, dass der User bestimmen kann, um welche Uhrzeit diese Updatesuche durchgeführt wird.

Wir wechseln in unser Projektverzeichnis, erhöhen auf eine neue Version.

<source lang="bash"> cd ~/debianpakete/delixs-refresh/delixs-refresh-0.3 debchange -im cd debian </source>

Zunächst legen wir die Datei 'templates' an, in der wir unsere Frage(n) definieren.


<source lang="bash"> mcedit templates </source>


<source lang="bash"> Template: delixs-refresh/cron-time Type: string Default: 4 Description: When should cron-apt search for new updates:

Enter the time of day at which cron-apt should get new updates.

Description-de.UTF-8: Wann soll cron-apt nach neuen Updates suchen:

Bitte geben Sie die Uhrzeit an, zu der cron-apt neue Updates abruft.

</source>

Der Aufbau dieser Datei ist recht einfach.
Eine Frage wird eingeleitet durch die Definition eines eindeutigen Namens, Angabe des Typs, eines zu erwartenden Standardwertes und der textuellen Kurz- und Lang-Definition der Frage an sich; zunächst in Englisch, dann optional in anderen Sprachen. Mehrere Fragen werden durch eine Leerzeile getrennt.

<source lang="bash"> Template: <paketname>/<fragen-bezeichnung> Type: select | multiselect | string | boolean | note | text | password Default: <default value> Description: Blah blah blah?

Blah blah blah. Blah blah. Blah blah blah. Blah blah? Blah
blah blah blah. Blah blah blah. Blah blah.

Description-<lang>: Blah blah blah?

Blah blah blah. Blah blah. Blah blah blah. Blah blah. Blah blah blah.
blah.

Template: .... .... </source>

Als nächstes müssen wir dem Paketmanager noch mitteilen, in welcher Reihenfolge unsere Fragen zu stellen sind, evtl. Antworten auf Fehleingaben überprüfen etc. Hierfür erstellen wir die Scriptdatei 'config'.

<source lang="bash"> touch config chmod 755 config </source>


<source lang="bash"> mcedit config </source>


<source lang="bash">

  1. !/bin/sh
  2. config script for delixs-refresh

set -e

. /usr/share/debconf/confmodule

db_version 2.0

  1. Fragen in gewuenschter Reihenfolge

db_input high delixs-refresh/cron-time || true db_input high delixs-refresh/zweite-frage || true ... db_go

  1. Eingaben pruefen:

db_get delixs-refresh/cron-time ret=$(echo $RET | tr -cd '[:digit:]') if [ "$ret" != "$RET" ] || [ "x$ret" = "x" ] ; then

  # Fehlerbehandlung, da Eingabe keine Zahl ...

fi

db_stop

exit 0 </source>

Erläuterung:
Zuerst werden die Routinen des Fragesystems eingebunden (confmodule) und dann mit 'db_input' die zu stellenden Fragen aufgelistet.
Ein 'db_go' weist das System an, die Fragen nun zu stellen und deren Antworten in der Datenbank zu speichern.
Mit 'db_get' wird die Datenbank nach einer Antwort befragt, das Ergebnis landet in der Variablen $RET.

Wie gesagt, diese Befragung findet noch vor der Installation des Pakets statt, aber natürlich können wir zu dem späteren Zeitpunkt der Konfiguration, z.B. in dem Script 'postinst', auf die Antworten zugreifen.

Hierzu müssen wir lediglich die Routinen des Fragesystems einbinden und dann wie schon in der 'config'-Datei die Antworten abrufen.

<source lang="bash"> mcedit postinst </source>


<source lang="bash">

  1. Am Anfang einbinden:

. /usr/share/debconf/confmodule

...

  1. Antworten abrufen und verarbeiten:

db_get delixs-refresh/cron-time crontime=$RET

... </source>

Noch ein paar Hinweise:

  • Zum Testen des 'config'-scripts muss das Paket nicht unbedingt installiert werden. Man kann es i.d.R. auch 'einfach so' als root starten.
  • Die Antworten bleiben auch nach einem 'remove' unseres Pakets in der Datenbank gespeichert, vergleichbar mit den Konfigurationsdateien unter '/etc/...'. Erst bei einem 'purge' unseres Pakets sollen sie entfernt werden.

Hierzu genügt es, in unserer 'rules'-Datei aus der Zeile
<source lang="bash">

  1. <----->dh_installdebconf

</source>
das Kommentarzeichen zu entfernen, dann kümmert sich der Paketmanager automatisch darum.

  • Wenn die Fragen erst mal als beantwortet in der Datenbank liegen, werden sie bei einer nächsten Ausführung durch den Paketmanager (z.B. bei einem Update oder der Neuinstallation nach einem 'remove') nicht wieder angezeigt.

Um die erneute Befragung zu erzwingen, können wir in der 'config'-Datei unsere Frage vorher als 'noch nie bearbeitet' markieren:

<source lang="bash"> db_fset delixs-refresh/cron-time seen false </source>

  • Sobald man die Routinen des Fragesystems mit '. /usr/share/debconf/confmodule' eingebunden hat, sollte man auf eigene Bildschirmausgaben und Consolen-Eingaben mit 'echo' oder 'read' verzichten, das das Fragesystem diese beiden Kanäle beansprucht. Insbesondere sollte man auf die Ausführung von daemons verzichten, da hierbei ja gerne die Ein-/Ausgabe-Deskriptoren verbogen werden. Sollte dies doch einmal notwendig sein, muss man vorher das Fragesystem mit 'db_stop' beenden.
  • Und selbstverständlich kann man auch auf Antworten aus den Fragen anderer Pakete zugreifen, z.B. ergibt

<source lang="bash"> db_get samba-common/workgroup </source>
als '$RET'-Value den Eintrag 'SCHULE'.
Die Klartext-Datenbank aller Antworten befindet sich unter '/var/cache/debconf/config.dat'.


Weblinks

Details zur Erstellung der 'config' und 'templates' Dateien:


zurück | Hauptseite


Hans-Jürgen Grimminger 2010