On RHEL 6 (yum/repoquery), repoquery --whatprovides can return the same NEVRA multiple times for a single package. tmt does not deduplicate these results, which breaks:
verify-installation during artifact prepare (packages reported as not installed)
- Artifact NEVRA override logic (duplicate matches prevent pinning install to a specific NEVRA)
tmt: 1.78.0
Steps to reproduce
- Use a RHEL 6 guest with
bind already installed.
- Run a plan that requires
bind and inject artifact RPMs:
<magic-rhel6-envs> tmt run --context distro=rhel-6.10 \
provision --how connect --guest <guest-ip> --key <key> \
prepare --insert --how artifact \
--provide file:/path/to/bind-*.rpm \
--provide file:/path/to/bind-libs-*.rpm \
--provide file:/path/to/bind-utils-*.rpm \
plan --name <plan> \
test --name <test requiring bind>
- Observe prepare failure in the auto-injected
verify-artifact-packages phase.
Actual result
Prepare fails with:
Package source verification failed for: bind, bind-utils
In the verify step, repoquery --installed --whatprovides produces no usable metadata:
Earlier in artifact prepare, resolve_provides also returns duplicate identical entries for bind and bind-utils from tmt-artifact-shared, so NEVRA override is not applied (len(packages) == 2 instead of 1).
Expected result
- Artifact verification should detect installed packages and confirm they came from
tmt-artifact-shared.
- When artifact repos contain a single unique NEVRA for a requested package, tmt should pin installation to that NEVRA.
Root cause
On RHEL 6, repoquery --whatprovides <name> can return the same NEVRA twice when a package matches both by name and by an explicit Provides entry.
Example on guest:
$ repoquery --installed --whatprovides bind
bind-32:9.8.2-0.68.rc1.el6_10.18.x86_64
bind-32:9.8.2-0.68.rc1.el6_10.18.x86_64
$ rpm -qa bind
bind-9.8.2-0.68.rc1.el6_10.18.x86_64
$ repoquery --installed bind
bind-32:9.8.2-0.68.rc1.el6_10.18.x86_64
$ rpm -q bind --provides | grep -E '^bind'
bind-config = 30:9.3.2-34.fc6
bind = 32:9.8.2-0.68.rc1.el6_10.18
bind(x86-64) = 32:9.8.2-0.68.rc1.el6_10.18
The package is installed once; RPM DB is not corrupted (dbinstance is singular). The duplicate is specific to --whatprovides.
tmt's YumEngine._repoquery_script() captures all lines into one variable:
full_nevra=$(repoquery --installed --whatprovides "$query")
repoquery --queryformat '...' "$full_nevra"
When full_nevra contains two lines, the second repoquery fails silently, YAML parsing yields null, and tmt treats the package as not installed.
Affected code
tmt/package_managers/dnf.py — YumEngine._repoquery_script(), installed-package lookup path (installed_only=True, packages_only=False)
tmt/package_managers/__init__.py — resolve_provides() may also need deduplication when parsing repoquery YAML output
tmt/steps/prepare/artifact/__init__.py — len(packages) == 1 check for NEVRA override is thrown off by duplicate identical results
Proposed fix
-
Deduplicate repoquery NEVRA output in YumEngine before use, e.g.:
full_nevra=$(repoquery --installed --whatprovides "$query" | sort -u | head -n1)
-
Deduplicate resolve_provides results by NEVRA before counting matches and before building verify mappings.
-
Optionally consider using repoquery --installed <pkgname> instead of --whatprovides when the query is already a package name (avoids the double-match path entirely).
On RHEL 6 (
yum/repoquery),repoquery --whatprovidescan return the same NEVRA multiple times for a single package. tmt does not deduplicate these results, which breaks:verify-installationduring artifact prepare (packages reported as not installed)tmt: 1.78.0
Steps to reproduce
bindalready installed.bindand inject artifact RPMs:verify-artifact-packagesphase.Actual result
Prepare fails with:
In the verify step,
repoquery --installed --whatprovidesproduces no usable metadata:Earlier in artifact prepare,
resolve_providesalso returns duplicate identical entries forbindandbind-utilsfromtmt-artifact-shared, so NEVRA override is not applied (len(packages) == 2instead of1).Expected result
tmt-artifact-shared.Root cause
On RHEL 6,
repoquery --whatprovides <name>can return the same NEVRA twice when a package matches both by name and by an explicit Provides entry.Example on guest:
The package is installed once; RPM DB is not corrupted (
dbinstanceis singular). The duplicate is specific to--whatprovides.tmt's
YumEngine._repoquery_script()captures all lines into one variable:When
full_nevracontains two lines, the secondrepoqueryfails silently, YAML parsing yieldsnull, and tmt treats the package as not installed.Affected code
tmt/package_managers/dnf.py—YumEngine._repoquery_script(), installed-package lookup path (installed_only=True,packages_only=False)tmt/package_managers/__init__.py—resolve_provides()may also need deduplication when parsing repoquery YAML outputtmt/steps/prepare/artifact/__init__.py—len(packages) == 1check for NEVRA override is thrown off by duplicate identical resultsProposed fix
Deduplicate repoquery NEVRA output in
YumEnginebefore use, e.g.:full_nevra=$(repoquery --installed --whatprovides "$query" | sort -u | head -n1)Deduplicate
resolve_providesresults by NEVRA before counting matches and before building verify mappings.Optionally consider using
repoquery --installed <pkgname>instead of--whatprovideswhen the query is already a package name (avoids the double-match path entirely).