Tuesday, April 30, 2019

How to make our application available in system PATH variable during RPM based installer

We are developing an application that would be used with RHEL.  So far we had not prepared an installer for our application.  So we were copying the binaries of our application in a directory, and updating system PATH variable to include that directory.  This way, the commands of our application were available to be executed from any directory.

The time had now arrived to prepare RPM based installer for our application.  I prepared a .spec file for this purpose.  We decided to copy files of our application in a separate sub-directory under /opt directory.  And not in /usr/bin directory.  Right, /usr/bin is for distribution-managed normal user programs.  But in our case, our own sub-directory under /opt was our chosen place.

I prepared the .spec file and used the rpmbuild command to create the .rpm file.  All went well as planned, except one problem.  Commands of our application that were present in /opt/our_app/ directory were not available in system PATH variable.  To get this done, I added code in %post scriptlet.  I updated value of PATH variable in .bash_profile file.  But then, to get the change into effect, the .bash_profile file must be reloaded.  I could not find a way to do that.  source .bash_profile did not help.  . .bash_profile did not help either.

After a lot of searching here and there, I came to know that reloading .bash_profile file is not possible during installation of the .rpm file.  And updating the value of system PATH variable in .bash_profile file is not the right approach.  The correct way is to create a symbolic link in /usr/bin/ directory, pointing to our command file.  And removing the symbolic link at the time of un-installation of our package.  So, in the %post scriptlet I created the required symbolic link. 

%post
# Create symbolic link of eventd in /usr/bin/
ln -sf /opt/our_app/our_cmd /usr/bin/our_cmd


And in %postun scriptlet I removed the symbolic link that was created in /usr/bin/ directory.

%postun
# After removing the files, remove the symbolic link that was created in /usr/bin/ directory
rm -f /usr/bin/our_cmd


The %post scriptlet is executed just after the package is installed on the target system.  The %postun scriptlet is executed just after the package is uninstalled from the target system.

Friday, April 26, 2019

How to create RPM based package that checks system's RHEL version prior to installation

I was creating a RPM based package for doing installation of the application that we are developing.  While I was writing a .spec file, a requirement came my way.  Check the RHEL version, and install the package only if RHEL version is 7.5 or greater.

You may be wondering, "What's a .spec file?"  A .spec file is the "recipe" that is used by rpmbuild command for creating packages.  It is a text file, written in a specific syntax.  The .spec file tells the rpmbuild command what to do.  How to build our application, actions to be performed at the time of installation and un-installation.  To know about .spec files and RPM packaging, this article was suggested by one of my colleagues.

After studying .spec files for some time, I figured out that the %pre scriptlet is what I needed.  Scriptlet is a section in a .spec file, for a specific purpose.  The %pre scriptlet is executed just before the package is installed on the target system.

Here is the %pre scriptlet I wrote, that did the required job.

%pre
# Before copying files, check that system is running RHEL, and version of RHEL is greater than 7.5
rhel_version=`cat /etc/redhat-release | cut -d ' ' -f 7`
echo "RHEL version is $rhel_version"
rhel_min_required="7.5"
echo "Minumum required RHEL version is $rhel_min_required"
check=`echo "$rhel_version>=$rhel_min_required" | bc -l`
if [ $check -ne 1 ]
then
    echo "RHEL version $rhel_version is not supported for this application"
    exit 1
else
    echo "RHEL version $rhel_version is OK for this application"
fi



To know more about the rpmbuild command, referring to its manual page is a good start.