linux_wiki:rpm_building

RPM Building

General Information

How to create RPM packages from source files.

Resources:

Checklist

  • Distro(s): Enterprise Linux 6

Setup Build Environment

  • Install packages
yum install rpm-build rpmdevtools gcc make
  • Create a user that will build rpms (regular user)
useradd builder
passwd builder
  • Login as user, create rpm build tree
su - builder
rpmdev-setuptree
  • This creates a tree structure like: ~/rpmbuild/
  • BUILD
  • RPMS
  • SOURCES
  • SPECS
  • SRPMS

Source Files

The source files are copied into ~/rpmbuild/SOURCES directory as a tar.gz file.

Follow the “Custom Scripts” example in each section to create a custom RPM that contain your own directories and shell scripts.

Create your directory structure:

mkdir -p ~/myscripts-1.0.0/opt/myscripts
  • Note: Everything under “myscripts-1.0.0/” will end up being the normal file system path. Re-create all system paths that you need.

Copy scripts into the directory

cp ~/scripts/*.sh ~/myscripts-1.0.0/opt/myscripts

Create “source” archive

tar -czvf ~/myscripts-1.0.0.tar.gz ~/myscripts-1.0.0/

Copy source archive to rpmbuild/SOURCES

cp ~/myscripts-1.0.0.tar.gz ~/rpmbuild/SOURCES/

Follow the “Xymon” examples in each section to build a RPM for the Xymon monitoring server and client. (https://www.xymon.com/)

Download source files, place a copy in rpmbuild's SOURCES directory.

  • Download the Xymon tar file
    wget http://downloads.sourceforge.net/project/xymon/Xymon/4.3.21/xymon-4.3.21.tar.gz
  • Extract
    tar -zxvf xymon-4.3.21.tar.gz
  • Copy the original tar file into rpmbuild's SOURCES
    cp ~/xymon-4.3.21.tar.gz ~/rpmbuild/SOURCES/
  • Copy all files but “xymon.spec” from the xymon-4.3.21/rpm directory into SOURCES
    cp ~/xymon-4.3.21/rpm/xymon-client* ~/rpmbuild/SOURCES/
    cp ~/xymon-4.3.21/rpm/xymon-init.d ~/rpmbuild/SOURCES/
    cp ~/xymon-4.3.21/rpm/xymon.logrotate ~/rpmbuild/SOURCES/
    • NOTE: All of the above files were copied into the SOURCES directory due to the spec file listing them all in the SOURCES section.

SPEC File

The spec (specification) file tells rpmbuild how the packages will be built.

The sections of a spec file are:

  • Preamble ⇒ Contains name, version, release, summary, group, license, url, vendor, source, prefix, packager, and buildroot information.
  • description ⇒ Longer description of the application.
  • prep ⇒ applies any patches from the source directory into a sub build directory. Previous build files are removed to ensure a new clean build.
  • build ⇒ compiles files underneath the build directory (./configure && make)
  • install ⇒ reads files under the build directory and writes them to the build root directory (make install)
  • files ⇒ contains a list of files that are part of the package. Only files listed will be included in the package. File permissions and ownership are set here too.
  • clean ⇒ removes files from the build root directory that are not needed anymore.

Vim creates a template for a spec file any time a file is created with a “.spec” suffix.

vim myapp.spec

This simplified package is to distribute custom scripts via a RPM.

Create spec file: vim ~/rpmbuild/SPECS/myscripts.spec

# Package information
Name: myscripts
Version: 1.0.0
Release: 1%{?dist}
Summary: My Custom Scripts
License: GPL+
Source0: %{name}-%{version}.tar.gz
 
%description
These are my custom scripts used for fun things.
 
# Don't create debug package
%define  debug_package %{nil}
 
# prep => remove previous build and extract source file (.tar.gz) to the builddir
%prep
%setup -q
 
# build => ./configure && make files in builddir; No building for shell scripts required
%build
 
# install => make install ; read files from builddir, write to buildrootdir. 
# Nothing to make install, so do a manual clean, mkdir, and copy.
%install
rm -rf %{buildroot}
mkdir -p %{buildroot}
cp -a * %{buildroot}
 
# clean => remove files from buildrootdir; redundant in Fedora, EPEL still requires this
%clean
rm -rf %{buildroot}
 
# files => set file permissions, owner, group, and what files/dirs to include
%files
%attr(755, root, root) /opt/myscripts
 
# changelog => RPM itself, not software's changelog
%changelog
* Thu Oct 22 2015 Robert Jones <rjones.email.com> 1.0.0-1
- Initial custom scripts packaging

This spec file is from Xymon's tar ball.


Copy xymon.spec into SPECS

cp ~/xymon-4.3.21/rpm/xymon.spec ~/rpmbuild/SPECS/


Modify the spec file so the version section works correctly:

vim ~/rpmbuild/SPECS/xymon.spec
 
Version: 4.3.21
 
Source: xymon-%version.tar.gz


Original Xymon spec file before mods above

Name: xymon
Version: @VER@
Release: 1
Group: Networking/Daemons
URL: http://xymon.sourceforge.net/
License: GPL
Source: xymon-@VER@.tar.gz
Source1: xymon-init.d
Source2: xymon.logrotate
Source3: xymon-client.init
Source4: xymon-client.default
Summary: Xymon network monitor
BuildRoot: /tmp/xymon-root
#BuildRequires: openssl-devel
#BuildRequires: pcre-devel
#BuildRequires: rrdtool-devel
#BuildRequires: openldap-devel
Conflicts: xymon-client
 
%description
Xymon (previously known as Hobbit) is a system for monitoring
your network servers and applications. This package contains
the server side of the Xymon package.
 
%package client
Summary: Xymon client reporting data to the Xymon server
Group: Applications/System
Conflicts: xymon
 
%description client
This package contains a client for the Xymon (previously known
as Hobbit) monitor. Clients report data about the local system to
the monitor, allowing it to check on the status of the system
load, filesystem utilisation, processes that must be running etc.
 
%prep
rm -rf $RPM_BUILD_ROOT
 
%setup
        USEXYMONPING=y \
        ENABLESSL=y \
        ENABLELDAP=y \
        ENABLELDAPSSL=y \
        XYMONUSER=xymon \
        XYMONTOPDIR=/usr/lib/xymon \
        XYMONVAR=/var/lib/xymon \
        XYMONHOSTURL=/xymon \
        CGIDIR=/usr/lib/xymon/cgi-bin \
        XYMONCGIURL=/xymon-cgi \
        SECURECGIDIR=/usr/lib/xymon/cgi-secure \
        SECUREXYMONCGIURL=/xymon-seccgi \
        HTTPDGID=apache \
        XYMONLOGDIR=/var/log/xymon \
        XYMONHOSTNAME=localhost \
        XYMONHOSTIP=127.0.0.1 \
        MANROOT=/usr/share/man \
        INSTALLBINDIR=/usr/lib/xymon/server/bin \
        INSTALLETCDIR=/etc/xymon \
        INSTALLWEBDIR=/etc/xymon/web \
        INSTALLEXTDIR=/usr/lib/xymon/server/ext \
        INSTALLTMPDIR=/var/lib/xymon/tmp \
        INSTALLWWWDIR=/var/lib/xymon/www \
        ./configure
 
%build
        PKGBUILD=1 make
 
%install
        INSTALLROOT=$RPM_BUILD_ROOT PKGBUILD=1 make install
        mkdir -p $RPM_BUILD_ROOT/etc/init.d
        cp %{SOURCE1} $RPM_BUILD_ROOT/etc/init.d/xymon
        cp %{SOURCE3} $RPM_BUILD_ROOT/etc/init.d/xymon-client
        mkdir -p $RPM_BUILD_ROOT/etc/logrotate.d
        cp %{SOURCE2} $RPM_BUILD_ROOT/etc/logrotate.d/xymon
        mkdir -p $RPM_BUILD_ROOT/etc/default
        cp %{SOURCE4} $RPM_BUILD_ROOT/etc/default/xymon-client
        mkdir -p $RPM_BUILD_ROOT/usr/bin
        cd $RPM_BUILD_ROOT/usr/bin && ln -sf ../lib/xymon/server/bin/{xymon,xymoncmd} .
        mkdir -p $RPM_BUILD_ROOT/etc/httpd/conf.d
        mv $RPM_BUILD_ROOT/etc/xymon/xymon-apache.conf $RPM_BUILD_ROOT/etc/httpd/conf.d/
        rmdir $RPM_BUILD_ROOT/usr/lib/xymon/client/tmp
        cd $RPM_BUILD_ROOT/usr/lib/xymon/client && ln -sf /tmp tmp
        rmdir $RPM_BUILD_ROOT/usr/lib/xymon/client/logs
        cd $RPM_BUILD_ROOT/usr/lib/xymon/client && ln -sf ../../../../var/log/xymon logs
        mv $RPM_BUILD_ROOT/usr/lib/xymon/client/etc/xymonclient.cfg /tmp/xymonclient.cfg.$$
        cat /tmp/xymonclient.cfg.$$ | sed -e 's!^XYMSRV=.*!include /var/run/xymonclient-runtime.cfg!' | grep -v "^XYMSERVERS=" >$RPM_BUILD_ROOT/usr/lib/xymon/client/etc/xymonclient.cfg
        rm /tmp/xymonclient.cfg.$$
 
%clean
rm -rf $RPM_BUILD_ROOT
 
 
%pre
id xymon 1>/dev/null 2>&1
if [ $? -ne 0 ]
then
   groupadd xymon || true
   useradd -g xymon -c "Xymon user" -d /usr/lib/xymon xymon
fi
if [ -e /var/log/xymon/xymonlaunch.pid -a -x /etc/init.d/xymon ]
then
        /etc/init.d/xymon stop || true
fi
 
%pre client
id xymon 1>/dev/null 2>&1
if [ $? -ne 0 ]
then
   groupadd xymon || true
   useradd -g xymon -c "Xymon user" -d /usr/lib/xymon xymon
fi
if [ -e /var/log/xymon/clientlaunch.pid -a -x /etc/init.d/xymon-client ]
then
        /etc/init.d/xymon-client stop || true
fi
 
 
%post
chkconfig --add xymon
 
%post client
chkconfig --add xymon-client
 
 
%preun
if [ -e /var/log/xymon/xymonlaunch.pid -a -x /etc/init.d/xymon ]
then
        /etc/init.d/xymon stop || true
fi
chkconfig --del xymon
 
%preun client
if [ -e /var/log/xymon/clientlaunch.pid -a -x /etc/init.d/xymon-client ]
then
        /etc/init.d/xymon-client stop || true
fi
chkconfig --del xymon-client
 
 
%files
%attr(-, root, root) %doc README README.CLIENT Changes* COPYING CREDITS RELEASENOTES
%attr(644, root, root) %doc /usr/share/man/man*/*
%attr(644, root, root) %config /etc/xymon/*
%attr(644, root, root) %config /etc/httpd/conf.d/xymon-apache.conf
%attr(755, root, root) %dir /etc/xymon
%attr(755, root, root) %dir /etc/xymon/tasks.d
%attr(755, root, root) %dir /usr/lib/xymon/server/download
%attr(755, root, root) %dir /etc/xymon/web
%attr(755, xymon, xymon) %dir /var/log/xymon
%attr(755, root, root) /etc/init.d/xymon
%attr(644, root, root) /etc/logrotate.d/xymon
%attr(-, root, root) /usr/lib/xymon
%attr(-, root, root) /usr/bin/*
%attr(-, xymon, xymon) /var/lib/xymon
%attr(775, xymon, apache) %dir /var/lib/xymon/www/rep
%attr(775, xymon, apache) %dir /var/lib/xymon/www/snap
%attr(644, root, root) %config /var/lib/xymon/www/menu/xymonmenu-grey.css
%attr(644, root, root) %config /var/lib/xymon/www/menu/xymonmenu-blue.css
%attr(755, xymon, xymon) %dir /usr/lib/xymon/client/ext
%attr(664, xymon, apache) %config /etc/xymon/critical.cfg
%attr(664, xymon, apache) %config /etc/xymon/critical.cfg.bak
%attr(4750, root, xymon) /usr/lib/xymon/server/bin/xymonping
%attr(750, root, xymon) /usr/lib/xymon/client/bin/logfetch
%attr(750, root, xymon) /usr/lib/xymon/client/bin/clientupdate
 
%files client
%attr(-, root, root) %doc README README.CLIENT Changes* COPYING CREDITS RELEASENOTES
%attr(-, root, root) /usr/lib/xymon/client
%attr(755, root, root) /etc/init.d/xymon-client
%attr(644, root, root) %config /etc/default/xymon-client
%attr(755, xymon, xymon) %dir /var/log/xymon
%attr(755, xymon, xymon) %dir /usr/lib/xymon/client/ext
%attr(750, root, xymon) /usr/lib/xymon/client/bin/logfetch
%attr(750, root, xymon) /usr/lib/xymon/client/bin/clientupdate

Build The Package

RPM Build Command

rpmbuild -ba ~/rpmbuild/SPECS/myapp.spec

Common Build Methods:

  • -ba ⇒ build binary and source packages
  • -bb ⇒ build binary package only
  • -bl ⇒ check to ensure all file exist that are listed in the spec's “%files” section.
  • -bs ⇒ build source package only

Build the custom scripts RPM

rpmbuild -ba ~/rpmbuild/SPECS/myscripts.spec

RPMs written to:

~/rpmbuild/RPMS/x86_64/myscripts-1.0.0-1.el6.x86_64.rpm

Optional: Edit client config file to point to an existing Xymon Server (10.0.0.1 in example)

vim ~/rpmbuild/SOURCES/xymon-client.default
 
XYMONSERVERS="10.0.0.1"

Build the RPMs

rpmbuild -ba ~/rpmbuild/SPECS/xymon.spec

Xymon Server and Client RPMs are written to:

~/rpmbuild/RPMS/x86_64/

Mock to Test Dependencies


Mock is used to rebuild binary RPMs from source RPMs in a clean environment to ensure you are not missing any dependencies in your SPEC file.

Install mock

yum install mock


Add user to the mock group

usermod -a -G mock builder


Set default mock config of the type of repos you are building for (ie EPEL 6, Fedora 23, etc)

Example: Set default config to EPEL 6 x86_64

cd /etc/mock
ln -sf epel-6-x86_64.cfg default.cfg


Go to where your source RPMs were built and run mock against that package

cd ~/rpmbuild/SRPMS
mock --rebuild myscripts-1.0.0-1.el6.src.rpm


Results location is displayed (/var/lib/mock/epel-6-x86_64/result/) in the above example.

ls -l /var/lib/mock/epel-6-x86_64/result
total 172
-rw-rw-r-- 1 builder mock   4500 Oct 16 07:32 build.log
-rw-rw-r-- 1 builder mock   2740 Oct 16 07:32 myscripts-1.0.0-1.el6.src.rpm
-rw-rw-r-- 1 builder mock   2524 Oct 16 07:32 myscripts-1.0.0-1.el6.x86_64.rpm
-rw-rw-r-- 1 builder mock 153606 Oct 16 07:32 root.log
-rw-rw-r-- 1 builder mock    782 Oct 16 07:32 state.log

  • linux_wiki/rpm_building.txt
  • Last modified: 2019/05/25 23:50
  • (external edit)