ostree/docs/manual/deployment.md
Colin Walters 3ab0d5e664 lib/sysroot: Support /usr/lib/modules/$kver for kernel/initramfs
This is the new Fedora kernel standard layout; it has the advantage
of being in `/usr` like `/usr/lib/ostree-boot`, but it's not OSTree
specific.

Further, I think in practice forcing tree builders to compute the checksum is an
annoying stumbling block; since we already switched to e.g. computing checksums
always when doing pulls, the cost of doing another checksum for the
kernel/initramfs is tiny. The "bootcsum" becomes more of an internal
implementation detail.

Now, there is a transition; my current thought for this is that rpm-ostree will
change to default to injecting into both `/usr/lib/ostree-boot` and
`/usr/lib/modules`, and stop doing `/boot`, then maybe next year say we drop the
`/usr/lib/ostree-boot` by default.

A twist here is that the default Fedora kernel RPM layout (and what's in
rpm-ostree today) includes a kernel but *not* an initramfs in
`/usr/lib/modules`. If we looked only there, we'd just find the kernel. So we
need to look in both, and then special case this - pick the legacy layout if we
have `/usr/lib/modules` but not an initramfs.

While here, rework the code to have an `OstreeKernelLayout` struct which makes
dealing with all of the variables nicer.

Closes: #1079
Approved by: jlebon
2017-08-18 17:34:36 +00:00

4.7 KiB

Deployments

Overview

Built on top of the OSTree versioning filesystem core is a layer that knows how to deploy, parallel install, and manage Unix-like operating systems (accessible via ostree admin). The core content of these operating systems are treated as read-only, but they transparently share storage.

A deployment is physically located at a path of the form /ostree/deploy/$stateroot/deploy/$checksum. OSTree is designed to boot directly into exactly one deployment at a time; each deployment is intended to be a target for chroot() or equivalent.

"stateroot" (AKA "osname"): Group of deployments that share /var

Each deployment is grouped in exactly one "stateroot" (also known as an "osname"); the former term is preferred.

From above, you can see that an stateroot is physically represented in the /ostree/deploy/$stateroot directory. For example, OSTree can allow parallel installing Debian in /ostree/deploy/debian and Red Hat Enterprise Linux in /ostree/deploy/rhel (subject to operating system support, present released versions of these operating systems may not support this).

Each stateroot has exactly one copy of the traditional Unix /var, stored physically in /ostree/deploy/$stateroot/var. OSTree provides support tools for systemd to create a Linux bind mount that ensures the booted deployment sees the shared copy of /var.

OSTree does not touch the contents of /var. Operating system components such as daemon services are required to create any directories they require there at runtime (e.g. /var/cache/$daemonname), and to manage upgrading data formats inside those directories.

Contents of a deployment

A deployment begins with a specific commit (represented as a SHA256 hash) in the OSTree repository in /ostree/repo. This commit refers to a filesystem tree that represents the underlying basis of a deployment. For short, we will call this the "tree", to distinguish it from the concept of a deployment.

First, the tree must include a kernel (and optionally an initramfs). The current standard locations for these are /usr/lib/modules/$kver/vmlinuz and /usr/lib/modules/$kver/initramfs. The "boot checksum" will be computed automatically. This follows the current Fedora kernel layout, and is the current recommended path. However, older versions of libostree don't support this; you may need to also put kernels in the previous (legacy) paths, which are vmlinuz(-.*)?-$checksum in either /boot or /usr/lib/ostree-boot. The checksum should be a SHA256 hash of the kernel contents; it must be pre-computed before storing the kernel in the repository. Optionally, the directory can also contain an initramfs, stored as initramfs(-.*)?-$checksum. If this exists, the checksum must include both the kernel and initramfs contents. OSTree will use this to determine which kernels are shared. The rationale for this is to avoid computing checksums on the client by default.

The deployment should not have a traditional UNIX /etc; instead, it should include /usr/etc. This is the "default configuration". When OSTree creates a deployment, it performs a 3-way merge using the old default configuration, the active system's /etc, and the new default configuration. In the final filesystem tree for a deployment then, /etc is a regular writable directory.

Besides the exceptions of /var and /etc then, the rest of the contents of the tree are checked out as hard links into the repository. It's strongly recommended that operating systems ship all of their content in /usr, but this is not a hard requirement.

Finally, a deployment may have a .origin file, stored next to its directory. This file tells ostree admin upgrade how to upgrade it. At the moment, OSTree only supports upgrading a single refspec. However, in the future OSTree may support a syntax for composing layers of trees, for example.

The system /boot

While OSTree parallel installs deployments cleanly inside the /ostree directory, ultimately it has to control the system's /boot directory. The way this works is via the Boot Loader Specification, which is a standard for bootloader-independent drop-in configuration files.

When a tree is deployed, it will have a configuration file generated of the form /boot/loader/entries/ostree-$stateroot-$checksum.$serial.conf. This configuration file will include a special ostree= kernel argument that allows the initramfs to find (and chroot() into) the specified deployment.

At present, not all bootloaders implement the BootLoaderSpec, so OSTree contains code for some of these to regenerate native config files (such as /boot/syslinux/syslinux.conf) based on the entries.