There has been much talk about modularity recently. Fedora even has a working group on this topic. Modularity is such a generic term that it is a bit hard to figure out what this is all about, but the wiki page gives some hints: …base module… …docker image… …reduced dependencies… …tooling…
A very high-level reading would be that this is about defining tools and processes to deliver software in modules, which can be larger units than packages, and e.g. come in the form of container images.
Another reading would be that this is an effort to come to grips with the changing role of distributions in a world were containers are the dominant way to run and deploy applications.
Modularity on the desktop
In this post, I want to look at how this modularity effort looks from the desktop perspective, and what we are doing in this area.
Our main goal for a while has been to make it easier to get desktop applications from application developers to users.
In the traditional Linux distribution world, this is a total nightmare: Once you’ve written your application, you need to either learn how to create an Ubuntu .deb, an Arch .pkg, a Fedora .rpm, to name just a few, and then follow lengthy processes to get your packages accepted into these distributions.
And once you’ve done all that, you will get bug reports that your application is broken with the one or other version of one of your dependencies. If not right away, then a few months down the road when the distributions move on to the latest and greatest releases. So, keeping those packages working requires the constant attention of a package maintainer.
To improve on this sad state of affairs, we need to make applications much less dependent on the OS they run on, and on the libraries that happen to come with the OS.
At this point, you might say: Aha, you want to bundle dependencies! Yes, but read on. Bundling is a bad word in the traditional distribution world. It implies duplication, since multiple applications may bundle the same library. And having multiple copies of the same library (possibly different versions, too), makes it harder to ensure that bug and security fixes get applied to all the copies. Not to mention that all the duplication consumes bandwidth when you have to download it all.
Bundling everything with the application certainly has its drawbacks. But there are several things we can do to preserve most of the benefits of bundling, while avoiding the worst of the problems.
One takeaway from the modularity discussions mentioned earlier is that going to larger units than individual packages (ie modules) has advantages: we thin out the dependency graph, and we get a large piece of functionality that can be tested, installed and updated as a unit.
And we can use a smart storage and transport mechanism such as OSTree to limit the impact that duplication has on bandwidth.
Desktop applications commonly depend on similar sets of libraries: the GTK+ stack is a good example, kdelibs is another. Treating these common library stacks as modules makes a lot of sense. We decided to call these modules runtimes. Applications can declare a single dependency on the runtime they need, and get a well-defined set of APIs and libraries in return.
What if you need a library that is not in the runtime ? In that case, you can still bundle it with your application. You will be reponsible for the libraries that you bundle, but in return your users get exactly the version that you’ve tested your app with.
By decoupling the runtimes from the OS and by making them available in the same way as the applications, we make it possible to have applications that can run on different distributions, regardless of the library versions that are included in the OS. Of course, there is limits to what we can achieve: the applications and runtimes still have requirements (e.g. on Linux kernel features, or on session services that are expected to be present). But building an application that can run on Fedora, Ubuntu, Arch, RHEL and other modern distributions is entirely possible.
But what about security updates? To make this system work, we need to offer well-maintained runtimes that application authors can rely on, and provide updates for them just as we do now with distribution packages.
But that is not enough. We also need to isolate applications from the rest of the system (and your data!) at runtime, in order to limit the damage that they can do. Historically, the Linux desktop has been really bad about this: X lets any client snoop all input, and applications are generally free to read whatever they find in your home directory. Part of our desktop modularity story is to use container technologies and e.g. Wayland to confine (or sandbox) applications at runtime.
We have been working towards this goal for quite a while, with the Wayland port and gnome-software as a non-package-centric installer.
What I’ve outlined above is more or less the architecture of the Flatpak system (formerly known as xdg-app). It is not 100% fleshed out yet, but enough pieces are in place now that you can try it out and e.g. install a nightly build of libreoffice that works on both Fedora and Ubuntu.
Head over to www.flatpak.org to learn more.