The DNF5 implementation has known issues, which are not yet fixed and in
some cases, they can't be fixed due to the limitations and state of the
DNF5 implementation itself. Skip them for now.
Signed-off-by: Tomáš Hozza <thozza@redhat.com>
Add a test case for installation of a package, which is excluded in a
different transaction. This is a common scenario in osbuild-composer,
where the image base package set is depsolved in the first transaction
and can contain package excludes. The user must be able to install these
excluded packages when specified explicitly in the Blueprint.
Signed-off-by: Tomáš Hozza <thozza@redhat.com>
Add a test case for depsolving a package group with specific optional
packages of the group being excluded. This is a common scenario in
many image definitions.
Signed-off-by: Tomáš Hozza <thozza@redhat.com>
Add a test case, that the repositories not enabled for a transaction are
not really used to depsolve its package specs. This is a common use case
for osbuild-composer, where the custom repositories specified by the
user are enabled only for the second transaction and not for the first
one (when depsolving the image base package set). This is important, so
that the user can't possibly replace important packages shipped by
the "system" repositories (e.g. kernel, systemd, etc.) with versions
from their custom repositories.
Signed-off-by: Tomáš Hozza <thozza@redhat.com>
Fix a bug in the `osbuild-depsolve-dnf`, which would cause the
`RepoError` to not be handled and producing a traceback.
Signed-off-by: Tomáš Hozza <thozza@redhat.com>
Implement the generator for repo config combinations, instead of
hard-coding it. The motivation is to be able to optionally add e.g.
q broken repo to the list to test `RepoError`.
Signed-off-by: Tomáš Hozza <thozza@redhat.com>
Porting the latests osbuild version in `osbuild/images` revealed a
regression in error messages returned by the tool in case a non-existent
package is requested in the depsolve request.
Test that requesting a non-existent package results in `MarkingErrors`,
which was the original behavior of the DNF4-based
`osbuild-depsolve-dnf`.
Signed-off-by: Tomáš Hozza <thozza@redhat.com>
Remove one test case, which does not really add value or extend the test
coverage, since the same thing is already tested by previous test case.
Signed-off-by: Tomáš Hozza <thozza@redhat.com>
Until now, the unit test tested only very simple case with a single
transaction, which happens only for vanilla images. Any user
customization would result in multiple transactions in the depsolve
request. This case is not yet tested at all.
Signed-off-by: Tomáš Hozza <thozza@redhat.com>
Modify the function that executes the depsolve command, so that does not
produce exception in case the command fails. Instead, return the message
returned by `osbuild-depsolve-dnf` and the exit code. This will allow to
test also other scenarios (such as depsolve errors) in the test case.
Signed-off-by: Tomáš Hozza <thozza@redhat.com>
This commit includes the used sovler in the dnfjson reply. This
is mostly information (e.g. in service logs) but also useful in
tests to ensure that the expected solver was really run.
Note that this needs https://github.com/osbuild/images/pull/723
first.
This moves the dnf and dnf5 code into a new osbuild module called
solver. The dnf specific code is in dnf.py and dnf5 is in dnf5.py
At runtime the osbuild-depsolve-dnf script reads a config file from
/usr/lib/osbuild/solver.json and imports the selected solver. This
currently just contains a 'use_dnf5' bool but can be extended to support
other configuration options or depsolvers.
At build time a config file is selected from tools/solver-dnf.json or
tools/solver-dnf5.json and installed. Currently dnf5 is not installed,
it will be added when dnf5 5.2.1.0 becomes available in rawhide (Fedora
41).
The error messages have been normalized since the top level functions in
osbuild-depsolve-dnf do not know which version of dnf is being used.
This commit allows to the user to define the "container-transport"
variable when they are defining a container image to be resolved by the
osbuild-mpp tool. When the user defines the "container-storage" as
"container-transport" osbuild-mpp will look for the image in the local
container-storage.
Signed-off-by: Roberto Majadas <rmajadas@redhat.com>
The `tree-diff` tool is used by the `gen-stage-diff` tool to generate
the stage `diff.json` files. A few of these stages have timestamped
files that need to be edited after the tool is run to replace the
`sha256` content hash with `null` so the stage diff tests ignore these
files.
This commit updates the `tree-diff` tool to check through a list of the
files that contain timestamps and to use the `null` value rather than
the `sha256` content hash so the stage tests don't fail.
The optional_metadata_types option isn't available in older versions of
dnf. We could version-guard the option, but let's be more explicit and
check if it exists instead.
If it doesn't we can safely ignore it and rely on dnf's default
behaviour.
When the filelists are enabled in the optional metadata, the local cache
for the depsolve will include a filelist file for each repository.
Count the files matching *filelists* using glob() and compare them with
the number of repositories when the option is enabled.
When the option is not enabled, there should be no filelists.
We originally enabled filelists unconditionally in dnf5. Let's make it
optional as part of the 'optional-metadata' option in the arguments so
that the caller can decide if it's needed, for example when using dnf5
with older repositories that have packages with file dependencies, but
don't download them when they're not needed, since the filelists are
quite large.
Filelist repo metadata is required when using newer versions of libdnf
with old repositories or packages that specify dependencies on files.
For example, depsolving with RHEL 9.3 repos on Fedora 40 fails to
resolve platform-python with the message
nothing provides /usr/libexec/platform-python needed by platform-python-...
Not loading filelists is beneficial because it greatly reduces the size
of the metadata to download. Filelists were downloaded by default for
repositories in the past, but with newer versions of dnf/libdnf (in
Fedora 40), they are downloaded on-demand (e.g. when running a query
that requires file information). Newer package guidelines prohibit
depending on file paths, so filelists are not needed for package
depsolving with newer distro repositories.
Add an 'optional-metadata' property to the 'arguments' object of the
depsolve request, so that callers can enable any optional metadata they
need.
Further reading:
- https://libdnf.readthedocs.io/en/stable/tutorial-py/#case-for-loading-the-filelists
- https://github.com/rpm-software-management/dnf/releases/tag/4.19.0
- https://dnf.readthedocs.io/en/stable/user_faq.html#starting-with-fedora-40-i-noticed-repository-metadata-is-synchronized-much-faster-what-happened
Also fix the test, it wasn't updated to use sslverify instead of
ignoressl. This now correctly passes on -dnf and fails on -dnf5 which
will be fixed in the next commit.
We run tests using tox to set up environments for different python
versions to test against. The problem is that when a test shells out to
a python script, like osbuild-depsolve-dnf5, it's not run inside the
environment but in the system environment. The `has_dnf5()` check
returns False because it fails to import dnf5 in the tox environment,
even though the script can be run and the test will succeed.
Use `python3 -c "import libdnf5"` to decide if the script is runnable
instead of using `importlib`. This doesn't solve the problem of our
tests running python scripts in a different environment than the one (we
think) we are testing, but it will enable tests of osbuild-depsolve-dnf5
for now.
The JSON output by go will use 'null' for nil slices, so we need to
use a [] when the field is missing, or when it is set to null.
Previously this was handled by checking the value before iterating but
when the code moved for the directory handling it was changed.
This implements the same behavior in a slightly cleaner way.
The go json serialize process takes a nil slice and converts that to a
'null' instead of an '[]' or leaving off the field. This means that the
json generated by python is not representative of what is output by
images/dnfjson and we have not been properly testing
osbuild-depsolve-dnf5
Testing dnf5 depsolving *also* requires that libdnf5 be present in the
environment, which is a separate problem that still needs to be fixed.
Given that the tests `test_depsolve{,_dnf5}` are identical except
the `command` extract them into a common test that is just parameterized.
This will also help to avoid drift between the two resolvers.
str.removeprefix() is not available in Python 3.6, which we need to
support EL8.
Instead of removing the prefix from the original path string, take the
path property of the parsed URL. Since we're dealing with file paths,
there will be no params, query, or fragment strings so the path should
be all we need.
So that we see any error output during the tests in "realtime". With
subprocess check=True and capture_output=True on exit_code != 0 no
stderr as part of the exception by default so this change helps
seeing issues from depsolve-dnf more easily.
Originally, I made releasever required only when root_dir was set. This
was initially done to maintain backwards compatibility but we broke that
already and osbuild/images will always include releasever in the
request.
Extract make_dnf_scafolding as a helper, mostly so that the config_combos()
function is easier to read. It seems one core concept here is the iteration
of "combo[0]" and "combo[1]" so having them symetrical at the same indent
level feel easier to read to me.
The "main" branch is failing right now in tests. The reason is
that we do not have a merge queue and when
https://github.com/osbuild/osbuild/pull/1715
was merged we had no test for `osbuild-depsolve-dnf` yet.
We have one now (THANK YOU achilleas-k) and it shows an issue :)
This commit fixes the issue.
Depsolver test that starts a temporary file server and queries it using
osbuild-depsolve-dnf.
Generates all combinations of repositories configured through the
depsolve-dnf request or the repositories directory and runs the test
cases. The results should be the same regardless of combination.
Test repos are defined with a fake gpg key on the request or repo config
and check if it is read correctly and attached to the repo configs in
the response. The name of the repo is appended to each repo's gpg key
so we can make sure that repo option values don't get swapped.
Some of the repository properties in the request were named differently
than the equivalent properties in the dnf repository configuration.
This can introduce bugs and confusion.
One such issue already existed with osbuild/images using 'gpgcheck' in
the request, osbuild-depsolve-dnf5 checking for 'check_gpg', and the dnf
repository configuration property being 'gpgcheck'. This didn't cause
any bad behaviour because osbuild/images reused the original (internal)
configuration to set the property in stages and depsolving isn't
affected by the value of this property.
Change the request properties to match the dnf repository configuration
to avoid confusion: gpgcheck, repo_gpgcheck, and sslverify. Users of
osbuild-depsolve-dnf5 should use property names that match dnf. Use
the same names in the response.
To maintain the same behaviour for SSL verification, a missing sslverify
default to True. The previous property had the opposite meaning,
ignore_ssl, and defaulted to False.
Add the full gpg keys to the repository configs in the response.
On each repository object from dnf, the gpg keys are URLs, either
file:// or http(s)://. We need to resolve these and return them with
in the response.
When the URL is a file:// path, and it comes from a .repo config file,
we assume that the path is relative to the root_dir, so we prepend it to
the path in the file. This is so that repo configs in OS root trees can
be used unmodified. However, when a key is defined in the request, we
should assume that the path is valid, either because it was defined by
the caller as a URL, or because it was defined in-line in the request
and osbuild-depsolve-dnf5 wrote it to the persistdir itself.
A new exception is defined to identify errors during this process.
Support loading repositories from a root tree instead of supplying them
with the request. The repositories should be in the standard yum repo
format. Both repository sources can be defined simultaneously, but at
least one is required.
The root_dir is expected to contain files necessary for depsolving in
the standard paths.
These files are:
- Repository (.repo) configurations in <root_dir>/etc/yum.repos.d/
- GPG key files in <root_dir>/etc/pki/rpm-gpg/
- This will be used to resolve gpg key paths specified in the .repo
files that are relative to the root_dir.
- (Optional) Custom dnf config variables in <root_dir>/etc/dnf/vars or
<root_dir>/usr/share/dnf5/vars.d.
- This is used by CentOS Stream to set the value of $stream.
Custom repository configurations in arbitrary (non-root) paths will have
to follow this directory structure.
A new variable is added to the request, `releasever`, which is mandatory
when using `root_dir`. This variable is used in repository URLs and GPG
key paths. In the default case, dnf reads this variable by inspecting
the rpm database. We will override it in the Solver the same way we
override the arch and basearch for variable substitution. In the
future, we will make this variable mandatory in all cases, which will
make the variable available for repo configs defined in the request as
well.
The root_dir is used in three ways:
- Set the base.conf.installroot
- Set the base.conf.varsdir to <root_dir>/usr/share/dnf5/vars.d and
<root_dir>/etc/dnf/vars to read resolve custom variables when loading
repositories.
- Call create_repos_from_dir() with <root_dir>/etc/yum.repos.d.
base.setup() should be called before loading repositories otherwise
substitutions might not work.
See https://github.com/rpm-software-management/dnf5/issues/1374#issuecomment-2038995031