Our recent blog post introducing the upcoming Ubuntu Core Desktop explains what Ubuntu Core Desktop is and outlined many of the features and, more importantly, our modular approach using the capabilities of snap. This will be the first post in a series detailing the architecture of Ubuntu Core Desktop, explaining the challenges we’ve had to overcome to make this a reality, and where we’re going.
Read on to learn about the major building blocks, and how they come together to create the desktop experience you would expect from Ubuntu. More background on what’s inside Ubuntu Core.
We designed Core Desktop with composability in mind, but what does that really mean? It means the OS is made up of discrete components, or building blocks, that you can add or remove. An overview of Core Desktop’s components is shown in the diagram below.
Let’s explain each of these building blocks.
Kernel
Obviously any system needs a kernel and drivers for their hardware. With Ubuntu Core, the kernel is installed as a snap rather than being built into the base system. The model will declare which kernel should be included, but as an independent component this can be switched to a different track. For example, imagine if there was a gaming optimised kernel published, a device could switch to this kernel and track the latest optimised kernel for their use case.
Snapd
Provides the necessary framework for all the components to work together. This is where the bulk of our work for a desktop built on Ubuntu Core is taking place, we’ll detail much more of that in future posts.
Gadget
Provides the boot loader and necessary information to construct the file system, configuration, and policy. For example, kernel arguments, encryption, and security requirements.
Boot Base
This is the root file system necessary to boot a minimal system and provides the display manager. Stay tuned to this series to learn more about how we adapted this for a desktop experience and how this will evolve in the future.
Additional Bases
A base snap provides the base file system necessary for an individual snap to function. Supporting multiple bases is how we can ensure applications published for varied versions of ubuntu will work as expected across other linux systems. If an application was built based on core18 (based on Ubuntu 18.04) and installed on a Ubuntu 22.04 system, the dependencies necessary to run that app are in that base to ensure compatibility.
Ubuntu Desktop Session
This is a snap that provides the Wayland session necessary to run the same Ubuntu Desktop user session our users would expect. This is GNOME running within the same confinement as other applications on your system. As one could imagine, getting a full desktop with all the necessary integration of desktop services within confinement was challenging. We’ll cover that in our second post in this series.
Applications
We include a set of applications most people would expect to see by default, each running within their own confinement nicely contained and integrated with necessary desktop services. Of course one of these apps is Ubuntu Software, enabling you to install other applications you need to get your work done or simply enjoy your desktop experience more, like installing Steam to play your favourite games.
Model Assertion
We define which of these components get pulled together to create a product as a model assertion. This model declares what snaps to include as well as the identity and signatures necessary to verify the model during initial boot to prepare the installed system and will ensure integrity of the resulting system.
You can think of these components as ingredients for a recipe to define an immutable desktop distribution. Derivatives/Flavours can be created by replacing individual ingredients to create unique experiences.
Fundamentally Ubuntu Core is quite different from a classic Ubuntu system. However, as an OS, it functions the same. From the boot loader, systemd, DBus services, to the desktop environment, they function in much the same way, thanks to snapd.
The Ubuntu Core file system
Let’s talk a little about what the file system looks like and how it’s actually constructed and presented. Each of these components are provided as individual snaps, which are actually compressed, read-only squashfs files which are mounted at runtime. The contents of these snaps will look a bit different depending on your context. For example, the system boots from the boot base snap, which is core22-desktop. This is a minimal environment to create the bootable system. If you look at it during runtime, it will look very much like a classic Ubuntu file system; however it’s really a single read-only file that’s been mounted and exposed via snapd at runtime.
ken@core-desktop:~$ ls -ltr / lrwxrwxrwx 1 root root 8 Aug 1 00:53 sbin -> usr/sbin lrwxrwxrwx 1 root root 10 Aug 1 00:53 libx32 -> usr/libx32 lrwxrwxrwx 1 root root 9 Aug 1 00:53 lib64 -> usr/lib64 lrwxrwxrwx 1 root root 9 Aug 1 00:53 lib32 -> usr/lib32 lrwxrwxrwx 1 root root 7 Aug 1 00:53 lib -> usr/lib lrwxrwxrwx 1 root root 7 Aug 1 00:53 bin -> usr/bin drwxr-xr-x 2 root root 3 Aug 1 00:53 srv drwxr-xr-x 2 root root 3 Aug 1 00:53 opt drwxr-xr-x 5 root root 4096 Aug 1 10:18 writable drwx------ 5 root root 4096 Aug 1 10:20 root drwxr-xr-x 31 root root 4096 Aug 1 10:24 snap drwxr-xr-x 4 root root 4096 Aug 1 10:26 home drwxr-xr-x 14 root root 229 Aug 1 14:42 usr drwxr-xr-x 7 root root 84 Aug 1 14:43 boot drwxrwxr-x 62 root root 2007 Aug 1 14:43 etc drwxr-xr-x 12 root root 171 Aug 1 14:43 var drwxr-xr-x 3 root root 43 Aug 1 14:43 meta dr-xr-xr-x 13 root root 0 Aug 1 14:46 sys dr-xr-xr-x 292 root root 0 Aug 1 14:46 proc drwxr-xr-x 2 root root 40 Aug 1 14:46 host drwxrwxrwt 2 root root 40 Aug 1 14:46 mnt drwxrwxrwt 2 root root 40 Aug 1 14:46 media drwxr-xr-x 17 root root 4480 Aug 1 14:47 dev drwxr-xr-x 26 root root 720 Aug 1 14:55 run drwxrwxrwt 14 root root 320 Aug 1 16:20 tmp
Of course there are parts of the OS that require the ability to edit configuration or runtime data.
ken@core-desktop:~$ ls -ltr /writable/ drwx------ 2 root root 16384 Aug 1 10:17 lost+found drwxr-xr-x 8 root root 4096 Aug 1 10:18 system-data drwxr-xr-x 4 root root 4096 Aug 1 10:26 user-data
Notice the /writable/system-data and /writable/user-data directories. These are used for writable data, like user home directories and system configuration and data that needs to be writable at runtime. The user-data directory is the writable location where user home directories will exist. In this case /writable/user-data/ken is a home directory which is mounted at /home/ken. The system-data dir is writable space for system configuration that needs to be editable. These files and directories will be bind mounted over the top of their read-only versions provided in the squashfs snap. For example, the system hostname can be changed because /writable/system-data/etc/writable/hostname is bind mounted over /etc/hostname.
Thanks for hanging with us for this introduction! The next post in this series will dive deeper into the Ubuntu Desktop Session snap, covering services it provides and some of the challenges we had in construction as a strictly confined snap.