Paketieren unter Linux

Vorgestern und heute konnte ich mein erstes rpm-Paket erstellen. Da ich so was noch nie gemacht hatte, war es für mich eine gewisse Herausforderung.
Das Ergebnis sollte ein RPM-Paket sein, welches beim Installieren eine Ordnerstruktur anlegt, Files kopiert und danach ein Script ausführt. Beim Deinstallieren soll zuerst ein Script ausgeführt werden und dann die Kopierten Files wieder gelöscht werden.

Für jemand, der das schon ein paar mal gemacht hat, mag das einfach klingen, ich weiss – für mich war es aber alles andere als das 😉

Jedoch, da ich auch schon mal für Windows paketiert habe, kann ich auch gleich einen Vergleich anstellen: Es ist viel unkomplizierter und einfacher unter Linux, wenn das SPEC-File mal steht… wenn 🙂

Doch nun zum Vorgehen!
Der Kern des Paketieren stellt das Programm rpmbuild und eine selbst erstellte SPEC-Datei dar.
Die SPEC-Datei kann man dabei wie eine Art Anleitung ansehen, wo aufgeschrieben wird, wann was getan werden soll. Anhand dieser Anleitung erstellt rpmbuild dann ein Paket.

Die allgemeine Funktionsweise habe ich mir aus dem Internet angeeignet. Besonders geholfen dabei hat mir diese Anleitung.

Das Problem aber, all diese Anleitungen basieren darauf, dass der Source aus dem Internet nachgeladen wird. Mein Paket musste aber alle Dateien lokal zur Verfügung haben.

Nun die erste Herausforderung: Wie mach ich das?
Nach viel probieren und testen hatte ich endlich eine Lösung… Unter dem Punkt %files werden die Dateien so aufgelistet, wie sie danach beim Zielsystem kopiert werden:

1
2
3
4
5
6
%files
/opt/itc/bin/soe-rootadd
/opt/itc/bin/soe-updatepubkeys
/opt/itc/prepost/install_post.sh
/opt/itc/prepost/remove_post.sh
/opt/itc/.sshsoe_id

Während dem Erstellen des Paketes mussten die Dateien aber im Ordner ~/rpmbuild/BUILDROOT/Paketname/opt/itc/../ liegen, damit es korrekt in das RPM integriert wird.

Die zweite Herausforderung war das Script: Unter %pre, wo ich auch alle Ordner erstellen liess, konnte ich das Script nicht starten, da zuerst %pre und danach erst %files abgearbeitet wird, wodurch das Script beim Starten noch gar nicht an seinem Platz ist.
Also habe ich es kurzerhand unter %install abgelegt. Doch aus welchem Grund auch immer – da wurde es nie gestartet…
Darauf habe ich ohne noch lange weiterzuprobieren, das Script unter %post abgelegt, welcher nach der Installation abgearbeitet wird.

Das die Dateien dann beim Deinstallieren wieder gelöscht werden, war ein kleines Problem. Einfach alles unter %preun eintragen und gut ist.

Mein SPEC-File sah am Schluss so aus:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
...
%pre
mkdir -p /opt/itc/bin/
mkdir -p /opt/itc/ssh/pubkeys/
mkdir -p /opt/itc/prepost/
 
%post
/opt/itc/bin/install_post.sh
 
%preun
/opt/itc/bin/remove_post.sh
rm -f /opt/itc/bin/soe-rootadd
rm -f /opt/itc/bin/soe-updatepubkeys
rm -f /opt/itc/bin/install_post.sh
rm -f /opt/itc/bin/remove_post.sh
rm -f /opt/itc/.sshsoe_id
 
%prep
%build
%install
%clean
rm -rf $RPM_BUILD_ROOT
 
%files
/opt/itc/bin/soe-rootadd
/opt/itc/bin/soe-updatepubkeys
/opt/itc/prepost/install_post.sh
/opt/itc/prepost/remove_post.sh
/opt/itc/.sshsoe_id

Beim erstellen des Paketes zeigt sich dann die Stärke von Linux. Auf dem 32Bit System, welches ich zur Erstellung verwendet habe, habe ich ohne Probleme mit dem Parameter –target x86_64 ein Paket für 64Bit Systeme erstellt.
Das Begeistert mich deshalb so, denn unter Windows konnte ich auf einem 32Bit-Host auch nur ein Paket für dessen Architektur machen.
Und da ich schon damit gerechnet hatte, für jede Architektur ein eigenes Hostsystem aufzusetzen, war ich umso erfreuter 🙂

2 Kommentare bei „Paketieren unter Linux

  1. hi,

    ich behaupte der teil unter preun ist unnötig 😉 rpm erledigt viele sachen automatisch. wenn du mit rpm -e ein rpm wieder löschst sollte er im normallfall die unter %files aufgelisteten files sowieso wieder mit abräumen, oder du hast irgendeinen prinzipiellen fehler drin der mir noch nciht aufgefallen ist 😉

    du erstellst scheinbar ein rpmbuildroot, benutzt es aber nicht in deinen pre und post funktionen. Wozu hast du dann das rpmbuildroot? pre sollte z.b. so aussehen

    %pre
    mkdir -p $RPM_BUILD_ROOT/opt/itc/bin/
    mkdir -p $RPM_BUILD_ROOT/opt/itc/ssh/pubkeys/
    mkdir -p $RPM_BUILD_ROOT/opt/itc/prepost/

    Versuch mal das rpm nicht als root zu bauen. Das dürfte in deinem fall nciht gehen, sollte es aber im normalfall (dafür sorgt eben die $RPM_BUILD_ROOT variable) 🙂 viel erfolg noch 😀

    grüsse

  2. @marcus
    Hi,
    Leider ist rpm zu schlau 😉 Anforderung ist, dass auch ein Ordner erstellt werden muss, welche leer ist. Und rpm erkennt, dass der Ordner unter %files leer ist und erstellt den nicht. Deshalb habe ich vorsichtshalber alle Ordner erstellen lassen.

    marcus :

    du erstellst scheinbar ein rpmbuildroot, benutzt es aber nicht in deinen pre und post funktionen. Wozu hast du dann das rpmbuildroot?

    Aus dem rpm-Buildroot werden die Dateien unter %files kopiert, bei mir nach folgender Struktur:

    ~/rpmbuild/BUILDROOT/Paketname/opt/itc/../

    Beim erstellen müssen die Dateien bei mir im BUILDROOT vorhanden sein, damit diese ins Paket integriert werden.

    Die pre und post erstellen nur die Ordner und führen danach das kopierte Script aus.

    Ob das rpm als root geht oder nicht, kann ich dir so nicht beantworten, da ich es einfach nicht probiert habe.

    Aber auch wenn das Script ein Bastelobjekt ist, es tut seine Dienste 😉

    Danke trotzdem für deine Hilfestellung 🙂

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.