The other day some of my colleagues were discussing about how to manage a package. From what I heard: SUSE decides to use kernel's bundled DRDB module instead of the version built out of DRDB's source tree, which is dropped in DRDB's new version anyway. The package for this new DRDB is called DRDB-user as it only contains the user-space part. The problem rises when a user of older version of SLE (SUSE Linux Enterprise) decides to update to this DRDB-user. DRDB-user is said to support some old versions, i.e. for these versions you can mix up kernel modules from old DRDB package with newer DRDB-user. The question is how to do the packaging? (I am totally ignorant about DRDB, so the details might not be exact but the important point here is packaging.)

I joined this discussion and throughout the course I've come to understand many concepts more clearly than before: no overlap among packages, different packaging methods, the meaning and differences between "Obsoletes" and "Conflicts"

How to design packages?

The most intuitive and also best way should be just to divide the old DRDB package into two: DRDB-user and DRDB-km. In this way, DRDB-user is just the new package and can be upgraded separately if needed. So far so good. But what if we don't want to change the old package? Why? In retrospect, I think it's truly evil to have thought in that way, but back then they wanted to limit the maintenance burden by reducing the number of packages.(Oh, I did support this view…, I understand…) And then we fell into the rabbit hole.

Packages should never overwrite each other.

The first idea was to have DRDB-user overwrite DRDB. This won't work. No matter how the dependency links are designed. Naive I was, I believed carefully-crafted dependency would avoid any package breaks. Even cyclic dependency was considered. As an afterthought, no overlap between packages is actually the number one rule of packaging. In this case, just think of re-installing DRDB after DRDB-user is installed.

However, this is the quickest solution. So if the use cases of mixing up old DRDB with new DRDB-user are only few, then it might not be necessary to design DRDB-km. To tell the sysadmin to be extra careful or add some warning to the (un)installation/update message would be enough.

Overwriting while packaging.

In the build&install phrase of packaging, build old DRDB and also new DRDB-user; install DRDB first, then DRDB-user, overwriting same files at the same time. At last you pack everything up and name it DRDB. This method should work in principle, but it's bizarre and in reality we maintain a new package even though it has an old name.

Several concepts

When talking about making new packages, we got confused on "Obsoletes" vs "Conflicts". I'll put up two good references:

"Re: Conflicts vs Obsoletes" from rpm5.org

PKGBUILD#replacesreplaces is just the Obsoletes in Arch's jargon.

In common, they all remove the designated packages. – here is the cause we get confused.

But have different purposes: Obsoletes prescribes an upgrade, so it's automatically done by the packaging system. Conflicts prevents installation and these packages are surely not in the upgraded package list.

After note

I didn't follow this discussion later and don't know what they've decided to do in the end. In reflection, I realized how little I knew about packaging and how real-life politics can affect engineering choice. The mentality to avoid designing necessary new packages might come from this fact: whoever introduces the package is likely to be responsible for maintaining it. And there are already A LOT of packages at each one's hand. Further, even the evil package-overwriting method might be useful, if only one or two customers need that special mix setup.


Comment: Github Issue