How to create rpm package

Install required tools

rpm -qa | grep rpmdevtools
yum list | grep rpmdevtools
yum install rpmdevtools

Create directory structure required for rpm build if not exist

rpmdev-setuptree
rpmbuild/
├── BUILD
├── RPMS
├── SOURCES
├── SPECS
└── SRPMS

Create source package under SOURCES

mkdir hello-0.0.1
cd hello-0.0.1

hello.sh

#!/bin/sh
echo "Hello world"
tar -cvzf hello-0.0.1.tar.gz hello-0.0.1

Create spec file and make necessary changes

cd ~/rpmbuild/SPECS
rpmdev-newspec hello.spec
Name:           hello
Version:        0.0.1
Release:        1%{?dist}
Summary:        A simple hello world script
BuildArch:      noarch

License:        GPL
Source0:        %{name}-%{version}.tar.gz

Requires:       bash

%description
A demo RPM build

%prep
%setup -q

%install
rm -rf $RPM_BUILD_ROOT
mkdir -p $RPM_BUILD_ROOT/opt/hello
cp * $RPM_BUILD_ROOT/opt/hello

%clean
rm -rf $RPM_BUILD_ROOT

%files
/opt/hello/*

%postun
rm -vrf /opt/hello

%changelog
* Sun Feb 04 2024 
- First version being packaged

Now directory structure should look like this

/home/tux/rpmbuild/
├── BUILD
├── BUILDROOT
├── RPMS
├── SOURCES
│   └── hello-0.0.1.tar.gz
├── SPECS
│   └── hello.spec
└── SRPMS

Build rpm using following command

rpmbuild -ba SPECS/hello.spec

where -b is build a is for both source and binary
if you want only binary then put -bb flag
if you want only source then put -bs flag

Install the rpm using following command

sudo rpm -ivh ~/rpmbuild/RPMS/noarch/hello-0.0.1-1.el8.noarch.rpm

Verify rpm installed successfully using following command

rpm -qi hello
tree /opt/hello

The %changelog entry of a package can be viewed, too:

rpm -q hello –changelog

Uninstall or erase installed rpm

sudo rpm -q | grep hello
sudo rpm -ve hello

Troubleshoot

To extract files and directories from rpm

rpm2cpio hello-0.0.1-1.el8.noarch.rpm | cpio -idmv

XML

users.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE users>
<?xml-stylesheet type="text/xsl" href="users.xslt"?>
<users>
  <user>
    <name>John Doe</name>
    <age>26</age>
    <city>New York</city>
  </user>
  <user>
    <name>Alice Smith</name>
    <age>25</age>
    <city>Los Angeles</city>
  </user>
  <user>
    <name>Pintu</name>
    <age>23</age>
    <city>Mumbai</city>
  </user>
</users>

users.xslt

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="html" indent="yes"/>

  <xsl:template match="/users">
    <html>
      <head>
        <title>User Information</title>
      </head>
      <body>
        <h2>User Information</h2>
        <table border="1">
          <tr>
            <th>Name</th>
            <th>Age</th>
            <th>City</th>
          </tr>
          <xsl:for-each select="user">
            <tr>
              <td><xsl:value-of select="name"/></td>
              <td><xsl:value-of select="age"/></td>
              <td><xsl:value-of select="city"/></td>
            </tr>
          </xsl:for-each>
        </table>
      </body>
    </html>
  </xsl:template>
</xsl:stylesheet>

POC

Run xml file on VSCode Live Server

Assignment

Remove city and use address with children city and state and then show same in html table