Skip to content

Commit

Permalink
handle "installonly" packages properly
Browse files Browse the repository at this point in the history
This is how DNF indicates to libsolv that kernel and related packages
are "install only", that is, can be installed in parallel. We need to
apply the same handling so that we correctly check conflicts between two
kernel packages, rather than ignoring the conflict assuming they can't
be installed together.

Bug: 1465734
Change-Id: I5feaf8eef0abacd087ba77484d5f91a6051052ff
  • Loading branch information
danc86 committed Aug 14, 2017
1 parent 3ab9e8d commit 99c7fc8
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 0 deletions.
32 changes: 32 additions & 0 deletions acceptance_tests/test_check_conflicts.py
Expand Up @@ -301,6 +301,38 @@ def cleanUp():
assert out == ''


# https://bugzilla.redhat.com/show_bug.cgi?id=1465734
def test_finds_conflicts_in_installonly_packages(request, dir_server):
kernel1 = rpmfluff.SimpleRpmBuild('kernel-core', '0.1', '1', ['i386'])
kernel1.add_installed_file(installPath='usr/share/licenses/kernel-core/COPYING',
sourceFile=rpmfluff.SourceFile('COPYING', 'content\n'))
# The modern mechanism for telling DNF a package is installonly is to add this virtual provide.
kernel1.add_provides('installonlypkg(kernel)')
baserepo = rpmfluff.YumRepoBuild([kernel1])
baserepo.make('i386')
dir_server.basepath = baserepo.repoDir

kernel2 = rpmfluff.SimpleRpmBuild('kernel-core', '0.2', '1', ['i386'])
kernel2.add_installed_file(installPath='usr/share/licenses/kernel-core/COPYING',
sourceFile=rpmfluff.SourceFile('COPYING', 'different content\n'))
kernel2.add_provides('installonlypkg(kernel)')
kernel2.make()

def cleanUp():
shutil.rmtree(baserepo.repoDir)
shutil.rmtree(kernel1.get_base_dir())
shutil.rmtree(kernel2.get_base_dir())
request.addfinalizer(cleanUp)

exitcode, out, err = run_rpmdeplint(['rpmdeplint', 'check-conflicts',
'--repo=base,{}'.format(dir_server.url),
kernel2.get_built_rpm('i386')])
assert exitcode == 3
assert err == ('Undeclared file conflicts:\n'
'kernel-core-0.2-1.i386 provides /usr/share/licenses/kernel-core/COPYING '
'which is also provided by kernel-core-0.1-1.i386\n')


# https://bugzilla.redhat.com/show_bug.cgi?id=1448768
def test_obeys_xml_base_when_downloading_packages(request, tmpdir, dir_server):
p2 = rpmfluff.SimpleRpmBuild('b', '0.1', '1', ['x86_64'])
Expand Down
32 changes: 32 additions & 0 deletions rpmdeplint/__init__.py
Expand Up @@ -20,6 +20,28 @@
logger = logging.getLogger(__name__)


installonlypkgs = [
# The default 'installonlypkgs' from dnf
# https://github.com/rpm-software-management/dnf/blob/dnf-2.5.1-1/dnf/const.py.in#L28
'kernel',
'kernel-PAE',
'installonlypkg(kernel)',
'installonlypkg(kernel-module)',
'installonlypkg(vm)',
# Additional names which yum 3.4.3 (RHEL7) has in its default 'installonlypkgs'
# https://github.com/rpm-software-management/yum/blob/cf8a5669165e958d56157abf40d0cdd552c8fbf9/yum/config.py#L650
'kernel-bigmem',
'kernel-enterprise',
'kernel-smp',
'kernel-modules',
'kernel-debug',
'kernel-unsupported',
'kernel-source',
'kernel-devel',
'kernel-PAE-debug',
]


class UnreadablePackageError(Exception):
"""
Raised if an RPM package cannot be read from disk (it's corrupted, or the
Expand Down Expand Up @@ -99,6 +121,16 @@ def __init__(self, repos, packages, arch=None):
self.pool.addfileprovides()
self.pool.createwhatprovides()

# Special handling for "installonly" packages: we create jobs to mark
# installonly package names as "multiversion" and then set those as
# pool jobs, which means the jobs are automatically applied whenever we
# run the solver on this pool.
multiversion_jobs = []
for name in installonlypkgs:
selection = self.pool.select(name, solv.Selection.SELECTION_PROVIDES)
multiversion_jobs.extend(selection.jobs(solv.Job.SOLVER_MULTIVERSION))
self.pool.setpooljobs(multiversion_jobs)

def __enter__(self):
return self

Expand Down

0 comments on commit 99c7fc8

Please sign in to comment.