Skip to content
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
22 changes: 19 additions & 3 deletions docs/user-guide/10-depsolving.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ Depsolving is how we often refer to the act of resolving package dependencies. I

Throughout this document, when referring to Image Builder, we mean the whole family of projects under the osbuild / Image Builder umbrella (https://github.com/osbuild). When referring to _the depsolver_, we mean the software that interfaces with the package manager in order to resolve the set of packages required for a build.

There is currently only one production-ready depsolver, [osbuild-depsolve-dnf](https://github.com/osbuild/osbuild/blob/main/tools/osbuild-depsolve-dnf). It uses the Python API to DNF (libdnf) to receive depsolve requests and returns lists of packages that satisfy the requested dependencies. A second depsolver for [Pacman](https://wiki.archlinux.org/title/Pacman) (the Arch Linux Package Manager) can be found as part of [osbuild-mpp](https://github.com/osbuild/osbuild/blob/main/tools/osbuild-mpp), however that is not fully featured and is currently only used for development and testing.
There is currently only one production-ready depsolver, [osbuild-depsolve-dnf](https://github.com/osbuild/osbuild/blob/main/tools/osbuild-depsolve-dnf). It uses the Python API to DNF (libdnf) to receive depsolve requests and returns lists of packages that satisfy the requested dependencies. The depsolver supports two backends, libdnf and the newer libdnf5 (controlled by the config file at `/usr/lib/osbuild/solver.json`). By default, the older libdnf is used, but both should produce the same results. The main difference between the two is that libdnf5 does not support [module streams](https://docs.fedoraproject.org/en-US/modularity/using-modules/).

A second depsolver for [Pacman](https://wiki.archlinux.org/title/Pacman) (the Arch Linux Package Manager) can be found as part of [osbuild-mpp](https://github.com/osbuild/osbuild/blob/main/tools/osbuild-mpp), however that is not fully featured and is currently only used for development and testing.

## Navigating this document

Expand All @@ -32,6 +34,7 @@ The general format of a depsolve request is as follows:
```json
{
"command": "depsolve",
"api_version": 2,
"arch": "x86_64",
"module_platform_id": "platform:f43",
"releasever": "43",
Expand Down Expand Up @@ -62,6 +65,8 @@ The general format of a depsolve request is as follows:
```
We will be using requests like this to demonstrate problems and their solutions.

As of this writing, the latest API version for the depsolver API is `2`. The format of the request and the API version may change.

## Background

### Image definitions and layering
Expand Down Expand Up @@ -108,6 +113,7 @@ In reality, the request to `osbuild-depsolve-dnf` will look similar to this:
```json
{
"command": "depsolve",
"api_version": 2,
"arch": "x86_64",
"module_platform_id": "platform:f43",
"releasever": "43",
Expand Down Expand Up @@ -155,6 +161,7 @@ Continuing from our example above, the following request, which would occur if a
```json
{
"command": "depsolve",
"api_version": 2,
"arch": "x86_64",
"module_platform_id": "platform:f43",
"releasever": "43",
Expand Down Expand Up @@ -206,6 +213,7 @@ A straightforward way to avoid excluded packages from creating problems with Blu
```json
{
"command": "depsolve",
"api_version": 2,
"arch": "x86_64",
"module_platform_id": "platform:f43",
"releasever": "43",
Expand Down Expand Up @@ -235,6 +243,7 @@ A straightforward way to avoid excluded packages from creating problems with Blu
}
{
"command": "depsolve",
"api_version": 2,
"arch": "x86_64",
"module_platform_id": "platform:f43",
"releasever": "43",
Expand Down Expand Up @@ -266,6 +275,7 @@ However, separating the requests this way can cause other problems. One major is
```json
{
"command": "depsolve",
"api_version": 2,
"arch": "x86_64",
"module_platform_id": "platform:f43",
"releasever": "43",
Expand Down Expand Up @@ -296,6 +306,7 @@ However, separating the requests this way can cause other problems. One major is
}
{
"command": "depsolve",
"api_version": 2,
"arch": "x86_64",
"module_platform_id": "platform:f43",
"releasever": "43",
Expand Down Expand Up @@ -334,6 +345,7 @@ Chain dependency solving ([osbuild/osbuild-composer PR#2568](https://github.com/
```json
{
"command": "depsolve",
"api_version": 2,
"arch": "x86_64",
"module_platform_id": "platform:f43",
"releasever": "43",
Expand Down Expand Up @@ -362,7 +374,8 @@ Chain dependency solving ([osbuild/osbuild-composer PR#2568](https://github.com/
{
"package-specs": [
"osbuild"
]
],
"install_weak_deps": false
}
]
}
Expand All @@ -377,10 +390,12 @@ The sequence above can be repeated for an arbitrary number of transactions.
This process is equivalent to the **package selection** part of running the following in an empty root tree (e.g. with `--installroot`):
```console
dnf install @core selinux-policy-targeted --exclude=firewalld
dnf install osbuild
dnf install --setopt=install_weak_deps=False osbuild
```
It solves the problem described in [Depsolve Blueprint packages separately](#depsolve-blueprint-packages-separately). When the second transaction is resolved, it is asking dnf to return the dependencies of `osbuild` under the assumption that `@core`, `selinux-policy-targeted`, and their dependencies are installed. The result of the second transaction will therefore also include `osbuild-selinux` because `selinux-policy-targeted` is part of the existing installed set.

Note the addition of `"install_weak_deps": false` in the second transaction. The depsolve request adds this option to the request for all user-selected packages. Blueprint package selection does not allow for excluding packages, so by disabling weak dependencies in this transaction, we allow users to select exactly the packages they need, with their dependencies, without needing to exclude any packages that might be selected, not required, and not desired.

For a thorough and much more technical investigation into different approaches to multi-transaction depsolving and the behaviour of each in different scenarios, Tomáš Hozza's experiments, which lead to the implementation described here, are available to see on GitHub ([thozza/dnf-api-depsolving](https://github.com/thozza/dnf-api-depsolving)).

### Multi-stage installation
Expand All @@ -397,6 +412,7 @@ When resolving dependencies with a set of packages marked as _installed_, descri
```json
{
"command": "depsolve",
"api_version": 2,
"arch": "x86_64",
"module_platform_id": "platform:f43",
"releasever": "43",
Expand Down