diff options
author | Timothée Ravier <travier@redhat.com> | 2020-10-02 14:34:33 +0200 |
---|---|---|
committer | Timothée Ravier <travier@redhat.com> | 2020-10-02 14:34:48 +0200 |
commit | 68ac9e9c50d0e190a5a82bef5fdea29bd46fdd0a (patch) | |
tree | 57e51adcd58f966a09beae6dd437c3e14a9d2273 /docs/adapting-existing.md | |
parent | 6ca312a92399c92b60d83eae161a8b8ea148989b (diff) | |
download | ostree-68ac9e9c50d0e190a5a82bef5fdea29bd46fdd0a.tar.gz |
docs: Move and update pages from the manual
Diffstat (limited to 'docs/adapting-existing.md')
-rw-r--r-- | docs/adapting-existing.md | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/docs/adapting-existing.md b/docs/adapting-existing.md new file mode 100644 index 00000000..cc4b76d2 --- /dev/null +++ b/docs/adapting-existing.md @@ -0,0 +1,180 @@ +--- +nav_order: 6 +--- + +# Adapting existing mainstream distributions +{: .no_toc } + +1. TOC +{:toc} + +## System layout + +First, OSTree encourages systems to implement +[UsrMove](http://www.freedesktop.org/wiki/Software/systemd/TheCaseForTheUsrMerge/) +This is simply to avoid the need for more bind mounts. By default +OSTree's dracut hook creates a read-only bind mount over `/usr`; you +can of course generate individual bind-mounts for `/bin`, all the +`/lib` variants, etc. So it is not intended to be a hard requirement. + +Remember, because by default the system is booted into a `chroot` +equivalent, there has to be some way to refer to the actual physical +root filesystem. Therefore, your operating system tree should contain +an empty `/sysroot` directory; at boot time, OSTree will make this a +bind mount to the physical / root directory. There is precedent for +this name in the initramfs context. You should furthermore make a +toplevel symbolic link `/ostree` which points to `/sysroot/ostree`, so +that the OSTree tool at runtime can consistently find the system data +regardless of whether it's operating on a physical root or inside a +deployment. + +Because OSTree only preserves `/var` across upgrades (each +deployment's chroot directory will be garbage collected +eventually), you will need to choose how to handle other +toplevel writable directories specified by the [Filesystem Hierarchy Standard](http://www.pathname.com/fhs/). +Your operating system may of course choose +not to support some of these such as `/usr/local`, but following is the +recommended set: + + - `/home` → `/var/home` + - `/opt` → `/var/opt` + - `/srv` → `/var/srv` + - `/root` → `/var/roothome` + - `/usr/local` → `/var/usrlocal` + - `/mnt` → `/var/mnt` + - `/tmp` → `/sysroot/tmp` + +Furthermore, since `/var` is empty by default, your operating system +will need to dynamically create the *targets* of these at boot. A +good way to do this is using `systemd-tmpfiles`, if your OS uses +systemd. For example: + +``` +d /var/log/journal 0755 root root - +L /var/home - - - - ../sysroot/home +d /var/opt 0755 root root - +d /var/srv 0755 root root - +d /var/roothome 0700 root root - +d /var/usrlocal 0755 root root - +d /var/usrlocal/bin 0755 root root - +d /var/usrlocal/etc 0755 root root - +d /var/usrlocal/games 0755 root root - +d /var/usrlocal/include 0755 root root - +d /var/usrlocal/lib 0755 root root - +d /var/usrlocal/man 0755 root root - +d /var/usrlocal/sbin 0755 root root - +d /var/usrlocal/share 0755 root root - +d /var/usrlocal/src 0755 root root - +d /var/mnt 0755 root root - +d /run/media 0755 root root - +``` + +Particularly note here the double indirection of `/home`. By default, +each deployment will share the global toplevel `/home` directory on +the physical root filesystem. It is then up to higher levels of +management tools to keep `/etc/passwd` or equivalent synchronized +between operating systems. Each deployment can easily be reconfigured +to have its own home directory set simply by making `/var/home` a real +directory. + +## Booting and initramfs technology + +OSTree comes with optional dracut+systemd integration code which follows +this logic: + +- Parse the `ostree=` kernel command line argument in the initramfs +- Set up a read-only bind mount on `/usr` +- Bind mount the deployment's `/sysroot` to the physical `/` +- Use `mount(MS_MOVE)` to make the deployment root appear to be the root filesystem + +After these steps, systemd switches root. + +If you are not using dracut or systemd, using OSTree should still be +possible, but you will have to write the integration code. See the +existing sources in +[src/switchroot](https://github.com/ostreedev/ostree/tree/master/src/switchroot) +as a reference. + +Patches to support other initramfs technologies and init systems, if +sufficiently clean, will likely be accepted upstream. + +A further specific note regarding `sysvinit`: OSTree used to support +recording device files such as the `/dev/initctl` FIFO, but no longer +does. It's recommended to just patch your initramfs to create this at +boot. + +## /usr/lib/passwd + +Unlike traditional package systems, OSTree trees contain *numeric* uid +and gids. Furthermore, it does not have a `%post` type mechanism +where `useradd` could be invoked. In order to ship an OS that +contains both system users and users dynamically created on client +machines, you will need to choose a solution for `/etc/passwd`. The +core problem is that if you add a user to the system for a daemon, the +OSTree upgrade process for `/etc` will simply notice that because +`/etc/passwd` differs from the previous default, it will keep the +modified config file, and your new OS user will not be visible. The +solution chosen for the [Gnome Continuous](https://live.gnome.org/Projects/GnomeContinuous) operating +system is to create `/usr/lib/passwd`, and to include a NSS module +[nss-altfiles](https://github.com/aperezdc/nss-altfiles) which +instructs glibc to read from it. Then, the build system places all +system users there, freeing up `/etc/passwd` to be purely a database +of local users. See also a more recent effort from [Systemd Stateless](http://0pointer.de/blog/projects/stateless.html) + +## Adapting existing package managers + +The largest endeavor is likely to be redesigning your distribution's +package manager to be on top of OSTree, particularly if you want to +keep compatibility with the "old way" of installing into the physical +`/`. This section will use examples from both `dpkg` and `rpm` as the +author has familiarity with both; but the abstract concepts should +apply to most traditional package managers. + +There are many levels of possible integration; initially, we will +describe the most naive implementation which is the simplest but also +the least efficient. We will assume here that the admin is booted +into an OSTree-enabled system, and wants to add a set of packages. + +Many package managers store their state in `/var`; but since in the +OSTree model that directory is shared between independent versions, +the package database must first be found in the per-deployment `/usr` +directory. It becomes read-only; remember, all upgrades involve +constructing a new filesystem tree, so your package manager will also +need to create a copy of its database. Most likely, if you want to +continue supporting non-OSTree deployments, simply have your package +manager fall back to the legacy `/var` location if the one in `/usr` +is not found. + +To install a set of new packages (without removing any existing ones), +enumerate the set of packages in the currently booted deployment, and +perform dependency resolution to compute the complete set of new +packages. Download and unpack these new packages to a temporary +directory. + +Now, because we are merely installing new packages and not +removing anything, we can make the major optimization of reusing +our existing filesystem tree, and merely +*layering* the composed filesystem tree of +these new packages on top. A command like this: + +``` +ostree commit -b osname/releasename/description +--tree=ref=$osname/$releasename/$description +--tree=dir=/var/tmp/newpackages.13A8D0/ +``` + +will create a new commit in the `$osname/$releasename/$description` +branch. The OSTree SHA256 checksum of all the files in +`/var/tmp/newpackages.13A8D0/` will be computed, but we will not +re-checksum the present existing tree. In this layering model, +earlier directories will take precedence, but files in later layers +will silently override earlier layers. + +Then to actually deploy this tree for the next boot: +`ostree admin deploy $osname/$releasename/$description` + +This is essentially what [rpm-ostree](https://github.com/projectatomic/rpm-ostree/) +does to support its [package layering model](https://rpm-ostree.readthedocs.io/en/latest/manual/administrator-handbook/#hybrid-imagepackaging-via-package-layering). + +###### Licensing for this document: +`SPDX-License-Identifier: (CC-BY-SA-3.0 OR GFDL-1.3-or-later)` |