Recently, I needed to check if a regression in Ubuntu 22.04 Beta was triggered by the mesa upgrade. Ok, sounds simple, let me just install the older mesa version.
Oh, wow, there are about 24 binary packages (excluding the packages for debug symbols) included in mesa!
Because it’s no longer published in Ubuntu 22.04, we can’t use our normal apt
way to install those packages. And downloading those one by one and then installing them sounds like too much work.
Step Zero: Prerequisites
If you are an Ubuntu (or Debian!) developer, you might already have ubuntu-dev-tools installed. If not, it has some really useful tools!
$ sudo apt install ubuntu-dev-tools
Step One: Create a Temporary Working Directory
Let’s create a temporary directory to hold our deb packages. We don’t want to get them mixed up with other things.
$ mkdir mesa-downgrade; cd mesa-downgrade
Step Two: Download All the Things
One of the useful tools is pull-lp-debs
. The first argument is the source package name. In this case, I next need to specify what version I want; otherwise it will give me the latest version which isn’t helpful. I could specify a series codename like jammy or impish but that won’t give me what I want this time.
$ pull-lp-debs mesa 21.3.5-1ubuntu2
By the way, there are several other variations on pull-lp-debs:
- pull-lp-source – downloads source package from Launchpad.
- pull-lp-debs – downloads debs package(s) from Launchpad.
- pull-lp-ddebs – downloads dbgsym/ddebs package(s) from Launchpad.
- pull-lp-udebs – downloads udebs package(s) from Launchpad.
- pull-debian-* – same as pull-lp-* but for Debian packages.
I use the LP and Debian source versions frequently when I just want to check something in a package but don’t need the full git repo.
Step Three: Install Only What We Need
This command allows us to install just what we need.
$ sudo apt install --only-upgrade --mark-auto ./*.deb
--only-upgrade
tells apt
to only install packages that are already installed. I don’t actually need all 24 packages installed; I just want to change the versions for the stuff I already have.
--mark-auto
tells apt
to keep these packages marked in dpkg
as automatically installed. This allows any of these packages to be suggested for removal once there isn’t anything else depending on them. That’s useful if you don’t want to have old libraries installed on your system in case you do manual installation like this frequently.
Finally, the apt
install syntax has a quirk: It needs a path to a file because it wants an easy way to distinguish from a package name. So adding ./
before filenames works.
I guess this is a bug. apt
should be taught that libegl-mesa0_21.3.5-1ubuntu2_amd64.deb is a file name not a package name.
Step Four: Cleanup
Let’s assume that you installed old versions. To get back to the current package versions, you can just upgrade like normal.
$ sudo apt dist-upgrade
If you do want to stay on this unsupported version a bit longer, you can specify which packages to hold:
$ sudo apt-mark hold
And you can use apt-mark list
and apt-mark unhold
to see what packages you have held and release the holds. Remember you won’t get security updates or other bug fixes for held packages!
And when you’re done with the debs we download, you can remove all the files:
$ cd .. ; rm -ri mesa-downgrade
Bonus: Downgrading back to supported
What if you did the opposite and installed newer stuff than is available in your current release? Perhaps you installed from jammy-proposed and you want to get back to jammy ? Here’s the syntax for libegl-mesa0
Note the /jammy
suffix on the package name.
$ sudo apt install libegl-mesa0/jammy
But how do you find these packages? Use apt list
Here’s one suggested way to find them:
$ apt list --installed --all-versions| grep local] --after-context 1
Finally, I should mention that apt
is designed to upgrade packages not downgrade them. You can break things by downgrading. For instance, a database could upgrade its format to a new version but I wouldn’t expect it to be able to reverse that just because you attempt to install an older version.
oh I should add a ?local pattern than you can do
apt install ?local?any-version(?not(?local))/
to install them back from the release.
sudo apt install –only-upgrade –mark-auto ./*.deb
Thank you for that! I can’t tell you how many times I’ve been in this exact scenario and never noticed these apt options. I always end up looking at the dpkg -l output for a while to try to figure out which specific packages to install. This is far, far, far better.