From 6ca2245ca182d3afe10dbd64e0df699d5db99cfb Mon Sep 17 00:00:00 2001 From: Tomas Kopecek Date: Apr 19 2023 07:41:11 +0000 Subject: CG: allow reimports into failed/cancelled builds Related: https://pagure.io/koji/issue/3776 --- diff --git a/kojihub/kojihub.py b/kojihub/kojihub.py index 45d223d..fba0e9a 100644 --- a/kojihub/kojihub.py +++ b/kojihub/kojihub.py @@ -6708,10 +6708,12 @@ class CG_Importer(object): raise koji.GenericError('Reservation token given, but no build_id ' 'in metadata') else: + # no build reservation buildinfo = get_build(metadata['build'], strict=False) - if buildinfo and not metadata['build'].get('build_id'): - # TODO : allow in some cases - raise koji.GenericError("Build already exists: %r" % buildinfo) + if buildinfo: + if (koji.BUILD_STATES[buildinfo['state']] not in ('CANCELED', 'FAILED')): + raise koji.GenericError("Build already exists: %r" % buildinfo) + # note: the checks in recycle_build will also apply when we call new_build later # gather needed data buildinfo = dslice(metadata['build'], ['name', 'version', 'release', 'extra', 'source']) if 'build_id' in metadata['build']: diff --git a/tests/test_hub/test_cg_importer.py b/tests/test_hub/test_cg_importer.py index e13cee3..e449000 100644 --- a/tests/test_hub/test_cg_importer.py +++ b/tests/test_hub/test_cg_importer.py @@ -27,6 +27,32 @@ class TestCGImporter(unittest.TestCase): self.lexists = mock.patch('os.path.lexists').start() self.path_build = mock.patch('koji.pathinfo.build').start() self.new_build = mock.patch('kojihub.kojihub.new_build').start() + self.buildinfo = { + 'id': 43, + 'package_id': 1, + 'package_name': 'testpkg', + 'name': 'testpkg', + 'version': '1.0.1e', + 'release': '42.el7', + 'epoch': None, + 'nvr': 'testpkg-1.0.1-1.fc24', + 'state': koji.BUILD_STATES['COMPLETE'], + 'task_id': 1, + 'owner_id': 1, + 'owner_name': 'jvasallo', + 'volume_id': 'id-1212', + 'volume_name':'testvolume', + 'creation_event_id': '', + 'creation_time': '', + 'creation_ts': 424242424242, + 'start_time': None, + 'start_ts': None, + 'completion_time': None, + 'completion_ts': None, + 'source': 'https://example.com', + 'extra': {}, + } + def tearDown(self): if os.path.exists(self.TMP_PATH): @@ -121,7 +147,7 @@ class TestCGImporter(unittest.TestCase): def test_prep_build_exists(self): self.path_work.return_value = os.path.dirname(__file__) - self.get_build.return_value = True + self.get_build.return_value = self.buildinfo x = kojihub.CG_Importer() x.get_metadata('default.json', 'cg_importer_json') with self.assertRaises(GenericError): @@ -140,20 +166,7 @@ class TestCGImporter(unittest.TestCase): x.assert_cg_access() x.prep_build() x.prepped_outputs = [] - self.get_build.return_value = {'id': 43, 'package_id': 1, - 'package_name': 'testpkg', - 'name': 'testpkg', 'version': '1.0.1e', - 'release': '42.el7', 'epoch': None, - 'nvr': 'testpkg-1.0.1-1.fc24', - 'state': 'complete', 'task_id': 1, - 'owner_id': 1, 'owner_name': 'jvasallo', - 'volume_id': 'id-1212', 'volume_name': 'testvolume', - 'creation_event_id': '', 'creation_time': '', - 'creation_ts': 424242424242, - 'start_time': None, 'start_ts': None, - 'completion_time': None, 'completion_ts': None, - 'source': 'https://example.com', 'extra': {} - } + self.get_build.return_value = self.buildinfo self.new_build.return_value = 43 x.get_build() assert x.buildinfo