-
Notifications
You must be signed in to change notification settings - Fork 0
How a deployment works
The deployment process for a system extension managed by ostree-sysext
can be broken down into the following steps:
Warning
Unless mentioned otherwise, all steps below are assumed to occur in a sandbox separate from the host's mount namespace.
Each plugin on the system gets called via the check_compatible()
function, in order to ascertain that the resulting stack of extensions does not give rise to conflicts.
Note
Example: A hypothetical rpm
plugin is called.
The rpm
plugin scans the package database for the base system, and for each extension, and checks that there are no conflicts.
If different versions of the same package are provided, and do not break the dependency graph, the rpm
plugin votes with CompatVote.WARN
. This blocks the deployment process, but leaves the possibility to use --force
.
If the dependency graph fails, or another fatal error is caused, the rpm
plugin votes with CompatVote.VETO
. This blocks the deployment process and cannot be circumvented.
Once approval is obtained, ostree-sysext
builds the layout for the deployment commit, which keeps track of all applied extensions, under /run/ostree/extensions
.
staged/ # Set of layered extensions
ext-id -> /ostree/extensions/ext-id/deploy/<hash>.0
state/ # Files dependent on the whole layered set, filled by the next step
Certain files need to be generated using the whole set of layered extensions as reference, and cannot be included in one specific extension. Those can be built by plugins during the deployment process, then linked to in the resulting set.
Note
Example 1: The hypothetical rpm
plugin.
RPM uses SQLite as a database to track installed packages. This is a robust, concurrent format but it would not make sense under layering.
In our example, the rpm
plugin builds a new SQLite database by merging entries from the base system and extensions' respective databases, then writes the result to /run/ostree/extensions/state/rpmdb.sqlite
.
Note
Example 2: The initramfs
plugin.
The initramfs is a system component that can depend on files brought from system extensions, such as Plymouth boot themes.
In our example, the initramfs
plugin calls dracut
on the merged extensions set, ensuring that it sees files provided by individual extensions. The result is written to /run/ostree/extensions/state/initramfs.img
.
The /run/ostree/extensions
directory is captured into an OSTree commit ref: ostree-sysext/<osname>/0
and checked out under /ostree/deploy/<osname>/extensions/deploy/<hash>.0
, and the checkout is referred to by a symbolic link /ostree/deploy/<osname>/deploy/<hash>.0.extensions
, ensuring the extensions are restored when the system is booted.
Our new commit is checked out to /run/ostree/extensions
on the host system. This has the effect of updating stateful files built above.
Important
The implementation details for this are subject to change. One approach would be to consider /run/ostree/extensions/state
as a system extension in and of itself.
Symbolic links (or composefs
mount points) under /run/extensions
are updated to reflect the new extension set.
systemd-sysext refresh
is called, which scans /run/extensions
and applies our new extension set. The deployment is now finished.