Some opinions on how package systems should allow you to pin versions
Good package management systems allow you to selectively pin or freeze the versions of some packages. Over time I have evolved some opinions on how this should work, usually by getting irritated by the limitations of some tool in doing this (which is what happened today). So here is the minimum things that your package management tool should support around this.
First, you should be able to pin a package at a version that is not the currently installed version. Such a pin means that the package system is allowed to upgrade the package to that version and no other. Ideally such a pinned version would anchor the update of other packages which require synchronized versions.
(Bonus points are awarded if the package system can be made to downgrade a package to that version as well.)
Second, you should be able to pin the version of a package that is not even installed. Such a pin means that only that version of the package is allowed to be installed later. As with the previous case, a 'can only install version X' pin should influence other packages through dependencies and so on.
When both situations primarily matter is during system installation where you will be applying package updates (which is often the case). If you can pin non-current versions and even future package installs, your install system has a simple workflow; it first installs all of your pins, then does its usual package updates and installations of extra packages without worrying about specific versions. If you cannot pin non-current or non-installed packages, knowledge of pinned packages (and their versions) leaks into the whole update and install process. When you apply updates, you have to limit some packages to be updated only so far; when you install new packages, you have to install specific versions of some packages. And on top of this you have to pin (or hold, or freeze) the packages as well, so that future updates won't undo your work of picking specific package versions.
(This can also matter later on if you decide that you now want to pin some additional packages before applying more updates or installing new packages.)
Sidebar: pinning specific versions versus holding back changes
Sometimes you want a specific version of a package because it's what you've determined will work, or because you want all systems to be the same for some important package, or the like. Other times you don't particularly care about the specific version, but you just don't want a package to change for various reasons (for example, kernel updates might require reboots which have to be scheduled well in advance, or grub updates often wind up causing problems for your update process).
In theory, holding package changes is a subset of pinning a specific
version (it is 'pin the current version of the package'). In practice
package managers that support both often implement the two in
different ways. I believe that Debian
apt is an example of this.
The Apache mod_qos module worked for us
We run a shared web server where our users can run CGIs and so on in response to incoming HTTP requests. This presents several obvious potential problems, and recently we ran into one of them. A user had a quite slow CGI (although not a CPU-consuming one) and, as sometimes happens when your users are computer scientists sharing their hot research results, it got linked to from a popular place and a result the requests for it just poured in. In not very much time at all, the slow CGIs were using up all of Apache's request slots and nothing else could get a request in edgewise.
On the one hand, I didn't want to just turn off the user's CGI entirely. It's actively great that lots of people are interested in people's research results and we'd be serving our users very badly if we shut that down whenever it happened. On the other hand, it's a shared web server with other important things hosted on it, so I needed to keep the web server functioning in general. What I needed was something to limit how many concurrent requests for this particular CGI. Fortunately there is a (third-party) Apache module that can do this, mod_qos.
Mod_qos has a whole lot of configuration settings, most of which I didn't try to play with. What I used (and what worked) is the simple QS_LocRequestLimitMatch directive:
QS_LocRequestLimitMatch "^/(~|%7E|%7e)USER/.*$" NNN
Rereading the documentation now suggests that I could have used the simpler QS_LocRequestLimit directive, but at the time it wasn't clear to me if this was the right choice. I used the three-part match for '~' because the mod_qos specifically says that the directive applies to the unparsed URL and I wasn't sure quite how unparsed it meant.
(At the time I was in a mood to be basically sure with one change, because it was happening on a Saturday.)
Given that this situation may come up in the future, it would be sort of nice if we could set up generic per-URL resource limits or something. The module has the QS_LocRequestLimitDefault directive, but I don't know if it sets a global limit or a per-URL one. I'd have to experiment with this.
(In general, mod_qos seems like the kind of thing I should experiment with. It's potentially useful but fairly complex, and the documentation is clearly written for people who are already somewhat familiar with various terms of art and so on.)