How to do RPM packaging and distribute software
Here in this article we will see how we can prepare source code, build and package the source code into RPM packages using the RPM package management tools and utilities. We will using a very basic python program to demonstrate this activity.
Test Environment
Fedora 36 server
What is RPM
RPM also called RPM Package Management system is a tool that helps in distributing, managing and updating the software on the system. It’s used on Linux based system (ie. Redhat, CentOS, Fedora). Some of the advantages of RPM management system is that it helps in installing, updating, removing and verify the software packages. The information related to packages that are installed is stored in a RPM database which can be queries.
It is also used to prepare the RPM packages with the sources files, utilities and build instructions which can be further distributed using by uploading them into the RPM repositories. Also it provides us with the facilities to sign the RPM packages using GNU GPG signing keys for maintaing the integrity of the packages.
If you are interested in watching the video. Here is the YouTube video on the same step by step procedure outlined below.
Procedure
Step1: Create a Python Hello World Program
Source code file contains human readable instructions which are given to the computer for carrying out the computational task. Here is a simple python helloworld source code which we will use here to package as an RPM for Fedora OS.
[admin@fedser36 ~]$ mkdir rpmpackaging
[admin@fedser36 ~]$ cd rpmpackaging/
[admin@fedser36 rpmpackaging]$ cat helloworld.py
#!/usr/bin/env python3
print("Hello Python!!")
Step2: Building Python Source code
For software written in compiled languages, the source code goes through a build process, producing machine code (eg. C/C++ language).
For software written in raw interpreted languages, the source code is not built, but executed directly (eg. Bash language).
For software written in byte-compiled interpreted languages, the source code is compiled into byte code, which is then executed by the language virtual machine (eg. Python).
In our case as we are building a Python source code so it comes in the third category of the software build process.
Compile the Python source code
[admin@fedser36 rpmpackaging]$ python3 -m compileall helloworld.py
Compiling 'helloworld.py'...
[admin@fedser36 rpmpackaging]$ tree .
.
├── helloworld.py
└── __pycache__
└── helloworld.cpython-310.pyc
As you can see the above step generates a compiled python file in pycache folder.
NOTE: Python is often byte-compiled, but not in the way described here. The following procedure aims not to conform to the community standards, but to be simple. For real-
world Python guidelines, see Software Packaging and Distribution.
Step3: Packaging the source code into a tarball
Developers often distribute software as compressed archives of source code, which are then used to create packages. Before packaging the source code make sure we create a license file as shown below to be incorporated into our package as the software should always be distributed with a software license.
[admin@fedser36 rpmpackaging]$ cat LICENSE
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.
Create a folder with version for the packaging and put required source code and license file for packaging
[admin@fedser36 rpmpackaging]$ mkdir ./helloworld-0.1.1
[admin@fedser36 rpmpackaging]$ mv helloworld.py ./helloworld-0.1.1/
[admin@fedser36 rpmpackaging]$ cp LICENSE ./helloworld-0.1.1/
Create the archive for distribution
[admin@fedser36 rpmpackaging]$ tar -cvzf helloworld-0.1.1.tar.gz helloworld-0.1.1
helloworld-0.1.1/
helloworld-0.1.1/helloworld.py
helloworld-0.1.1/LICENSE
[admin@fedser36 rpmpackaging]$ ls -ltr helloworld-0.1.1.tar.gz
-rw-r--r--. 1 admin admin 600 Jun 25 13:43 helloworld-0.1.1.tar.gz
Step4: Install RPM packaging tool
Here in this step we are going to install the core tools for RPM packaging provided by rpmdevtools package. Along with that we are going to install rpmlint for carrying out package sanity (ie. verification) and git as a week dependency for source code management.
[admin@fedser36 rpmpackaging]$ sudo dnf install rpmdevtools rpmlint git-all
...
Installed:
ansible-srpm-macros-1-5.fc36.noarch binutils-2.37-27.fc36.x86_64 binutils-gold-2.37-27.fc36.x86_64 debugedit-5.0-3.fc36.x86_64
dwz-0.14-2.fc35.x86_64 efi-srpm-macros-5-5.fc36.noarch fakeroot-1.29-1.fc36.x86_64 fakeroot-libs-1.29-1.fc36.x86_64
fonts-srpm-macros-1:2.0.5-7.fc36.noarch fpc-srpm-macros-1.3-5.fc36.noarch ghc-srpm-macros-1.5.0-6.fc36.noarch gnat-srpm-macros-4-15.fc36.noarch
go-srpm-macros-3.0.15-1.fc36.noarch http-parser-2.9.4-6.fc36.x86_64 kernel-srpm-macros-1.0-14.fc36.noarch koji-1.29.0-1.fc36.noarch
libgit2-1.3.0-2.fc36.x86_64 libssh2-1.10.0-4.fc36.x86_64 lua-srpm-macros-1-6.fc36.noarch nim-srpm-macros-3-6.fc36.noarch
ocaml-srpm-macros-6-6.fc36.noarch openblas-srpm-macros-2-11.fc36.noarch package-notes-srpm-macros-0.4-14.fc36.noarch patch-2.7.6-16.fc36.x86_64
perl-srpm-macros-1-43.fc36.noarch python-srpm-macros-3.10-18.fc36.noarch python3-babel-2.9.1-5.fc36.noarch python3-decorator-5.1.1-2.fc36.noarch
python3-gssapi-1.7.2-2.fc36.x86_64 python3-koji-1.29.0-1.fc36.noarch python3-progressbar2-3.53.2-4.fc36.noarch python3-pygit2-1.7.1-3.fc36.x86_64
python3-pytz-2022.1-1.fc36.noarch python3-requests-gssapi-1.2.3-4.fc36.noarch python3-rpmautospec-0.2.6-1.fc36.noarch python3-utils-2.5.6-5.fc36.noarch
qt5-srpm-macros-5.15.3-1.fc36.noarch redhat-rpm-config-221-1.fc36.noarch rpm-build-4.17.0-10.fc36.x86_64 rpmautospec-rpm-macros-0.2.6-1.fc36.noarch
rpmdevtools-9.6-1.fc36.noarch rust-srpm-macros-21-1.fc36.noarch systemd-rpm-macros-250.3-8.fc36.noarch zstd-1.5.2-2.fc36.x86_64
...
Complete!
We can list the RPM packaging utilities provides by the above package as shown below.
[admin@fedser36 rpmpackaging]$ rpm -ql rpmdevtools | grep bin
/usr/bin/rpmargs
/usr/bin/rpmdev-bumpspec
/usr/bin/rpmdev-checksig
/usr/bin/rpmdev-cksum
/usr/bin/rpmdev-diff
/usr/bin/rpmdev-extract
/usr/bin/rpmdev-md5
/usr/bin/rpmdev-newinit
/usr/bin/rpmdev-newspec
/usr/bin/rpmdev-packager
/usr/bin/rpmdev-rmdevelrpms
/usr/bin/rpmdev-setuptree
/usr/bin/rpmdev-sha1
/usr/bin/rpmdev-sha224
/usr/bin/rpmdev-sha256
/usr/bin/rpmdev-sha384
/usr/bin/rpmdev-sha512
/usr/bin/rpmdev-sort
/usr/bin/rpmdev-spectool
/usr/bin/rpmdev-sum
/usr/bin/rpmdev-vercmp
/usr/bin/rpmdev-wipetree
/usr/bin/rpmelfsym
/usr/bin/rpmfile
/usr/bin/rpminfo
/usr/bin/rpmls
/usr/bin/rpmpeek
/usr/bin/rpmsodiff
/usr/bin/rpmsoname
/usr/bin/spectool
Step5: Setup RPM packaging workspace
The below step helps in preparing the skeleton workspace directory structure for RPM package building.
[admin@fedser36 rpmpackaging]$ rpmdev-setuptree
[admin@fedser36 rpmpackaging]$ tree ~
/home/admin/
├── rpmbuild
│ ├── BUILD
│ ├── RPMS
│ ├── SOURCES
│ ├── SPECS
│ └── SRPMS
Step6: Copy the Compressed source file package into RPM build workspace
Copy the compressed tar archive of source code into the RPM packing workspace location as shown below.
[admin@fedser36 rpmpackaging]$ cp helloworld-0.1.1.tar.gz ~/rpmbuild/SOURCES/
Step7: Create new RPM build spec file
A build spec file contains information that is required by rpmbuild utility to build an RPM. There are two types of RPM packages that we could build.
Source RPM (SRPM) – An SRPM contains source code and a SPEC file, which describes how to build the source code into a binary RPM. Optionally, the patches to source code are included as well.
Binary RPM (RPM) – A binary RPM contains the binaries built from the sources and patches.
The spec file can be divided into two sections, they are preamble and body part. The Preamble part contains a series of metadata items that are used in the Body part. The Body part represents the main part of the instructions. We can create a new build spec file with the below command.
[admin@fedser36 rpmpackaging]$ cd ~/rpmbuild/SPECS
[admin@fedser36 SPECS]$ rpmdev-newspec helloworld
helloworld.spec created; type minimal, rpm version >= 4.17.
Update the spec file as shown below with the server details as per your hostname. These are just dummy references provided.
[admin@fedser36 SPECS]$ cat helloworld.spec
Name: helloworld
Version: 0.1.1
Release: 1%{?dist}
Summary: Python HelloWorld package
License: GPLv3+
URL: https://fedser36.stack.com/%{name}
Source0: https://fedser36.stack.com/%{name}/releases/%{name}-%{version}.tar.gz
BuildRequires: python3
Requires: python3
Requires: bash
BuildArch: noarch
%description
This is simple python helloworld rpm package
%prep
%setup -q
%build
python -m compileall %{name}.py
%install
mkdir -p %{buildroot}/%{_bindir}
mkdir -p %{buildroot}/usr/lib/%{name}
cat > %{buildroot}/%{_bindir}/%{name} <<EOF
#!/bin/bash
/usr/bin/python3 /usr/lib/%{name}/%{name}.py
EOF
chmod 0755 %{buildroot}/%{_bindir}/%{name}
install -m 0644 %{name}.py* %{buildroot}/usr/lib/%{name}/
%files
%license LICENSE
%dir /usr/lib/%{name}/
%{_bindir}/%{name}
/usr/lib/%{name}/%{name}.py*
%changelog
* Sat Jun 25 2022 admin - 0.1.1
- Hello World Python Package
Step8: Building Source RPM package
Here in this step we are going to build the source rpm (ie. SRPM) as shown below. This will write the SRPM into the build workspace under SRPMS subfolder as shown below.
[admin@fedser36 SPECS]$ rpmbuild -bs helloworld.spec
setting SOURCE_DATE_EPOCH=1656115200
Wrote: /home/admin/rpmbuild/SRPMS/helloworld-0.1.1-1.fc36.src.rpm
[admin@fedser36 SPECS]$ rpm -ql /home/admin/rpmbuild/SRPMS/helloworld-0.1.1-1.fc36.src.rpm
helloworld-0.1.1.tar.gz
helloworld.spec
Step9: Building Binary RPM package
Here in this step we are going to build the binary rpm (ie. RPM) as shown below. This will write the Binary RPM into the build workspace under RPMS subfolder as shown below.
[admin@fedser36 SPECS]$ rpmbuild -bs helloworld.spec
setting SOURCE_DATE_EPOCH=1656115200
Wrote: /home/admin/rpmbuild/SRPMS/helloworld-0.1.1-1.fc36.src.rpm
[admin@fedser36 SPECS]$
[admin@fedser36 SPECS]$ rpmbuild -bb helloworld.spec
setting SOURCE_DATE_EPOCH=1656115200
Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.XbA2iy
+ umask 022
+ cd /home/admin/rpmbuild/BUILD
+ cd /home/admin/rpmbuild/BUILD
+ rm -rf helloworld-0.1.1
+ /usr/bin/gzip -dc /home/admin/rpmbuild/SOURCES/helloworld-0.1.1.tar.gz
+ /usr/bin/tar -xof -
+ STATUS=0
+ '[' 0 -ne 0 ']'
+ cd helloworld-0.1.1
+ /usr/bin/chmod -Rf a+rX,u+w,g-w,o-w .
+ RPM_EC=0
++ jobs -p
+ exit 0
Executing(%build): /bin/sh -e /var/tmp/rpm-tmp.nnunTZ
+ umask 022
+ cd /home/admin/rpmbuild/BUILD
+ CFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection'
+ export CFLAGS
+ CXXFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection'
+ export CXXFLAGS
+ FFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -I/usr/lib64/gfortran/modules'
+ export FFLAGS
+ FCFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -I/usr/lib64/gfortran/modules'
+ export FCFLAGS
+ LDFLAGS='-Wl,-z,relro -Wl,--as-needed -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--build-id=sha1 -Wl,-dT,/home/admin/rpmbuild/BUILD/helloworld-0.1.1/.package_note-helloworld-0.1.1-1.fc36.x86_64.ld'
+ export LDFLAGS
+ LT_SYS_LIBRARY_PATH=/usr/lib64:
+ export LT_SYS_LIBRARY_PATH
+ CC=gcc
+ export CC
+ CXX=g++
+ export CXX
+ '[' -f /usr/lib/rpm/generate-rpm-note.sh ']'
+ /usr/lib/rpm/generate-rpm-note.sh helloworld 0.1.1-1.fc36 x86_64
+ cd helloworld-0.1.1
+ python3 -m compileall helloworld.py
Compiling 'helloworld.py'...
+ RPM_EC=0
++ jobs -p
+ exit 0
Executing(%install): /bin/sh -e /var/tmp/rpm-tmp.qMBnXh
+ umask 022
+ cd /home/admin/rpmbuild/BUILD
+ '[' /home/admin/rpmbuild/BUILDROOT/helloworld-0.1.1-1.fc36.x86_64 '!=' / ']'
+ rm -rf /home/admin/rpmbuild/BUILDROOT/helloworld-0.1.1-1.fc36.x86_64
++ dirname /home/admin/rpmbuild/BUILDROOT/helloworld-0.1.1-1.fc36.x86_64
+ mkdir -p /home/admin/rpmbuild/BUILDROOT
+ mkdir /home/admin/rpmbuild/BUILDROOT/helloworld-0.1.1-1.fc36.x86_64
+ CFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection'
+ export CFLAGS
+ CXXFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection'
+ export CXXFLAGS
+ FFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -I/usr/lib64/gfortran/modules'
+ export FFLAGS
+ FCFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -I/usr/lib64/gfortran/modules'
+ export FCFLAGS
+ LDFLAGS='-Wl,-z,relro -Wl,--as-needed -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--build-id=sha1 -Wl,-dT,/home/admin/rpmbuild/BUILD/helloworld-0.1.1/.package_note-helloworld-0.1.1-1.fc36.x86_64.ld'
+ export LDFLAGS
+ LT_SYS_LIBRARY_PATH=/usr/lib64:
+ export LT_SYS_LIBRARY_PATH
+ CC=gcc
+ export CC
+ CXX=g++
+ export CXX
+ cd helloworld-0.1.1
+ mkdir -p /home/admin/rpmbuild/BUILDROOT/helloworld-0.1.1-1.fc36.x86_64//usr/bin
+ mkdir -p /home/admin/rpmbuild/BUILDROOT/helloworld-0.1.1-1.fc36.x86_64/usr/lib/helloworld
+ cat
+ chmod 0755 /home/admin/rpmbuild/BUILDROOT/helloworld-0.1.1-1.fc36.x86_64//usr/bin/helloworld
+ install -m 0644 helloworld.py /home/admin/rpmbuild/BUILDROOT/helloworld-0.1.1-1.fc36.x86_64/usr/lib/helloworld/
+ /usr/bin/find-debuginfo -j8 --strict-build-id -m -i --build-id-seed 0.1.1-1.fc36 --unique-debug-suffix -0.1.1-1.fc36.x86_64 --unique-debug-src-base helloworld-0.1.1-1.fc36.x86_64 --run-dwz --dwz-low-mem-die-limit 10000000 --dwz-max-die-limit 110000000 -S debugsourcefiles.list /home/admin/rpmbuild/BUILD/helloworld-0.1.1
find: 'debug': No such file or directory
+ '[' '%{buildarch}' = noarch ']'
+ QA_CHECK_RPATHS=1
+ case "${QA_CHECK_RPATHS:-}" in
+ /usr/lib/rpm/check-rpaths
+ /usr/lib/rpm/check-buildroot
+ /usr/lib/rpm/redhat/brp-ldconfig
+ /usr/lib/rpm/brp-compress
+ /usr/lib/rpm/redhat/brp-strip-lto /usr/bin/strip
+ /usr/lib/rpm/brp-strip-static-archive /usr/bin/strip
+ /usr/lib/rpm/check-rpaths
+ /usr/lib/rpm/redhat/brp-mangle-shebangs
mangling shebang in /usr/bin/helloworld from /bin/bash to #!/usr/bin/bash
+ /usr/lib/rpm/brp-remove-la-files
+ /usr/lib/rpm/redhat/brp-python-bytecompile '' 1 0
+ /usr/lib/rpm/redhat/brp-python-hardlink
Processing files: helloworld-0.1.1-1.fc36.noarch
Executing(%license): /bin/sh -e /var/tmp/rpm-tmp.XgK7fI
+ umask 022
+ cd /home/admin/rpmbuild/BUILD
+ cd helloworld-0.1.1
+ LICENSEDIR=/home/admin/rpmbuild/BUILDROOT/helloworld-0.1.1-1.fc36.x86_64/usr/share/licenses/helloworld
+ export LC_ALL=C
+ LC_ALL=C
+ export LICENSEDIR
+ /usr/bin/mkdir -p /home/admin/rpmbuild/BUILDROOT/helloworld-0.1.1-1.fc36.x86_64/usr/share/licenses/helloworld
+ cp -pr LICENSE /home/admin/rpmbuild/BUILDROOT/helloworld-0.1.1-1.fc36.x86_64/usr/share/licenses/helloworld
+ RPM_EC=0
++ jobs -p
+ exit 0
Provides: helloworld = 0.1.1-1.fc36
Requires(rpmlib): rpmlib(CompressedFileNames) <= 3.0.4-1 rpmlib(FileDigests) <= 4.6.0-1 rpmlib(PayloadFilesHavePrefix) <= 4.0-1
Requires: /usr/bin/bash
Checking for unpackaged file(s): /usr/lib/rpm/check-files /home/admin/rpmbuild/BUILDROOT/helloworld-0.1.1-1.fc36.x86_64
Wrote: /home/admin/rpmbuild/RPMS/noarch/helloworld-0.1.1-1.fc36.noarch.rpm
Executing(%clean): /bin/sh -e /var/tmp/rpm-tmp.6uuykP
+ umask 022
+ cd /home/admin/rpmbuild/BUILD
+ cd helloworld-0.1.1
+ /usr/bin/rm -rf /home/admin/rpmbuild/BUILDROOT/helloworld-0.1.1-1.fc36.x86_64
+ RPM_EC=0
++ jobs -p
+ exit 0
Step10: Checking the RPM spec for sanity
rpmlint is a tool provided to validate the SPEC files and RPMS that were build to check for common errors in rpm packages.
Checking the build spec file
[admin@fedser36 SPECS]$ rpmlint helloworld.spec
=================================================================================== rpmlint session starts ===================================================================================
rpmlint: 2.2.0
configuration:
/usr/lib/python3.10/site-packages/rpmlint/configdefaults.toml
/etc/xdg/rpmlint/fedora.toml
/etc/xdg/rpmlint/licenses.toml
/etc/xdg/rpmlint/scoring.toml
/etc/xdg/rpmlint/users-groups.toml
/etc/xdg/rpmlint/warn-on-functions.toml
checks: 32, packages: 1
helloworld.spec:2: W: mixed-use-of-spaces-and-tabs (spaces: line 1, tab: line 2)
==================================================== 0 packages and 1 specfiles checked; 0 errors, 1 warnings, 0 badness; has taken 0.0 s ====================================================
Checking the Source RPM
[admin@fedser36 SPECS]$ rpmlint ~/rpmbuild/SRPMS/helloworld-0.1.1-1.fc36.src.rpm
=================================================================================== rpmlint session starts ===================================================================================
rpmlint: 2.2.0
configuration:
/usr/lib/python3.10/site-packages/rpmlint/configdefaults.toml
/etc/xdg/rpmlint/fedora.toml
/etc/xdg/rpmlint/licenses.toml
/etc/xdg/rpmlint/scoring.toml
/etc/xdg/rpmlint/users-groups.toml
/etc/xdg/rpmlint/warn-on-functions.toml
checks: 32, packages: 1
helloworld.src: W: name-repeated-in-summary HelloWorld
helloworld.spec:2: W: mixed-use-of-spaces-and-tabs (spaces: line 1, tab: line 2)
==================================================== 1 packages and 0 specfiles checked; 0 errors, 2 warnings, 0 badness; has taken 0.1 s ====================================================
Checking the Binary RPM
[admin@fedser36 SPECS]$ rpmlint ~/rpmbuild/RPMS/noarch/helloworld-0.1.1-1.fc36.noarch.rpm
=================================================================================== rpmlint session starts ===================================================================================
rpmlint: 2.2.0
configuration:
/usr/lib/python3.10/site-packages/rpmlint/configdefaults.toml
/etc/xdg/rpmlint/fedora.toml
/etc/xdg/rpmlint/licenses.toml
/etc/xdg/rpmlint/scoring.toml
/etc/xdg/rpmlint/users-groups.toml
/etc/xdg/rpmlint/warn-on-functions.toml
checks: 32, packages: 1
helloworld.noarch: W: only-non-binary-in-usr-lib
helloworld.noarch: E: non-executable-script /usr/lib/helloworld/helloworld.py 644 /usr/bin/env python3
helloworld.noarch: W: no-manual-page-for-binary helloworld
helloworld.noarch: W: no-documentation
helloworld.noarch: W: name-repeated-in-summary HelloWorld
helloworld.noarch: W: incoherent-version-in-changelog 0.1.1 ['0.1.1-1.fc36', '0.1.1-1']
==================================================== 1 packages and 0 specfiles checked; 1 errors, 5 warnings, 1 badness; has taken 0.0 s ====================================================
The non-executable-script error warns that the /usr/lib/helloworld/helloworld.py file has no execute permissions. The rpmlint tool expects the file to be executable, because the file contains the shebang. For the purpose of this example, you can leave this file without execute permissions and ignore this error.
Step11: Logging RPM activity to syslog
The below logging package installation allows us to track all the activities related to the package in the syslog messages which will help in later troubleshooting if any issues with the RPM management.
[admin@fedser36 SPECS]$ sudo dnf install rpm-plugin-syslog
Step12: Install Binary RPM package
[admin@fedser36 SPECS]$ sudo dnf install ~/rpmbuild/RPMS/noarch/helloworld-0.1.1-1.fc36.noarch.rpm
Last metadata expiration check: 2:51:26 ago on Saturday 25 June 2022 12:31:24 PM.
Dependencies resolved.
==============================================================================================================================================================================================
Package Architecture Version Repository Size
==============================================================================================================================================================================================
Installing:
helloworld noarch 0.1.1-1.fc36 @commandline 7.7 k
Transaction Summary
==============================================================================================================================================================================================
Install 1 Package
Total size: 7.7 k
Installed size: 724
Is this ok [y/N]: y
Downloading Packages:
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
Preparing : 1/1
Installing : helloworld-0.1.1-1.fc36.noarch 1/1
Running scriptlet: helloworld-0.1.1-1.fc36.noarch 1/1
Verifying : helloworld-0.1.1-1.fc36.noarch 1/1
Installed:
helloworld-0.1.1-1.fc36.noarch
Complete!
Now that we have our Binary RPM package installed, let us verify the information related to our RPM package as shown below.
[admin@fedser36 SPECS]$ rpm -qi helloworld
Name : helloworld
Version : 0.1.1
Release : 1.fc36
Architecture: noarch
Install Date: Saturday 25 June 2022 03:22:54 PM
Group : Unspecified
Size : 724
License : GPLv3+
Signature : (none)
Source RPM : helloworld-0.1.1-1.fc36.src.rpm
Build Date : Saturday 25 June 2022 03:06:39 PM
Build Host : fedser36.stack.com
URL : https://fedser36.stack.com/helloworld
Summary : Python HelloWorld package
Description :
This is simple python helloworld rpm package
Now, let us list the package file which are installed on the system.
Now, let us list the package file which are installed on the system.
[admin@fedser36 SPECS]$ rpm -ql helloworld
/usr/bin/helloworld
/usr/lib/helloworld
/usr/lib/helloworld/helloworld.py
/usr/share/licenses/helloworld
/usr/share/licenses/helloworld/LICENSE
Now, we are ready to run our “Hello Python” software as a binary shown below.
[admin@fedser36 SPECS]$ helloworld
Hello Python!!
NOTE: Files installed from the RPM packages are placed according to Filesystem Hierarchy Standard (ie. FHS). For example, an executable file should go into a directory that is in the system $PATH variable.
Hope you enjoyed reading this article. Thank you..
Leave a Reply
You must be logged in to post a comment.