RPM Versioning
By: JesseKeating
Version 1.3
Overview
When building updates for Legacy Red Hat Linux and Fedora Core releases, one must use the proper RPM versioning. A large problem that currently exists is that Red Hat did not/does not version their packages appropriately to inter operate with third party package providers, nor to cleanly handle same package versions across multiple releases. The move from Red Hat Linux 9 to Fedora Core 1 does not help matters either. In order to prevent situations where a package from an older Red Hat Linux or Fedora Core release will seem to RPM to be newer than the packages in a newer Red Hat Linux or Fedora Core release one must use a specific version scheme outlined below. Because Fedora Legacy deals with already released and end of life'd products, our goal is to change as absolutely little as possible. To this end, if a package version can safely be bumped using the existing versioning scheme and not introduce a distribution upgrade issue, then the original package version scheme should be followed. Examples below.
Base Version Scheme
The base Fedora Legacy versioning scheme for a package is as follows:
packagename-version-distver.release.legacy.arch.rpm
So for a package for afio, version 2.5, release number 4, for Red Hat Linux 7.3, for the x86 platform, the legacy version would look like:
afio-2.5-0.7.3.4.legacy.i386.rpm
Yes it looks somewhat ugly, but it's necessary to have it this way. The version is rather self explanatory. The spec file would have:
Name: afio Version: 2.5
But the distver, or Distribution Version, might look a little funny. For Red Hat Linux 7.3, we used "0.7.3". Whats that "0" doing there you ask? Well we add the "0" before anything to work around the move from Red Hat Linux "9" to Fedora Core "1". Below is a table of Red Hat/Fedora Core versions and their corresponding distver:
Red Hat Linux 7.2 | 0.7.2 |
Red Hat Linux 7.3 | 0.7.3 |
Red Hat Linux 8.0 | 0.8.0 |
Red Hat Linux 9 | 0.9 |
Fedora Core 1 | 1 |
This format will ensure that regardless of the build number, a Fedora Core 1 package will *ALWAYS* (not withstanding epoch) be newer than the same package for Red Hat Linux 9. So for our above mentioned package, we now have the name, the version, and the first part of the release:
Release: 0.7.3
After that comes the build number or "release". This number indicates the build, or release of this particular version. In the past, this was usually the only number in the "Release:" tag of the RPM spec file. As bugfixes and/or security updates were made to a package within Red Hat Linux, the Version would stay the same, but the Release would get bumped. This was all fine and dandy within the world of Red Hat, but as the community grew, this release scheme quickly became inadequate to deal with third party contributions, and situations where the same package version was used across all Red Hat Linux releases. Unfortunately, a lot of the damage has already been done, and our above naming scheme does not work well when backporting a fix to an existing package version. I'll discuss more on this later. So, after the distver comes the build number, or release, in this case "4":
Release: 0.7.3.4
After the build number comes the "legacy" tag. This, in a more global scope, is the "repotag", or Repository Tag. This tag lets you know where the package came from. In our case, we use "legacy" to indicate Fedora Legacy. Once we add this tag, our Release is complete:
Name: afio Version: 2.5 Release: 0.7.3.4.legacy
When to use our scheme
As stated above, this scheme is not always usable. In fact, the only time this full scheme can be used is when a new Version is used. This happens from time to time, when it makes more technical sense to upgrade a given package rather than backport a fix to it. Upgrading should ONLY be done when backporting is not possible, or not technically/timely feasible, and when the upgrade will not break any other packages on the system.
For existing packages, where a backport is performed, the situation is a bit tougher. We have to maintain the current naming scheme, insert our "legacy" tag, bump the build/release number, and make sure we don't introduce a version conflict with packages for newer releases. To start with, check the current latest version of the package in each of the releases we deal with. Lets pick on the xsane package. Below is a table with the latest xsane packages for Red Hat Linux 7.2-9:
Red Hat Linux 7.2 | xsane-0.82-3.1.i386.rpm |
Red Hat Linux 7.3 | xsane-0.84-2.i386.rpm |
Red Hat Linux 8.0 | xsane-0.84-8.i386.rpm |
Red Hat Linux 9 | xsane-0.89-3.i386.rpm |
This package gives us both examples. The Version changed between 7.2 and 7.3, but stayed the same between 7.3 and 8.0, and changed again for 9. Lets say a flaw in xsane was found, that affects all xsane versions. We are now faced with the task of backporting this fix (lets assume it's an easy one) to our supported xsane's. For Red Hat 7.2, it's a no brainer. We don't have to worry about version conflicts, as the newer Red Hat Linux releases have a newer xsane version. So for 7.2, our legacy package will be:
xsane-0.82-4.legacy.i386.rpm
Now for Red Hat Linux 7.3 and 8.0 we have to make sure that we don't have a conflict. Since 0.84-8 is the latest build of a 0.84 version, we start with this number, and bump it for Red Hat Linux 7.3:
xsane-0.84-9.legacy.i386.rpm
And bump it one more time for 8.0:
xsane-0.84-10.legacy.i386.rpm
For Red Hat Linux 9, we'll have to peek at what xsane version is in Fedora Core 1. It just so happens to be xsane-0.91-1.i386.rpm, which is a newer version than whats in Red Hat Linux 9. This lets us know we're safe to just bump the build number for the Red Hat Linux 9 package:
xsane-0.89-4.legacy.i386.rpm
Now here is a table with the old version to legacy version for each Distro version:
Red Hat Linux 7.2 | xsane-0.82-3.1.i386.rpm -> xsane-0.82-4.legacy.i386.rpm |
Red Hat Linux 7.3 | xsane-0.84-2.i386.rpm -> xsane-0.84-9.legacy.i386.rpm |
Red Hat Linux 8.0 | xsane-0.84-8.i386.rpm -> xsane-0.84-10.legacy.i386.rpm |
Red Hat Linux 9 | xsane-0.89-3.i386.rpm -> xsane-0.89-4.legacy.i386.rpm |
As we can see, each legacy package is clearly newer than the last Red Hat provided package, but is older than any legacy package for the newer Red Hat Linux release.
Build Updates
As a package is built and put into QA or testing, problems may be found which will require building a new package, and there for increasing some number. Unfortunately just bumping the build number is not always possible. When we're dealing with new package versions, and we're able to use our full naming scheme, it's ok to just bump the build number, as the package will always be older than the package for the next distribution release. So for our above example package afio, if say there was a problem with the 7.3 build of it, a new build would just bump the build number:
afio-2.5-0.7.3.4.legacy.i386.rpm -> afio-2.5-0.7.3.5.legacy.i386.rpm
But if a package is like our above xsane example, this method will not work. If we were to bump the build number of the 7.3 release (xsane-0.84-9.legacy.i386.rpm), it would conflict with the package for 8.0 (xsane-0.84-10.legacy.i386.rpm). In these cases, it's best to add another "point" or "." to the build number. This gives us plenty of space to increase the build number, but without conflicting with later releases. So if we add a point to our 7.3 build, the transition is as follows:
xsane-0.84-9.legacy.i386.rpm -> xsane-0.84-9.1.legacy.i386.rpm
Now we have a build of "9.1" as opposed to the original build of just "9". RPM comparison will find "9.1" to be newer than "9", yet it remains older than 8.0's package build of "10".
Summary
These basic rules gives us a guideline when deciding how to version a package we are updating. Each package does need to be looked at individually to decide on exactly how to version it, but with the above rules, you should be able to figure it out. If you have any questions, the fedora-legacy-list will be happy to help you version your package.