In this tutorial, we will walk through the process of creating an RPM package for a Python script using a sample project named "testproject1." This project contains a script named hello_echo.py that prints a greeting message.
1.Prerequisites.
Before we start, ensure you have the necessary tools installed. Run the following commands to install rpmdevtools and rpmlint:
[root@siddhesh ~]# yum -y install rpmdevtools rpmlint
2. Setting Up the RPM Build Environment.
Create the RPM build directory structure using the following command:
[root@siddhesh ~]# rpmdev-setuptree
[root@siddhesh ~]# ls -R rpmbuild/
rpmbuild/:
BUILD RPMS SOURCES SPECS SRPMS
rpmbuild/BUILD:
rpmbuild/RPMS:
rpmbuild/SOURCES:
rpmbuild/SPECS:
rpmbuild/SRPMS:
[root@siddhesh ~]#
The RPM build directory is organized into several subdirectories under the rpmbuild directory. Here's a brief explanation of each directory:
BUILD: This directory is where the source code of the packages being built will be extracted and compiled.
RPMS: This directory will eventually contain the binary RPM packages once they are built.
SOURCES: This directory is used to store the source files (e.g., tarballs) that will be used to build the RPM packages.
SPECS: RPM spec files, which define how the package should be built, installed, and configured, are stored in this directory.
SRPMS: This directory will contain the source RPM packages. Source RPMs are useful for distributing the source code along with the spec file and any necessary patches.
3. Preparing the Project.
Now, let's create the project directory, navigate into it, and create the Python script:
[root@siddhesh ~]# mkdir testproject1-1.0
[root@siddhesh ~]# cd testproject1-1.0
[root@siddhesh testproject1-1.0]# echo 'print("Hello, Builddevops Users!")' > hello_echo.py
[root@siddhesh testproject1-1.0]# chmod +x hello_echo.py
[root@siddhesh testproject1-1.0]# cd ..
[root@siddhesh ~]#
4. Packaging the Project.
Move back to the parent directory, create a tarball of your project, and move it to the RPM build sources directory:
[root@siddhesh ~]# tar -cvpf testproject1-1.0.tar.gz testproject1-1.0/
testproject1-1.0/
testproject1-1.0/hello_echo.py
[root@siddhesh ~]# mv testproject1-1.0.tar.gz /root/rpmbuild/SOURCES/testproject1-1.0.tar.gz
[root@siddhesh ~]#
5. Creating the Spec File.
Generate a spec file for your project using the following command:
[root@siddhesh ~]# rpmdev-newspec /root/rpmbuild/SPECS/testproject1.spec
/root/rpmbuild/SPECS/testproject1.spec created; type minimal, rpm version >= 4.11.
[root@siddhesh ~]#
Edit the generated spec file (/root/rpmbuild/SPECS/testproject1.spec) with the details of your package. Below is a sample spec file:
Name: testproject1
Version: 1.0
Release: 1%{?dist}
Summary: Script of testproject1
License: GPL
URL: https://builddevops.com
Source0: %{name}-%{version}.tar.gz
Requires: bash
%description
A test rpm creation for builddevops project
%prep
%setup -q
%install
rm -rf $RPM_BUILD_ROOT
mkdir -p $RPM_BUILD_ROOT/%{_bindir}
cp hello_echo.py $RPM_BUILD_ROOT/%{_bindir}
%clean
rm -rf $RPM_BUILD_ROOT
%files
%{_bindir}/hello_echo.py
%changelog
* Sun Dec 24 2023 Siddhesh Kadam <siddhesh@builddevops.com> - 1.0
- First version of test rpm for builddevops project
6. Building the RPM Package.
Now, it's time to build the RPM package. Run the following commands:
[root@siddhesh ~]# rpmbuild -bs /root/rpmbuild/SPECS/testproject1.spec
Wrote: /root/rpmbuild/SRPMS/testproject1-1.0-1.el7.src.rpm
[root@siddhesh ~]#
The command, rpmbuild -bs /root/rpmbuild/SPECS/testproject1.spec, instructs rpmbuild to build the source RPM based on the spec file provided.
[root@siddhesh ~]# rpmbuild -bb /root/rpmbuild/SPECS/testproject1.spec
Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.oa095I
+ umask 022
+ cd /root/rpmbuild/BUILD
+ cd /root/rpmbuild/BUILD
+ rm -rf testproject1-1.0
+ /usr/bin/tar -xf /root/rpmbuild/SOURCES/testproject1-1.0.tar.gz
+ cd testproject1-1.0
+ /usr/bin/chmod -Rf a+rX,u+w,g-w,o-w .
+ exit 0
Executing(%install): /bin/sh -e /var/tmp/rpm-tmp.woBc9H
+ umask 022
+ cd /root/rpmbuild/BUILD
+ '[' /root/rpmbuild/BUILDROOT/testproject1-1.0-1.el7.x86_64 '!=' / ']'
+ rm -rf /root/rpmbuild/BUILDROOT/testproject1-1.0-1.el7.x86_64
++ dirname /root/rpmbuild/BUILDROOT/testproject1-1.0-1.el7.x86_64
+ mkdir -p /root/rpmbuild/BUILDROOT
+ mkdir /root/rpmbuild/BUILDROOT/testproject1-1.0-1.el7.x86_64
+ cd testproject1-1.0
+ rm -rf /root/rpmbuild/BUILDROOT/testproject1-1.0-1.el7.x86_64
+ mkdir -p /root/rpmbuild/BUILDROOT/testproject1-1.0-1.el7.x86_64//usr/bin
+ cp hello_echo.py /root/rpmbuild/BUILDROOT/testproject1-1.0-1.el7.x86_64//usr/bin
+ '[' '%{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-compress
+ /usr/lib/rpm/redhat/brp-strip /usr/bin/strip
+ /usr/lib/rpm/redhat/brp-strip-comment-note /usr/bin/strip /usr/bin/objdump
+ /usr/lib/rpm/redhat/brp-strip-static-archive /usr/bin/strip
+ /usr/lib/rpm/brp-python-bytecompile /usr/bin/python 1
+ /usr/lib/rpm/redhat/brp-python-hardlink
+ /usr/lib/rpm/redhat/brp-java-repack-jars
Processing files: testproject1-1.0-1.el7.x86_64
Provides: testproject1 = 1.0-1.el7 testproject1(x86-64) = 1.0-1.el7
Requires(rpmlib): rpmlib(CompressedFileNames) <= 3.0.4-1 rpmlib(FileDigests) <= 4.6.0-1 rpmlib(PayloadFilesHavePrefix) <= 4.0-1
Checking for unpackaged file(s): /usr/lib/rpm/check-files /root/rpmbuild/BUILDROOT/testproject1-1.0-1.el7.x86_64
Wrote: /root/rpmbuild/RPMS/x86_64/testproject1-1.0-1.el7.x86_64.rpm
Executing(%clean): /bin/sh -e /var/tmp/rpm-tmp.YNmK0G
+ umask 022
+ cd /root/rpmbuild/BUILD
+ cd testproject1-1.0
+ rm -rf /root/rpmbuild/BUILDROOT/testproject1-1.0-1.el7.x86_64
+ exit 0
[root@siddhesh ~]#
The command, rpmbuild -bb /root/rpmbuild/SPECS/testproject1.spec, instructs rpmbuild to build the binary RPM based on the spec file provided.
Both the source and binary RPMs can be found at the following location.
[root@siddhesh ~]# ll /root/rpmbuild/SRPMS/testproject1-1.0-1.el7.src.rpm
-rw-r--r-- 1 root root 2288 Dec 26 16:36 /root/rpmbuild/SRPMS/testproject1-1.0-1.el7.src.rpm
[root@siddhesh ~]# ll /root/rpmbuild/RPMS/x86_64/testproject1-1.0-1.el7.x86_64.rpm
-rw-r--r-- 1 root root 2268 Dec 26 16:38 /root/rpmbuild/RPMS/x86_64/testproject1-1.0-1.el7.x86_64.rpm
[root@siddhesh ~]#
6. Installing the RPM Package.
[root@siddhesh ~]# rpm -ivh /root/rpmbuild/RPMS/x86_64/testproject1-1.0-1.el7.x86_64.rpm
Preparing... ################################# [100%]
Updating / installing...
1:testproject1-1.0-1.el7 ################################# [100%]
[root@siddhesh ~]# ls -lhrt /bin/hello_echo.py
-rwxr-xr-x 1 root root 35 Dec 26 16:38 /bin/hello_echo.py
[root@siddhesh ~]# cat /bin/hello_echo.py
print("Hello, Builddevops Users!")
[root@siddhesh ~]# python /bin/hello_echo.py
Hello, Builddevops Users!
[root@siddhesh ~]# rpm -qa |grep -i testproject
testproject1-1.0-1.el7.x86_64
[root@siddhesh ~]# rpm -ql testproject1-1.0-1.el7.x86_64
/usr/bin/hello_echo.py
[root@siddhesh ~]#
It seems everything is in order, and the RPM package installation and script execution were successful.
In depth explanation with example and simple language to understand