Konfigurationspakete equivs

wall < "Konfigurationspakete mit equivs"

Broadcast message from spillerm@unixe.de (pts/1) (Sa Aug 11 09:02:45 2012):
4
Diesen Beitrag schrieb ich vor 6 Jahren. Behalte das beim Lesen bitte im Hinterkopf.

Mein Anspruch war nicht so arg hoch: ich wollte mir Debian-Pakete bauen, sie zu einem Dienst — beispielsweise LDAP — die benötigten Konfigurationsdateien in ein System installieren; und zwar installieren, nicht modifizieren. Gar nicht so einfach, denn ich fand wenig Information dazu! Deshalb notiere ich mir nachfolgend auf, wie ich es letztendlich gelöst habe — in ein paar Monaten weiss ich das aus dem Stehgreif ganz sicher nicht mehr ;-)

Die Vorgehensweise soll hierbei sein:

  • Eventuelle Abhängigkeiten werden angegeben und mitinstalliert.
  • Die Konfiguration wird nach /etc/localwurst geschrieben.
  • Die originale Konfiguration wird mittels dpkg-divert gesichert.
  • Die localwurst-Konfiguration wird eingebunden, indem Symlinks gesetzt werden.
  • Falls benötigt wird der entsprechende Dienst neu gestartet.

Abhängigkeiten installieren

Es wird das Paket equivs benötigt.

$ apt-get install equivs

Das Template anpassen

Nun ist absehbar, dass ich mehr als ein Paket bauen möchte; also ist es sinnvoll, manche Default-Werte direkt anzupassen, das erspart mir viel Tipperei. Ich sichere mir also das ursprüngliche Template und bearbeite eine Kopie:

$ echo 5 > /usr/share/equivs/template/debian/compat
$ cp /usr/share/equivs/template.ctl /usr/share/equivs/template.ctl-ORIG
$ vim /usr/share/equivs/template.ctl
### Commented entries have reasonable defaults.
### Uncomment to edit them.
Section: misc
Priority: optional
Homepage: https://www.spiller.me/
Standards-Version: 3.6.2
 
Package: localwurst-...
Version: 0.1
Maintainer: Local Wurst <pelle@localwurst.de>
# Pre-Depends: <comma-separated list of packages>
Depends: paket1, paket2
# Recommends: <comma-separated list of packages>
# Suggests: <comma-separated list of packages>
# Provides: <comma-separated list of packages>
# Replaces: <comma-separated list of packages>
Architecture: all
# Copyright: <copyright file; defaults to GPL2>
Changelog: /root/build/changelog/localwurst-...
# Readme: <README.Debian file; defaults to a generic one>
# Files: <pair of space-separated paths; First is file to include, second is destination>
#  <more pairs, if there's more than one file to include. Notice the starting space>
Extra-Files: /root/build/config/localwurst-.../localwurst-....tar.gz
Description: localwurst default configuration for ...
This package extends the system with the default localwurst ... configuration. 
 .
 <pelle@localwurst.de>

Die drei Punkte bei localwurst-... sind Platzhalter; sie sollen verdeutlichen, dass sich der Name der Pakete immer aus localwurst- und einem sprechenden Anhang zusammensetzt — auch, um Überschneidungen zu vermeiden.

Arbeitsverzeichnis erstellen

Ich möchte im Verzeichnis /root/build arbeiten, also muss ich das zuerst noch erstellen:

$ mkdir /root/build

Das Paket anlegen am Beispiel localwurst-ldap

Im Arbeitsverzeichnis wird nun das Paket angelegt:

$ cd /root/build
$ equivs-control localwurst-ldap

Dann wird das Archiv mit den Konfigurationsdateien erstellt.
Das Paket wird Konfigurationsdateien ins System einspielen; diese Dateien müssen dem Paket in Form eines Archivs mitgegeben werden.
Zuerst also wird das Verzeichnis erstellt, in dem die Konfigurationsdateien liegen:

$ mkdir -p /root/build/config/localwurst-ldap/etc/localwurst/ldap

Nun werden die Konfigurationsdateien an Ort und Stelle kopiert.

$ cp /etc/nsswitch.conf /root/build/config/localwurst-ldap/etc/localwurst/
$ cp /etc/ldap.conf /root/build/config/localwurst-ldap/etc/localwurst/
$ mkdir /root/build/config/localwurst-ldap/etc/localwurst/ssl
$ cp /etc/ssl/dfn.crt /root/build/config/localwurst-ldap/etc/localwurst/ssl
$ cp /etc/ldap/ldap.conf /root/build/config/localwurst-ldap/etc/localwurst/ldap

Wie man an diesem Beispiel erkennt gibt es einen Unterschied:

  • einige der Dateien (Bsp. nsswitch.conf) liegen in /etc und
  • einige Dateien (Bsp. ldap.conf) liegen in /etc/ldap bzw. /etc/ssl (das Zertifikat)

Nun muss aus den Dateien noch das Archiv erstellt werden — das Archiv, das im Konfig-File Archiv unter dem Punkt Extra-Files: eingebunden wird!

$ cd /root/build/config/localwurst-ldap
$ tar cvfz localwurst-ldap.tar.gz etc/

Installationsroutine erstellen

Hierzu ist die Datei /root/build/localwurst-ldap zu bearbeiten.

Section: misc
Priority: optional
Homepage: https://www.spiller.me/
Standards-Version: 3.6.2
 
Package: localwurst-ldap
Version: 0.1
Maintainer: Local Wurst <pelle@localwurst.de>
Depends: libnss-ldap,
 nscd,
 ldap-auth-client,
 ldap-auth-config,
 ldap-utils,
 libpam-ldap,
 finger
Architecture: all
Changelog: /root/build/changelog/localwurst-ldap
Extra-Files: /root/build/config/localwurst-ldap/localwurst-ldap.tar.gz
File: postinst
 # Die Routine prüft ab, welche Konfigurationsdateien im Archiv vorhanden sind und
 # führt die Schritte für jedes einzelne davon aus. Das Paket installiert die Dateien
 # nach /etc/localwurst, bearbeitet die Originale mit dpkg-divert und setzt Symlinks.
 # Im Anschluss daran wird der nscd restartet - spezifisch eine LDAP-Sache.
 #!/bin/sh -e
 .
 set -e
 .
 PKG="localwurst-ldap"
 .
     if [ "$1" = configure ] ; then
 .
     tar xzfo /usr/share/doc/"$PKG"/"$PKG".tar.gz -C / 2>&1 > /dev/null
     tar tzf /usr/share/doc/"$PKG"/"$PKG".tar.gz -C / > .tmp
 .
     while IFS= read -r i 
     do
        if [ ! -d /$i ] ; then
          FILE=`basename $i` 
          CONFFILE="/`echo $i | sed -e 's/localwurst\///'`"
          dpkg-divert --add --package "$PKG" --divert $CONFFILE-orig --rename $CONFFILE
          [ ! -e $CONFFILE -o -L $CONFFILE ] && ln -sf /$i $CONFFILE
	fi
     done<".tmp"
 .
     fi 
 .
 #DEBHELPER#
 .
     /etc/init.d/nscd restart
     exit 0
File: prerm
 #!/bin/sh -e
 .
 set -e
 .
 PKG="localwurst-ldap"
 BASE="/etc/localwurst/ldap"
 .
  if [ "$1" = remove -o "$1" = purge ] ; then
 .
    tar tzfo /usr/share/doc/"$PKG"/"$PKG".tar.gz > .tmp
 .
   while IFS= read -r i     
    do
      if [ ! -d /$i ] ; then
        FILE=`basename $i`
        CONFFILE="/`echo $i | sed -e 's/localwurst\///'`"
        [ -L $CONFFILE ] && rm $CONFFILE
        dpkg-divert --remove --package "$PKG" --rename --divert $CONFFILE-orig $CONFFILE
      fi
     done<".tmp"
 .
 fi
 .
 rm -rf $BASE
 .
    #DEBHELPER#
 .
    exit 0
 Description: localwurst default LDAP configuration
  This package extends the system with the default localwurst LDAP configuration. 
  .
  <pelle@localwurst.de>

Changelog bauen

Das Changelog-File muss da liegen, wo man es im Konfig-File definiert hat; in diesem Fall ist das /root/build/changelog/localwurst-ldap:

localwurst-ldap (0.1) lucid; urgency=low
 
  * First version of package 
  * Added nsswitch.conf, dfn.crt, ldap.conf
 
 -- Local Wurst <pelle@localwurst.de>  Fri, 08 Jun 2012 18:34:21 -0200

Wichtig ist das Format des Changelog-Files: das muss immer streng eingehalten werden.

Das Paket bauen

Um das Paket final zu bauen, muss lediglich equivs-build gefolgt vom Paketnamen aufgerufen werden; der Rest passiert automatisch:

$ cd /root/build
$ equivs-build localwurst-ldap
dh_testdir
dh_testroot
dh_clean -k
dh_testdir
dh_testroot
dh_install
dh_installdocs
dh_installchangelogs
dh_compress
dh_fixperms
dh_installdeb
dh_gencontrol
dh_md5sums
dh_builddeb
dpkg-deb: building package `localwurst-ldap' in `../localwurst-ldap_0.1_all.deb'.
 
The package has been created.
Attention, the package has been created in the current directory,
not in ".." as indicated by the message above!

Der Vorgang ergibt also das File /root/build/localwurst-ldap_0.1_all.deb — die Nummer ist natürlich von der Versionsnummer abhängig. Und hat man einen Webserver entsprechend konfiguriert, kann man das Paket nun auf diesen Server werfen und in den Index aufnehmen:

$ cd /path/to/debpackages
$ apt-ftparchive packages . > Packages
$ gzip -9 Packages
$ apt-ftparchive release . > Release

Das lässt sich ganz prima scripten, cron-jobben oder was auch immer. (Sinnvollerweise signiert man seinen Kram dann auch noch, darauf gehe ich hier mal aber nicht näher ein.)

Auf den Hosts muss dann der Server in /etc/apt/sources.list eingetragen werden, beispielsweise in der Form:

deb https://yourpackages.example.com/debpackages ./

Und dann kann auf einem beliebigen Host das Paket installiert auch schon werden:

$ apt-get update
$ apt-cache search ldap
$ localwurst-ldap - localwurst default configutation for ldap
$ apt-get install localwurst-ldap
$ dpkg --list|grep ldap
...
ii  localwurst-ldap             0.1              localwurst default LDAP configuration
...

Und das war’s auch schon — hat doch fast gar nicht weh getan, oder?

Ein Wort zum Schluss

Wie sicherlich ersichtlich wurde: eine allgemeingültige Anleitung zum Bauen der Konfigurationspakete kann und wird es nicht geben — zu unterschiedlich sind denn doch die Anforderungen. Während ein Dienst seine Konfiguration in /etc ablegt, packt ein anderer sie in einen Unterordner (Bsp. /etc/nullmailer), und wieder andere tun sowohl das eine als auch das andere (Bsp. LDAP mit /etc/ldap.conf und /etc/ldap/ldap.conf) — da bleibt nichts anderes, als die Pakete entsprechend zuzuschneiden und vor dem Einsatz sorgfältig zu testen.

Und dieser Weg ist natürlich nicht der Weisheit letzter Schluss; es gibt sicherlich elegantere Methoden, insbesondere das mit dem .tmp-File gewinnt sicher keine Preise — aber für den Moment funktioniert es und tut exakt das, was es soll. Die grosse Feile kann immer noch angesetzt werden — das ist ja das Schöne!

4