In our previous demo we built a binary file from a shell script. Now, we will name it as “findit” and create a RPM package.
The binary file that we created still depends on bash.
1 2 3 4 5 6 |
[root@pvmove shc-3.8.7]# ll find_script.sh.x -rwx--x--x. 1 root root 30408 Aug 25 17:51 find_script.sh.x [root@pvmove shc-3.8.7]# [root@pvmove shc-3.8.7]# ./findit Essayer avec ./findit -h pour voir les options disponibles |
1) Install rpm-build package
yum install rpm-build
1 2 3 |
[root@pvmove shc-3.8.7]# yum list installed | grep -i rpm-build rpm-build.x86_64 4.8.0-59.el6 @base [root@pvmove shc-3.8.7]# |
2) Install rpmdevtools.noarch package
1 2 3 |
[root@pvmove shc-3.8.7]# yum list installed | grep -i rpmdevtools.noarch rpmdevtools.noarch 7.5-2.el6 @base [root@pvmove shc-3.8.7]# |
After this step on Redhat or Centos 7 distributions you will see following directories have been created automatically.
1 2 3 4 5 6 7 |
ls -lF /root/rpmbuild/ drwxr-xr-x. 2 root root 4096 Feb 4 12:21 BUILD/ drwxr-xr-x. 2 root root 4096 Feb 4 12:21 BUILDROOT/ drwxr-xr-x. 2 root root 4096 Feb 4 12:21 RPMS/ drwxr-xr-x. 2 root root 4096 Feb 4 12:21 SOURCES/ drwxr-xr-x. 2 root root 4096 Feb 4 12:21 SPECS/ drwxr-xr-x. 2 root root 4096 Feb 4 12:21 SRPMS/ |
But if it does not exist, you should consider creating them manually.
To avoid possible system libraries and other files damage, you should NEVER build an RPM with the root user. You should always use an unprivileged user for this purpose.
I am switching to another user. Then will create directories.
3) Create directories under your user’s home
mkdir -p ~/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}
Next command will overwrite an existing .rpmmacros file if it exists, so check that you don’t already have one before continuing.
1 2 3 4 5 |
[mufit@pvmove rpmbuild]$ echo '%_topdir %(echo $HOME)/rpmbuild' > ~/.rpmmacros [mufit@pvmove rpmbuild]$ sudo updatedb [mufit@pvmove rpmbuild]$ sudo locate .rpmmacros /home/mufit/.rpmmacros [mufit@pvmove rpmbuild]$ |
After running the two commands above, your environment is set up to build most RPMs without further setup.
4) Now, package your shell script into a tar.gz file and move that to SOURCES directory.
Here I recommend to use locate directory because depending on your distribution rpm-build directories may change. On Redhat 7 you can find it under /usr/src/redhat/SOURCES/ but in our case, as I set it up manually, we have directories under our home folder.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
[mufit@pvmove rpmbuild]$ cd /tmp/shc-3.8.7 [mufit@pvmove shc-3.8.7]$ ls CHANGES find_script.sh.x.c match.x.c shc-3.8.7.c test.bash Copying Makefile pru.sh shc.c test.csh findit match shc shc.html test.ksh find_script.sh match.x shc.1 shc.README [mufit@pvmove shc-3.8.7]$ sudo tar cvzf findit-1.0.tar.gz findit findit [mufit@pvmove shc-3.8.7]$ ls CHANGES find_script.sh match.x shc.1 shc.README Copying find_script.sh.x.c match.x.c shc-3.8.7.c test.bash findit Makefile pru.sh shc.c test.csh findit.tar.gz match shc shc.html test.ksh [mufit@pvmove shc-3.8.7]$ |
1 2 3 4 5 6 7 |
[mufit@pvmove shc-3.8.7]$ sudo mv findit.tar.gz ~/rpmbuild/SOURCES/ [mufit@pvmove shc-3.8.7]$ ls -la ~/rpmbuild/SOURCES/ total 36 drwxrwxr-x. 2 mufit mufit 4096 Aug 26 14:09 . drwxrwxr-x. 7 mufit mufit 4096 Aug 26 13:54 .. -rw-r--r--. 1 root root 26155 Aug 26 14:02 findit-1.0.tar.gz [mufit@pvmove shc-3.8.7]$ |
5) Create a .spec file that describes where everything is
Before showing you my .spec file, it is good to share general information about its content.
- Preamble – The preamble section contains information about the package being built and define any dependencies to the package. In general, the preamble consists of entries, one per line, that start with a tag followed by a colon, and then some information.
- %prep – In this section, we prepare the software for building process. Any previous builds are removed during this process and the source file(.tar) file is expanded, etc.
- One more key thing is to understand there are pre-defined macros available to perform various shortcut options to build rpm. You may be using this macros when you try to build any complex packages. In the below example, I have used a macro called %setup which removes any previous builds, untar the source files and changes the ownership of the files. You can also use sh scripts under %prep section to perform this action but %setup macro simplifies the process by using predefined sh scripts.
- %description – the description section usually contains description about the package.
- %build – This is the section that is responsible for performing the build. Usually the %build section is an sh script.
- %install – the % install section is also executed as sh script just like %prep and %build. This is the step that is used for the installation.
- %files – This section contains the list of files that are part of the package. If the files are not part of the %files section then it wont be available in the package. Complete paths are required and you can set the attributes and ownership of the files in this section.
- %clean – This section instructs the RPM to clean up any files that are not part of the application’s normal build area. Lets say for an example, If the application creates a temporary directory structure in /tmp/ as part of its build, it will not be removed. By adding a sh script in %clean section, the directory can be removed after the build process is completed.
Be careful to use same name as your script for .spec file also within its content. Check my spec file:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
[mufit@pvmove SPECS]$ cat findit.spec Name: findit Version: 1.0 Release: 1%{?dist} Summary: Find only files with / only names dates. Create archives, compress, change extensions or delete Vendor: Mufit SAKA Packager: itechsweb@gmail.com Group: Applications License: GPL URL: http://itechsweb.com Source0: findit-%{version}.tar.gz BuildArch: noarch BuildRoot: %{_tmppath}/%{name}-root Requires: bash %define _binaries_in_noarch_packages_terminate_build 0 %description This is an interactive tool to find files according to a given date/hour by nameor/and date. With this tool you can list, compress, create archives, move archives to other locations or delete them. %prep %setup -q -c %build %install rm -rf ${RPM_BUILD_ROOT} mkdir -p ${RPM_BUILD_ROOT}/usr/bin install -m 755 findit ${RPM_BUILD_ROOT}/%{_bindir} %clean rm -rf ${RPM_BUILD_ROOT} %files %defattr(-,root,root) %attr(755,root,root) %{_bindir}/findit %changelog * Wed Jul 25 2018 Mufit SAKA <mufit.saka@pl.ibm.com> -Find program. [mufit@pvmove SPECS]$ |
6) Build your spec file for rpm package creation
rpmbuild -ba findit.spec
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
[mufit@pvmove SPECS]$ rpmbuild -ba findit.spec Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.3PYzbU + umask 022 + cd /home/mufit/rpmbuild/BUILD + LANG=C + export LANG + unset DISPLAY + cd /home/mufit/rpmbuild/BUILD + rm -rf findit-1.0 + /bin/mkdir -p findit-1.0 + cd findit-1.0 + /bin/tar -xf - + /usr/bin/gzip -dc /home/mufit/rpmbuild/SOURCES/findit-1.0.tar.gz + STATUS=0 + '[' 0 -ne 0 ']' + /bin/chmod -Rf a+rX,u+w,g-w,o-w . + exit 0 Executing(%build): /bin/sh -e /var/tmp/rpm-tmp.fb8NRx + umask 022 + cd /home/mufit/rpmbuild/BUILD + cd findit-1.0 + LANG=C + export LANG + unset DISPLAY + exit 0 Executing(%install): /bin/sh -e /var/tmp/rpm-tmp.dlWhzb + umask 022 + cd /home/mufit/rpmbuild/BUILD + '[' /home/mufit/rpmbuild/BUILDROOT/findit-1.0-1.el6.x86_64 '!=' / ']' + rm -rf /home/mufit/rpmbuild/BUILDROOT/findit-1.0-1.el6.x86_64 ++ dirname /home/mufit/rpmbuild/BUILDROOT/findit-1.0-1.el6.x86_64 + mkdir -p /home/mufit/rpmbuild/BUILDROOT + mkdir /home/mufit/rpmbuild/BUILDROOT/findit-1.0-1.el6.x86_64 + cd findit-1.0 + LANG=C + export LANG + unset DISPLAY + rm -rf /home/mufit/rpmbuild/BUILDROOT/findit-1.0-1.el6.x86_64 + mkdir -p /home/mufit/rpmbuild/BUILDROOT/findit-1.0-1.el6.x86_64/usr/bin + install -m 755 findit /home/mufit/rpmbuild/BUILDROOT/findit-1.0-1.el6.x86_64//usr/bin + /usr/lib/rpm/find-debuginfo.sh --strict-build-id /home/mufit/rpmbuild/BUILD/findit-1.0 + /usr/lib/rpm/check-buildroot + /usr/lib/rpm/redhat/brp-compress + /usr/lib/rpm/redhat/brp-strip-static-archive /usr/bin/strip + /usr/lib/rpm/redhat/brp-strip-comment-note /usr/bin/strip /usr/bin/objdump + /usr/lib/rpm/brp-python-bytecompile /usr/bin/python + /usr/lib/rpm/redhat/brp-python-hardlink + /usr/lib/rpm/redhat/brp-java-repack-jars Processing files: findit-1.0-1.el6.noarch Requires(rpmlib): rpmlib(CompressedFileNames) <= 3.0.4-1 rpmlib(FileDigests) <= 4.6.0-1 rpmlib(PayloadFilesHavePrefix) <= 4.0-1 Requires: libc.so.6()(64bit) libc.so.6(GLIBC_2.2.5)(64bit) libc.so.6(GLIBC_2.7)(64bit) rtld(GNU_HASH) warning: Arch dependent binaries in noarch package Checking for unpackaged file(s): /usr/lib/rpm/check-files /home/mufit/rpmbuild/BUILDROOT/findit-1.0-1.el6.x86_64 warning: Could not canonicalize hostname: pvmove Wrote: /home/mufit/rpmbuild/SRPMS/findit-1.0-1.el6.src.rpm Wrote: /home/mufit/rpmbuild/RPMS/noarch/findit-1.0-1.el6.noarch.rpm Executing(%clean): /bin/sh -e /var/tmp/rpm-tmp.bHqZck + umask 022 + cd /home/mufit/rpmbuild/BUILD + cd findit-1.0 + rm -rf /home/mufit/rpmbuild/BUILDROOT/findit-1.0-1.el6.x86_64 + exit 0 [mufit@pvmove SPECS]$ |
Note: If you are using SuSE Linux, if rpmbuild is not available, try using “rpm -ba” to build the rpm package.
7) Verify source and binary RPM files
1 2 3 4 5 6 7 |
[mufit@pvmove SPECS]$ ll ../RPMS/ total 4 drwxr-xr-x. 2 mufit mufit 4096 Aug 26 14:37 noarch [mufit@pvmove SPECS]$ ll ../RPMS/noarch/ total 28 -rw-rw-r--. 1 mufit mufit 28040 Aug 26 14:37 findit-1.0-1.el6.noarch.rpm [mufit@pvmove SPECS]$ |
8) Sign your RPM package (Optional)
1. First, generate a gpg key pair.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
[mufit@pvmove noarch]$ sudo gpg --gen-key gpg (GnuPG) 2.0.14; Copyright (C) 2009 Free Software Foundation, Inc. This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Please select what kind of key you want: (1) RSA and RSA (default) (2) DSA and Elgamal (3) DSA (sign only) (4) RSA (sign only) Your selection? 1 RSA keys may be between 1024 and 4096 bits long. What keysize do you want? (2048) Requested keysize is 2048 bits Please specify how long the key should be valid. 0 = key does not expire <n> = key expires in n days <n>w = key expires in n weeks <n>m = key expires in n months <n>y = key expires in n years Key is valid for? (0) o invalid value Key is valid for? (0) O invalid value Key is valid for? (0) 0 Key does not expire at all Is this correct? (y/N) y GnuPG needs to construct a user ID to identify your key. Real name: Mufit Saka Email address: mufitsaka@gmail.com Comment: Rpm packages You selected this USER-ID: "Mufit Saka (Rpm packages) <mufitsaka@gmail.com>" Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O You need a Passphrase to protect your secret key. can't connect to `/root/.gnupg/S.gpg-agent': No such file or directory gpg-agent[5125]: directory `/root/.gnupg/private-keys-v1.d' created We need to generate a lot of random bytes. It is a good idea to perform some other action (type on the keyboard, move the mouse, utilize the disks) during the prime generation; this gives the random number generator a better chance to gain enough entropy. We need to generate a lot of random bytes. It is a good idea to perform some other action (type on the keyboard, move the mouse, utilize the disks) during the prime generation; this gives the random number generator a better chance to gain enough entropy. jıjhıohıuhuıhıugyfytfvbhj uı gpg: key A82CAA1E marked as ultimately trusted public and secret key created and signed. gpg: checking the trustdb gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u pub 2048R/A82CAA1E 2018-08-26 Key fingerprint = DFC3 2190 532D 89E3 637E D792 A3C1 D405 A82C AA1E uid Mufit Saka (Rpm packages) <mufitsaka@gmail.com> sub 2048R/80E285DE 2018-08-26 |
2. Verify your gpg key.
1 2 3 4 5 6 |
[mufit@pvmove noarch]$ sudo gpg --list-keys /root/.gnupg/pubring.gpg ------------------------ pub 2048R/A82CAA1E 2018-08-26 uid Mufit Saka (Rpm packages) <mufitsaka@gmail.com> sub 2048R/80E285DE 2018-08-26 |
3. Share your gpg key with RPM DB
First, export your gpg key into a test file with following command:
sudo gpg –export -a “Mufit Saka” > RPM-GPG-KEY-Saka
1 2 3 4 5 6 7 8 9 |
[mufit@pvmove .gnupg]$ sudo rpm --import RPM-GPG-KEY-Saka [mufit@pvmove .gnupg]$ ls gpg.conf pubring.gpg RPM-GPG-KEY-Saka trustdb.gpg private-keys-v1.d random_seed secring.gpg [mufit@pvmove .gnupg]$ rpm -q gpg-pubkey --qf '%{name}-%{version}-%{release} --> %{summary}\n' gpg-pubkey-c105b9de-4e0fd3a3 --> gpg(CentOS-6 Key (CentOS 6 Official Signing Key) <centos-6-key@centos.org>) gpg-pubkey-98ab5139-4bf2d0b0 --> gpg(Oracle Corporation (VirtualBox archive signing key) <info@virtualbox.org>) gpg-pubkey-0608b895-4bd22942 --> gpg(EPEL (6) <epel@fedoraproject.org>) gpg-pubkey-a82caa1e-5b82ac13 --> gpg(Mufit Saka (Rpm packages) <mufitsaka@gmail.com>) |
4. Configure your ~/.rpmmacros file
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
[mufit@pvmove ~]$ cat .rpmmacros %_topdir %(echo $HOME)/rpmbuild # %_signature => This will always be gpg # %_gpg_path => Enter full path to .gnupg in your home directory # %_gpg_name => Use the Real Name you used to create your key # %_gpbin => run `which gpg` (without ` marks) to get full path %_signature gpg %_gpg_path /home/mufit/.gnupg %_gpg_name Mufit Saka %_gpgbin /usr/bin/gpg [mufit@pvmove ~]$ |
5. You can sign each RPM file individually:
sudo rpm –addsign ../rpmbuild/RPMS/noarch/findit-1.0-1.el6.noarch.rpm
If because of any reason above command is not working, try to check your .rpmmacros file:
%_gpg_name => Use the Real Name you used to create your key
If gpg_name is the same name with your package creation step, type then following command:
1 2 3 4 |
[mufit@pvmove .gnupg]$ sudo rpm --define "_gpg_name Mufit Saka" --addsign ../rpmbuild/RPMS/noarch/findit-1.0-1.el6.noarch.rpm Enter pass phrase: Pass phrase is good. ../rpmbuild/RPMS/noarch/findit-1.0-1.el6.noarch.rpm: |
6. Check the signature to make sure it was signed
To sign a package during build operation add –sign option.
sudo rpmbuild -ba –sign //name//.spec
9) Install the package and start to use it
1 2 3 4 5 6 7 8 9 10 |
[mufit@pvmove .gnupg]$ sudo rpm -ivh ../rpmbuild/RPMS/noarch/findit-1.0-1.el6.noarch.rpm Preparing... ########################################### [100%] 1:findit ########################################### [100%] [mufit@pvmove .gnupg]$ [mufit@pvmove .gnupg]$ Finally, let’s check our package: [mufit@pvmove .gnupg]$ rpm -qa | grep -i findit findit-1.0-1.el6.noarch [mufit@pvmove .gnupg]$ |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
[mufit@pvmove .gnupg]$ rpm -qi findit-1.0-1.el6.noarch Name : findit Relocations: (not relocatable) Version : 1.0 Vendor: Mufit SAKA Release : 1.el6 Build Date: Sun 26 Aug 2018 02:37:47 PM CEST Install Date: Sun 26 Aug 2018 04:35:39 PM CEST Build Host: pvmove Group : Applications Source RPM: findit-1.0-1.el6.src.rpm Size : 30296 License: GPL Signature : RSA/SHA1, Sun 26 Aug 2018 04:04:37 PM CEST, Key ID a3c1d405a82caa1e Packager : itechsweb@gmail.com URL : http://itechsweb.com Summary : Find only files with / only names dates. Create archives, compress, change extensions or delete Description : This is an interactive tool to find files according to a given date/hour by nameor/and date. With this tool you can list, compress, create archives, move archives to other locations or delete them. [mufit@pvmove .gnupg]$ rpm -ql findit-1.0-1.el6.noarch /usr/bin/findit |
1 2 3 4 5 6 7 8 9 10 11 |
Program has been added in your default path. Run it like a normal bash command. [mufit@pvmove .gnupg]$ findit -h Essayer avec findit -h pour voir les options disponibles ****** -l: Pour lister les fichiers dans l'intervalle donnee. ****** -c: Compresser les fichiers trouves, les fichiers sont verifiables via findit -l commande. ****** -t: Creer un archive tar.gz a partir des fichiers trouves. ****** -d: Supprimer les fichiers trouves. ****** -e: Manipuler l'extension. ****** -o: Traitement par nom. |
Leave A Comment