Technology Solutions for Everyday Folks

In-Place Upgrade of WSL Ubuntu 18.04 to 20.04

About two months back (early March to be exact), I had the opportunity to finally deprecate some old versions of applications and packages due to planned retirements and upgrades. Most specifically a full-on move to PHP 7.4 was in sight, though there were other bits. I run and have access to a bunch of different environments so it felt right to get environments back to a standard (or at least closer) base configuration.

I've been running Windows Subsystem for Linux (WSL) almost as long as it's been generally available, and I love it. WSL has been life-changing for me in all sorts of ways due to the mixed environments I touch. When I first set up WSL I went with Ubuntu 18.04 LTS and have kept it pretty well updated between environments. When I shifted to WSL 2, I mistakenly thought I also managed to upgrade WSL to Ubuntu 20.04 LTS in the process.

In resetting PHP versions, I encountered a peculiar issue with trying to install PHP 7.4: no default repository had it available. That was peculiar...

Finding The Problem

After some creative The Googling and using the lsb_release -a command, I discovered that my normal runtime WSL 2 instance was still using Ubuntu 18.04, for which PHP 7.2 was a default. The apt repositories for 18.04 don't include options for 7.4, leading to my issue. I have a couple of options: use a personal package archive (PPA) for PHP builds (staying in 18.04), or just upgrade to 20.04. Since there was no obvious reason to not upgrade to 20.04 (and doing so would avoid using a non-officially-supported repository), I chose that path. Especially since I'd mistakenly thought I was already on 20.04.

Performing a Switch/Upgrade

The WSL documentation indicates that with a command line switch, specifically wsl --set-version Ubuntu-20.04 2, I can set the default distribution and use case. It's unclear if such a command will actually do anything in my case since I'm already using WSL 2. Further, if it does work, I have no clue if my existing environment settings and configuration will be ported over or if we start afresh. The latter is not what I want. So it's time to figure out an in-place upgrade. Fortunately I found this helpful write-up of the process which I used as my guide.

Cleaning Up and Prestage

Per the previously noted guide, I ran the following commands:

sudo apt update
sudo apt list --upgradable
sudo apt upgrade
sudo apt --purge autoremove
sudo apt install update-manager-core

Attempting the Upgrade

I started with the release upgrade command:

sudo do-release-upgrade

The first attempt complained about Ubuntu needing to restart (which is simple enough with wsl --shutdown after closing all the terminals); once WSL had been restarted the upgrade launched its own process and looked promising. However, after an extended wait time it would terminate with a strange and unhelpful error like this (tail snippet):

Reading state information... Done

Restoring original system state

Reading package lists... Done
Building dependency tree
Reading state information... Done
=== Command detached from window (<date string>) ===
=== Command terminated with exit status 1 (<date string>) ===

Some Googling later, I found that my likely blocker was indeed snapd and that this is a somewhat common problem in WSL upgrades with Ubuntu. So I needed to (temporarily) remove it as 20.04 would replace snapd:

sudo apt remove --purge snapd

Re-running sudo do-release-upgrade after uninstalling snapd was the magic trick—I had a working upgrade process, complete with the 'warning' about "Installing the upgrade can take several hours..."

After watching the upgrade download its bits and install, I was presented with the successful completion notice. Launching WSL now gives me the login information:

Welcome to Ubuntu 20.04.4 LTS (GNU/Linux x86_64)

 * Documentation:
 * Management:
 * Support:

  System information as of <date string>

  System load:  0.0                Processes:             18
  Usage of /:   0.9% of 250.98GB   Users logged in:       0
  Memory usage: 3%                 IPv4 address for eth0: <private ipv4>
  Swap usage:   0%

0 updates can be applied immediately.

Hooray! Everything is happy and some quick tests indicate that all of my old environment bits are still happily chugging along in place.

While it was fresh in my mind, I invoked the same upgrade process on my other workstations with WSL. All were successful!

And Now for PHP

dpkg --get-selections | grep -i php

The above command lists all PHP packages and modules installed and identifies the PHP 7.2-specific packages needing an upgrade to their 7.4 versions. Installing the 7.4 versions and uninstalling the 7.2 versions along the way with the normal sudo apt commands brought me successfully (and in an 'officially supported' way) to PHP 7.4 on all my WSL boxen.

Now we're all set until the switch to PHP 8.x comes along. At this point it looks like an upgrade to Ubuntu 22.04 will be necessary to 'officially' support 8.x, but there's always the PPA route that many folks use. That can be a decision path for a different time, though.

Upgrade Thoughts

I struggled with and got sucked into the "I'll do a better job staying on top of all the things moving forward" rabbit hole through this process. At the end of the day I settled on a 'keep it vanilla and supported' balance. This might mean running some 'older' versions, but without the overhead of (or having to remember to) setting up alternate package paths and whatnot. This balance helps keep things simple, generally-supported, and most importantly easy to rebuild in a crisis or change. A much smaller house of cards. I can always reevaluate or diverge as necessary as a one-off, but as it stands this trajectory keeps things simple, specifically my standard updatewsl alias of sudo apt update && sudo apt upgrade.

I don't need to be on the bleeding edge, but it's nice to be in the middle ground of supported versions. That was my target, so I consider the whole process successful!