Software und Configuration-Management mit RPM leicht gemacht
Wer mehrere Red Hat Enterprise Linux-Systeme (oder äquivalente Ableger, wie CentOS oder Scientific Linux) betreut, entwickelt im Laufe der Zeit eine gewisse Routine, mit welcher die einzelnen Hosts eingerichtet und administriert werden. Da jedoch selbst der beste Administrator mal etwas vergessen kann, wäre eine zentralisierte Software- und Konfigurationsverteilung von Vorteil. Mit Chef und Puppet gibt es zwei sehr mächtige Management-Tools zur Verwaltung von Konfigurations- und Programmständen. Je nach Systemlandschaft und Anforderungen sind diese Programme aber vielleicht auch "oversized" - RPM kann sich hier als funktionale Alternative entpuppen.
Es wird häufig vergessen, dass sich RPM auch hervorragend zur Verteilung von eigener Software und Konfigurationen eignet. Wer nicht gerade große Systemlandschaften mit "Software-Wildwuchs" verwaltet und eine einfache, unkomplizierte Lösung sucht, dürfte mit RPM gut bedient sein.
Ich selbst verwalte meine gesamte Red Hat Enterprise Linux-Systemlandschaft gänzlich mittels RPM - dieser Artikel soll zeigen, wie RPM zur Vereinfachung der Systemverwaltung beitragen kann.
Aufbau
Kernstück dieses Szenarios ist ein Webserver-Dienst, der entweder auf einem dedizierten Host ausgeführt wird oder auf einem anderen Server "mitläuft" (beispielsweise auf einem Webserver) und RPM-Programmpakete zum Download anbietet. Dieser Webserver muss noch nicht mal ein RHEL-/CentOS-System sein, da der Webserver im Idealfall lediglich RPM-Dateien zur Verfügung stellt (und nicht selbst erstellt).
Auf dedizierten RHEL-/CentOS-Systemen (je nach Anzahl der Releases die unterstützt werden sollen - z. B. RHEL 5 und 6) werden die RPM-Pakete erstellt und mittels SSH und Rsync auf den Webserver repliziert. Mittels createrepo
wird vorab aus dem RPM-Konvolut ein YUM-Repository erstellt, welches von anderen Servern eingebunden wird. Das Repository besteht aus Unterordnern (je nach Prozessorarchitektur) in denen sich erstellte RPM-Pakete befinden. Nachdem das neue Repository auf den Clients konfiguriert wurde, können diese die angebotenen Programmpakete herunterladen und installieren. Wer lediglich ein Release betreuen muss, kann die Testumgebung entsprechend kleiner dimensionieren.
In diesem Beispiel wird ein YUM-Repository für die Red Hat Enterprise Linux-Relases 5 und 6 erstellt.
Webserver-Dateistruktur
Das Verzeichnis des YUM-Reposities (in diesem Beispiel myrepo
) enthält noch pro Release einen oder mehrere Unterordner mit Programmpaketen - je nach Prozessorarchitekturen, die unterstützt werden sollen. Der Name des Ordners ist wichtig - idealerweise wird es auf den entsprechenden Wert der jeweiligen YUM-Variable $releasever
(dazu später mehr!) gesetzt.
Eine Tabelle gängiger RPM-basierender Linux-Distributionen:
$releasever | Bedeutung |
5Server | RHEL 5 |
6Server | RHEL 6 |
5Workstation | RHED 5 |
6Workstation | RHED 6 |
5 / 5.1 / 5.2 / ... | CentOS / Scientific Linux 5 |
6 / 6.1 / 5.2 / ... | CentOS / Scientific Linux 6 |
17 / 18 / ... | Fedora 17 / 18 / ... |
Beispiel: Wer Programmpakete für die Red Hat Enterprise Linux-Releases 5 und 6 anbieten will, benötigt zwei Unterordner: 5Server
und 6Server
.
Daraus ergibt sich folgende Ordnerstruktur:
1myrepo/
2 /5Server
3 .../repodata
4 .../noarch
5 ...
6 .../i686
7 ...
8 .../x86_64
9 ...
10 /6Server
11 (siehe oben)
12 ...
Auf dem Server werden die entsprechenden Hauptordner angelegt, die weiteren Inhalte werden später per SSH / Rsync von den Testmaschinen kopiert:
1# mkdir -p /var/www/html/myrepo/{5,6}Server
Vorbereitung
Damit RPM-Pakete überhaupt erstellt und in Form eines YUM-Repositories anderen Hosts zur Verfügung gestellt werden können, fehlen noch einige Entwicklerwerkzeuge:
1# yum install rpm-build createrepo rpmdevtools
Ich persönlich empfehle das Erstellen von RPM-Paketen auf einem dedizierten Host oder in einer virtuellen Maschine vorzunehmen und die fertigen Pakete mittels SSH und Rsync auf den Webserver zu übertragen - der Webserver sollte aus Sicherheitsgründen niemals auch gleichzeitig die Entwicklungsumgebung sein. Insbesondere, wenn man Pakete für mehrere Releases erstellt (RHEL5, RHEL6), kommt man um entsprechende Testumgebungen nicht herum.
Der Webserver-Host muss natürlich noch mit dem entsprechenden Dienst versehen werden (falls noch nicht geschehen) - beispielsweise wie folgt für ein EL-System:
1# yum install httpd
2# chkconfig httpd on
3# system-config-firewall-tui
4# service httpd start
Auf den Entwicklungsmaschinen wird zur Erstellung von Paketen zuerst aus Sicherheitsgründen ein unpriviligierter Servicebenutzer angelegt. RPM-Pakete sollten niemals als root erstellt werden! Anschließend werden mit rpmdev-setuptree
die benötigten Ordnerstrukturen angelegt (unter EL5 gibt es dieses Kommando nicht):
1# useradd su-rpmdev
2# passwd su-rpmdev
3# su - su-rpmdev
4$ rpmdev-setuptree
5$ ln -s /usr/src/redhat ~su-rpmdev/rpmbuild #symb. Link unter EL5
Unter EL5 ist die benötigte Struktur schon unterhalb /usr/src/redhat
anzufinden - die Dateirechte müssen für den angelegten Benutzer su-rpmdev
noch entsprechend vergeben werden. Im neu angelegten Ordner rpmbuild
(bzw. unterhalb /usr/src/redhat
) sind die folgenden Unterordner zu finden:
BUILD
- Ordner, in dem Quellcode-Pakete entpackt und übersetzt werdenRPMS
- erstellte RPM-Pakete, für jede Architektur gibt es einen entsprechenden Unterordener (x86_64, i686, noarch,...)SOURCES
- Quellcode-Pakete, die zur Erstellung der RPM-Binärpakete benötigt werden; beispielsweise Programmquellcodes oder Archive mit Konfigurationsdateien (siehe kommendes Beispiel)SPECS
- beinhaltet Gerüstdateien (.spec-Files), die den Inhalt und Aufbau des RPM-Pakets definieren; diese Datei wird zwingend benötigt, um das RPM-Paket zu erstellenSRPMS
- Quellcode RPM-Pakete; werden auf Wunsch erstellt. Für Clients besteht so die Möglichkeit beispielsweise mittelsyumdownloader
die entsprechenden Quellcodes herunterzuladen, um das Paket eigenhändig zu übersetzen.
Die wichtigsten Ordner sind SOURCES
und SPECS
- in diesen Ordnern bewegt sich der RPM-Paketbauer am meisten. 😉
Beispiel 1: Konfigurationsdateien
Die meisten Administratoren werden die verwendeten Standardkonfigurationen eines Enterprise Linux-Systems an die eigenen Anforderungen anpassen. Um mal einige Beispiele anpassungswürdiger Konfigurationsdateien zu nennen:
- NTP
- sudo
- Umgebungsprofile (unterhalb /etc/profile.d)
- WINS/DNS-Konfiguration
Prinzipiell ist das Erstellen von RPM-Paketen ein relativ komplexes Thema, das hier nur oberflächlich angerissen wird. Wer mehr wissen will, findet im Fedora-Wiki und in der Fedora-Dokumentation sehr umfangreiche Informationen:
- http://fedoraproject.org/wiki/How_to_create_an_RPM_package
- http://docs.fedoraproject.org/en-US/Fedora_Draft_Documentation/0.1/html/RPM_Guide/ch-creating-rpms.html
In diesem Szenario geht es um eine beispielhafte NTP-Konfiguration, die mithilfe von RPM unternehmensweit auf allen Servern ausgerollt werden soll. Für das spätere RPM-Paket, welches die Konfiguration enthält, wird ein Specfile erstellt:
1$ cd ~su-rpmdev/rpmbuild/SPECS
2$ rpmdev-newspec mycompany-ntp
3Skeleton specfile (minimal) has been created to "mycompany-ntp.spec".
Unter EL5 gibt es sämtliche rpmdev
-Tools nicht, die SPEC-Datei muss hier eigenhändig angelegt werden!
Unter EL6 wurde mithilfe des vorherigen Befehls das Grundgerüst eines RPM-Specfiles angelegt. Diese Datei wird nun mit einem Editor geöffnet und editiert:
1$ vim mycompany-ntp.spec
2Name: mycompany-ntp
3Version:
4Release: 1%{?dist}
5Summary:
6
7Group:
8License:
9URL:
10Source0:
11
12BuildRequires:
13Requires:
14
15%description
16
17%prep
18%setup -q
19
20%build
21%configure
22make %{?_smp_mflags}
23
24%install
25rm -rf $RPM_BUILD_ROOT
26make install DESTDIR=$RPM_BUILD_ROOT
27
28%clean
29rm -rf $RPM_BUILD_ROOT
30
31%files
32%defattr(-,root,root,-)
33%doc
34
35%changelog
Neben Metainformationen über die zu paketierenden Anwendung sind auch Skript-Abschnitte, in denen das Paket übersetzt und erstellt wird, enthalten. Die einzelnen Meta-Variablen sind weitestgehend selbstklärend - anbei einige Erklärungen:
Name
- Name des Programmpakets (mycompany-ntp
-1.0-1)Version
- Version des Programmpakets (my-company-ntp-1.0
-1)Release
- Release des Programmpakets (my-company-ntp-1.0-1
)Summary
- Kurzbeschreibung des PaketsGroup
- Softwaregruppe, der das Paket zuzuordnen ist, eine vollständige Auflistung möglicher Gruppen findet sich unter:/usr/share/doc/rpm-*/GROUPS
License
- verwendete Lizenz (GPL, AGPL, MIT,...)URL
- URL zur Projektwebseite/Programm-InternetpräsenzSource0
- Relativer Pfad vonSOURCES
zum ProgrammquellcodeBuildRequires
- Abhängigkeiten, die zur Übersetzung des Programms benötigt werden (beispielsweise Header-Dateien oder Quellcodes von verwendeten Programmbibliotheken)Requires
- Abhängigkeiten, die zum Betrieb des Programms benötigt werden (in diesem Fall: NTP-Daemon)Conflicts
- definiert dritte Programmpakete und -versionen, die zum eigenen Programmpaket inkompatibel sind (fehlt im Template, ist aber sehr wichtig)%description
- Längere Beschreibung des Programms%changelog
- Changelog des Pakets, angewendete Änderungen, Autoren, etc...
Zu den einzelnen Skript bzw. Makro-Abschnitten gehören unter anderem:
%prep
- Vorbereitung vor Übersetzung des Quellcodes; beispielsweise Anwenden von Patchen%build
- Übersetzen des Programmquellcodes%install
- Erstellen des RPM-Pakets; kopieren von erstellten Binärdateien und Ordnerstrukturen in das RPM-Paket
Zugegebenermaßen verliert man hier am Anfang etwas den Überblick. Ich kann nur empfehlen, fertige RPM-Specfiles zu betrachten. Nicht selten lernt man so den ein oder anderen "Trick".
Um fertige Specfiles zu begutachten, gibt es prinzipiell zwei Ansätze. Zahlreiche zusätzliche Repositories bieten ihre Specfiles über SVN oder GIT an. Als Beispiel sei hier der GIT-Mirror von Repoforge genannt: [klick mich!]
Eine andere Möglichkeit wäre, die optionalen Quellcode-Channels zusätzlicher Repositories einzubinden - beispielweise EPEL - und Quellcode-Pakete herunterzuladen:
1# vi /etc/yum.repos.d/epel.repo
2...
3[epel-source]
4...
5enabled=1
6
7ESC ZZ
8
9# yum install yum-utils
10# yumdownloader --source nrpe
Die RPM-Pakete kann man entweder eigenhändig mit cpio
bearbeiten oder komfortablerweise den Midnight Commander verwenden, um die Inhalte des RPM-Pakets zu inspizieren. Im RPM-Paket ist ein CPIO-Archiv namens CONTENTS.cpio
zu finden - dort befinden sich i.d.R. in der obersten Ebene das gewünschte Specfile:
Um ein möglichst "sauberes" Paket zu bauen, empfiehlt es sich auch bei der Verteilung von Konfigurationsdateien ein Quellcode-Paket anzulegen. Es ist zwar möglich, Dateien direkt im Install-Makro des RPM-Specfiles zu erstellen - wenn man jedoch mehrere oder längere Konfigurationsdateien pakiert, leidet die Übersichtlichkeit darunter. In diesem Fall wird ein Archiv erstellt, welches lediglich über die NTP-Konfigurationsdatei verfügt:
1$ mkdir ~/rpmbuild/SOURCES/mycompany-ntp-1.0
2$ cd ~/rpmbuild/SOURCES/mycompany-ntp-1.0
3$ vi ntp.conf
4driftfile /var/lib/ntp/drift
5server localserver.loc
6
7ESC ZZ
8
9$ cd ..
10$ tar cf mycompany-ntp-1.0.tar.gz mycompany-ntp-1.0/*
Anschließend wird das RPM-Specfile angepasst - meine Version sieht wie folgt aus:
1$ cd ../SPECS
2$ cat mycompany-ntp.spec
3Name: mycompany-ntp
4Version: 1.0
5Release: 1%{?dist}
6Summary: MyCompany customized NTP configuration
7
8Group: System Environment/Daemons
9License: GPL
10Source0: %name-%version.tar.gz
11
12Requires: ntp
13
14%description
15This package includes MyCompany customized NTP configuration files.
16Feel free to delete this package if received outside the MyCompany network.
17
18%prep
19%setup -q
20
21%build
22
23%install
24rm -rf $RPM_BUILD_ROOT
25install -m 0755 -d %{buildroot}%{_sysconfdir}/mycompany
26install -m 0644 ntp.conf %{buildroot}%{_sysconfdir}/mycompany/ntp.conf
27
28%clean
29rm -rf $RPM_BUILD_ROOT
30
31%files
32%config(noreplace) %{_sysconfdir}/mycompany/ntp.conf
Zuerst wird vermutlich ins Auge fallen, dass die NTP-Konfigurationsdatei nicht an ihrem eigentlichen Ort (/etc/ntp.conf
) sondern an einen alternativen Ort (/etc/mycompany/ntp.conf
) gesichert wird. Das liegt daran, dass das Überschreiben der ursprünglichen Konfigurationsdatei (die durch das ntp
-Paket bereitgestellt wird) aufgrund des noreplace
-Flags nicht möglich ist:
1#Auszug aus dem ntp RPM Specfile
2%files
3%config(noreplace) %{_sysconfdir}/ntp.conf
Das hier gezeigte Paket sichert seine Konfigurationsdatei an einem anderen Ort, an welchem kein anderes RPM-Paket Änderungen vornehmen darf.
Man muss sich hier einem "Trigger-Trick" bedienen, der nach der Installation die urpsprüngliche Konfigurationsdatei sichert und anschließend eine symbolische Verknüpfung zur neuen Konfigurationsdatei erstellt. Nach einer eventuellen Paket-Deinstallation wird dieser Schritt rückgängig gemacht. Hierzu müssen die folgenden Makros hinzugefügt werden:
1%triggerin -- mycompany-ntp
2if [ ! -h /etc/ntp.conf -o ! "`readlink /etc/ntp.conf`" = "/etc/mycompany/ntp.conf" ] ; then
3 if [ -e /etc/ntp.conf ] ; then
4 mv -f /etc/ntp.conf /etc/ntp.conf.orig
5 fi
6 ln -s /etc/mycompany/ntp.conf /etc/ntp.conf
7fi
8
9%triggerun -- mycompany-ntp
10if [ $1 -eq 0 -a $2 -gt 0 -a -e /etc/ntp.conf.orig ] ; then
11 mv -f /etc/ntp.conf.orig /etc/ntp.conf
12fi
13
14%triggerpostun -- mycompany-ntp
15if [ $2 -eq 0 ]; then
16 rm -f /etc/ntp.conf.rpmsave /etc/ntp.conf.orig
17fi
18if [ -e /etc/ntp.conf.rpmnew ] ; then
19 mv /etc/ntp.conf.rpnnew /etc/ntp.conf.orig
20fi
21
22%postun
23if [ -e /etc/ntp.conf.orig -a -h /etc/ntp.conf -a ! -e "`readlink /etc/ntp.conf`" ] ; then
24 mv -f /etc/ntp.conf.orig /etc/ntp.conf
25fi
Vereinfacht ausgedrückt bewirken die Trigger folgendes:
- Installation: Wenn die ursprüngliche Konfigurationsdatei vorhanden ist, wird an den Dateinamen ein "
.orig
" angehängt und ein symbolischer Link zur neuen Konfigurationsdatei hergestellt - Deinstallation der benutzerdefinierten NTP-Konfiguration: Wenn die ursprüngliche Konfigurationsdatei noch vorhanden ist, wird der Dateiname zurückgesetzt
- Nach der Deinstallation der benutzerdefinierten NTP-Konfiguration: weitere verbleibende ursprüngliche oder neu hinzugekommene Konfigurationsdateien werden gelöscht
- Nach der Deinstallation: Zurücksetzen des Dateinamens der ursprünglichen Konfigurationsdatei
Im oberen Specfile wurde auf die URL
- und BuildRequires
-Tags verzichtet, da es für eine benutzerdefinierte NTP-Konfiguration weder eine Webseite, noch Abhängigkeiten zum Kompilieren gibt. 😉
Beispiel 2: Meta-Pakete
Häufig gibt es eine Auswahl an Programmen und Konfigurationen, die zu einer benutzerdefinierten Grundinstallation gehören - um mal einige Praxis-Beispiele zu nennen: sudo-Konfiguration, GNU Screen (natürlich!), und benutzerdefinierte Anwendungsprofile.
Damit man diese Programmauswahl nicht jedes Mal aus dem Gedächtnis abrufen muss, lassen sich kinderleicht Metapakete implementieren. Diese Pakete haben keine eigenen Dateien, sondern verfügen lediglich über Abhängigkeiten zu den einzelnen Software-Paketen. RPM-Metapakete sind daher auch keiner bestimmten Prozessor-Architektur (x86_64, i686, s390,...) zuzuordnen - sie erhalten im Specfile die Zuweisung "BuildArch noarch
".
Hier ein anderes Beispiel aus der Praxis: ein Metapaket zur Installation von NTP inklusive unternehmenskonformer Konfiguration und telnet
zur Verifizierung, ob der Daemon auch aktiv ist:
1$ cd SOURCES
2$ mkdir mycompany-ntp-full-1.0
3$ tar cvfz mycompany-ntp-full-1.0.tar.gz mycompany-ntp-full-1.0
4$ cd ../SPECS
5$ cat mycompany-ntp-full.spec
6Name: mycompany-ntp-full
7Version: 1.0
8Release: 1%{?dist}
9Summary: MyCompany customized NTP configuration and netstat utility
10
11Group: System Environment/Daemons
12License: GPL
13Source0: %name-%version.tar.gz
14
15BuildArch: noarch
16Requires: ntp mycompany-ntp net-tools
17
18%description
19This package includes MyCompany customized NTP configuration files.
20Feel free to delete this package if received outside the MyCompany network.
21
22%prep
23%setup -q
24
25%build
26
27%install
28
29%clean
30rm -rf $RPM_BUILD_ROOT
31
32%files
Mithilfe von rpm
kann man aus dem erstellen RPM-Paket die Abhängigkeiten ablesen:
1$ rpmbuild -bb mycompany-ntp-full.spec
2$ rpm --query -Rp ../RPMS/noarch/mycompany-ntp-full-1.0-1.el6.noarch.rpm
3ntp
4mycompany-ntp
5net-tools
6rpmlib(PayloadFilesHavePrefix) <= 4.0-1
7rpmlib(CompressedFileNames) <= 3.0.4-1
Paketabhängigkeiten lassen sich übrigens mithilfe von Bedingungen je nach Release unterschiedlich gestalten. In diesem Beispiel zwischen RHEL5 und 6 - die Pakete, die das telnet
-Kommando bereitstellen, variieren hier nämlich zufälligerweise:
1rhel5 # rpm -qf $(which telnet)
2krb5-workstation-1.6.1-70.el5_9.2
3rhel6 # rpm-qf $(which telnet)
4net-tools-1.60-110.el6_2.x86_64
Berücksichtigt wird das im Specfile folgendermaßen:
1Requires: ntp mycompany-ntp
2%{?el5:Requires: krb5-workstation}
3%{?el6:Requires: net-tools}
Die erste Liste von Abhängigkeiten gilt für jedes Release, die darauf folgenden entweder für RHEL5 oder RHEL6.
Zusammen mit den Requires
- und Conflicts
-Tags lassen sich auch Versionen definieren - beispielsweise, um ein myapp
-Paket zu referenzieren, das mindestens in der Version 1.1 vorliegt. Eine der beiden folgenden Zeilen ergibt hier Sinn:
1Requires: myapp >= 1.1
2Conflicts: myapp < 1.1
Möchte man nun eine bestimmte Version als Abhängigkeit definieren, hat man die Wahl zwischen einer der beiden folgenden Zeilen:
1Requires: myapp = 1.1
2Conflicts: myapp < 1.1 myapp > 1.1
Welche der beiden Zeilen man nun verwendet ist ein ähnlich philosophiesches Thema, wie die Frage, ob das Glas halb voll oder halb leer ist - entweder schließe ich eben aus oder ich referenziere explizit. 😉
Weitere Informationen zu RPM-Abhängigkeiten gibt es auf der offiziellen RPM-Seite: [klick mich!]
Zurück zur eigentlichen Motivation dieses Metapakets: Alternativ lassen sich übrigens auch Paketgruppen im eigenen YUM-Repository definieren. Wer schon mal mit den YUM-Kommandos grouplist
, groupinstall
und groupremove
gearbeitet hat, kennt diese logische Gruppierung von Software-Paketen. Im YUM-Wiki gibt es hierüber einen interessanten Artikel: [klick mich!]
Paketbau und Repo-Erstellung
Schön, wir haben nun ein RPM-Specfile - und weiter? Die eigentliche Erstellung des Programmpakets erfolgt mithilfe von rpmbuild
. Dieses Tool kennt zahlreiche Schalter, so lassen sich beispielsweise auch noch Quellcode-Programmpakete erstellen oder Anwendungen für alternative Prozessorarchitekturen paketieren.
Wichtige Parameter:
Parameter | Bedeutung |
-ba | Erstellt ein Binär- + Source-Paket |
-bb | Erstellt ein Binär-Paket |
-bp | Entpacken und Patchen (falls nötig) des Quellcodes |
-bs | Erstellt ein Source-Paket |
--target=noarch | Erstellt ein plattformunabhängiges Paket |
--target=i686 | ...ein 32-bit Paket |
--target=x86_64 | ...ein 64-bit Paket |
Einige Programmbeispiele:
1# Erstellt ein Binär- und Quellcode-Paket von myapp
2$ rpmbuild -ba myapp.spec
3# Erstellt ein 32-bit Binärpaket von myapp
4$ rpmbuild -bb --target=i686 myapp.spec
Anschließend findet sich unterhalb RPMS
je nach verwendeter Architektur ein Paket unterhalb noarch
, i686
oder x86_64
. Wer einen IBM System Z-Großrechner sein Eigen nennt, wird unterhalb s390
bzw. s390x
fündig. 😉
1$ ls RPMS/*/*.rpm
2RPMS/i386/mycompany-ntp-1.0-1.el6.i386.rpm
Dieses RPM-Paket könnte jetzt, wie gewohnt, mittels YUM installiert werden:
1# yum localinstall --nogpgcheck mycompany-ntp-1.0-1.el6.i386.rpm
Synchronisierung und Automatisierung
Wenn die RPM-Pakete auf den einzelnen Testmaschinen erstellt wurden (z. B. RHEL6 und RHEL5), müssen diese noch auf den eigentlichen Webserver repliziert werden. Hier empfiehlt sich der Einsatz von SSH und Rsync, um die Daten zuerst von den Testmaschinen zur Haupt-Testmaschine und anschließend zum Webserver zu kopieren.
Das Ganze lässt sich natürlich mit einem kleinen Skript automatisieren, damit die einzelnen Befehle nicht jedes Mal aufs Neue eingegeben werden müssen:
1.Von der EL5-Testmaschine zur Haupt-Testmaschine:
1$ ln -s /usr/src/redhat /home/su-rpmdev/rpmbuild
2$ vi /home/su-rpmdev/export_repo.sh
3#!/bin/sh
4rsync -avz --delete /home/su-rpmdev/rpmbuild/RPMS/ /opt/myrepo
5createrepo --database /opt/myrepo/
6rsync -avz --delete -e ssh /opt/myrepo/ su-rpmdev@MAIN:/opt/myrepo/5Server
7
8ESC ZZ
9
10$ chmod +x /home/su-rpmdev/export_repo.sh
11$ ./home/su-rpmdev/export_repo.sh
Der erste rsync
-Befehl synchronisiert sämtliche RPM-Pakete aller Prozessorarchitekturen nach /opt/myrepo
- aller nicht mehr in der Quelle vorhandenen RPM-Pakete werden auch unterhalb /opt/myrepo
gelöscht. Der createrepo
-Aufruf erstellt eine SQLite-Datenbank für das unterhalb /opt/myrepo
angelegte YUM-Repository (myrepo
). Der zweite rsync-Befehl synchronisiert das YUM-Repository über SSH auf den Haupt-Repository Server (MAIN
).
2.Von der Haupt-Testmaschine (EL6) zum Webserver:
1$ vi /home/su-rpmdev/export_repo.sh
2#!/bin/sh
3rsync -avz --delete /home/su-rpmdev/rpmbuild/RPMS/ /opt/myrepo/6Server
4createrepo --database /opt/myrepo/6Server
5rsync -avz --delete -e ssh /opt/myrepo/ su-rpmdev@WEB:/var/www/html/myrepo
6
7ESC ZZ
8
9$ chmod +x /home/su-rpmdev/export_repo.sh
10$ ./home/su-rpmdev/export_repo.sh
Der erste rsync
-Befehl synchronisiert sämtliche (EL6) RPM-Pakete nach /opt/myrepo/6Server
. Anschließend erstellt createrepo
eine SQLite-Datenbank für das EL6-Repository. Der zweite rsync
-Befehl synchronisiert das gesamte Repository (also auch die Pakete des anderen Testsystems) auf den Webserver (WEB
).
Einbindung und Test
Damit das frisch erstellte YUM-Repository auf anderen Hosts verwendet werden kann, muss eine entsprechende YUM-Konfigurationsdatei angelegt werden. In dieser Datei werden die Repository-URL und andere Parameter, wie beispielsweise Paketsignierung, definiert. Der Syntax erinnert ein wenig an frühere Windows .ini
-Dateien:
1# vi /etc/yum.repos.d/myrepo.repo
2[myrepo]
3name=mycompany packages for EL
4baseurl=http://server01/$releasever
5enabled=1
6gppgcheck=0
7
8ESC ZZ
Hier fällt gleich die Variable $releasever
ins Auge - wir erinnern uns an die obrige Tabelle. Die Variable wird, je nach verwendeter Distribution, durch einen anderen Wert ersetzt - in diesem Fall durch 5Server
oder 6Server
. Diese Ordner werden durch die obrigen Skripte mit den entsprechenden RPM-Paketen der Test-Maschinen befüllt.
Anschließend werden alle verfügbaren Pakete des Repositorys aufgelistet:
1# yum --disablerepo='*' --enablerepo='myrepo' makecache
2# yum --disablerepo='*' --enablerepo='myrepo' list available
3...
4mycompany-ntp 1.0-1 myrepo
Wenn man mehrere Repository-Webserver hat, beispielsweise bei großen Setups, um die Anzahl der Anfragen zu bewerkstelligen oder Ausfälle zu kompensieren, kann man noch eine Mirrorlist hinzufügen:
1# vi /etc/yum.repos.d/myrepo.repo
2[myrepo]
3...
4#baseurl=...
5mirrorlist=myrepo.mirror
6
7ESC ZZ
8# vi /etc/yum.repos.d/myrepo.mirror
9http://server01/$releasever
10http://server02/$releasever
11http://server03/$releasever
Für jeden Download geht YUM dann die einzelnen Server durch - beginnend bei dem ersten. Fällt dieser aus oder verfügt nicht über die benötigte Datei, wird der nächste in der Liste gewählt.
Diese Konfigurationsdatei(en) wären übrigens auch ein Kandidat für ein RPM-Paket - so muss man nur ein RPM-Paket installieren und kann anschließend auf das gesamte YUM-Repository zugreifen. Bei Fedora's Extra Packages For Enterprise Linux (EPEL) wird das beispielsweise so gemacht: [klick mich!]
Ein solches Paket könnte wie folgt aussehen:
1# vi SPECS/myrepo-release.spec
2Name: myrepo-release
3Version: 1.0
4Release: 1%{?dist}
5Summary: mycompany Packages for Enterprise Linux repository configuration
6
7Group: System Environment/Base
8BuildArch: noarch
9License: GPL
10URL: http://www.mycompany.com
11Source0: myrepo-release-%{version}.tar.gz
12BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
13
14%description
15This package contains the mycompany customized Packages for Enterprise Linux repository.
16
17%prep
18%setup -q
19
20%build
21
22%install
23install -m 0755 -d %{buildroot}%{_sysconfdir}/yum.repos.d/
24install -m 0755 myrepo.repo %{buildroot}%{_sysconfdir}/yum.repos.d/myrepo.repo
25install -m 0755 myrepo.mirror %{buildroot}%{_sysconfdir}/yum.repos.d/myrepo.mirror
26
27%clean
28rm -rf $RPM_BUILD_ROOT
29
30%files
31%config(noreplace) %{_sysconfdir}/yum.repos.d/myrepo.repo
32%config(noreplace) %{_sysconfdir}/yum.repos.d/myrepo.mirror
33
34%changelog
35* Sat Jun 29 2013 FirstName LastName <name@company.com> - 1.0-1
36- initial release
37
38ESC ZZ
39
40# tar tvfz SOURCES/myrepo-release-1.0.tar.gz
41-rw-r--r-- su-rpmdev/su-rpmdev 94 2013-06-28 18:12 myrepo-release-1.0/myrepo.mirror
42-rw-r--r-- su-rpmdev/su-rpmdev 189 2013-06-28 18:09 myrepo-release-1.0/myrepo.repo
43
44# tar xvfz SOURCES/myrepo-release-1.0.tar.gz -C SOURCES/
45
46# cat SOURCES/myrepo-release-1.0/myrepo.mirror
47http://server01/$releasever
48http://server02/$releasever
49http://server03/$releasever
50
51# cat SOURCES/myrepo-release-1.0/myrepo.repo
52[myrepo]
53name=mycompany packages for EL
54#baseurl=http://server01/$releasever
55mirrorlist=/etc/yum.repos.d/myrepo.mirror
56enabled=1
57gppgcheck=0
Nachdem das Specfile entsprechend erstellt wurde, kann das Paket einfach erstellt und verteilt werden. Es genügend dann, das RPM-Paket zu installieren, um das YUM-Repository nutzen zu können:
1# rpmbuild -bb SPECS/myrepo-release.spec
2# scp RPMS/noarch/myrepo-release-1.0-1.rpm root@host:/root
3root@host # yum localinstall --nogpgcheck myrepo-release*.rpm
4root@host # yum repolist
5repoid reponame
6...
7myrepo mycompany packages for EL
Et voilà! 🙂
Ausblick / Weitere Ideen
Natürlich könnte man diesen Aufbau noch weiter optimieren. Um mal einige verbesserungswürdige Punkte zu erwähnen:
- SSH Public-Key-Authentifizierung - Beim Synchronisieren der RPM-Pakete müssen für die Haupt-Testmaschine und den Webserver derzeit zwei Passwörter eingegeben werden. Durch SSH Public-Key-Authentifizierung lässt sich das automatisieren.
- Theme für Ansicht im Web-Browser - Wenn das Repository im Web-Browser aufgerufen wird, wird - abhängig vom verwendeten Webserver- lediglich der Inhalt des Verzeichnisses aufgelistet, was nicht sonderlich hübsch aussieht. Man könnte noch einen Header mit einem Firmen-Logo und Verwendungsinformationen erstellen.
- Versionsverwaltung mit SVN / GIT - Insbesondere wenn man im Team arbeitet, ist eine Versionsverwaltung mithilfe von SVN oder GIT äußerst sinnvoll.
- Integration in Red Hat Network Satellite, Spacewalk oder SuSE Manager - Wer eine größere Anzahl an Hosts verwaltet, verfügt (hoffentlich) über eine Management-Suite seines favorisierten Distributors. Eigene Pakete können in diese Software integriert und so einfach verteilt werden.
- Paketsignierung - Um manipulierten Datenpaketen vorzubeugen, lassen sich Pakete mit einem Key, den alle Clients importieren müssen, signieren. Somit ist sichergestellt, dass es sich um authentische Pakete handelt.
Um eine größere Anzahl an Systemen zu verwalten, braucht es keine "eierlegende Wollmilchsau" - mit RPM gibt es ein vielseitiges Werkzeug, das auch zum Software- und Configuration-Management verwendet werden kann. Wer sich intensiv mit Red Hat Enterprise Linux beschäftigt, wird öfter in die Situation kommen, bei der etwas schnell automatisiert werden muss. Und genau hier kann RPM durchaus schnell zum Ziel führen. 😉