I’ve used rpm-based bundle managers to put in software program on Red Hat and Fedora Linux since I began utilizing Linux greater than 20 years in the past. I’ve used the rpm program itself, yum, and DNF, which is a detailed descendant of yum, to put in and replace packages on my Linux hosts. The yum and DNF instruments are wrappers across the rpm utility that present extra performance, similar to the power to seek out and set up bundle dependencies.
Over the years I’ve created various Bash scripts, a few of which have separate configuration information, that I like to put in on most of my new computer systems and digital machines. It reached the purpose that it took a substantial amount of time to put in all of those packages, so I made a decision to automate that course of by creating an rpm bundle that I may copy to the goal hosts and set up all of those information of their correct areas. Although the rpm software was previously used to construct rpm packages, that operate was eliminated and a brand new software, rpmbuild, was created to construct new rpms.
When I began this undertaking, I discovered little or no details about creating rpm packages, however I managed to discover a e book, Maximum RPM, that helped me determine it out. That e book is now considerably outdated, as is the overwhelming majority of knowledge I’ve discovered. It can also be out of print, and used copies go for tons of of dollars. The on-line model of Maximum RPM is out there at no cost and is stored updated. The RPM website additionally has hyperlinks to different web sites which have a variety of documentation about rpm. What different data there’s tends to be temporary and apparently assumes that you have already got a great deal of information in regards to the course of.
In addition, each one of many paperwork I discovered assumes that the code must be compiled from sources as in a growth setting. I’m not a developer. I’m a sysadmin, and we sysadmins have completely different wants as a result of we don’t—or we shouldn’t—compile code to make use of for administrative duties; we should always use shell scripts. So we now have no supply code within the sense that it’s one thing that must be compiled into binary executables. What we now have is a supply that can also be the executable.
For essentially the most half, this undertaking needs to be carried out because the non-root person pupil. Rpms ought to by no means be constructed by root, however solely by non-privileged customers. I’ll point out which elements needs to be carried out as root and which by a non-root, unprivileged person.
Preparation
First, open one terminal session and su
to root. Be positive to make use of the -
choice to make sure that the entire root setting is enabled. I don’t imagine that sysadmins ought to use sudo
for any administrative duties. Find out why in my private weblog submit: Real SysAdmins don’t sudo.
[pupil@testvm1 ~]$ su -
Password:
[root@testvm1 ~]#
Create a pupil person that can be utilized for this undertaking and set a password for that person.
[root@testvm1 ~]# useradd -c "Student User" pupil
[root@testvm1 ~]# passwd pupil
Changing password for person pupil.
New password: <Enter the password>
Retype new password: <Enter the password>
passwd: all authentication tokens up to date efficiently.
[root@testvm1 ~]#
Building rpm packages requires the rpm-build
bundle, which is probably going not already put in. Install it now as root. Note that this command can even set up a number of dependencies. The quantity might range, relying upon the packages already put in in your host; it put in a complete of 17 packages on my check VM, which is fairly minimal.
dnf set up -y rpm-build
The remainder of this undertaking needs to be carried out because the person pupil except in any other case explicitly directed. Open one other terminal session and use su
to change to that person to carry out the remainder of these steps. Download a tarball that I’ve ready of a growth listing construction, utils.tar, from GitHub utilizing the next command:
wget https://github.com/opensourceway/how-to-rpm/uncooked/grasp/utils.tar
This tarball contains all the information and Bash scripts that will likely be put in by the ultimate rpm. There can also be an entire spec file, which you should utilize to construct the rpm. We will go into element about every part of the spec file.
As person pupil, utilizing your own home listing as your current working listing (pwd), untar the tarball.
[pupil@testvm1 ~]$ cd ; tar -xvf utils.tar
Use the tree
command to confirm that the listing construction of ~/growth and the contained information appears like the next output:
[pupil@testvm1 ~]$ tree growth/
growth/
├── license
│ ├── Copyright.and.GPL.Notice.txt
│ └── GPL_LICENSE.txt
├── scripts
│ ├── create_motd
│ ├── die
│ ├── mymotd
│ └── sysdata
└── spec
└── utils.specthree directories, 7 information
[pupil@testvm1 ~]$
The mymotd
script creates a “Message Of The Day” information stream that’s despatched to stdout. The create_motd
script runs the mymotd
scripts and redirects the output to the /and so forth/motd file. This file is used to show a day by day message to customers who log in remotely utilizing SSH.
The die
script is my very own script that wraps the kill
command in a little bit of code that may discover operating applications that match a specified string and kill them. It makes use of kill -9
to make sure that they can not ignore the kill message.
The sysdata
script can spew tens of 1000’s of strains of knowledge about your pc , the put in model of Linux, all put in packages, and the metadata of your exhausting drives. I take advantage of it to doc the state of a number at a cut-off date. I can later use it for reference. I used to do that to keep up a document of hosts that I put in for patrons.
You might have to alter possession of those information and directories to pupil.pupil. Do this, if crucial, utilizing the next command:
chown -R pupil.pupil growth
Most of the information and directories on this tree will likely be put in on Fedora methods by the rpm you create throughout this undertaking.
Creating the construct listing construction
The rpmbuild
command requires a really particular listing construction. You should create this listing construction your self as a result of no automated method is supplied. Create the next listing construction in your house listing:
~ ─ rpmbuild
├── RPMS
│ └── noarch
├── SOURCES
├── SPECS
└── SRPMS
We is not going to create the rpmbuild/RPMS/X86_64 listing as a result of that may be architecture-specific for 64-bit compiled binaries. We have shell scripts that aren’t architecture-specific. In actuality, we gained’t be utilizing the SRPMS listing both, which might include supply information for the compiler.
Examining the spec file
Each spec file has various sections, a few of which can be ignored or omitted, relying upon the particular circumstances of the rpm construct. This specific spec file will not be an instance of a minimal file required to work, however it’s a good instance of a reasonably complicated spec file that packages information that don’t must be compiled. If a compile had been required, it could be carried out within the %construct
part, which is omitted from this spec file as a result of it isn’t required.
Preamble
This is the one part of the spec file that doesn’t have a label. It consists of a lot of the data you see when the command rpm -qi [Package Name]
is run. Each datum is a single line which consists of a tag, which identifies it and textual content information for the worth of the tag.
###############################################################################
# Spec file for utils
################################################################################
# Configured to be constructed by person pupil or different non-root person
################################################################################
#
Summary: Utility scripts for testing RPM creation
Name: utils
Version: 1.Zero.Zero
Release: 1
License: GPL
URL: http://www.each.org
Group: System
Packager: David Both
Requires: bash
Requires: display screen
Requires: mc
Requires: dmidecode
BuildRoot: ~/rpmbuild/# Build with the next syntax:
# rpmbuild --target noarch -bb utils.spec
Comment strains are ignored by the rpmbuild
program. I all the time like so as to add a remark to this part that comprises the precise syntax of the rpmbuild
command required to create the bundle. The Summary tag is a brief description of the bundle. The Name, Version, and Release tags are used to create the identify of the rpm file, as in utils-1.00-1.rpm. Incrementing the discharge and model numbers allows you to create rpms that can be utilized to replace older ones.
The License tag defines the license beneath which the bundle is launched. I all the time use a variation of the GPL. Specifying the license is essential to make clear the truth that the software program contained within the bundle is open supply. This can also be why I included the license and GPL assertion within the information that will likely be put in.
The URL is normally the net web page of the undertaking or undertaking proprietor. In this case, it’s my private net web page.
The Group tag is attention-grabbing and is normally used for GUI functions. The worth of the Group tag determines which group of icons within the functions menu will include the icon for the executable on this bundle. Used at the side of the Icon tag (which we’re not utilizing right here), the Group tag permits including the icon and the required data to launch a program into the functions menu construction.
The Packager tag is used to specify the individual or group accountable for sustaining and creating the bundle.
The Requires statements outline the dependencies for this rpm. Each is a bundle identify. If one of many specified packages will not be current, the DNF set up utility will attempt to find it in one of many outlined repositories outlined in /and so forth/yum.repos.d and set up it if it exists. If DNF can’t discover a number of of the required packages, it can throw an error indicating which packages are lacking and terminate.
The BuildRoot line specifies the top-level listing wherein the rpmbuild
software will discover the spec file and wherein it can create short-term directories whereas it builds the bundle. The completed bundle will likely be saved within the noarch subdirectory that we specified earlier. The remark exhibiting the command syntax used to construct this bundle contains the choice –goal noarch
, which defines the goal structure. Because these are Bash scripts, they aren’t related to a particular CPU structure. If this feature had been omitted, the construct can be focused to the structure of the CPU on which the construct is being carried out.
The rpmbuild
program can goal many alternative architectures, and utilizing the --target
choice permits us to construct architecture-specific packages on a number with a unique structure from the one on which the construct is carried out. So I may construct a bundle meant to be used on an i686 structure on an x86_64 host, and vice versa.
Change the packager identify to yours and the URL to your individual web site when you’ve got one.
%description
The %description
part of the spec file comprises an outline of the rpm bundle. It could be very brief or can include many strains of knowledge. Our %description
part is slightly terse.
%description
A set of utility scripts for testing RPM creation.
%prep
The %prep
part is the primary script that’s executed throughout the construct course of. This script will not be executed throughout the set up of the bundle.
This script is only a Bash shell script. It prepares the construct listing, creating directories used for the construct as required and copying the suitable information into their respective directories. This would come with the sources required for a whole compile as a part of the construct.
The $RPM_BUILD_ROOT listing represents the basis listing of an put in system. The directories created within the $RPM_BUILD_ROOT listing are totally certified paths, similar to /person/native/share/utils, /usr/native/bin, and so forth, in a reside filesystem.
In the case of our bundle, we now have no pre-compile sources as all of our applications are Bash scripts. So we merely copy these scripts and different information into the directories the place they belong within the put in system.
%prep
################################################################################
# Create the construct tree and replica the information from the event directories #
# into the construct tree. #
################################################################################
echo "BUILDROOT = $RPM_BUILD_ROOT"
mkdir -p $RPM_BUILD_ROOT/usr/native/bin/
mkdir -p $RPM_BUILD_ROOT/usr/native/share/utilscp /dwelling/pupil/growth/utils/scripts/* $RPM_BUILD_ROOT/usr/native/bin
cp /dwelling/pupil/growth/utils/license/* $RPM_BUILD_ROOT/usr/native/share/utils
cp /dwelling/pupil/growth/utils/spec/* $RPM_BUILD_ROOT/usr/native/share/utilsexit
Note that the exit assertion on the finish of this part is required.
%information
This part of the spec file defines the information to be put in and their areas within the listing tree. It additionally specifies the file attributes and the proprietor and group proprietor for every file to be put in. The file permissions and ownerships are non-obligatory, however I like to recommend that they be explicitly set to remove any likelihood for these attributes to be incorrect or ambiguous when put in. Directories are created as required throughout the set up if they don’t exist already.
%information
%attr(0744, root, root) /usr/native/bin/*
%attr(0644, root, root) /usr/native/share/utils/*
%pre
This part is empty in our lab undertaking’s spec file. This can be the place to place any scripts which can be required to run throughout set up of the rpm however previous to the set up of the information.
%submit
This part of the spec file is one other Bash script. This one runs after the set up of information. This part could be just about something you want or need it to be, together with creating information, operating system instructions, and restarting providers to reinitialize them after making configuration adjustments. The %submit
script for our rpm bundle performs a few of these duties.
%submit
################################################################################
# Set up MOTD scripts #
################################################################################
cd /and so forth
# Save the outdated MOTD if it exists
if [ -e motd ]
then
cp motd motd.orig
fi
# If not there already, Add hyperlink to create_motd to cron.day by day
cd /and so forth/cron.day by day
if [ ! -e create_motd ]
then
ln -s /usr/native/bin/create_motd
fi
# create the MOTD for the primary time
/usr/native/bin/mymotd > /and so forth/motd
The feedback included on this script ought to make its objective clear.
%postun
This part comprises a script that may be run after the rpm bundle is uninstalled. Using rpm or DNF to take away a bundle removes all the information listed within the %information
part, but it surely doesn’t take away information or hyperlinks created by the %submit
part, so we have to deal with that on this part.
This script normally consists of cleanup duties that merely erasing the information beforehand put in by the rpm can’t accomplish. In the case of our bundle, it contains eradicating the hyperlink created by the %submit
script and restoring the saved unique of the motd file.
%postun
# take away put in information and hyperlinks
rm /and so forth/cron.day by day/create_motd# Restore the unique MOTD if it was backed up
if [ -e /and so forth/motd.orig ]
then
mv -f /and so forth/motd.orig /and so forth/motd
fi
%clear
This Bash script performs cleanup after the rpm construct course of. The two strains within the %clear
part beneath take away the construct directories created by the rpm-build
command. In many instances, extra cleanup might also be required.
%clear
rm -rf $RPM_BUILD_ROOT/usr/native/bin
rm -rf $RPM_BUILD_ROOT/usr/native/share/utils
%changelog
This non-obligatory textual content part comprises a listing of adjustments to the rpm and information it comprises. The latest adjustments are recorded on the high of this part.
%changelog
* Wed Aug 29 2018 Your Name <Youremail@yourdomain.com>
- The unique bundle contains a number of helpful scripts. it's
primarily meant for use for instance the method of
constructing an RPM.
Replace the information within the header line with your individual identify and e-mail deal with.
Building the rpm
The spec file should be within the SPECS listing of the rpmbuild tree. I discover it best to create a hyperlink to the precise spec file in that listing in order that it may be edited within the growth listing and there’s no want to repeat it to the SPECS listing. Make the SPECS listing your pwd, then create the hyperlink.
cd ~/rpmbuild/SPECS/
ln -s ~/growth/spec/utils.spec
Run the next command to construct the rpm. It ought to solely take a second to create the rpm if no errors happen.
rpmbuild --target noarch -bb utils.spec
Check within the ~/rpmbuild/RPMS/noarch listing to confirm that the brand new rpm exists there.
[pupil@testvm1 ~]$ cd rpmbuild/RPMS/noarch/
[pupil@testvm1 noarch]$ ll
whole 24
-rw-rw-r--. 1 pupil pupil 24364 Aug 30 10:00 utils-1.Zero.Zero-1.noarch.rpm
[pupil@testvm1 noarch]$
Testing the rpm
As root, set up the rpm to confirm that it installs appropriately and that the information are put in within the right directories. The actual identify of the rpm will rely on the values you used for the tags within the Preamble part, however for those who used those within the pattern, the rpm identify will likely be as proven within the pattern command beneath:
[root@testvm1 ~]# cd /dwelling/pupil/rpmbuild/RPMS/noarch/
[root@testvm1 noarch]# ll
whole 24
-rw-rw-r--. 1 pupil pupil 24364 Aug 30 10:00 utils-1.Zero.Zero-1.noarch.rpm
[root@testvm1 noarch]# rpm -ivh utils-1.Zero.Zero-1.noarch.rpm
Preparing... ################################# [100%]
Updating / putting in...
1:utils-1.Zero.Zero-1 ################################# [100%]
Check /usr/native/bin to make sure that the brand new information are there. You must also confirm that the create_motd hyperlink in /and so forth/cron.day by day has been created.
Use the rpm -q --changelog utils
command to view the changelog. View the information put in by the bundle utilizing the rpm -ql utils
command (that could be a lowercase L in ql
.)
[root@testvm1 noarch]# rpm -q --changelog utils
* Wed Aug 29 2018 Your Name <Youremail@yourdomain.com>
- The unique bundle contains a number of helpful scripts. it's
primarily meant for use for instance the method of
constructing an RPM.[root@testvm1 noarch]# rpm -ql utils
/usr/native/bin/create_motd
/usr/native/bin/die
/usr/native/bin/mymotd
/usr/native/bin/sysdata
/usr/native/share/utils/Copyright.and.GPL.Notice.txt
/usr/native/share/utils/GPL_LICENSE.txt
/usr/native/share/utils/utils.spec
[root@testvm1 noarch]#
Remove the bundle.
rpm -e utils
Experimenting
Now you’ll change the spec file to require a bundle that doesn’t exist. This will simulate a dependency that can’t be met. Add the next line instantly beneath the prevailing Requires line:
Requires: badrequire
Build the bundle and try to put in it. What message is displayed?
We used the rpm
command to put in and delete the utils
bundle. Try putting in the bundle with yum or DNF. You should be in the identical listing because the bundle or specify the complete path to the bundle for this to work.
Conclusion
There are many tags and a pair sections that we didn’t cowl on this take a look at the fundamentals of making an rpm bundle. The sources listed beneath can present extra data. Building rpm packages will not be troublesome; you simply want the precise data. I hope this helps you—it took me months to determine issues out by myself.
We didn’t cowl constructing from supply code, however in case you are a developer, that needs to be a easy step from this level.
Creating rpm packages is one other good solution to be a lazy sysadmin and save effort and time. It offers a straightforward methodology for distributing and putting in the scripts and different information that we as sysadmins want to put in on many hosts.
Resources
-
Edward C. Baily, Maximum RPM, Sams Publishing, 2000, ISBN Zero-672-31105-Four
-
Edward C. Baily, Maximum RPM, up to date on-line model
-
RPM Documentation: This net web page lists a lot of the out there on-line documentation for rpm. It contains many hyperlinks to different web sites and details about rpm.