Intro

This is an alternative take on ReleaseBasedVersioning. It aims to remove its shortcomings in handling the general multiple-versions scenarios packagers face. I do not expect this to become reality soon, just a plan where things could head slowly.

Goal

Leave it up to the packager to allow all following upgrade outcomes (in all cases it's given packages that should be installed at the same time have no file conficts):

  1. foo-1.2-1 installed and foo-1.3-1 is released. Allow foo-1.3-1 upgrading foo-1.2-1 (the typical upgrade case)
  2. foo-1.2-1 installed and foo-1.3-1 is released. Allow installation of both packages at the same time. (installonly case)
  3. foo-1.2-1 and foo-2.3-1 installed. foo-1.3-1 is released, upgrade foo-1.2-1 but leave foo-2.3-1 intact. (gtk2/3 and Python2/3 case)
  4. foo-1.3-1 and foo-1.4-1 installed. foo-1.4-2 is released. Upgrade foo-1.4-1 and leave foo-1.3-1 intact (what the ruby ecosystem wants)
    1. then foo-1.5-1 is installed and it turns out it is 100% compatible with foo-1.4-1 which is not secure and will not receive further updates. Upgrade foo-1.4-1 to foo-1.5-1 but leave foo-1.3-1 intact. (what we need to prevent the parallel-versioned packages staying on the system forever. impossible under the name$version scheme?)

Proposed solution

Have an RPM flag specifying the range of packages of the same name it is allowed to upgrade. For the cases above:

  1. No tag needed.
  2. in foo-1.3-1: Upgrades: 1.3 <= foo <= 1.4
  3. in foo-1.3-1: Upgrades: 1 <= foo < 2
  4. in foo-1.4-2: Upgrades: 1.4 <= foo < 1.5
    1. in foo-1.5-1: Upgrades: 1.4 <= foo < 1.6

Note

I have doubts solutions based on wildcarting a part of the version make sense, e.g. Upgrades: foo-1.*.*. This is because nothing enforces any standard versioning scheme to be used (and stay so) for a package. We can only tell if two versions are the same or one is greater.

How to implement

As we have a lot of stuff on our plates, we have to leave this topic for a while. This section is a note to ourselves so we can pick up right where we left.

  • Upgrade ranges are here to solve problems described in ReleaseBasedVersioning (see the Use cases section)
  • Basically what we need is a behaviour similar to installonlypkgs. The problem with installonlypkgs is that it completely ignores Obsoletes RPM tag
  • The solution would be to modify this behaviour in following way:
    • introduce new config option releaseupgradepkgs with the same syntax as installonlypkgs
    • If necessary, introduce new RPM tag: Upgrades. Syntax and semantics of this tag will be the same as for tag Obsoletes
    • packages in this list would behave similarly as installonlypkgs with one exception: old packages are removed if stated in Upgrades/Obsoletes tag

The easiest solution would be to utilize Obsoletes and not to introduce the new tag. In such way only a plugin to yum / dnf should be enough to do the trick. No modifications in rpm/rpmbuild are necessary. Of course this solution might be impossible for some reason. In such case the new tag should be introduced. Note that the new tag will be introduced anyway, as the second step after utilizing Obsoletes. Introduction of this new tag is important to allow maintainer of the package / buildsystem to enable/disable this feature if the package is not prepared for it.