From ed59c2da2c9b762cf9594171a4383ac24ba3db8a Mon Sep 17 00:00:00 2001 From: Chenxiong Qi Date: Jan 03 2018 05:51:00 +0000 Subject: Request boot.iso compose for base image rebuild Signed-off-by: Chenxiong Qi --- diff --git a/freshmaker/handlers/errata/errata_advisory_rpms_signed.py b/freshmaker/handlers/errata/errata_advisory_rpms_signed.py index d5d7ef5..9e75519 100644 --- a/freshmaker/handlers/errata/errata_advisory_rpms_signed.py +++ b/freshmaker/handlers/errata/errata_advisory_rpms_signed.py @@ -24,6 +24,10 @@ import json import koji +import requests + +from six.moves import cStringIO +from six.moves import configparser from freshmaker import conf, db, log from freshmaker.events import ErrataAdvisoryRPMsSignedEvent @@ -132,7 +136,8 @@ class ErrataAdvisoryRPMsSignedHandler(ContainerBuildHandler): return [] - def _fake_odcs_new_compose(self, compose_source, tag, packages=None): + def _fake_odcs_new_compose( + self, compose_source, tag, packages=None, results=[]): """ Fake KojiSession.buildContainer method used dry run mode. @@ -143,7 +148,7 @@ class ErrataAdvisoryRPMsSignedHandler(ContainerBuildHandler): :return: Fake odcs.new_compose dict. """ self.log_info("DRY RUN: Calling fake odcs.new_compose with args: %r", - (compose_source, tag, packages)) + (compose_source, tag, packages, results)) # Generate the new_compose dict. ErrataAdvisoryRPMsSignedHandler._FAKE_COMPOSE_ID += 1 @@ -152,6 +157,8 @@ class ErrataAdvisoryRPMsSignedHandler(ContainerBuildHandler): new_compose['result_repofile'] = "http://localhost/%d.repo" % ( new_compose['id']) new_compose['state'] = COMPOSE_STATES['done'] + if results: + new_compose['results'] = ['boot.iso'] # Generate and inject the ODCSComposeStateChangeEvent event. event = ODCSComposeStateChangeEvent( @@ -295,6 +302,61 @@ class ErrataAdvisoryRPMsSignedHandler(ContainerBuildHandler): return new_compose + def _get_base_image_build_target(self, image): + dockerfile = image.dockerfile + image_build_conf_url = dockerfile['content_url'].replace( + dockerfile['filename'], 'image-build.conf') + response = requests.get(image_build_conf_url) + try: + response.raise_for_status() + except requests.exceptions.HTTPError as e: + log.error( + 'Cannot get image-build.conf from %s.', image_build_conf_url) + log.exception('Server response: %s', e) + return None + config_buf = cStringIO(response.content) + config = configparser.RawConfigParser() + try: + config.readfp(config_buf) + except configparser.MissingSectionHeaderError: + return None + finally: + config_buf.close() + try: + return config.get('image-build', 'target') + except (configparser.NoOptionError, configparser.NoSectionError): + log.exception('image-build.conf does not have option target.') + return None + + def _get_base_image_build_tag(self, build_target): + with koji_service(conf.koji_profile, log) as session: + target_info = session.get_build_target(build_target) + if target_info is None: + return target_info + else: + return target_info['build_tag_name'] + + def _request_boot_iso_compose(self, image): + """Request boot.iso compose for base image""" + target = self._get_base_image_build_target(image) + if not target: + return None + build_tag = self._get_base_image_build_tag(target) + if not build_tag: + return None + + odcs = ODCS(conf.odcs_server_url, + auth_mech=AuthMech.Kerberos, + verify_ssl=conf.odcs_verify_ssl) + if conf.dry_run: + new_compose = self._fake_odcs_new_compose( + build_tag, 'tag', results=['boot.iso']) + else: + with krb_context(): + new_compose = odcs.new_compose( + build_tag, 'tag', results=['boot.iso']) + return new_compose + def _get_packages_for_compose(self, nvr): """Get RPMs of current build NVR @@ -481,6 +543,23 @@ class ErrataAdvisoryRPMsSignedHandler(ContainerBuildHandler): db.session.commit() build.add_composes(db.session, [db_compose]) + if image.is_base_image: + compose = self._request_boot_iso_compose(image) + if compose is None: + log.error( + 'Failed to request boot.iso compose for base ' + 'image %s.', nvr) + build.transition( + ArtifactBuildState.FAILED.value, + 'Cannot rebuild this base image because failed to ' + 'requeset boot.iso compose.') + # FIXME: mark all builds associated with build.event FAILED? + else: + db_compose = Compose(odcs_compose_id=compose['id']) + db.session.add(db_compose) + db.session.commit() + build.add_composes(db.session, [db_compose]) + builds[nvr] = build return builds diff --git a/freshmaker/kojiservice.py b/freshmaker/kojiservice.py index a02889c..540e9bd 100644 --- a/freshmaker/kojiservice.py +++ b/freshmaker/kojiservice.py @@ -164,6 +164,9 @@ class KojiService(object): def get_task_request(self, task_id): return self.session.getTaskRequest(task_id) + def get_build_target(self, target_name): + return self.session.getBuildTarget(target_name) + @contextlib.contextmanager def koji_service(profile=None, logger=None, login=True): diff --git a/freshmaker/lightblue.py b/freshmaker/lightblue.py index 5ea677c..4e8ab8c 100644 --- a/freshmaker/lightblue.py +++ b/freshmaker/lightblue.py @@ -118,6 +118,21 @@ class ContainerImage(dict): def __hash__(self): return hash((self['brew']['build'])) + @property + def is_base_image(self): + return (self['parent'] is None and + len(self['parsed_data']['layers']) == 2) + + @property + def dockerfile(self): + dockerfile = [file for file in self['parsed_data']['files'] + if file['filename'] == 'Dockerfile'] + if not dockerfile: + log.warning('Image %s does not contain a Dockerfile.', + self['brew']['build']) + return None + return dockerfile[0] + def _get_default_additional_data(self): return {"repository": None, "commit": None, "target": None, "git_branch": None, "error": None} diff --git a/tests/test_errata_advisory_rpms_signed_handler.py b/tests/test_errata_advisory_rpms_signed_handler.py index b13dae8..31e3ce1 100644 --- a/tests/test_errata_advisory_rpms_signed_handler.py +++ b/tests/test_errata_advisory_rpms_signed_handler.py @@ -20,6 +20,7 @@ # SOFTWARE. import unittest +import requests from mock import patch @@ -28,6 +29,7 @@ import freshmaker from freshmaker import db from freshmaker.events import ErrataAdvisoryRPMsSignedEvent from freshmaker.handlers.errata import ErrataAdvisoryRPMsSignedHandler +from freshmaker.lightblue import ContainerImage from freshmaker.models import Event from freshmaker.types import EventState @@ -60,6 +62,13 @@ class TestErrataAdvisoryRPMsSignedHandler(unittest.TestCase): '_find_images_to_rebuild') self.mock_find_images_to_rebuild = self.find_images_patcher.start() + self.request_boot_iso_compose_patcher = patch( + 'freshmaker.handlers.errata.ErrataAdvisoryRPMsSignedHandler.' + '_request_boot_iso_compose', + side_effect=[{'id': 1}, {'id': 2}]) + self.mock_request_boot_iso_compose = \ + self.request_boot_iso_compose_patcher.start() + # Fake images found to rebuild has these relationships # # Batch 1 | Batch 2 | Batch 3 @@ -67,7 +76,7 @@ class TestErrataAdvisoryRPMsSignedHandler(unittest.TestCase): # image_b | image_d (child of image_a) | # | image_e (child of image_b) | # - self.image_a = { + self.image_a = ContainerImage({ 'repository': 'repo_1', 'commit': '1234567', 'target': 'docker-container-candidate', @@ -77,8 +86,14 @@ class TestErrataAdvisoryRPMsSignedHandler(unittest.TestCase): 'build': 'image-a-1.0-2', }, 'parent': None, - } - self.image_b = { + 'parsed_data': { + 'layers': [ + 'sha512:7890', + 'sha512:5678', + ] + }, + }) + self.image_b = ContainerImage({ 'repository': 'repo_2', 'commit': '23e9f22', 'target': 'docker-container-candidate', @@ -88,8 +103,14 @@ class TestErrataAdvisoryRPMsSignedHandler(unittest.TestCase): 'build': 'image-b-1.0-1' }, 'parent': None, - } - self.image_c = { + 'parsed_data': { + 'layers': [ + 'sha512:1234', + 'sha512:4567', + ] + }, + }) + self.image_c = ContainerImage({ 'repository': 'repo_2', 'commit': '2345678', 'target': 'docker-container-candidate', @@ -99,8 +120,15 @@ class TestErrataAdvisoryRPMsSignedHandler(unittest.TestCase): 'build': 'image-c-0.2-9', }, 'parent': self.image_a, - } - self.image_d = { + 'parsed_data': { + 'layers': [ + 'sha512:4ef3', + 'sha512:7890', + 'sha512:5678', + ] + }, + }) + self.image_d = ContainerImage({ 'repository': 'repo_2', 'commit': '5678901', 'target': 'docker-container-candidate', @@ -110,8 +138,15 @@ class TestErrataAdvisoryRPMsSignedHandler(unittest.TestCase): 'build': 'image-d-2.14-1', }, 'parent': self.image_a, - } - self.image_e = { + 'parsed_data': { + 'layers': [ + 'sha512:f109', + 'sha512:7890', + 'sha512:5678', + ] + }, + }) + self.image_e = ContainerImage({ 'repository': 'repo_2', 'commit': '7890123', 'target': 'docker-container-candidate', @@ -121,8 +156,15 @@ class TestErrataAdvisoryRPMsSignedHandler(unittest.TestCase): 'build': 'image-e-1.0-1', }, 'parent': self.image_b, - } - self.image_f = { + 'parsed_data': { + 'layers': [ + 'sha512:5aae', + 'sha512:1234', + 'sha512:4567', + ] + }, + }) + self.image_f = ContainerImage({ 'repository': 'repo_2', 'commit': '3829384', 'target': 'docker-container-candidate', @@ -132,7 +174,14 @@ class TestErrataAdvisoryRPMsSignedHandler(unittest.TestCase): 'build': 'image-f-0.2-1', }, 'parent': self.image_b, - } + 'parsed_data': { + 'layers': [ + 'sha512:8b9e', + 'sha512:1234', + 'sha512:4567', + ] + }, + }) # For simplicify, mocking _find_images_to_rebuild to just return one # batch, which contains images found for rebuild from parent to # childrens. @@ -145,6 +194,7 @@ class TestErrataAdvisoryRPMsSignedHandler(unittest.TestCase): ]) def tearDown(self): + self.request_boot_iso_compose_patcher.stop() self.find_images_patcher.stop() self.prepare_pulp_repo_patcher.stop() self.messaging_publish_patcher.stop() @@ -212,3 +262,205 @@ class TestErrataAdvisoryRPMsSignedHandler(unittest.TestCase): db_event = Event.get(db.session, event.msg_id) self.assertEqual(EventState.BUILDING.value, db_event.state) + + +class TestGetBaseImageBuildTarget(unittest.TestCase): + """Test ErrataAdvisoryRPMsSignedHandler._get_base_image_build_target""" + + def setUp(self): + self.image = ContainerImage({ + 'repository': 'repo_1', + 'commit': '1234567', + 'target': 'docker-container-candidate', + 'git_branch': 'rhel-7.4', + 'content_sets': ['image_a_content_set_1', 'image_a_content_set_2'], + 'brew': { + 'build': 'image-a-1.0-2', + }, + 'parent': None, + 'parsed_data': { + 'layers': [ + 'sha512:7890', + 'sha512:5678', + ], + 'files': [ + { + 'filename': 'Dockerfile', + 'content_url': 'http://pkgs.localhost/cgit/rpms/' + 'image-a/plain/Dockerfile?id=fa521323', + 'key': 'buildfile' + } + ] + }, + }) + self.handler = ErrataAdvisoryRPMsSignedHandler() + + @patch('requests.get') + def test_get_target_from_image_build_conf(self, get): + get.return_value.content = '''\ +[image-build] +name = image-a +arches = x86_64 +format = docker +disk_size = 10 +ksurl = git://git.localhost/spin-kickstarts.git?rhel7#HEAD +kickstart = rhel-7.4-server-docker.ks +version = 7.4 +target = guest-rhel-7.4-docker +distro = RHEL-7.4 +ksversion = RHEL7''' + + result = self.handler._get_base_image_build_target(self.image) + self.assertEqual('guest-rhel-7.4-docker', result) + + @patch('requests.get') + def test_image_build_conf_is_unavailable_in_distgit(self, get): + get.return_value.raise_for_status.side_effect = \ + requests.exceptions.HTTPError('error') + + result = self.handler._get_base_image_build_target(self.image) + self.assertIsNone(result) + + @patch('requests.get') + def test_image_build_conf_is_empty(self, get): + get.return_value.content = '' + + result = self.handler._get_base_image_build_target(self.image) + self.assertIsNone(result) + + @patch('requests.get') + def test_image_build_conf_is_not_INI(self, get): + get.return_value.content = 'abc' + + result = self.handler._get_base_image_build_target(self.image) + self.assertIsNone(result) + + +class TestGetBaseImageBuildTag(unittest.TestCase): + """Test ErrataAdvisoryRPMsSignedHandler._get_base_image_build_tag""" + + def setUp(self): + self.image = ContainerImage({ + 'repository': 'repo_1', + 'commit': '1234567', + 'target': 'docker-container-candidate', + 'git_branch': 'rhel-7.4', + 'content_sets': ['image_a_content_set_1', 'image_a_content_set_2'], + 'brew': { + 'build': 'image-a-1.0-2', + }, + 'parent': None, + 'parsed_data': { + 'layers': [ + 'sha512:7890', + 'sha512:5678', + ], + 'files': [ + { + 'filename': 'Dockerfile', + 'content_url': 'http://pkgs.localhost/cgit/rpms/' + 'image-a/plain/Dockerfile?id=fa521323', + 'key': 'buildfile' + } + ] + }, + }) + self.handler = ErrataAdvisoryRPMsSignedHandler() + + @patch('freshmaker.kojiservice.KojiService') + def test_get_build_tag_name(self, KojiService): + koji_service = KojiService.return_value + koji_service.get_build_target.return_value = { + 'build_tag': 10052, + 'build_tag_name': 'guest-rhel-7.4-docker-build', + 'dest_tag': 10051, + 'dest_tag_name': 'guest-rhel-7.4-candidate', + 'id': 3205, + 'name': 'guest-rhel-7.4-docker' + } + + result = self.handler._get_base_image_build_tag( + 'guest-rhel-7.4-docker') + self.assertEqual('guest-rhel-7.4-docker-build', result) + + @patch('freshmaker.kojiservice.KojiService') + def test_no_target_is_returned(self, KojiService): + koji_service = KojiService.return_value + koji_service.get_build_target.return_value = None + + result = self.handler._get_base_image_build_tag( + 'guest-rhel-7.4-docker') + self.assertIsNone(result) + + +class TestRequestBootISOCompose(unittest.TestCase): + """Test ErrataAdvisoryRPMsSignedHandler._request_boot_iso_compose""" + + def setUp(self): + self.image = ContainerImage({ + 'repository': 'repo_1', + 'commit': '1234567', + 'target': 'docker-container-candidate', + 'git_branch': 'rhel-7.4', + 'content_sets': ['image_a_content_set_1', 'image_a_content_set_2'], + 'brew': { + 'build': 'image-a-1.0-2', + }, + 'parent': None, + 'parsed_data': { + 'layers': [ + 'sha512:7890', + 'sha512:5678', + ], + 'files': [ + { + 'filename': 'Dockerfile', + 'content_url': 'http://pkgs.localhost/cgit/rpms/' + 'image-a/plain/Dockerfile?id=fa521323', + 'key': 'buildfile' + } + ] + }, + }) + self.handler = ErrataAdvisoryRPMsSignedHandler() + + @patch('freshmaker.handlers.errata.errata_advisory_rpms_signed.krb_context') + @patch('freshmaker.handlers.errata.errata_advisory_rpms_signed.ODCS') + @patch('freshmaker.handlers.errata.ErrataAdvisoryRPMsSignedHandler.' + '_get_base_image_build_target') + @patch('freshmaker.handlers.errata.ErrataAdvisoryRPMsSignedHandler.' + '_get_base_image_build_tag') + def test_get_boot_iso_compose( + self, get_base_image_build_tag, get_base_image_build_target, + ODCS, krb_context): + odcs = ODCS.return_value + odcs.new_compose.return_value = {'id': 1} + + get_base_image_build_target.return_value = 'build-target' + get_base_image_build_tag.return_value = 'build-tag' + + result = self.handler._request_boot_iso_compose(self.image) + + self.assertEqual(odcs.new_compose.return_value, result) + odcs.new_compose.assert_called_once_with( + 'build-tag', 'tag', results=['boot.iso']) + + @patch('freshmaker.handlers.errata.ErrataAdvisoryRPMsSignedHandler.' + '_get_base_image_build_target') + def test_cannot_get_image_build_target(self, get_base_image_build_target): + get_base_image_build_target.return_value = None + + result = self.handler._request_boot_iso_compose(self.image) + self.assertIsNone(result) + + @patch('freshmaker.handlers.errata.ErrataAdvisoryRPMsSignedHandler.' + '_get_base_image_build_target') + @patch('freshmaker.handlers.errata.ErrataAdvisoryRPMsSignedHandler.' + '_get_base_image_build_tag') + def test_cannot_get_build_tag_from_target( + self, get_base_image_build_tag, get_base_image_build_target): + get_base_image_build_target.return_value = 'build-target' + get_base_image_build_tag.return_value = None + + result = self.handler._request_boot_iso_compose(self.image) + self.assertIsNone(result) diff --git a/tests/test_errata_advisory_state_changed.py b/tests/test_errata_advisory_state_changed.py index 4b8e067..82fa0e3 100644 --- a/tests/test_errata_advisory_state_changed.py +++ b/tests/test_errata_advisory_state_changed.py @@ -26,13 +26,13 @@ import json from mock import patch, PropertyMock, Mock, call -from freshmaker.handlers.errata import ErrataAdvisoryRPMsSignedHandler -from freshmaker.handlers.errata import ErrataAdvisoryStateChangedHandler +from freshmaker import conf, db, events +from freshmaker.errata import ErrataAdvisory from freshmaker.events import ErrataAdvisoryRPMsSignedEvent from freshmaker.events import ErrataAdvisoryStateChangedEvent -from freshmaker.errata import ErrataAdvisory - -from freshmaker import conf, db, events +from freshmaker.handlers.errata import ErrataAdvisoryRPMsSignedHandler +from freshmaker.handlers.errata import ErrataAdvisoryStateChangedHandler +from freshmaker.lightblue import ContainerImage from freshmaker.models import Event, ArtifactBuild, EVENT_TYPES from freshmaker.types import ArtifactBuildState, ArtifactType, EventState @@ -271,10 +271,23 @@ class TestBatches(unittest.TestCase): def _mock_build(self, build, parent=None, error=None): if parent: parent = {"brew": {"build": parent + "-1-1.25"}} - return {'brew': {'build': build + "-1-1.25"}, - 'repository': build + '_repo', 'commit': build + '_123', - 'parent': parent, "target": "t1", 'git_branch': 'mybranch', - "error": error, "content_sets": ["first-content-set"]} + return ContainerImage({ + 'brew': {'build': build + "-1-1.25"}, + 'repository': build + '_repo', + 'parsed_data': { + 'layers': [ + 'sha512:1234', + 'sha512:4567', + 'sha512:7890', + ], + }, + 'commit': build + '_123', + 'parent': parent, + "target": "t1", + 'git_branch': 'mybranch', + "error": error, + "content_sets": ["first-content-set"] + }) @patch('freshmaker.handlers.errata.errata_advisory_rpms_signed.ODCS.new_compose') @patch('freshmaker.handlers.errata.errata_advisory_rpms_signed.ODCS.get_compose') @@ -901,7 +914,15 @@ class TestRecordBatchesImages(unittest.TestCase): side_effect=[{'id': 1}, {'id': 2}]) self.mock_prepare_pulp_repo = self.prepare_pulp_repo_patcher.start() + self.request_boot_iso_compose_patcher = patch( + 'freshmaker.handlers.errata.' + 'ErrataAdvisoryRPMsSignedHandler._request_boot_iso_compose', + side_effect=[{'id': 100}, {'id': 200}]) + self.mock_request_boot_iso_compose = \ + self.request_boot_iso_compose_patcher.start() + def tearDown(self): + self.request_boot_iso_compose_patcher.stop() self.prepare_pulp_repo_patcher.stop() self.event_types_patcher.stop() @@ -911,12 +932,18 @@ class TestRecordBatchesImages(unittest.TestCase): def test_record_batches(self): batches = [ - [{ + [ContainerImage({ "brew": { "completion_date": "20170420T17:05:37.000-0400", "build": "rhel-server-docker-7.3-82", "package": "rhel-server-docker" }, + 'parsed_data': { + 'layers': [ + 'sha512:12345678980', + 'sha512:10987654321' + ] + }, "parent": None, "content_sets": ["content-set-1"], "repository": "repo-1", @@ -924,19 +951,32 @@ class TestRecordBatchesImages(unittest.TestCase): "target": "target-candidate", "git_branch": "rhel-7", "error": None - }], - [{ + })], + [ContainerImage({ "brew": { "build": "rh-dotnetcore10-docker-1.0-16", "package": "rh-dotnetcore10-docker", "completion_date": "20170511T10:06:09.000-0400" }, - "parent": { + 'parsed_data': { + 'layers': [ + 'sha512:2345af2e293', + 'sha512:12345678980', + 'sha512:10987654321' + ] + }, + "parent": ContainerImage({ "brew": { "completion_date": "20170420T17:05:37.000-0400", "build": "rhel-server-docker-7.3-82", "package": "rhel-server-docker" }, + 'parsed_data': { + 'layers': [ + 'sha512:12345678980', + 'sha512:10987654321' + ] + }, "parent": None, "content_sets": ["content-set-1"], "repository": "repo-1", @@ -944,14 +984,14 @@ class TestRecordBatchesImages(unittest.TestCase): "target": "target-candidate", "git_branch": "rhel-7", "error": None - }, + }), "content_sets": ["content-set-1"], "repository": "repo-1", "commit": "987654321", "target": "target-candidate", "git_branch": "rhel-7", "error": None - }] + })] ] handler = ErrataAdvisoryRPMsSignedHandler() @@ -975,12 +1015,18 @@ class TestRecordBatchesImages(unittest.TestCase): def test_pulp_compose_is_stored_for_each_build(self): batches = [ - [{ + [ContainerImage({ "brew": { "completion_date": "20170420T17:05:37.000-0400", "build": "rhel-server-docker-7.3-82", "package": "rhel-server-docker" }, + 'parsed_data': { + 'layers': [ + 'sha512:12345678980', + 'sha512:10987654321' + ] + }, "parent": None, "content_sets": ["content-set-1"], "repository": "repo-1", @@ -988,19 +1034,32 @@ class TestRecordBatchesImages(unittest.TestCase): "target": "target-candidate", "git_branch": "rhel-7", "error": None - }], - [{ + })], + [ContainerImage({ "brew": { "build": "rh-dotnetcore10-docker-1.0-16", "package": "rh-dotnetcore10-docker", "completion_date": "20170511T10:06:09.000-0400" }, - "parent": { + 'parsed_data': { + 'layers': [ + 'sha512:2345af2e293', + 'sha512:12345678980', + 'sha512:10987654321' + ] + }, + "parent": ContainerImage({ "brew": { "completion_date": "20170420T17:05:37.000-0400", "build": "rhel-server-docker-7.3-82", "package": "rhel-server-docker" }, + 'parsed_data': { + 'layers': [ + 'sha512:12345678980', + 'sha512:10987654321' + ] + }, "parent": None, "content_sets": ["content-set-1"], "repository": "repo-1", @@ -1008,14 +1067,14 @@ class TestRecordBatchesImages(unittest.TestCase): "target": "target-candidate", "git_branch": "rhel-7", "error": None - }, + }), "content_sets": ["content-set-1"], "repository": "repo-1", "commit": "987654321", "target": "target-candidate", "git_branch": "rhel-7", "error": None - }] + })] ] handler = ErrataAdvisoryRPMsSignedHandler() @@ -1025,28 +1084,40 @@ class TestRecordBatchesImages(unittest.TestCase): parent_build = query.filter( ArtifactBuild.original_nvr == 'rhel-server-docker-7.3-82' ).first() - self.assertEqual(1, len(parent_build.composes)) - self.assertEqual(1, parent_build.composes[0].compose.id) + self.assertEqual(2, len(parent_build.composes)) + compose_ids = sorted([rel.compose.odcs_compose_id + for rel in parent_build.composes]) + # Ensure both pulp compose id and boot.iso compose id are stored + self.assertEqual([1, 100], compose_ids) child_build = query.filter( ArtifactBuild.original_nvr == 'rh-dotnetcore10-docker-1.0-16' ).first() self.assertEqual(1, len(child_build.composes)) - self.assertEqual(2, child_build.composes[0].compose.id) + self.assertEqual(2, child_build.composes[0].compose.odcs_compose_id) self.mock_prepare_pulp_repo.assert_has_calls([ call(child_build.event, ["content-set-1"]), call(child_build.event, ["content-set-1"]) ]) + self.mock_request_boot_iso_compose.assert_called_once_with( + batches[0][0]) + def test_mark_failed_state_if_image_has_error(self): batches = [ - [{ + [ContainerImage({ "brew": { "completion_date": "20170420T17:05:37.000-0400", "build": "rhel-server-docker-7.3-82", "package": "rhel-server-docker" }, + 'parsed_data': { + 'layers': [ + 'sha512:12345678980', + 'sha512:10987654321' + ] + }, "parent": None, "content_sets": ["content-set-1"], "repository": "repo-1", @@ -1054,7 +1125,7 @@ class TestRecordBatchesImages(unittest.TestCase): "target": "target-candidate", "git_branch": "rhel-7", "error": "Some error occurs while getting this image." - }] + })] ] handler = ErrataAdvisoryRPMsSignedHandler() @@ -1069,12 +1140,18 @@ class TestRecordBatchesImages(unittest.TestCase): def test_mark_state_failed_if_depended_image_is_failed(self): batches = [ - [{ + [ContainerImage({ "brew": { "completion_date": "20170420T17:05:37.000-0400", "build": "rhel-server-docker-7.3-82", "package": "rhel-server-docker" }, + 'parsed_data': { + 'layers': [ + 'sha512:12345678980', + 'sha512:10987654321' + ] + }, "parent": None, "content_sets": ["content-set-1"], "repository": "repo-1", @@ -1082,19 +1159,32 @@ class TestRecordBatchesImages(unittest.TestCase): "target": "target-candidate", "git_branch": "rhel-7", "error": "Some error occured." - }], - [{ + })], + [ContainerImage({ "brew": { "build": "rh-dotnetcore10-docker-1.0-16", "package": "rh-dotnetcore10-docker", "completion_date": "20170511T10:06:09.000-0400" }, - "parent": { + 'parsed_data': { + 'layers': [ + 'sha512:378a8ef2730', + 'sha512:12345678980', + 'sha512:10987654321' + ] + }, + "parent": ContainerImage({ "brew": { "completion_date": "20170420T17:05:37.000-0400", "build": "rhel-server-docker-7.3-82", "package": "rhel-server-docker" }, + 'parsed_data': { + 'layers': [ + 'sha512:12345678980', + 'sha512:10987654321' + ] + }, "parent": None, "content_sets": ["content-set-1"], "repository": "repo-1", @@ -1102,14 +1192,14 @@ class TestRecordBatchesImages(unittest.TestCase): "target": "target-candidate", "git_branch": "rhel-7", "error": None - }, + }), "content_sets": ["content-set-1"], "repository": "repo-1", "commit": "987654321", "target": "target-candidate", "git_branch": "rhel-7", "error": "Some error occured too." - }] + })] ] handler = ErrataAdvisoryRPMsSignedHandler() @@ -1126,6 +1216,37 @@ class TestRecordBatchesImages(unittest.TestCase): ).first() self.assertEqual(ArtifactBuildState.FAILED.value, build.state) + def test_mark_base_image_failed_if_fail_to_request_boot_iso_compose(self): + batches = [ + [ContainerImage({ + "brew": { + "completion_date": "20170420T17:05:37.000-0400", + "build": "rhel-server-docker-7.3-82", + "package": "rhel-server-docker" + }, + 'parsed_data': { + 'layers': [ + 'sha512:12345678980', + 'sha512:10987654321' + ] + }, + "parent": None, + "content_sets": ["content-set-1"], + "repository": "repo-1", + "commit": "123456789", + "target": "target-candidate", + "git_branch": "rhel-7", + "error": "Some error occured." + })], + ] + + handler = ErrataAdvisoryRPMsSignedHandler() + handler._record_batches(batches, self.mock_event) + + build = db.session.query(ArtifactBuild).filter_by( + original_nvr='rhel-server-docker-7.3-82').first() + self.assertEqual(ArtifactBuildState.FAILED.value, build.state) + class TestPrepareYumReposForRebuilds(unittest.TestCase): """Test ErrataAdvisoryRPMsSignedHandler._prepare_yum_repos_for_rebuilds"""