Sysfrpm

Bernard Piette , B.M.A.G.Piette@durham.ac.uk

v1.01, 22 February 2002


Sysfrpm is a system administration tool which compares the RPMS installed on a large number of computers to a lists of expected RPMS. It can also compare the packages installed on two different computers. Sysfrpm was designed to check that the packages installed on every hosts on a network are the one that are expected.

1. Introduction

On a Linux system, the installed RPMS come from various sources: the distribution packages, the extra packages (powertools) installed afterwards as well as the RPM patches. When managing a network of Linux systems, one question that arises is if all the expected RPMS are installed and up to date. This is particularly important to check that all the latest patches have been installed.

Sysfrpm is a tool which checks and compare lists of RPMS. In particular it can compare the list of installed packages with lists of packages written in files or the rpm files in a directory or any combination of both.

When maintaining a large number of computers, it is common to install the same packages on all of them. This include in particular all the patches. If a computer is unavailable for a short time when new packages are installed across the network, it is easy to forget about it and forget to update that computer when it is brought back. When installing a new computer it is also important to install the common set of packages. One must thus compare the list of installed packages with the list of expected packages.

When upgrading the operating system on a computer, one wants to install the same packages as before, but, when they are available, with a more recent version. One thus need a way to compare two lists of packages regardless of their version.

.sysfrpm was designed to check if the packages installed on a given computer match a given list of packages. This list of packages can be extracted from the rpm files in various directories or from files that contain lists of packages or any combinations of both. If one keeps all the rpm files that are installed in a few directories, say one for the powertools and one for the patch rpms, sysfrpm can check these directories and find out which package has not been installed yet. One can also specify hosts specific files to add or remove some packages from the expected list.

Sysfrpm checks the RPMS in 3 stages:

Sysfrpm can also produce lists of packages build from multiple sources or from the installed packages.

Here are a few examples:

2. Command Syntax

The syntax for sysfrpm is as follow

          sysfrpm SRC_LIST [INST_LIST] [COMMAND] [FLAGS]

3. Master File

The master file is a list of files (one per line) and directories from which a list of RPMS is constructed. Empty lines and lines starting with a # are ignored, allowing to put comments in the master file. Directories are scanned for any ".rpm" file.

The -MasterFile=mf argument builds the SRC_LIST while the -InstMasterFile=imf argument builds the INST_LIST.

Each RPM is added to the RPM list and the RPM name is used as the key. Except when requested (see below), the key is kept unique, meaning that any existing RPM version and architecture are overwritten by any new ones for the same package. This means that the RPM lists in the master file must be ordered so that RPM update or patches come after the original list.

One can also remove RPMS from the RPM list either by removing en entire list or one rpm at a time.

3.1 Master File Syntax.

A master file is used to specify what the expected list of installed RPMS should be. The master file will normally be the same for every host on the network. The specificities, if they exist, of individual hosts are taken into account using host specific files.

Each line in the master file is taken as a path. Empty lines or lines staring with a # are ignored. The path can point to a file or a directory. Files or directories that do not exist are ignored.

If a path contains the string $h or $H, it is replaced by the host name in lower case and upper case letter respectively. This allows the use of host specific lists.

Entries can be of the following type:

3.2 RPM file syntax

Each line in the file is taken as an RPM name of the form NAME-VERSION-RELEASE.ARCH. Empty lines or lines staring with a # are ignored. Entries can be of the following type:

4. Preparing a Master File

The master file will typically list the following lists of packages (the path names are the ones we assumes for our examples below):

The list of distribution packages will be put into a file (/usr/local/System/RedHat7.1/redhat7.1.DIST) the reason being that they are not all installed.

The Master File (redhat7.1.mf) will then look as follow:

/usr/local/System/RedHat7.1/redhat7.1.DIST
/usr/local/System/RedHat7.1/ContribRPM_STDINST
/usr/local/System/RedHat7.1/Patches
/usr/local/System/RedHat7.1/Patches/Kernel
/usr/local/System/RedHat7.1/rpm_list.$h

4.1 Creating the Distribution Package List

We now create the file (redhat7.1.DIST) that will contain all the installed distribution packages by reading the packages from the distribution directory (/redhat7.1_disk1/RedHat/RPMS).:

      # sysfrpm -d @/redhat7.1_disk1/RedHat/RPMS > redhat7.1.DIST

4.2 Tailoring the Distribution Package List

One must then remove from the distribution list the packages that are not installed. First we create the list (redhat7.1.DIST.miss) of RPMS that are not installed:

        # sysfrpm -CS -n redhat7.1.DIST -nw > redhat7.1.DIST.miss
We then create the master file redhat7.1.DIST.mf
        @redhat7.1.DIST
        -@redhat7.1.DIST.miss
to subtract the packages in redhat7.1.DIST.miss from redhat7.1.DIST:
        # sysfrpm -mf redhat7.1.DIST.mf > redhat7.1.DIST2
        # mv redhat7.1.DIST2 redhat7.1.DIST 
One then does a further check:
        # sysfrpm -mf redhat7.1.m -D
and all packages listed as having the wrong version can be added to the redhat7.1.DIST file, and all packages listed as extras can be added to the redhat7.1.DIST file with the @ prefix.

4.3 Creating a Host Specific List File.

If a host has extra packages or packages that have not been installed, one can list those in the host specific file rpm_list.HOST_NAME where HOST_NAME is the name of the host. It will contain the following type of entries:

5. A practical example

Let us now consider a concrete example. Most computers are assumed to have the same packages installed except gates which because of disk limitation only has a subset of packages installed, and trovald which has a few extra packages.

The rpm files installed as in the following directories:

We will save the rpm lists and master files in the directory /usr/local/sys/rpm_check (which can be changed to anything one likes but should be on a partition NFS mounted on every host). First we create the list of distribution RPMS with the command

    # cd /usr/local/sys/rpm_check
    # sysfrpm -d @/packages/redhat7.2_disk1/RedHat/RPMS > redhat7.2.DIST
This list of packages should not change, so we can create a list file for it.

Then we create the master file rpm_lists.mf:

/usr/local/sys/rpm_check/redhat7.2.DIST
/packages/RPMS/extras
/packages/RPMS/patches
/packages/RPMS/patches/kernel
@/usr/local/sys/rpm_check/rpm_list.multi_key
@/usr/local/sys/rpm_check/rpm_list.multi_key.$h
-/usr/local/sys/rpm_check/rpm_rem_list
-@/usr/local/sys/rpm_check/rpm_rem_list.$h    
/usr/local/sys/rpm_check/rpm_list.$h

The first line lists all the distribution RPMS. The next three line are the directories where all the extra rpms have been saved.

In the line /usr/local/sys/rpm_check/rpm_list.$h, the $h will be replace by the host name. In our example, we will have a file called rpm_list.trovald which lists the extra packages installed on trovald. If the file does not exist for a given hosts, it is simply ignored.

The files rpm_list.multi_key and rpm_list.multi_key.$h will contain the list of packages that are installed for different versions (for all computers and for specific hosts respectively). This is typically the case for kernel patches. Initially these file will be created with no content. Then after running sysfrpm the first time, one will discover which packages need to be added to these lists.

The file rpm_rem_list will contain the list of packages that must be removed from the list build so far. When upgrading packages, some old rpms are sometimes removed without being replaced. Rather that editing the other rpm list files it is neater to remove them here.

The file rpm_rem_list.$h will contains the list of packages that must be removed for specific hosts. In our example we will expect to have one for gates.

After creating these configuration files, one runs the command

    # sysfrpm -mf /usr/local/sys/rpm_check/rpm_lists.mf -diff
to check the configuration on the current host. The output will display three types of packages: EXTRA RPMS, MISSING RPMS and WRONG VERSION RPMS. Each must be looked at separately:

If for example, sysfrpm produces the following output on the hosts trovald:

# MISSING RPM :
openssh-askpass-2.9p2-11.7
openssh-2.9p2-11.7
openssh-server-2.9p2-11.7
openssh-clients-2.9p2-11.7
openssh-askpass-gnome-2.9p2-11.7

# EXTRA RPM :
kernel-2.4.3-12.i386
mtools-3.9.7-4

# WRONG VERSION RPM :
apache-1.3.22-1.7.1.i386
apache-devel-1.3.22-1.7.1.i386
apache-manual-1.3.22-1.7.1.i386
mod_ssl-2.8.5-0.7.i386
we can solve the inconsistency by creating the file /usr/local/sys/rpm_check/rpm_list.trovald (we do it in a single file for simplicity):
# MISSING RPM :
-openssh-askpass-2.9p2-11.7
-openssh-2.9p2-11.7
-openssh-server-2.9p2-11.7
-openssh-clients-2.9p2-11.7
-openssh-askpass-gnome-2.9p2-11.7
# EXTRA RPM :
+@kernel-2.4.3-12.i386
mtools-3.9.7-4
# WRONG VERSION RPM :
apache-1.3.22-1.7.1.i386
apache-devel-1.3.22-1.7.1.i386
apache-manual-1.3.22-1.7.1.i386
mod_ssl-2.8.5-0.7.i386
Notice that for the kernel-2.4.3-12.i386 package we use the @ prefix to add this entry without overwriting any existing one for the package kernel. One usually has to experiment with this as kernel packages are often installed more than once.

After doing this on every host, one can then run sysfrpm on every hosts at regular interval using a cron job. Here is a csh script file that does the job, using sysf to get the list of all hosts, and Emailinmg the result to the user admin:

#!/bin/csh

set SYSFRPM_PATH="/usr/local/sys/rpm_check"

echo "" >>! /tmp/ck.log

foreach h (`sysf -lah -h ALL`)
  echo $h >> /tmp/ck.log
  (rsh $h sysfrpm -mf $SYSFRPM_PATH/rpm_lists.mf -diff) >> & /tmp/ck.log
end

mail -s "sysfrpm_check" admin < /tmp/ck.log