Ubuntu Touch release process: From code to image update

Slashdot it! Delicious Share on Facebook Tweet! Digg!
wajan, 123RF

wajan, 123RF

Touch and Go

A short story of how new image-based updates are prepared for all the supported devices – from a single commit to the over-the-air update.

Ubuntu Touch, also known as the Ubuntu Phone, is the Ubuntu flavor specifically designed for touch devices such as smartphones and tablets. Although it's based on the same core packages as its desktop counterpart, it follows a completely different release and upgrade model. One of the reasons for that is because the touch devices use an image-based update mechanism on top of its default read-only core filesystem.

This means that a phone user only gets new and upgraded core packages for its system when an image is built and published to the respective stable image channel – notifying the users of the available over-the-air (OTA) upgrade. However, this happens only after each change goes through various stages of development, quality assurance, testing, and coordination.

In this article, I'll take a look at how all this works. An overview of the general release workflow can be seen in Figure 1. I'll start this update journey from the very top – the code.

Figure 1: A diagram showing the general overview of the update release process.

The Code

The first stage of any change is, of course, the code. Almost all Ubuntu upstream projects use the Launchpad and Bazaar for source development and hosting [1]. Each Touch-specific component has its own Launchpad project registered and a trunk branch managed by the project's maintainers.

Launchpad and Bazaar

Most Ubuntu users probably already know these two tools. Launchpad is a web service offering code hosting, bug tracking, private package archives, and builders. Anyone can register a project and get Git or Bazaar repository hosting along with all the other goodies. Bazaar, on the other hand, is Canonical's authored version control system, used by most Ubuntu-specific projects. It has a very similar distributed nature as Git. Currently, it's also possible to host your code in Git repositories instead.

When a developer wants to submit a fix, enhancement, or any other piece of code, she or he prepares a bzr branch based off trunk, submits the changes on top of it, pushes it to Launchpad, and creates a so-called merge request to trunk. (See the "Launchpad and Bazaar" box for more details.)

This merge request then gets reviewed by the maintainers and approved if everything looks and works fine. However, this doesn't mean that the change is yet merged or released into the world in any physical form – for now, it's still only code. How does this get transformed to binary form to be used on the system? That takes me to the next stage.

CI Train

Both the Ubuntu desktop and its touch equivalent use Debian (.deb) packages to provide core components. By core components, I mean all the base system files, libraries, graphical interfaces, system daemons, tools, etc. Every Ubuntu-owned Touch component carries Debian packaging in their bzr code trunks, allowing building binary packages in an easy way that can be then installed on any Ubuntu system. Building binary packages is a rather trivial task, but sometimes it can be time consuming, because a lot depends on the environment in which the packages are being built.

To make sure the generated binaries are clean and ready to be used on live systems everywhere, special chroot builders are required. Also, in a distributed development environment and given the need for continuous integration, a special tool that could automate at least parts of the process was required. The current approach used by Ubuntu for this is the CI Train [2].

The CI Train is a set of tools that basically helps build, test, and coordinate package releases to the Ubuntu archives (Figure 2). Now for some explanation of the most important terms: It's a database consisting of "landings" – or isolated batches of code changes – which are prepared by "landers," who are developers responsible for releasing those changes.

Figure 2: The landing requests view of the CI Train web tool.

For those interested in technical details, the CI Train is a Jenkins instance running Python 3 scripts for the core functionality, a Flask-based back end, PostgreSQL database, and a JavaScript user front end. Each landing is assigned a "silo" – basically a specific Launchpad PPA that is used for building the end .deb packages for each landing.

All the lander needs to do is list all merges for the projects she wants to build as part of the landing and get it assigned to a silo. The train then takes all the merge branches, merges them locally, and builds Debian binary packages out of them in the assigned silo PPA – informing the lander of success or failure.

For landings targeting the stable phones, there's one additional testing step required. Once the lander is happy with the packages, each silo then requires a QA sign-off – the end packages get double-checked by testers from the QA Team making sure that all the components work and that there are no regressions in existing features (Figure 3).

Figure 3: Diagram showing the general steps of a CI Train landing.

A landing that has been approved by both the landers and the QA team gets published by the Landing Team "trainguards" – that is, the people responsible for doing the final sign-off of the package to the archives. This is also where the package is checked for correctness.

Buy this article as PDF

Express-Checkout as PDF

Pages: 4

Price $0.99
(incl. VAT)

Buy Ubuntu User

Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content