I’m celebrating nine years at Canonical, and coming up on 15 years since I started contributing to Ubuntu in the community. It’s been quite the ride, helping build, support and advocate for the most popular Linux desktop, and most used Linux distribution in the cloud.
Over those years, we’ve strived to make it easy for users to get the latest software onto their Linux systems. We had a couple of interesting diversions along the way, but our destination has always been bringing the best of Linux and the Open Source community to desktop, cloud, server, and more recently mobile and IoT.
Let’s take a look back and retrospect how we got where we are.
Right from the start, Ubuntu was determined to have time-based releases, every 6 months, regular as clockwork (Ubuntu 6.06 LTS aside). When each version of Ubuntu was released, the archive of software, composed of thousands of ‘deb’ packages, was somewhat frozen. Bug fixes and security updates would still flow back into stable releases via the Stable Release Update (SRU) process. Major software updates with significant new features, UI redesigns or other breaking changes would not.
As the next release of Ubuntu was prepared, new(er) versions of software, which had been released in the meantime, would be packaged and made available in the archive of the upcoming Ubuntu version. However, those major software releases were typically not ‘backported’ to the previous (or any other earlier) Ubuntu release.
For example, Ubuntu 4.10 (Warty Warthog) shipped in October 2004 with Mozilla Thunderbird 0.8. When Thunderbird 1.0 was released in December 2004, Ubuntu users needed to wait for an upgrade to Ubuntu 5.04 in April the following year. Adventurous users could go outside the curated Ubuntu archive and download a binary build of Thunderbird (or whatever new software they desired) and manage updates themselves manually. Alternatively, users could grab the source code of Thunderbird and build it themselves. Or, they could just wait up to six months and upgrade Ubuntu from 4.10 to 5.04 to get the latest version.
Some users saw it as a feature that they had stability of unchanging software versions, while others preferred the bleeding edge. The latter might choose to run the pre-release of the next release of Ubuntu, or may even switch to Debian Unstable, or perhaps a rolling distribution such as Arch. Most users didn’t do this, and thus Ubuntu became a tremendously popular distribution for experts, enthusiasts and tinkerers alike.
With the advent of the first Ubuntu LTS release in 2006, the stability & staleness of software became even better (or worse, depending on your point of view). A conservative user running Ubuntu 6.06 LTS would have Mozilla Thunderbird 1.5 pre-installed. If they stuck to Long Term Support releases of Ubuntu, they wouldn’t get a full Thunderbird update to 2.0 until Ubuntu 8.04 LTS, two years later. Some users and customers prefer this, of course. Not everyone wants the very latest of everything, but would prefer a stable base, and not have to upgrade every 6 months or two years.
In 2007, Canonical announced the Launchpad Personal Package Archive (PPA) service, a free platform enabling developers to build and publish applications for wider testing. With the Ubuntu archive being ‘frozen’ every six months for a new release, PPAs enabled developers to build and publish software without having to wait for the next Ubuntu release. A developer needed to sign up to Launchpad, create a Debian packaging recipe for their software, and upload the source and its recipe. Launchpad would then build the binaries and publish them if successful.
PPAs have some limitations, however. Developers need to learn how to create valid Debian (.deb) packages. Developers who were new to packaging for Linux had a steep learning curve ahead of them. Creating and maintaining debs is not a straightforward or easy process.
They’re not mirrored, unlike the rest of the Ubuntu archive, so the load is not evenly distributed around the world, making downloads slow for some users. If the developer wishes to support multiple versions of Ubuntu, or indeed derivatives of Ubuntu based on multiple versions, then they are required to update the packaging recipes each time, for every package. This may be as simple as changing a codename in one file, or it could be more significant if underlying libraries or other dependencies have changed between one Ubuntu release and the next, which is rather common.
Packages in PPAs are not confined or containerised, just like applications in the Ubuntu Archive. But unlike the Ubuntu archive, packages in PPAs are not required to be reviewed by any robot or human for security or fitness. The user of the PPA needs to trust the owner of the PPA completely.
Packages in PPAs can do anything to a client system as the maintainer scripts in the package are run as root on end-user systems. Developers can add software to a PPA that may conflict or override the well-supported packages on end-user systems. This can cause immediate problems by removing crucial packages for users, or worse, cause major problems months or years later when the user attempts to upgrade to the next release.
In short, PPAs were never designed or envisaged to be a primary distribution method for software to Ubuntu and derivatives. But they became a victim of their own success, and many thousands of PPAs exist, enabling developers to share packages to millions of users.
Over time, software started moving faster. Upstream developers released major version updates with desirable new features. The Ubuntu developers made a series of exceptions to the Stable Release Update process, to enable major release updates to flow back to older versions of Ubuntu. This allowed users to stay on LTS releases of Ubuntu, yet still get a limited set of fresher software, such as Web browsers and email clients.
The downside of this is that significant engineering time is required to maintain multiple builds of the same application for all the supported releases of Ubuntu. As LTS releases are supported for five years on the desktop, there can be occasions where there are five separate builds of one application, required to cover all releases. As I write this, the latest update to Mozilla Firefox (82) has been published to Ubuntu 16.04 LTS, 18.04 LTS, 20.04 LTS, 20.10 and the upcoming development release, which will become 21.04.
This is a somewhat unique situation for Ubuntu, which doesn’t manifest in most other Linux distributions. Rolling Linux distributions, for example, generally only support the packaging for one current, latest release of any given piece of software.
By 2010 PPAs were well used, but hard to discover for new users. A new “Ubuntu Software Center” application was developed, and a process developed to make it easier to publish applications for Ubuntu users. Developers could package their applications as deb packages and submit them for review. Once reviewed the applications would appear in the Ubuntu Software Center desktop application and be available for users to buy and install.
Under the covers, the PPA infrastructure was used for building and publishing. So it still had some of the limitations outlined above. The developer still needed to learn how to make a deb. At the time, there weren’t as many ‘helper’ packaging tools that could automagically create debs as there are now.
The other problem with this process was a human factor. The queue of applications requiring review was long, and the Application Review Board was a small team, so it just didn’t scale well. Frequently, applications had to be sent back to developers for packaging adjustments to pass the somewhat onerous debian packaging requirements.
Furthermore, as new Ubuntu releases came out, the application developers had to adjust their debian packaging and re-submit their software, as they would for PPAs. This was too time consuming, and as such developers gave up publishing via this method.
Around 2013, Canonical took a slight diversion into the mobile and convergence space with Ubuntu Touch – the operating system for phones and tablets (and optimistically, TVs).
A new packaging format was designed for battery powered, low-resource and intermittently connected devices, which would be more reliable and lightweight than debs. Click packages enabled developers to bundle their application and dependencies into a .click file, then submit that to the Ubuntu Click Store.
Application developers targeted a Qt QML-based SDK, and could self-serve uploads of their application with no human review. Packaged applications were delivered in a read-only container format, which couldn’t mess with other packages on the system. An automated review process ran to ensure the application didn’t go outside the bounds of the confinement model.
This overcame many of the problems of PPAs. A central app store model made discovery of new applications easier. Applications were built against a single SDK based on one Ubuntu core release. This meant developers didn’t need to update their applications so frequently, as with the six-monthly desktop releases.
While Ubuntu Touch was relatively short-lived, many lessons were learned, which fed into the next iteration of software delivery on Ubuntu, and beyond.
Snaps were initially designed for packing and publishing applications for IoT platforms. Some of the existing infrastructure and concepts of Click packages – including the single store model, review tools, and bundling of libraries – were re-used. The snap design enables developers to publish applications, Linux kernels, system properties (gadget) and runtime environments (base) in the Snap Store.
Users love discovering new software, and many Ubuntu users aren’t keen on veering off-piste to build binaries from a GitHub releases page, or download random debs from a free file sharing service. Having a central store where users can browse by category, learn about and install new software is a night-and-day change from the PPA experience. It also closely matches the typical experience on other contemporary desktop and mobile platforms. Adventurous users can still elect to chart their own path with software built from source, or debs added via sneakernet.
Snaps build upon existing kernel features like apparmor and cgroups to confine applications when installed on end-user systems. A browser installed as a snap package can’t inject repositories in a sources.list, or sniff around hidden files in a user’s home directory. The emoji picker doesn’t need webcam access, so it doesn’t get it. With confinement users can feel more confident that applications aren’t doing unexpected or unwanted things with their data.
One problem snaps were designed to solve was that of outdated devices in the field. Stories of IoT devices with no upgrade path were a solid motivator for a better solution for software delivery on Linux. So from the start, snaps have been automatically updating, getting the latest kernel, drivers, security patches, and application updates soon after publication. On the desktop, it turns out that users are pretty terrible at applying updates. Developers faced frustration at having old, unsupported versions of their software in the field, and users had the risk of potentially getting compromised. Over time, snap grew features to defer updates, or schedule them for a particular day, week or minute. More work could be done here, especially in surfacing the options in the graphical desktop, and we’ll get there.
When a deb update fails, generally the path to success is “remove it” or “wait for an update which fixes the problem”. There’s not really a good concept of rollbacks in the deb world which retains data integrity. Snaps have a rollback capability, so users can manually revert to the ‘last known good’ version of software which has been updated. In addition, the developer can detect if something goes wrong during a snap update, and can trigger a revert with no user interaction.
For developers, building a snap is often (but not always) easier and faster than making and publishing a deb. I appreciate those developers who already vanquished the dragon that is the Debian Packaging Guide may disagree. We’ve put a lot of work into making snapcraft a fun tool to turn your software into a package. Having a single snap package which works all the way from Ubuntu 14.04 LTS, through 16.04, 18.04 and 20.04 LTS and beyond, as well as most of the other major Linux distributions is a massive time and resource saver.
Every non-private snap which is published in the Snap Store gets a web page on the storefront. Developers need to just signpost this page to cover their Linux installation instructions. The developer can customise the page to show images and videos, detailed instructions and links back to their home pages, bug tracker and more. Each page shows all the versions of the snap that users can install. A link enables users to install via a graphical app store, and command line gurus are catered for with the exact statements required to get the application. This includes Linux distribution specific commands and tips to smooth the end user experience of getting the software.
All that said, not everything makes sense as a snap. The deb package isn’t going away any time soon. Indeed most of the snaps which exist today rely heavily on debs already existing as part of their construction. Fast moving, popular and high profile applications, developer tools, games, utilities and even the kernel make sense to deliver as a snap. Individual libraries, frameworks, desktop extensions and components, maybe make less sense to package as a snap. The goal isn’t to snap the entire world, even if it looks that way. The goal is to make it frictionless for users to discover and securely get the software and updates they want on Linux, and to enable developers to control their publishing process.
We’ve come a long way since the Warty Warthog in 2004. Snapcraft and snapd aren’t considered “finished” software, by a long shot. There are bugs to fix, features yet to be implemented, and performance improvements to be made. If you’d like to join our community, making snaps as good as they can be, you’ll find us over on the snapcraft forum. See you there.
Photo by Tabea Damm on Unsplash