limit distRepo tasks per tag

Introduces 'distrepo.cancel_others` extra flag for tags. If enabled, new
distRepo task will cancel previous non-finished ones leaving only new
one.

Fixes: https://pagure.io/koji/issue/1630
This commit is contained in:
Tomas Kopecek 2019-12-10 16:46:31 +01:00
parent 14901ced87
commit 4d03794657
4 changed files with 41 additions and 5 deletions

View file

@ -6952,8 +6952,14 @@ def handle_regen_repo(options, session, args):
def handle_dist_repo(options, session, args):
"""Create a yum repo with distribution options"""
usage = _("usage: %prog dist-repo [options] <tag> <key_id> [<key_id> ...]")
parser = OptionParser(usage=get_usage_str(usage))
usage = _("usage: %prog dist-repo [options] <tag> <key_id> [<key_id> ...]\n\n"
"In normal mode, dist-repo behaves like any other koji task.\n"
"Sometimes you want to limit running distRepo tasks per tag to only\n"
"one. For such behaviour admin (with 'tag' permission) needs to\n"
"modify given tag's extra field 'distrepo.cancel_others' to True'\n"
"via 'koji edit-tag -x distrepo.cancel_others=True'\n")
usage += _("\n(Specify the --help option for a list of other options)")
parser = OptionParser(usage=usage)
parser.add_option('--allow-missing-signatures', action='store_true',
default=False,
help=_('For RPMs not signed with a desired key, fall back to the '

View file

@ -11438,6 +11438,20 @@ class RootExports(object):
context.session.assertPerm('dist-repo')
repo_id, event_id = dist_repo_init(tag, keys, task_opts)
task_opts['event'] = event_id
# cancel potentially running distRepos
tinfo = get_tag(tag, strict=True)
if tinfo['extra'].get('distrepo.cancel_others', False):
tasks = self.listTasks(opts={
'state': [koji.TASK_STATES['FREE'],
koji.TASK_STATES['OPEN'],
koji.TASK_STATES['ASSIGNED']],
'method': 'distRepo',
'decode': True})
# filter only for this tag
task_ids = [t['id'] for t in tasks if t['request'][0] == tag]
for task_id in task_ids:
logger.debug("Cancelling distRepo task %d" % task_id)
Task(task_id).cancel(recurse=True)
return make_task('distRepo', [tag, repo_id, keys, task_opts], priority=15, channel='createrepo')
def newRepo(self, tag, event=None, src=False, debuginfo=False, separate_src=False):

View file

@ -45,7 +45,14 @@ class TestDistRepo(utils.CliTestCase):
self.session.distRepo.return_value = self.task_id
self.error_format = """Usage: %s dist-repo [options] <tag> <key_id> [<key_id> ...]
(Specify the --help global option for a list of other help options)
In normal mode, dist-repo behaves like any other koji task.
Sometimes you want to limit running distRepo tasks per tag to only
one. For such behaviour admin (with 'tag' permission) needs to
modify given tag's extra field 'distrepo.cancel_others' to True'
via 'koji edit-tag -x distrepo.cancel_others=True'
(Specify the --help option for a list of other options)
%s: error: {message}
""" % (self.progname, self.progname)
@ -249,7 +256,14 @@ class TestDistRepo(utils.CliTestCase):
self.assert_help(
handle_dist_repo,
"""Usage: %s dist-repo [options] <tag> <key_id> [<key_id> ...]
(Specify the --help global option for a list of other help options)
In normal mode, dist-repo behaves like any other koji task.
Sometimes you want to limit running distRepo tasks per tag to only
one. For such behaviour admin (with 'tag' permission) needs to
modify given tag's extra field 'distrepo.cancel_others' to True'
via 'koji edit-tag -x distrepo.cancel_others=True'
(Specify the --help option for a list of other options)
Options:
-h, --help show this help message and exit

View file

@ -85,15 +85,17 @@ class TestDistRepoInit(unittest.TestCase):
class TestDistRepo(unittest.TestCase):
@mock.patch('kojihub.get_tag')
@mock.patch('kojihub.dist_repo_init')
@mock.patch('kojihub.make_task')
def test_DistRepo(self, make_task, dist_repo_init):
def test_DistRepo(self, make_task, dist_repo_init, get_tag):
session = kojihub.context.session = mock.MagicMock()
# It seems MagicMock will not automatically handle attributes that
# start with "assert"
session.assertPerm = mock.MagicMock()
dist_repo_init.return_value = ('repo_id', 'event_id')
make_task.return_value = 'task_id'
get_tag.return_value = {'extra': {}}
exports = kojihub.RootExports()
ret = exports.distRepo('tag', 'keys')