Integrate source code patches into RPM packages
Rcently I packaged the software scponly for Enterprise Linux using rpmbuild
and stumbled upon an error message:
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)
During the "installation" of compiled files within the RPM package changing the file owner fails - but why? Having a look at the Makefile
should help. Runtime data of previous compiling processes can be found inside the BUILD
folder:
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};
When having a look at the Makefile I discovered the install
parameters -o
and -g
. They are used to set a particular user or group - 0
represents the root user or group in this case. Defining root
as user or group during the RPM package creation is unnecessary as it is the default anyway.
When manually compiling the software I figured out that the process finishes if the parameters mentioned above are removed. So - the software source code needs to be patched in order to build the RPM package without any issues.
First of all, a copy of the appropriate folder needs to be created - ensure that you are in the BUILD
folder:
1$ cd ..
2$ mkdir scponly-3xxx-revised
3$ cp -R scponly-3xxx scponly-3xxx-revised
Aferwards the affected file - Makefile in this scenario - is edited:
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
Afterwards the two directories are compared using diff
- changes are documented in a patch file. It is a good idea to store this file in the SOURCES
folder where also the software source code is stored. This is essential to enable referencing the patch within the RPM spec file!
1$ diff -urN scponly-3xxx scponly-3xxx-revised > ../SOURCES/scponly-3xxx-makefile.patch
In the RPM Spec file a Patch line including the patch file name is added right after the Source line. In the %prep
section, a new line for patching the source code is added right after the %setup
line: %patch0 -p1
.
Of course it is also possible to reference multiple patches - the lines contain a continuous number. In this scenario the first patch was referenced - as a result, the keywords are Patch0
and %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
Afterwards, the RPM package creation succeeded:
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
If you have a look inside the RPM package (e.g. using cpio
or Midnight Commander), you will see, that the files belong to root. So there is no interference after applying the patch:
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
Feel free to use my RPM spec file and the patch for reproducing the issue.