Jay: A program for removing excess kernels

Ubuntu is pretty easy as far as regular software maintenance goes, thanks to APT. However, there’s one task which (as far as I can tell) isn’t automated.

Whenever there’s a minor update to the Linux kernel, apt-get (or GUI equivalent) will diligently download and install it. Unlike with applications, though, APT doesn’t remove the old version — because you’re running it, and bad things can happen if dynamically loadable kernel modules disappear while the system is running.

So as time goes on, your Ubuntu system collects more and more old kernels. My work laptop had over 700MB of them, and a server at work running a Ubuntu LTS release had over 800MB.

There’s a proposal to build a utility to clean out the excess, but as far as I can tell nobody has actually built it. Instead, there are lots of tutorials on how to clean out kernels manually. It’s a pretty ugly task to do properly, because each kernel is split into three or four packages, depending on your hardware — as well as the generic Linux kernel, there can be proprietary hardware drivers, backported modules, and headers for use in software development. You need to make sure that for each kernel you keep, you keep the matching versions of the headers and modules, and throw away the rest.

After doing this manually enough times, I looked to see if someone had written a script to solve the problem. I couldn’t find one, so I wrote a program to do it in Ruby. It works with plain Ruby 1.8 or 1.9, no extra gems or libraries required; it calls the standard APT utilities in Ubuntu 8.x to query the package database and do the actual work.

It also makes use of a neat Ruby feature: the Comparable mixin. I define a class to represent a version number (e.g. 2.6.15), implement the <=> operator, and import Comparable. I can then use my Version objects just like any other number, and compare them and sort them as easily as if they were ordinary integers.

Download it and give it a try, and let me know if you find any bugs or have any suggestions for improvements.

Update 2011-06: This is still needed on some Ubuntu LTS releases that are supported as of 2011. I just removed 1.1GB of old kernels from one machine. Moved the code to GitHub and added a manual page.