Ubuntu 10.04 ("Lucid Lynx" aka "Lucid") was a Long Term Support (LTS) release (see also all current Ubuntu releases) from 2010-04-29, with support in the server version for 5 years -- for the core server packages (the rest were 3 years or less: list of supported 10.04 packages past 2013-04-29; desktop packages EOL 2013-05-09). Now that it is less than a year from the end of that 5 year support, and two LTS releases have been made, it is time to start thinking about upgrading.

The next LTS release was Ubuntu 12.04 ("Precise Penguin" aka "Precise") released 2012-04-26. And the current LTS release is Ubuntu 14.04 ("Trusty Tahr" aka "Trusty") released 2014-04-17. Ubuntu 12.04 LTS is supported through mid 2017, and Ubuntu 14.04 LTS is scheduled to be supported through mid 2019 -- both with a fairly complete set of packages (as the 5 year LTS was extended to the Desktop version starting with Ubuntu 12.04 LTS).

To upgrade from 10.04 LTS to 14.04 LTS requires two steps:

  1. 10.04 LTS to 12.04 LTS

  2. 12.04 LTS to 14.04 LTS

and until the Ubuntu 14.04.1 incremental release upgrading from 12.04 to 14.04 will not be offered by default (14.04.1 is scheduled for 2014-07-24).

Given the volume of software changed (12.04 release notes; and 14.04 release notes), and particularly that 14.04 LTS isn't fully debugged, this process is only suggested for "simple" systems (ie, with few things that are likely to break when upgraded). More complex systems are probably best reinstalled from scratch, especially if you have a system like Salt to automatically set the system up.

Also given the volume of software, having a local Ubuntu mirror helps dramatically with the upgrade speed -- even on the minimal system I tested this with, around 250MB of packages files had to be downloaded for each version upgrade. Thanks to Citylink for providing a New Zealand Ubuntu Linux Mirror.

Upgrading from 10.04 LTS to 12.04 LTS

For about 18 months, Ubuntu 10.04 LTS has been offering an upgrade to Ubuntu 12.04 LTS at login. The process is pretty simple:

  • Make a full system backup

  • Ensure that Ubuntu 10.04 LTS install is up to date

  • Remove extraneous old linux-image-* files, leaving only the last couple installed (the one you are runnnig, plus perhaps one older one to be able to revert back to).

  • Run: do-release-upgrade and follow prompts.

do-release-upgrade recommends against doing the upgrade through a ssh session, but if you're confident in your abilities to recover from being cut off (eg, you have easy access to the console if necessary, either as a serial console or network KVM, or by visiting a data centre) then it could be okay. Certainly for the simple upgrade I tested, upgrading via ssh worked out okay.

The release upgrade process basically ensures your system is up to date, removes any "third party" package repositories (commenting them out), and then updates the sources list to point at Ubuntu 12.04 and downloads the updates, installs them, and tidies up afterwards.

There were a few niggles that needed to be sorted out:

  • /etc/default/grub-pc needed merging by hand (serial console changes in my version; BadRAM handling in Ubuntu 12.04 version)

  • SNMP config files (/etc/snmp/snmpd.conf and /etc/default/snmpd) also needed merging by hand

  • /etc/resolv.conf needed to be fixed up, because resolvconf had its own idea about what nameserver to be used that did not match mine.

Ubuntu 12.04 LTS and resolvconf

With Ubuntu 12.04, Ubuntu switched to using resolvconf (as part of an "Improvement to DNS resolving in Ubuntu" blueprint).

By deafult, if the system has bind9 installed, then the /etc/resolv.conf will be dynamically rewritten to point at just nameserver 127.0.0.1, ignoring the dns-nameservers entries in /etc/network/interfaces. This is controlled by RESOLVCONF=yes in /etc/default/bind9, which is the default setting.

If the bind9 installation is not a useful recursive nameserver (eg it is configured to be an authoritative only nameserver!) then this effectively breaks DNS resolution. The solution is to set:

# run resolvconf?
RESOLVCONF=no

in /etc/default/bind9. And then reboot.

ETA, 2014-07-16: There is an alternative to rebooting:

sudo rm /run/resolvconf/interface/lo.named
sudo service bind9 restart
ls /run/resolvconf/interface/     # Make sure lo.named is not recreated!
sudo resolvconf -u
cat /etc/resolv.conf

Rebooting works because /run is a tmpfs recreated on boot. The other part of the problem is that setting RESOLVCONF=no does not remove the lo.named file, even if bind9 is restarted -- that file has to be removed by hand -- which means that all attempts at recreating resolv.conf will just use lo.named -- and hence the BIND9 server -- until something happens to cause lo.named not to be there. (I eventually found a hint to this at the end of Ubuntu bug 933723; see also an Ask Ubuntu question about it, and the Debian bug about this behaviour. It appears somewhere after Ubuntu 12.04 LTS was released the default changed, but any existing systems kept the -- IMHO broken default -- behaviour.)

Ubuntu 12.04 LTS to Ubuntu 14.04 LTS

The upgrade process to go from Ubuntu 12.04 LTS to Ubuntu 14.04 LTS is pretty similar to the 10.04 to 12.04 process described above, but because Ubuntu 14.04.1 has not been released yet (due 2014-07-24) the Ubuntu 14.04 LTS is still considered "developmental", and so you have to prod do-release-upgrade into installing it with:

do-release-upgrade -d

after that the process is basically the same. There didn't seem to be any new problems resulting from that upgrade (just the same things noted above needing attention again).

ETA, 2014-07-16: On doing this on another system, it failed to reboot after the do-release-upgrade -d step initiated a reboot, with a message like:

file not found

repeated several times, and then the screen blanked, very early in the boot (ie, it appeared that Grub was failing to load something). Ubuntu Bug 1289977, of someone else with a similar issue, gave the hint that grub hadn't been reinstalled correctly. So the fix is:

  1. Boot the system some other way (eg, of the Ubuntu 14.04 LTS CD with the same version you're using, eg 32-bit or 64-bit, same as your install)

  2. Choose to "Rescue a broken system" (last menu option)

  3. Answer the prompts to get the recovery environment started

  4. Mount your existing root file system (/dev/sda1 or /dev/sda3 or similar -- it really helps if you remember this!)

  5. Start a shell in your root file system

  6. Reinstall the first stages of grub boot environment:

    sudo grub-install --recheck /dev/sda
    

    (or whatever drive you actually boot from -- it really helps if you remember this too; if you're using RAID mirroring you may want to install on both drives to be sure.)

  7. Exit out of the shell, and choose to reboot (making sure to eject the CD or whatever you booted off)

(An alternative might be to use Boot Repair, possibly from within the Ubuntu 14.04 Live CD, but I didn't try that -- and it looks like it might need a bit more effort to get running for Ubuntu 14.04 LTS at present. There are also other recovery options using a Live CD, which I did not need -- but beware that documentation seems to pre-date the Ubuntu 14.04 LTS CD, which provides a menu option -- noted above -- to get to a recovery environment.)

Tidying up after upgrades

After doing these upgrades, it's useful to flush the cached binary packages from the disk, unless you want to retain them for another upgrade, with:

apt-get clean

and to make sure the system reboots cleanly (eg, watching the system console for errors: I found /etc/postfix/main.cf needed inet_interfaces = 127.0.0.1 rather than inet_interfaces = lo, but I'm not sure if that is a change or it was a typo in the beginning; I also removed lm-sensors since the system was a VM).

Also be sure to look for any remaining config that needs to be merged:

cd /etc
sudo find . -name "*-dist"

(which covers both *.dpkg-dist and *.ucd-dist)

One other thing to watch out for is that the nobody user gets a shell of /usr/sbin/nologin:

nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin

(although various other accounts still have a shell of /bin/false). So running commands as nobody needs a bit more work. Eg, in a crontab:

SHELL=/bin/sh

or from the shell:

sudo su -s /bin/bash -c ${COMMAND} nobody

(I found this because I have a report-back tool which runs as nobody by default.)

ETA, 2014-07-16: I also found that there are a number of older packages which the upgrade process removes but does not purge, so they are left in "rc" state, as old clutter. You can review these with:

dpkg -l | grep -v "^ii"

If there are ones with "rc" flags at the start of the line, and they should all be removed, you could do something like:

sudo apt-get --purge remove $(dpkg -l | awk '/^rc/ { print $2; }')

to remove them all -- if there is more than one you should get one last prompt for confirmation (but probably not if there is only one).