Quellcode-Patches in RPM-Dateien integrieren
Neulich habe ich die Software scponly mittels rpmbuild
für Enterprise Linux paketiert und bin dabei auf eine Fehlermeldung gestoßen:
1$ cd ~/rpmbuild/SPECS
2$ rpmbuild -ba scponly.spec
3checking for libgiertz...
4...
5/usr/bin/install -c -o 0 -g 0 scponly /home/cstan/rpmbuild/BUILDROOT/scponly-4.8-1.el7.centos.x86_64/usr/bin/scponly
6/usr/bin/install: cannot change ownership of '/home/cstan/rpmbuild/BUILDROOT/scponly-4.8-1.el7.centos.x86_64/usr/bin/scponly': Operation not permitted
7make: *** [install] Error 1
8error: Bad exit status from /var/tmp/rpm-tmp.Zx3wsc (%install)
9
10RPM build errors:
11 Bad exit status from /var/tmp/rpm-tmp.Zx3wsc (%install)
Beim "Installieren" der übersetzten Dateien innerhalb des RPM-Pakets schlägt also das Ändern des Dateibesitzers fehl - aber warum? Das Makefile
sollte hier Aufschluss geben. Unterhalb des BUILD
-Ordners befinden sich Laufzeitdaten von vorherigen Übersetzungsprozessen:
1$ cd ../BUILD/scponly-3xxx
2$ less Makefile.in
3...
4 ${INSTALL} -o 0 -g 0 scponly ${DESTDIR}${bindir}/scponly
5 ${INSTALL} -o 0 -g 0 -m 0644 scponly.8 ${DESTDIR}${mandir}/man8/scponly.8
6 ${INSTALL} -o 0 -g 0 -m 0644 debuglevel ${DESTDIR}${DEBUGFILE}
7 if test "x${CHROOTED_NAME}" != "x"; then
8 ${INSTALL} -d ${DESTDIR}${sbindir};
9 rm -f ${DESTDIR}${sbindir}/${CHROOTED_NAME};
10 cp scponly ${CHROOTED_NAME};
11 ${INSTALL} -o 0 -g 0 -m 4755 ${CHROOTED_NAME} ${DESTDIR}${sbindir}/${CHROOTED_NAME};
Beim Konsultieren des Makefiles fielen mir die install
-Parameter -o
und -g
auf. Mithilfe dieser Parameter kann ein spezieller Benutzer bzw. eine spezielle Gruppe angegeben werden - 0
steht hier für den root-Benutzer bzw. die root-Gruppe. Beim Erstellen von RPM-Paketen ist das spezielle Definieren von root
an dieser Stelle überflüssig, da - sofern nicht anders angegeben - jede Datei erstmal root gehört.
Bei einem manuellen Übersetzen der Software hat sich gezeigt, dass der Prozess ohne die oben erwähnten Parameter fehlerfrei durchläuft. Nun muss nur der Quellcode gepatcht werden, damit das RPM-Paket fehlerfrei erstellt werden kann.
Hierfür muss zuerst eine Kopie des entsprechenden Ordners erstellt werden - wir befinden uns wieder im BUILD
-Ordner:
1$ cd ..
2$ mkdir scponly-3xxx-revised
3$ cp -R scponly-3xxx scponly-3xxx-revised
Nun wird die entsprechende Datei - hier das Makefile - angepasst:
1$ vi scponly-3xxx-revised/Makefile.in
2...
3 ${INSTALL} scponly ${DESTDIR}${bindir}/scponly
4 ${INSTALL} -m 0644 scponly.8 ${DESTDIR}${mandir}/man8/scponly.8
5 ${INSTALL} -m 0644 debuglevel ${DESTDIR}${DEBUGFILE}
6 if test "x${CHROOTED_NAME}" != "x"; then
7 ${INSTALL} -d ${DESTDIR}${sbindir};
8 rm -f ${DESTDIR}${sbindir}/${CHROOTED_NAME};
9 cp scponly ${CHROOTED_NAME};
10 ${INSTALL} -m 4755 ${CHROOTED_NAME} ${DESTDIR}${sbindir}/${CHROOTED_NAME};
11ESC ZZ
Anschließend wird mittels diff
ein Vergleich der beiden Verzeichnisse durchgeführt - die Änderungen werden in einer Patch-Datei dokumentiert. Idealerweise legt man diese direkt im SOURCES
-Ordner ab, wo sich auch bereits der Programmquellcode befindet. Das ist wichtig, damit im RPM Specfile darauf verwiesen werden kann!
1$ diff -urN scponly-3xxx scponly-3xxx-revised > ../SOURCES/scponly-3xxx-makefile.patch
Im RPM Specfile wird nun nach der Source
-Zeile eine Patch
-Zeile eingefügt, die den Dateinamen des Patches enthält . In der %prep
-Sektion der Datei wird nach der %setup
-Zeile eine neue Zeile zum Patchen des Quellcodes eingefügt: %patch0 -p1
.
Natürlich ist es auch möglich, mehrere Patches zu referenzieren - die Zeilen enthalten eine fortlaufende Nummer. In diesem Fall wurde der erste Patch referenziert - daher heißen die Schlagwörter Patch0
bzw. %patch0
:
1$ cd ../SPECS
2$ vi scponly.spec
3...
4Source0: https://github.com/scponly/scponly/archive/3xxx.zip
5Patch0: scponly-3xxx-makefile.patch
6...
7%prep
8%setup -q -n scponly-3xxx
9%patch0 -p1
10...
11
12ESC ZZ
Anschließend ließ sich das RPM-Paket wie gewohnt erstellen:
1$ rpmbuild -ba scponly.spec
2...
3Executing(%clean): /bin/sh -e /var/tmp/rpm-tmp.jchHSk
4+ umask 022
5+ cd /home/cstan/rpmbuild/BUILD
6+ cd scponly-3xxx
7+ /usr/bin/rm -rf /home/cstan/rpmbuild/BUILDROOT/scponly-4.8-1.el7.centos.x86_64
8+ exit 0
Wenn man einen Blick in das RPM-Paket wirft (beispielsweise mit cpio
oder Midnight Commander), sieht man, dass die Dateien root gehören - es gibt also keine Beeinträchtigung der Software nach Übernahme des Patches:
1-rw-r--r-- 1 root root 2 Jun 30 18:22 /etc/scponly/debuglevel
2-rwxr-xr-x 1 root root 24720 Jun 30 18:22 /usr/bin/scponly
3-rwxr-xr-x 1 root root 24720 Jun 30 18:22 /usr/sbin/scponlyc
4-rw-r--r-- 1 root root 2534 Jun 30 18:22 /usr/share/man/man8/scponly.8.gz
Wer das Beispiel gerne nachstellen möchte, kann gerne mein RPM Spec und den Patch verwenden.