Ubuntu is a general-purpose, free-as-in-speech, zero-cost operating system based on Debian GNU/Linux, designed for use on desktops, laptops, servers, and mobile devices. The project is committed to a regular six-monthly release schedule, security updates for 9 months after release (or longer for Long Term Support releases), and to providing a single installation CD with further packages available for download. All of these commitments have an effect on its overall architecture. This page sketches the main architectural features of Ubuntu, in order that ongoing development work can be designed in a consistent and elegant fashion.
For more detail on the processes involved here, see UbuntuDevelopment.
- There should be exactly one recommended way to accomplish a task in the default installation, to promote consistent documentation and support
- Applications should work immediately upon installation, without requiring additional steps, whenever possible. This "instant gratification" makes users more productive and allows them to explore the software choices available
- Features should be easily discoverable, or they will go unused
The system should fit on a single CD, to make it available to the widest audience (no longer valide since ubuntu 12.10)
Dialogs should conform to the GNOME Human Interface Guidelines (HIG) to promote ease of use
- User-visible text should be written in plain language so that non-technical users can understand what the system is telling them
Ubuntu packages are created in the Debian format. That is, source packages consist of a .dsc control file, plus either a .tar.gz tarball or an .orig.tar.gz tarball plus a .diff.gz patch, while binary packages are .deb files (or .udeb files for specialised use by the installer). For further information, see the dpkg manual pages and the Debian policy manual's sections on binary and source packages.
The Ubuntu policy manual applies, and is maintained collaboratively by the Ubuntu core developers. It is derived from the Debian policy manual, and technical standards are similar to those in Debian. Different standards apply to some subsystems.
Ubuntu-specific changes are logged in debian/changelog as usual, with ubuntu1, ubuntu2, etc. being appended to the version number, or -0ubuntu1 appended to the upstream version in the event that a new upstream release is needed in Ubuntu. The presence of ubuntu in a version number means that the package will not be automatically synced from Debian, and must have changes merged by hand.
Ubuntu was originally initialised by taking a copy of Debian unstable, and new versions are merged from Debian at the start of every Ubuntu release cycle in order to be able to make good use of the expertise and effort available in the Debian development community. Ubuntu developers are expected to bear this process in mind when making changes.
The Ubuntu archive is a Debian-style pooled package repository. The entries in the dists tree are divided into one set of entries per Ubuntu release, with one entry per "pocket" (the main release, security updates, general updates, proposed general updates, and backports of new features). A new development tree is created every six months, and all routine development work takes place in the current development branch. Stable releases receive updates from time to time for severe problems, but as a general rule stable releases are best kept stable simply by not changing them unless absolutely necessary. As such, great effort goes into ensuring that each release is as high-quality as possible by its release date, and the release cycle is structured around an initial flurry of invasive feature development moving through to an atmosphere of great caution and conservative bug-fixes.
At the beginning of each release cycle, the new development branch is resynchronised with the current contents of Debian unstable, and other relevant "upstream" projects (i.e. those from which Ubuntu draws code). Packages that have not been changed in Ubuntu are updated semi-automatically by one of the archive administration team; others must be merged by hand.
Normal developer uploads to Ubuntu consist of source packages only. The upload of a source package and its acceptance into the archive cause build daemons for each architecture to fetch the source and build binary packages, which are in turn uploaded automatically to the archive if successfully built.
Occasionally, builds with circular build-dependencies must be bootstrapped by hand (e.g. new architectures, compilers and language runtimes, etc.). This task must be performed by hand by a build administrator, usually repeating the build process more than once in order to ensure that the new packages can continue to build themselves.
Flavours and Derivatives
The modern Linux world is one of a small number of general-purpose distributions and many special-purpose distributions. Ubuntu acknowledges this and strives to support it. We define two different levels of derivation. A "flavour" is one hosted within the Ubuntu archive, which requires that it must draw from the same pool of packages and so cannot make incompatible or go-it-alone changes, but may select a different set of packages. A full "derivative" may make more extensive changes, but must provide its own archive hosting.
As it turns out, flavours are quite adequate for many purposes. Kubuntu, Edubuntu, and Xubuntu all make extensive changes to their own specialised packages. Gobuntu is very similar to Ubuntu but removes packages with restrictive licensing terms (Ubuntu does not support many of these, but makes exceptions for items like firmware).
Acknowledging the prevalence and usefulness of derivation, packages in the Ubuntu archive should generally avoid explicit user-visible Ubuntu branding.
When the Ubuntu project started, the founding developers were faced with a huge selection of packages from the Debian archive out of which to build Ubuntu. Among their considerations were ensuring that the main supported set of packages was reasonably secure and sufficiently stable that it would be possible to support them for 18 months after release; avoiding excessive duplication; selecting a set of packages known to be widely useful; allowing users to install without excessive amounts of manual configuration; and maintaining a level of quality and standards-compliance such that developers could do efficient work across the distribution. These considerations live on in the UbuntuMainInclusionRequirements. Packages which have not been selected for the main supported set are available from the universe and multiverse components of Ubuntu, and may be promoted to main or restricted (according to their licensing terms) if they are necessary and meet the requirements.
It quickly became necessary to maintain a list of those packages which had been selected for Ubuntu main, and the reasons why they were selected; thus the seeds were created, and the germinate program to expand their dependencies into full lists of packages. The initial seed list was base (the minimum set of packages required to run an Ubuntu system), desktop (the set installed in a default Ubuntu desktop installation), and supported (everything else in main). Nowadays, every object (CD/DVD images, live filesystems, various installation profiles) built from the Ubuntu archive has a corresponding set of seeds listing the packages it contains; the seeds and germinate are essential components of the Ubuntu archive and CD image building systems.
The seeds are stored in Bazaar branches, one per flavour.
Quick and straightforward installation is tremendously important to Ubuntu, as is the ability to build installation images with a minimum of human intervention. We support two basic installer designs:
The "alternate" installer was the only supported installation mechanism up to and including Ubuntu 5.10, and is still supported as a secondary mechanism for desktop installs and as the primary mechanism for server installs. It starts with a small self-hosting initial ramdisk which is capable of using extra .udeb packages to build up its capabilities at run-time, like a miniature Linux distribution. It then builds a functional base system on the target system from individual .deb packages using debootstrap, and goes on from there to install extra packages appropriate for the installation profile (desktop, server, etc.).
- The "desktop" installer was introduced in Ubuntu 6.06, and is now the primary mechanism promoted for use by desktop users. It runs from a live CD, and operates by copying the contents of the live filesystem to the target system and then making small configuration adjustments to it.
The live filesystem itself is produced by the livecd-rootfs package, using debootstrap to build a base system and then installing desktop packages on top of that; the casper package deals with booting the live filesystem and making the necessary small number of tweaks at run-time in order for it to function well as a live CD.
Thus, all Ubuntu installations start out with an invocation of debootstrap, directly or indirectly. debootstrap itself installs all packages with Priority: required or Priority: important, which are set from the expansions of the required and minimal seeds respectively. The remaining packages are typically installed using either binaries from *-meta source packages (ubuntu-meta, kubuntu-meta, etc.), or using Task fields. Both of these are generated automatically or semi-automatically from the corresponding seeds.
The upshot is that seed changes are typically propagated to installation images with at most an updated upload of *-meta.
The boot process of an Ubuntu system starts with the boot loader (typically GRUB) which loads the kernel and an initial ramdisk (initramfs). The initramfs sets up the console, usually including a splash screen, starts the udev daemon to process device events from the kernel, finds and mounts the root filesystem, and chains to it, mounting some important virtual filesystems along the way.
Once the root filesystem is mounted, upstart takes over as PID 1, and begins to start tasks specified in /etc/init/. While this will change in the future, at the moment these tasks are essentially shims for System V init scripts and runlevels, defined in /etc/rc*.d/. In the default configuration, upstart runs the contents of /etc/rcS.d/, which sets up hardware and filesystems, and then runs the contents of /etc/rc2.d/, which starts a variety of system services.
In a desktop installation, one of the services launched is an X display manager, which presents a login screen. Otherwise, the user may log in on a virtual console using one of the getty instances started by upstart.