RPM-Pakete pflegen

Siehe auch

Dieses Kapitel beschreibt, wie man eigene RPM-Pakete unter RHEL erstellt und in einem Repository ablegt. Ausführliche Hilfe erhält man auf der Seite des Fedora-Projektes sowie dem RPM Reference Manual und dem Maximum RPM Book .

Build-Maschine bereitstellen

Eine separate Build-Maschine unter RHEL 7 richtet man wie folgt ein:

yum -y install prelink rpm-build rpmdevtools

useradd rpmbuild
usermod --comment="RPM Package Builder" --home=/home/rpmbuild rpmbuild

Erforderliche Struktur im Home-Verzeichnis des rpmbuild-Benutzers erstellen lassen:

su - rpmbuild
rpmdev-setuptree

Danach sieht /home/rpmbuild wie folgt aus:

└── rpmbuild
    ├── BUILD
    ├── RPMS
    ├── SOURCES
    ├── SPECS
    └── SRPMS

SPEC-Datei definieren

RPMs werden basierend auf einer SPEC-Datei gebaut.

Diese SPEC-Datei kopiert einfach nur einige Dateien aus dem RPM in die angegebenen Zielverzeichnisse. Im Beispiel heisst das Projekt mycompany-myproduct. Vom Prinzip her erinnert die SPEC-Datei an eine Kickstart-Datei

Name:     mycompany-myproduct
Version:  2.1
Release:  0%{?dist}
Summary:  MyCompany Package for MyProduct

Group:    Applications/System
License:  GPLv2+
Requires: java-1.7.0-openjdk,wget,mailx

Source0:  %{name}-%{version}.tar.gz

%description
# nothing to do here

# separate "dub-package" for SELinux support
%package        selinux
Summary:        SELinux support for myproduct
Requires:       %{name} = %{version}-%{release}
Requires(post): policycoreutils, %{name}
Requires(preun): policycoreutils, %{name}
Requires(postun): policycoreutils

# available macros (non-exhaustive):
# from https://docs.fedoraproject.org/en-US/packaging-guidelines/RPMMacros/
# %{_sysconfdir}     = /etc
# %{_prefix}         = /usr
# %{_exec_prefix}    = %{_prefix}
# %{_includedir}     = %{_prefix}/include
# %{_bindir}         = %{_exec_prefix}/bin
# %{_lib}            = lib64 on 64bit platforms, otherwise lib
# %{_libdir}         = %{_exec_prefix}/%{_lib}
# %{_libexecdir}     = %{_exec_prefix}/libexec
# %{_datarootdir}    = %{_prefix}/share
# %{_datadir}        = %{_datarootdir}
# %{_infodir}        = %{_datarootdir}/info
# %{_mandir}         = %{_datarootdir}/man
# %{_docdir}         = %{_datarootdir}/doc
# %{_rundir}         = /run
# %{_localstatedir}  = /var
# %{_sharedstatedir} = /var/lib

%prep
# extract sources, i.e. the tarball placed in ~/rpmbuild/SOURCES/ and change directory to it
%setup

%build
# compilation (if needed) should happen here

%install
# install/copy files that should end up in the package to %{buildroot}
install mydriver.so %{buildroot}%{_libdir}/mydriver.so
# and so on...

%files
# all files that are installed must be listed here
%defattr(-,root,root,-)
%{_sysconfdir}/sysconfig/iptables
%{_libdir}/mydriver.so
/root/myproduct-status-report.sh
/opt/mycompany/myproduct/
%license LICENSE.txt

# Post sections are executed during package installation
%post
/sbin/ldconfig
service iptables restart

chmod +x /root/myproduct-status-report.sh
chmod +x /opt/mycompany/myproduct/bin/*

ln -s /lib/mydriver.so.5.00 /usr/lib/libeToken.so.5
# and more...

%post selinux
# This post section is for the selinux subpackage only
restorecon -r %{_libdir}/mydriver.so

%changelog
* Tue Mai 27 2025 Linuxfabrik GmbH, Zurich, Switzerland <info@linuxfabrik.ch>
- Added selinux support, ...
* Wed Dec 18 2014 Linuxfabrik GmbH, Zurich, Switzerland <info (at) linuxfabrik (dot) ch> 2.1.0
- Bufix-Release; improved connection handling; ...

Bemerkung

Debian kennt für DEB-Pakete ähnliche Konzepte, allerdings aufgeteilt über mehrere Dateien:

  • debian/control: beinhaltet Paket-Metadaten, ähnlich wie der Teil bis zur ersten Sektion (z.B. %prep).

  • debian/changelog: aus dem Changelog wird beim Packaging die Version abgeleitet.

  • debian/install: ähnliche Funktionalität zur %files Sektion.

  • debian/rules: Makefile, meistens genutzt in Kombination mit debhelper (dh).

Reproduzierbare RPM (Cross-)Builds

# nur source-rpm mit rpmbuild bauen
rpmbuild -bs ~/rpmbuild/SPECS/linuxfabrik-monitoring-plugins.spec

# (binary) rpm in einer sauberen, isolierten mock-Umgebung bauen
mock --root /etc/mock/default.cfg ~/SRPMS/mypackage.spec

# Für eine andere Zielkonfigurationen bauen
# z.B. auf Rocky9 für Rocky8 mit EPEL:
mock --root /etc/mock/rhel+epel-8-x86_64.cfg ~/SRPMS/mypackage.spec

Bemerkung

Das Debian-Äquivalent zu mock für DEB-Pakete ist sbuild.

RPM erstellen und veröffentlichen

Nach der Erstellung/Anpassung der SPEC-Datei kann das RPM gebaut werden.

su - rpmbuild
rm -rf rpmbuild/BUILDROOT/*

Den Source-Tarball mit den gewünschten Dateien in /home/rpmbuild/rpmbuild/SOURCES ablegen. Anschliessend die Binary-Pakete bauen (ohne Source-Package).

rpmbuild -bb rpmbuild/SPECS/mycompany-myproduct.spec

Unter /home/rpmbuild/rpmbuild/RPMS findet sich das erzeugte RPM, als Beispiel x86_64/mycompany-myproduct-2.1-0.el8.x86_64.rpm. Dieses lässt sich entweder direkt - ohne Abhängigkeiten aufzulösen - per rpm --install --verbose mycompany-myproduct-2.1-0.el8.x86_64.rpm oder mittels dnf install mycompany-myproduct-2.1-0.el8.x86_64.rpm installieren.

RPM in eigenem Repo veröffentlichen

Nach erfolgreichem Test kann man das RPM-Paket von der Build-Maschine auf den Repository-Server kopieren.

scp /home/rpmbuild/rpmbuild/RPMS/x86_64/* root@repo-server:/var/www/html/packages/rhel/8/x86_64

Auf dem Repository-Server muss anschliessend die Repository-„Datenbank“ per createrepo aktualisiert werden, siehe Repo Server.

Built on 2025-07-14