Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: Add apply-live #2655

Merged
merged 1 commit into from
Mar 12, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions docs/apply-live.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
---
nav_order: 6
---

# Architecture of apply-live
{: .no_toc }

1. TOC
{:toc}

## Copying into an "underlay"

As noted in the architecture doc, everything in rpm-ostree is oriented
around creating and managing hardlinked complete bootable filesystem trees.

In this flow then, `rpm-ostree install --apply-live strace` will first
create a new pending deployment, run sanity tests on it, prepare it to be booted, etc.

However, the first time `apply-live` is invoked, we create an `overlayfs`
mount over `/usr`. It's mounted `ro` from the perspective of the rest
of the system, but rpm-ostree can write to it.

## Package and filesystem diffs

When `apply-live` is invoked, rpm-ostree computes the diff between
the source and target OSTree commit for `/usr`. If this is the *first* `apply-live`,
the source commit is the booted commit. For subsequent invocations,
it will be based on the current live commit.

We also compute a package-level diff; this is how `apply-live`
currently distinguishes between pure package additions versus upgrades.

## Copying data for /usr

Per the core OSTree model, almost everything we care about is in `/usr`.
So the first step is to apply the diff to the transient writable `overlayfs`.

One downside is that that this diff will take extra memory and disk space
proportional to its size.

## Updating /etc

The second aspect we need to take care of is `/etc`. Normally, the libostree
core handles the `/etc` merge during shutdown as part of `ostree-finalize-staged.service`,
but we need to do it now in order to ensure that we get new config files
(or remove ones).
Comment on lines +41 to +46
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, is there a gap here? If we fiddle with /etc, then the changes are not actually completely transient, and we may accumulate cruft in /etc which never goes away (e.g. if you then rpm-ostree cleanup -p because you actually just wanted to install a debug package you never intended to permanently overlay).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, this is absolutely an issue, but mostly mitigated by the fact that what we're stabilizing so far is rpm-ostree install -A in which case the admin is expressing the desire for the changes to persist.

If we added something like rpm-ostree install --transient this would be more of an issue.

I added a blurb on this.


Note that the changes in `/etc` are persistent, live-applied changes there are
also hence not updated transactionally. It is hence possible for configuration
files to "leak" from partially applied live updates.

## Updating /var

Normally, libostree core never touches `/var`. Today rpm-ostree generates
`systemd-tmpfiles` snippets for RPM packages which contain directories in
`/var`. In a regular update, these will hence be generated at boot
time by `systemd-tmpfiles-setup.service`.

But here, we need to do this live. So rpm-ostree directly starts a
transient systemd unit running `systemd-tmpfiles`.

## Tracking live state

Because the `overlayfs` is transient (goes away on reboot), the `apply-live`
operation also writes its state into the transient `/run` directory, specifically
a stamp file is stored at `/run/ostree/deployment-state/$deployid/`.

Currently, there is also a persistent ostree ref `rpmostree/live-apply` for
the current live commit. Eventually the goal is that libostree itself would
gain direct awareness of live apply, and we wouldn't write a persistent ref.