diff --git a/builder/kojid b/builder/kojid index 278430fb..7f4557af 100755 --- a/builder/kojid +++ b/builder/kojid @@ -5550,6 +5550,9 @@ class CreaterepoTask(BaseTaskHandler): # generate repo url list, starting with our local premerge repo repos = ['file://' + localdir + '/'] for repo in external_repos: + if repo['arches'] and arch not in repo['arches'].split(): + # ignore external repo with non-relevant archlist + continue ext_url = repo['url'] # substitute $arch in the url with the arch of the repo we're generating ext_url = ext_url.replace('$arch', arch) diff --git a/cli/koji_cli/commands.py b/cli/koji_cli/commands.py index eb0de89d..e50e904a 100644 --- a/cli/koji_cli/commands.py +++ b/cli/koji_cli/commands.py @@ -4973,8 +4973,11 @@ def anon_handle_taginfo(goptions, session, args): if external_repos: print("External repos:") for rinfo in external_repos: + if not rinfo['arches']: + rinfo['arches'] = 'inherited from tag' + # TODO else intersection of arches? print(" %(priority)3i %(external_repo_name)s " - "(%(url)s, merge mode: %(merge_mode)s)" % rinfo) + "(%(url)s, merge mode: %(merge_mode)s), arches: %(arches)s" % rinfo) print("Inheritance:") for parent in session.getInheritanceData(info['id'], **event_opts): parent['flags'] = format_inheritance_flags(parent) @@ -5520,6 +5523,8 @@ def handle_add_external_repo(goptions, session, args): parser.add_option("-p", "--priority", type='int', help=_("Set priority (when adding to tag)")) parser.add_option("-m", "--mode", help=_("Set merge mode")) + parser.add_option("-a", "--arches", metavar="ARCH1,ARCH2, ...", + help=_("Use only subset of arches from given repo")) (options, args) = parser.parse_args(args) activate_session(session, goptions) if options.mode: @@ -5549,6 +5554,8 @@ def handle_add_external_repo(goptions, session, args): callopts = {} if options.mode: callopts['merge_mode'] = options.mode + if options.arches: + callopts['arches'] = options.arches session.addExternalRepoToTag(tag, rinfo['name'], priority, **callopts) print("Added external repo %s to tag %s (priority %i)" % (rinfo['name'], tag, priority)) @@ -5567,6 +5574,8 @@ def handle_edit_external_repo(goptions, session, args): parser.add_option("-m", "--mode", metavar="MODE", help=_("Edit the merge mode of the repo for the tag specified by --tag. " "Options: %s.") % ", ".join(koji.REPO_MERGE_MODES)) + parser.add_option("-a", "--arches", metavar="ARCH1,ARCH2, ...", + help=_("Use only subset of arches from given repo")) (options, args) = parser.parse_args(args) if len(args) != 1: parser.error(_("Incorrect number of arguments")) @@ -5581,12 +5590,14 @@ def handle_edit_external_repo(goptions, session, args): tag_repo_opts['priority'] = options.priority if options.mode: tag_repo_opts['merge_mode'] = options.mode + if options.arches is not None: + tag_repo_opts['arches'] = options.arches if not tag_repo_opts: parser.error(_("At least, one of priority and merge mode should be specified")) tag_repo_opts['tag_info'] = options.tag tag_repo_opts['repo_info'] = args[0] else: - for k in ('priority', 'mode'): + for k in ('priority', 'mode', 'arches'): if getattr(options, k) is not None: parser.error(_("If %s is specified, --tag must be specified as well") % k) diff --git a/docs/schema-upgrade-1.23-1.24.sql b/docs/schema-upgrade-1.23-1.24.sql new file mode 100644 index 00000000..998849aa --- /dev/null +++ b/docs/schema-upgrade-1.23-1.24.sql @@ -0,0 +1,9 @@ +-- upgrade script to migrate the Koji database schema +-- from version 1.23 to 1.24 + + +BEGIN; + +ALTER TABLE tag_external_repos ADD COLUMN arches TEXT; + +COMMIT; diff --git a/docs/schema.sql b/docs/schema.sql index 3870d9ff..498ccdd6 100644 --- a/docs/schema.sql +++ b/docs/schema.sql @@ -465,7 +465,7 @@ create table external_repo ( -- fake repo id for internal stuff (needed for unique index) INSERT INTO external_repo (id, name) VALUES (0, 'INTERNAL'); -create table external_repo_config ( +CREATE TABLE external_repo_config ( external_repo_id INTEGER NOT NULL REFERENCES external_repo(id), url TEXT NOT NULL, -- versioned - see earlier description of versioning @@ -481,11 +481,12 @@ create table external_repo_config ( UNIQUE (external_repo_id, active) ) WITHOUT OIDS; -create table tag_external_repos ( +CREATE TABLE tag_external_repos ( tag_id INTEGER NOT NULL REFERENCES tag(id), external_repo_id INTEGER NOT NULL REFERENCES external_repo(id), priority INTEGER NOT NULL, merge_mode TEXT NOT NULL DEFAULT 'koji', + arches TEXT, -- versioned - see earlier description of versioning create_event INTEGER NOT NULL REFERENCES events(id) DEFAULT get_event(), revoke_event INTEGER REFERENCES events(id), diff --git a/hub/kojihub.py b/hub/kojihub.py index c4e0611f..5f1ea89b 100644 --- a/hub/kojihub.py +++ b/hub/kojihub.py @@ -3675,7 +3675,7 @@ def delete_external_repo(info): update.execute() -def add_external_repo_to_tag(tag_info, repo_info, priority, merge_mode='koji'): +def add_external_repo_to_tag(tag_info, repo_info, priority, merge_mode='koji', arches=None): """Add an external repo to a tag""" context.session.assertPerm('tag') @@ -3701,7 +3701,7 @@ def add_external_repo_to_tag(tag_info, repo_info, priority, merge_mode='koji'): insert = InsertProcessor('tag_external_repos') insert.set(tag_id=tag_id, external_repo_id=repo_id, priority=priority, - merge_mode=merge_mode) + merge_mode=merge_mode, arches=arches) insert.make_create() insert.execute() @@ -3726,7 +3726,7 @@ def remove_external_repo_from_tag(tag_info, repo_info): update.execute() -def edit_tag_external_repo(tag_info, repo_info, priority=None, merge_mode=None): +def edit_tag_external_repo(tag_info, repo_info, priority=None, merge_mode=None, arches=None): """Edit a tag<->external repo association This allows you to update the priority and merge_mode without removing/adding the repo. @@ -3747,7 +3747,7 @@ def edit_tag_external_repo(tag_info, repo_info, priority=None, merge_mode=None): tag_repo = tag_repos[0] data = {} - for k in ('priority', 'merge_mode'): + for k in ('priority', 'merge_mode', 'arches'): val = locals().get(k) # None value means no change if val is not None and val != tag_repo[k]: @@ -3755,7 +3755,7 @@ def edit_tag_external_repo(tag_info, repo_info, priority=None, merge_mode=None): if not data: return False else: - for k in ('priority', 'merge_mode'): + for k in ('priority', 'merge_mode', 'arches'): data.setdefault(k, tag_repo[k]) remove_external_repo_from_tag(tag_id, repo_id) add_external_repo_to_tag(tag_id, repo_id, **data) @@ -3800,6 +3800,7 @@ def get_tag_external_repos(tag_info=None, repo_info=None, event=None): 'tag.name': 'tag_name', 'url': 'url', 'merge_mode': 'merge_mode', + 'arches': 'arches', } columns, aliases = zip(*fields.items()) @@ -10553,7 +10554,7 @@ class RootExports(object): deleteExternalRepo = staticmethod(delete_external_repo) def addExternalRepoToTag(self, tag_info, repo_info, priority, - merge_mode='koji'): + merge_mode='koji', arches=None): """Add an external repo to a tag. :param tag_info: Tag name or ID number @@ -10564,7 +10565,8 @@ class RootExports(object): the default is "koji". """ # wrap the local method so we don't expose the event parameter - add_external_repo_to_tag(tag_info, repo_info, priority, merge_mode) + add_external_repo_to_tag(tag_info, repo_info, priority, + merge_mode=merge_mode, arches=arches) def removeExternalRepoFromTag(self, tag_info, repo_info): """ diff --git a/tests/test_cli/test_edit_external_repo.py b/tests/test_cli/test_edit_external_repo.py index 6adf1c83..c1b17d39 100644 --- a/tests/test_cli/test_edit_external_repo.py +++ b/tests/test_cli/test_edit_external_repo.py @@ -91,6 +91,8 @@ Options: --tag. -m MODE, --mode=MODE Edit the merge mode of the repo for the tag specified by --tag. Options: %s. + -a ARCH1,ARCH2, ..., --arches=ARCH1,ARCH2, ... + Use only subset of arches from given repo """ % (self.progname, ', '.join(koji.REPO_MERGE_MODES))) diff --git a/tests/test_hub/test_edit_tag_external_repo.py b/tests/test_hub/test_edit_tag_external_repo.py index a71b5ece..c96a1733 100644 --- a/tests/test_hub/test_edit_tag_external_repo.py +++ b/tests/test_hub/test_edit_tag_external_repo.py @@ -18,7 +18,8 @@ class TestEditTagExternalRepo(unittest.TestCase): self.get_tag_external_repos.return_value = [{'external_repo_id': 11, 'tag_id': 1, 'priority': 5, - 'merge_mode': 'simple'}] + 'merge_mode': 'simple', + 'arches': 'x86_64 i686'}] self.remove_external_repo_from_tag = mock.patch( 'kojihub.remove_external_repo_from_tag').start() @@ -33,7 +34,8 @@ class TestEditTagExternalRepo(unittest.TestCase): self.get_external_repo.assert_called_once_with('ext_repo', strict=True) self.get_tag_external_repos.assert_called_once_with(tag_info=1, repo_info=11) self.remove_external_repo_from_tag.assert_called_once_with(1, 11) - self.add_external_repo_to_tag.assert_called_once_with(1, 11, priority=6, merge_mode='bare') + self.add_external_repo_to_tag.assert_called_once_with(1, 11, priority=6, merge_mode='bare', + arches='x86_64 i686') self.assertTrue(rv) def test_edit_no_tag_repo(self): @@ -74,9 +76,10 @@ class TestEditTagExternalRepo(unittest.TestCase): self.get_tag_external_repos.return_value = [{'external_repo_id': 11, 'tag_id': 1, 'priority': 5, - 'merge_mode': None}] + 'merge_mode': None, + 'arches': None}] rv = kojihub.edit_tag_external_repo('tag', 'ext_repo', priority=None, merge_mode='simple') self.remove_external_repo_from_tag.assert_called_once_with(1, 11) - self.add_external_repo_to_tag.assert_called_once_with(1, 11, + self.add_external_repo_to_tag.assert_called_once_with(1, 11, arches=None, priority=5, merge_mode='simple') self.assertTrue(rv)