rpm-ostree Documentation

repository·main·Indexed 21 days ago

https://github.com/coreos/rpm-ostree

A hybrid image/package system merging image-based deployments via libostree with traditional RPM package management via libdnf. It provides transactional, versioned, and rollbackable operating system images with capabilities for package layering, base image overrides, and live updates via apply-live and usroverlay. Designed around an immutable /usr directory, it ensures system reproducibility by regenerating the target filesystem tree from scratch during updates.

Tokens
27.1K
Snippets
72
Records
112
Agent score
76%

What's inside rpm-ostree

  1. What is rpm-ostree?

    main

    rpm-ostree is a hybrid image/package system that combines the libostree base image format with RPM package management. It allows for transactional, versioned, and checksummed upgrades using either bootable container images or an 'ostree native' HTTP model.

    Key capabilities include:

    • Transactional Upgrades: Background image-based upgrades.
    • OS Rollback: Reverting the OS state without affecting user data in /etc or /var (it targets /usr).
    • Package Layering: Adding individual packages or overrides on top of a base image on the client side.
    • Custom Base Images: Creating custom images via rpm-ostree compose image (using containers) or rpm-ostree compose tree (using ostree repositories).
  2. Understand the rpm-ostree source code structure

    main

    The rpm-ostree source code is organized into several key functional areas:

    • src/app: The rpm-ostree CLI application.
    • src/daemon: The rpm-ostree daemon, which provides the D-Bus API.
    • src/lib: The public library containing APIs for exploring the rpmdb in OSTrees.
    • src/libpriv: A private API shared specifically between the app and the daemon components.
    .
    └─ src
      ├── app                       rpm-ostree CLI application
      ├── daemon                    rpm-ostree daemon providing D-Bus API
      ├── lib                       Public library: contains APIs for exploring rpmdb in OSTrees
      └── libpriv                   Private API shared between app and daemon
  3. Locate rpm-ostree documentation and man pages

    main

    Documentation for the project is distributed across several locations:

    • docs/: General documentation for the repository.
    • man/: Man pages for the rpm-ostree command.
    • HACKING.md: Information specifically for developers looking to contribute or modify the codebase.
  4. What is a treefile?

    main
    A treefile is a JSON or YAML-formatted specification used as input to the rpm-ostree compose tree command. It serves as a manifest that binds a specific set of RPM packages and configurations to an OSTree commit. It is recommended to manage treefiles in version control (like Git) and use a CI system (like Jenkins) to automate builds whenever they change.
  5. How DNF Count Me works on rpm-ostree

    main

    The DNF Count Me feature allows systems to anonymously report uptime to help improve package management. While classic DNF-based systems include a countme variable in RPM repository metadata requests, rpm-ostree systems do not fetch this metadata by default (unless a package overlay is present).

    Instead, rpm-ostree implements this functionality via a standalone timer called rpm-ostree-countme.timer. This timer triggers automatically after 5 minutes following a boot, and then bi-weekly. In both instances, the timer executes with a random delay to preserve anonymity.

  6. How rpm-ostree handles kernel and initramfs

    main

    In rpm-ostree, a bootable deployment is defined as the pair of a (kernel, userspace).

    • Single Kernel: Unlike dnf which may keep multiple kernels via installonly, rpm-ostree maintains exactly one kernel per userspace filesystem tree.
    • Initramfs Generation: rpm-ostree manages initramfs regeneration (via dracut) as a controlled, transactional process. If a kernel is replaced or if client-side regeneration is enabled, rpm-ostree runs dracut inside a container to generate the CPIO archive, which is then placed in /usr/lib/modules/$kver.
  7. Authorization via Polkit

    main

    The rpm-ostree daemon uses polkit to authorize system mutations. When a client calls a D-Bus method (like Upgrade()), the daemon converts that call into a polkit action via os_authorize_method and consults the polkit framework to decide if the user has permission.

    • Policy Files: The project includes a base policy file (org.projectatomic.rpmostree1.policy) defining available actions.
    • Distro Customization: Distributions may extend these rules (e.g., Fedora uses org.projectatomic.rpmostree1.rules) to allow authorization based on specific criteria like group membership.
  8. Behavior of wrapped commands (rpm, dracut, grubby, dnf)

    main

    When cliwrap is active, rpm-ostree intercepts certain commands to provide redirection or safer execution.

    rpm

    rpm-ostree wraps the rpm binary. If arguments are deemed "not known safe," rpm-ostree may drop privileges before executing. If you need to bypass the wrapper and use the real binary, it is located at /usr/libexec/rpm-ostree/wrapped/rpm.

    dracut

    Intercepts dracut calls and instructs users to use rpm-ostree initramfs for initramfs generation, as it is integrated with the OSTree transaction mechanism.

    grubby

    Intercepts grubby calls and instructs users to use rpm-ostree kargs instead.

    yum/dnf

    • dnf update is translated to rpm-ostree update.
    • Other commands (like dnf install) are currently not implemented and will print a suggestion to use toolbox, podman, docker, or rpm-ostree install for layered packages.
  9. How rpm-ostree manages /var content

    main

    To separate the OS from machine-local state, rpm-ostree automatically synthesizes systemd tmpfiles.d snippets from directories found in /var.

    • Behavior: Directories in /var will be recreated on boot. This facilitates "factory reset" scenarios by allowing the wiping of /var without losing the OS structure.
    • Limitation: Currently, any non-directory items (regular files or symbolic links) in /var are discarded during this process.
  10. How apply-live works in rpm-ostree

    main

    The apply-live mechanism allows applying updates to the running system without a reboot by using a transient overlayfs mount over /usr.

    When you run a command like rpm-ostree install --apply-live <package>, the following lifecycle occurs:

    1. Deployment Creation: A new pending deployment is created and sanity-tested.
    2. Overlay Setup: On the first invocation, an overlayfs is mounted over /usr. This mount is read-only (ro) for the rest of the system but writable by rpm-ostree.
    3. Diff Computation: rpm-ostree computes a filesystem diff for /usr between the source commit (the booted commit on first run, or the current live commit on subsequent runs) and the target commit. It also computes a package-level diff to distinguish between additions and upgrades.
    4. Applying /usr: The filesystem diff is applied to the transient writable overlayfs.
    5. Applying /etc: Unlike standard updates where /etc merges happen at shutdown, apply-live performs the merge immediately to ensure new or removed configuration files are available. Note: Changes to /etc are persistent and not transactional; a partially applied update may cause configuration files to "leak."
    6. Applying /var: To handle directories in /var defined by RPM packages, rpm-ostree starts a transient systemd unit to run systemd-tmpfiles immediately.
    7. State Tracking: Because the overlayfs is transient and disappears on reboot, state is tracked via a stamp file in /run/ostree/deployment-state/$deployid/ and a persistent OSTree ref rpmostree/live-apply.
    rpm-ostree install --apply-live strace
  11. Inject metadata into container-derived OSTree commits

    main

    When a container image is converted to an OSTree commit, container-specific metadata (such as the version label) is not automatically mapped to OSTree commit metadata.

    To include this metadata in your OSTree deployment, you should create a new derived commit that reuses the content from the base container commit but allows for custom metadata injection using the --tree flag.

    # Create a new commit derived from the container base to inject metadata
    ostree commit --tree=ref=$base