rpmsync - determine which RPMs to install to bring a system up to date


rpmsync [<unrecognized-options-passed-to-rpm>] [-d|--distribution [[distribution] ...] [-p|--rpmpath [dir | url [^cacheurl]]...] [-F|--freshen [[name] ...]] [-U|--upgrade [[name] ...]] [-g|--ignore  [[regex] ...]] [-e|--remove  [[name] ...]] [-G|--group   [group] ...] [--rpm [command [[args] ...]]] [--update-cache] [--help] [--version]


rpmsync traverses a set of directories (backed by URLs, see below) looking for RPMs to upgrade. It will use the most up-to-date packages it is able to find and it undertands RPM dependencies. Freshening all installed packages from the current directory is the default action so that rpmsync with no options is more or less like ``rpm -F *.rpm''. It is different in that it will work even if there are multiple versions of the same package found and by default it will install not upgrade kernel packages. Additionally rpmsync will also install packages it finds that are needed by the packages it plans to upgrade. rpmsync only addresses dependency problems that can be fixed by adding packages found on its search path. In particular, it will not remove a package that is not explicitly obsoleted or upgraded.

If possible RPM header information is cached per directory in a file called .rpmsync-cache.

rpmsync can also download the RPMs it needs from a URL. To do this it needs a file, an hdlist file or an .rpmsync-cache file for each URL describing the RPMs that are available. The hdlist file is provided by RedHat for their original distributions, but not for their updates. Additional URLs (preceded by a '^') can be provided as locations to find the RPM header information if it is different from the URL for the RPMs themselves.

rpmsync is a simple self contained perl(1) script. All RPM access is through the command line program rpm(1) or by parsing the RPMs directly. It is not linked with an RPM library, so it should run on even the most minimal installations.

rpmsync does not actually install anything itself, it just prints the rpm commands needed to perform the specified actions. You can pipe the output to ``sh'' or ``sh -x'' in order to execute it.

You can set many of the command line options in either /etc/rpmsync or ~/.rpmsyncrc, so for example if you put



   rpmsync -U glib-devel

would work like 'apt-get install glib-devel' as it would look on the current path and find glib-devel and everything that it depends on. A better way to do this would be with distributions (described below).



This will freshen every installed rpm from those found in the detected default distribution or if none is detected from those found in the current directory.

   rpmsync -d fedora-3

This will use the given distribution. This can be used, for example, for upgrading

   rpmsync -d fedora-3 atrpms -U mythtv

or for cherry picking certain packages from other distribution sites while picking up needed dependenies from somewhere else first. Additional local paths can be specified as well

   rpmsync -p /local-fedora-4-rpms -d fedora-4

This will look in the local directory

   rpmsync --rpmpath /redhat-7.0/local/RPMS \
                     /redhat-7.0/i386/updates/RPMS \
                     /redhat-7.0/i386/Redhat/RPMS \
           --upgrade xmms glibc-devel \
           --freshen \
           --remove magicdev

This would make sure that the newest version of all installed packages are installed while ensuring that the latest xmms and glibc-devel are installed (even if they were not before) and that magicdev is not installed. Also any packages needed by these new packages are installed.

   rpmsync --group Applications/Publishing

Will make sure that the latest version of every package in the current directory that is in the Applications/Publishing group is installed.

For example you could create a new install of redhat that has at least XEmacs and everything it needs with something like the following.

   mkdir -p /tmp/new-install/var/lib/rpm
   rpm --root /tmp/new-install --initdb
   rpmsync --rpm rpm --root /tmp/new-install \
           --rpmpath /redhat-7.2/RPMS \
           --group "System Environment/Base" \
           --upgrade xemacs \
   | sh -x

Note that you could theoretically leave off the ``System Environment/Base'' group, and it should work, but for example neither XEmacs or anything it depends on seems to actually depend on rpm, so you wont get it unless you add it explicitly. rpmsync by default wont choose between two RPMs it could add that both provide a requirement, so this will choose packages from the base as a default. This must be done as root since rpm --root does a chroot(3).


rpmsync takes its option names from rpm(1) where possible.

Initial unrecognized options will be directly passed to the the installation and removal rpm (not the query) commands. Common options passed this way are

-v, --hash, -h, --test, --nodeps, --force

-p|--rpmpath [dir | url [^cacheurl]]...
The set of directories to search for the RPM packages to be considered. The default is the current directory. URLs can be specified. RPMs are downloaded into the first directory that precedes their URL in the path. Each URL must provide either a yum style headers/ file, a Red Hat distribution style ../base/hdlist file (only for URLs that end in ``RPMS'') or an rpmsync .rpmsync-cache file that describes the headers of the RPMs available there, or must provide another url (prepended with a '^') from which to get this file.

-d|--distribution [[distribution] ...]
A distribution chooses an --rpmpath from a preset list of paths based on the string given. The default distribution is gleened from files such as /etc/redhat-release and by default will look something like redhat-7.3. There is a default list of distributions, but you can configure or override the defaults with new distributions in the .rpmsyncrc file. It could for example contain
 $distribution{'redhat-7.2'} = ['/local/rpms',
 $distribution{'redhat-7.3'} = ['/local/rpms',

The paths indicated by a distribution are put after any paths given on the command line so that if you download some new packages into the current directory then

 rpmsync -d redhat-7.2 -p .

would look there first and then in the ``redhat-7.2'' distribution's directories. Though unless two RPMs have exactly the same version, the order doesn't matter since only the newest RPMs are used.

-F|--freshen [[name] ...]
This option takes a set of rpm names to install if the package is already installed and a newer version is found along the path.

This corresponds to the -F option of rpm(1).

An empty list matches all installed packages. This is the default.

-U|--upgrade [[name] ...]
This option takes a set of rpm package names to install (removing the old ones) if found along the path even if the package is not already installed.

This corresponds to the -U option of rpm(1).

An empty list matches all packages encountered.

-G|--group [group] ...
This option is the same as --upgrade but instead of specifying individual packages, you can specify groups of packages. See /usr/share/doc/rpm-$version/GROUPS and rpm(1) for more info.

Could use the comps file too.

-i|--install [[regex] ...]
If a package name matches any of the given regular expressions will be installed when it would otherwise be upgraded. When rpm upgrades (-U) a package it removes older versions of the package, whereas it when installs (-i) one it leaves the older versions installed as well. When upgrading a kernel package it is wise to keep the older versions installed so that you can revert to an older kernel if the new kernel doesn't boot. Unlike most packages kernels are usually made such that many versions can be installed at once.

By default packages the packages kernel, kernel-smp, kernel-bigmem and kernel-enterprise are installed instead of upgraded.

-g|--ignore [[regex] ...]
If a package name matches any of the given regular expressions it will not be upgraded, freshened or removed unless it is explicitly upgraded with -U.

-e|--remove [[name] ...]
This option takes a set of rpm names to remove if installed.

This corresponds to the -e option of rpm(1).

RPMs often require files like /bin/sh but packages like bash do not explicitly provide them since it is assumed that all RPMs implicitly provide every file they contain. This means that if we want to cache provision information we would need a list of every file in every RPM. This is an excessive amount of data for rpmsync to store. Generally rpmsync only searches through RPMs looking at the list of files if it needs to. It then caches the results so it wont have to look through them the next time it is run. That is to say that the searching is generally demand driven. For example, if there is are two versions of an RPM in the path then the oldest version will never be searched through. If one RPM is known to provide a file then rpmsync will not bother to look through any other RPMs.

When rpmsync is used with this option it will update the file provision cache of every RPM in the path regardless of version, architecture or which packages are currently installed then exit.

--update-cache is generally not necessary except in the case when some users do not have write access to the cache files and you still want them to have the benefit of using them. This is useful, for example, if you provide HTTP access to your RPMs or in order to save bandwidth if you have many clients acessing your RPMs over a slow or read-only network filesystem.

--rpm command [[args]...]
Will use the given rpm command and arguments, instead of ``rpm'' which is the default, to query installed packages and rpm files, and for the installation and removal rpm commands.


/etc/rpmsync ~/.rpmsyncrc

.rpmsync-cache headers/ ../base/hdlist





       Jim Radford <>