repoclosure: add option to use dnf backend

This adds a new option repoclosure_backend that changes what tool is
used for repoclosure.

Checking build dependencies is currently not supported, as `dnf` does
not have the corresponding option.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
This commit is contained in:
Lubomír Sedlář 2017-01-26 09:19:12 +01:00
parent 95fc0fa4ab
commit e3fe67be53
7 changed files with 109 additions and 21 deletions

View File

@ -152,6 +152,12 @@ Options
([*str*]) -- list of variants which should be included; if undefined, all
variants from variants.xml will be included
**repoclosure_backend**
(*str*) -- Select which tool should be used to run repoclosure over created
repositories. By default ``yum`` is used, but you can switch to ``dnf``.
Please note that when ``dnf`` is used, the build dependencies check is
skipped.
Example
-------

View File

@ -468,6 +468,11 @@ def _make_schema():
"type": "boolean",
"default": False,
},
"repoclosure_backend": {
"type": "string",
"default": "yum",
"enum": ["yum", "dnf"],
},
"hashed_directories": {
"type": "boolean",

View File

@ -64,7 +64,8 @@ def run_repoclosure(compose):
for i, lookaside_url in enumerate(get_lookaside_repos(compose, arch, variant)):
lookaside["lookaside-%s.%s-%s" % (variant.uid, arch, i)] = lookaside_url
cmd = repoclosure.get_repoclosure_cmd(repos=repos, lookaside=lookaside, arch=arches)
cmd = repoclosure.get_repoclosure_cmd(backend=compose.conf['repoclosure_backend'],
repos=repos, lookaside=lookaside, arch=arches)
# Use temp working directory directory as workaround for
# https://bugzilla.redhat.com/show_bug.cgi?id=795137
tmp_dir = compose.mkdtemp(prefix="repoclosure_")
@ -87,7 +88,11 @@ def run_repoclosure(compose):
# In this case, it's an obvious bug in the test.
# check BuildRequires (self-hosting)
cmd = repoclosure.get_repoclosure_cmd(repos=all_repos, arch=all_arches, builddeps=True)
try:
cmd = repoclosure.get_repoclosure_cmd(backend=compose.conf['repoclosure_backend'],
repos=all_repos, arch=all_arches, builddeps=True)
except RuntimeError as exc:
compose.log_error('%s, skipping builddeps check...' % str(exc))
# Use temp working directory directory as workaround for
# https://bugzilla.redhat.com/show_bug.cgi?id=795137
tmp_dir = compose.mkdtemp(prefix="repoclosure_")

View File

@ -19,19 +19,22 @@ import os
from kobo.shortcuts import force_list
def get_repoclosure_cmd(arch=None, builddeps=False,
def get_repoclosure_cmd(backend='yum', arch=None, builddeps=False,
repos=None, lookaside=None):
if backend == 'dnf' and builddeps:
raise RuntimeError('dnf repoclosure does not support builddeps')
cmds = {
'yum': {'cmd': ['/usr/bin/repoclosure'], 'repoarg': '--repoid=%s', 'lookaside': '--lookaside=%s'},
'dnf': {'cmd': ['dnf', 'repoclosure'], 'repoarg': '--repo=%s', 'lookaside': '--repo=%s'},
}
try:
cmd = cmds[backend]['cmd']
except KeyError:
raise RuntimeError('Unknown repoclosure backend: %s' % backend)
cmd = ["/usr/bin/repoclosure"]
# There are options that are not exposed here, because we don't need
# them. These are:
# --config
# --basearch
# --tempcache
# --quiet
# --newest
# --pkg
# --group
# them.
for i in force_list(arch or []):
cmd.append("--arch=%s" % i)
@ -42,12 +45,17 @@ def get_repoclosure_cmd(arch=None, builddeps=False,
repos = repos or {}
for repo_id, repo_path in repos.iteritems():
cmd.append("--repofrompath=%s,%s" % (repo_id, _to_url(repo_path)))
cmd.append("--repoid=%s" % repo_id)
cmd.append(cmds[backend]['repoarg'] % repo_id)
if backend == 'dnf':
# For dnf we want to add all repos with the --repo option (which
# enables only those and not any system repo), and the repos to
# check are also listed with the --check option.
cmd.append('--check=%s' % repo_id)
lookaside = lookaside or {}
for repo_id, repo_path in lookaside.iteritems():
cmd.append("--repofrompath=%s,%s" % (repo_id, _to_url(repo_path)))
cmd.append("--lookaside=%s" % repo_id)
cmd.append(cmds[backend]['lookaside'] % repo_id)
return cmd

View File

@ -389,5 +389,17 @@ class TestRegexValidation(ConfigTestCase):
[])
class RepoclosureTestCase(ConfigTestCase):
def test_invalid_backend(self):
cfg = load_config(
PKGSET_REPOS,
repoclosure_backend='fnd', # Intentionally with a typo
)
self.assertValidation(
cfg,
["Failed validation in repoclosure_backend: 'fnd' is not one of ['yum', 'dnf']"])
if __name__ == '__main__':
unittest.main()

View File

@ -18,6 +18,16 @@ class RepoclosureWrapperTestCase(unittest.TestCase):
self.assertEqual(rc.get_repoclosure_cmd(),
['/usr/bin/repoclosure'])
def test_minimal_dnf_command(self):
self.assertEqual(rc.get_repoclosure_cmd(backend='dnf'),
['dnf', 'repoclosure'])
def test_unknown_backend(self):
with self.assertRaises(RuntimeError) as ctx:
rc.get_repoclosure_cmd(backend='rpm')
self.assertEqual(str(ctx.exception), 'Unknown repoclosure backend: rpm')
def test_multiple_arches(self):
self.assertEqual(rc.get_repoclosure_cmd(arch=['x86_64', 'ppc64']),
['/usr/bin/repoclosure', '--arch=x86_64', '--arch=ppc64'])
@ -38,6 +48,22 @@ class RepoclosureWrapperTestCase(unittest.TestCase):
'--repoid=my-repo',
'--lookaside=fedora'])
def test_full_dnf_command(self):
repos = {'my-repo': '/mnt/koji/repo'}
lookaside = {'fedora': 'http://kojipkgs.fp.o/repo'}
cmd = rc.get_repoclosure_cmd(backend='dnf', arch='x86_64',
repos=repos, lookaside=lookaside)
self.assertEqual(cmd[:2], ['dnf', 'repoclosure'])
self.assertItemsEqual(
cmd[2:],
['--arch=x86_64',
'--repofrompath=my-repo,file:///mnt/koji/repo',
'--repofrompath=fedora,http://kojipkgs.fp.o/repo',
'--repo=my-repo',
'--check=my-repo',
'--repo=fedora'])
def test_expand_repo(self):
repos = {
'local': '/mnt/koji/repo',

View File

@ -177,7 +177,7 @@ class TestRepoclosure(PungiTestCase):
@mock.patch('pungi.wrappers.repoclosure.get_repoclosure_cmd')
@mock.patch('pungi.phases.test.run')
def test_calls_repoclosure(self, mock_run, mock_grc):
def test_repoclosure_default_backend(self, mock_run, mock_grc):
compose = DummyCompose(self.topdir, {})
test_phase.run_repoclosure(compose)
self.maxDiff = None
@ -189,17 +189,43 @@ class TestRepoclosure(PungiTestCase):
self.assertItemsEqual(
mock_grc.call_args_list,
[mock.call(arch=['amd64', 'x86_64', 'noarch'], lookaside={},
[mock.call(backend='yum', arch=['amd64', 'x86_64', 'noarch'], lookaside={},
repos=self._get_repo('Everything', 'amd64')),
mock.call(arch=['amd64', 'x86_64', 'noarch'], lookaside={},
mock.call(backend='yum', arch=['amd64', 'x86_64', 'noarch'], lookaside={},
repos=self._get_repo('Client', 'amd64')),
mock.call(arch=['amd64', 'x86_64', 'noarch'], lookaside={},
mock.call(backend='yum', arch=['amd64', 'x86_64', 'noarch'], lookaside={},
repos=self._get_repo('Server', 'amd64')),
mock.call(arch=['x86_64', 'noarch'], lookaside={},
mock.call(backend='yum', arch=['x86_64', 'noarch'], lookaside={},
repos=self._get_repo('Server', 'x86_64')),
mock.call(arch=['x86_64', 'noarch'], lookaside={},
mock.call(backend='yum', arch=['x86_64', 'noarch'], lookaside={},
repos=self._get_repo('Everything', 'x86_64')),
mock.call(arch={'x86_64', 'amd64', 'noarch'}, builddeps=True, repos=all_repos)])
mock.call(backend='yum', arch={'x86_64', 'amd64', 'noarch'}, builddeps=True, repos=all_repos)])
@mock.patch('pungi.wrappers.repoclosure.get_repoclosure_cmd')
@mock.patch('pungi.phases.test.run')
def test_repoclosure_dnf_backend(self, mock_run, mock_grc):
compose = DummyCompose(self.topdir, {'repoclosure_backend': 'dnf'})
test_phase.run_repoclosure(compose)
self.maxDiff = None
all_repos = {}
for variant in compose.variants.itervalues():
for arch in variant.arches:
all_repos.update(self._get_repo(variant.uid, arch))
all_repos.update(self._get_repo(variant.uid, 'src', 'source/tree'))
self.assertItemsEqual(
mock_grc.call_args_list,
[mock.call(backend='dnf', arch=['amd64', 'x86_64', 'noarch'], lookaside={},
repos=self._get_repo('Everything', 'amd64')),
mock.call(backend='dnf', arch=['amd64', 'x86_64', 'noarch'], lookaside={},
repos=self._get_repo('Client', 'amd64')),
mock.call(backend='dnf', arch=['amd64', 'x86_64', 'noarch'], lookaside={},
repos=self._get_repo('Server', 'amd64')),
mock.call(backend='dnf', arch=['x86_64', 'noarch'], lookaside={},
repos=self._get_repo('Server', 'x86_64')),
mock.call(backend='dnf', arch=['x86_64', 'noarch'], lookaside={},
repos=self._get_repo('Everything', 'x86_64')),
mock.call(backend='dnf', arch={'x86_64', 'amd64', 'noarch'}, builddeps=True, repos=all_repos)])
if __name__ == "__main__":