def _get_fake_container_image(self, architecture='amd64', arches='x86_64'): rpm_manifest = [{ u'rpms': [{ u'architecture': architecture, u'gpg': u'199e2f91fd431d51', u'name': u'apache-commons-lang', u'nvra': u'apache-commons-lang-2.6-15.el7.noarch', u'release': u'15.el7', u'srpm_name': u'apache-commons-lang', u'srpm_nevra': u'apache-commons-lang-0:2.6-15.el7.src', u'summary': u'Provides a host of helper utilities for the java.lang API', u'version': u'2.6' }, { u'architecture': architecture, u'gpg': u'199e2f91fd431d51', u'name': u'avalon-logkit', u'nvra': u'avalon-logkit-2.1-14.el7.noarch', u'release': u'14.el7', u'srpm_name': u'avalon-logkit', u'srpm_nevra': u'avalon-logkit-0:2.1-14.el7.src', u'summary': u'Java logging toolkit', u'version': u'2.1' }] }] return ContainerImage.create({ u'arches': arches, # Populated based on Brew build u'architecture': architecture, # Populated from Lightblue data u'rpm_manifest': rpm_manifest, })
def _prepare_builds(self, db_event, bundles_by_digest, to_rebuild_digests): """ Prepare models.ArtifactBuild instance for every bundle that will be rebuilt :param models.Event db_event: database event that will contain builds :param dict bundles_by_digest: mapping of bundle digest to bundle data :param list to_rebuild_digests: digests of bundles to rebuild :return: builds that already in database and ready to be submitted to brew :rtype: list """ builds = [] csv_mod_url = conf.freshmaker_root_url + "/api/2/pullspec_overrides/{}" for digest in to_rebuild_digests: bundle = bundles_by_digest[digest] # Reset context to db_event for each iteration before # the ArtifactBuild is created. self.set_context(db_event) rebuild_reason = RebuildReason.DIRECTLY_AFFECTED.value bundle_name = koji.parse_NVR(bundle["nvr"])["name"] build = self.record_build(db_event, bundle_name, ArtifactType.IMAGE, state=ArtifactBuildState.PLANNED.value, original_nvr=bundle["nvr"], rebuild_reason=rebuild_reason) # Set context to particular build so logging shows this build # in case of error. self.set_context(build) build.transition(ArtifactBuildState.PLANNED.value, "") additional_data = ContainerImage.get_additional_data_from_koji( bundle["nvr"]) build.build_args = json.dumps({ "repository": additional_data["repository"], "commit": additional_data["commit"], "target": additional_data["target"], "branch": additional_data["git_branch"], "arches": additional_data["arches"], "operator_csv_modifications_url": csv_mod_url.format(build.id), }) build.bundle_pullspec_overrides = { "append": bundle["append"], "pullspecs": bundle["pullspecs"], "update": bundle["update"], } db.session.commit() builds.append(build) return builds
def test_verify_repository(self): self.lb.find_container_repositories.return_value = [ ContainerRepository({ "repository": "foo/bar", "release_categories": ["Generally Available"], "published": True, "auto_rebuild_tags": ["latest"] }) ] self.lb.find_images_with_included_rpms.return_value = [ ContainerImage({ "brew": { "build": "foo-1-1" }, "content_sets": ["content-set"], "repositories": [ { "registry": "registry.example.com", "published": True, "repository": "foo/bar", "tags": [{ "name": "1" }, { "name": "latest" }, { "name": "1-1" }], }, { "registry": "registry.build.example.com", "published": False, "repository": "buildsys/foobar", "tags": [{ "name": "1-1" }, { "name": "1.old" }], }, ] }) ] ret = self.verifier.verify_repository("foo/bar") expected = { "repository": { "auto_rebuild_tags": ["latest"] }, "images": { "foo-1-1": { "content_sets": ["content-set"], "tags": ["1", "latest", "1-1"] } }, } self.assertEqual(ret, expected)
def test_get_verify_image(self): self.lb.find_container_repositories.return_value = [ ContainerRepository({ "repository": "foo/bar", "release_categories": ["Generally Available"], "published": True, "auto_rebuild_tags": ["latest"] }) ] self.lb.get_images_by_nvrs.return_value = [ ContainerImage({ "brew": {"build": "foo-1-1"}, "content_sets": ["content-set"] }) ] ret = self.verifier.verify_image("foo-1-1") self.assertEqual(ret, {"foo-1-1": ["content-set"]})
def test_verify_repository_no_content_sets(self): self.lb.find_container_repositories.return_value = [ ContainerRepository({ "repository": "foo/bar", "release_categories": ["Generally Available"], "published": True, "auto_rebuild_tags": ["latest"] }) ] self.lb.find_images_with_included_srpms.return_value = [ ContainerImage({ "brew": {"build": "foo-1-1"}, "content_sets": [] }) ] self.assertRaisesRegex( ValueError, r'.*are not set for this image.', self.verifier.verify_repository, "foo/bar")
def setUp(self): super(TestRebuildImagesOnAsyncManualBuild, self).setUp() self.patcher = helpers.Patcher( 'freshmaker.handlers.koji.RebuildImagesOnAsyncManualBuild.') # We do not want to send messages to message bus while running tests self.mock_messaging_publish = self.patcher.patch( 'freshmaker.messaging.publish') # Mocking koji self.mock_get_build = self.patcher.patch( 'freshmaker.kojiservice.KojiService.get_build', return_value={'build_id': 123456, 'extra': {'container_koji_task_id': 21938204}}) self.mock_get_task_request = self.patcher.patch( 'freshmaker.kojiservice.KojiService.get_task_request', return_value=[ 'git://example.com/rpms/repo-1#commit_hash1', 'test-target', {'compose_ids': None, 'git_branch': 'test_branch', 'scratch': False, 'signing_intent': None, 'yum_repourls': [('fake-url.repo')]}]) self.mock_allow_build = self.patcher.patch('allow_build', return_value=True) # Mocking Lightblue self.mock_find_images_to_rebuild = self.patcher.patch('_find_images_to_rebuild') self.mock_lightblue = self.patcher.patch('init_lightblue_instance') self.mock_start_to_build_images = self.patcher.patch('start_to_build_images') self.mock_get_image_builds_in_first_batch = self.patcher.patch( 'freshmaker.models.Event.get_image_builds_in_first_batch') # Structure of the images used for testing: # image_0 # + # | # + # image_a # + # | # +----+----+ # | | # + + # image_b image_d # + # | # + # image_e # image_c and image_f are unrelated. # image_0 is a base image, with no parent self.image_0 = ContainerImage({ 'repository': 'repo_1', 'commit': '1234567', 'target': 'container-candidate', 'git_branch': 'test_branch', 'content_sets': ['image_0_content_set_1', 'image_0_content_set_2'], 'arches': 'x86_64', 'brew': { 'build': 'image-container-1.0-2', 'package': 'image-container', }, 'parent': None, 'parsed_data': { 'layers': [ 'sha512:7890', 'sha512:5678', ] }, 'published': False, }) self.image_a = ContainerImage({ 'repository': 'repo_1', 'commit': '1234567', 'target': 'container-candidate', 'git_branch': 'test_branch', 'content_sets': ['image_a_content_set_1', 'image_a_content_set_2'], 'arches': 'x86_64', 'brew': { 'build': 'image-a-container-1.0-2', 'package': 'image-a-container', }, 'parent': self.image_0, 'parsed_data': { 'layers': [ 'sha512:7890', 'sha512:5678', ] }, 'published': False, }) # image_b is a child image of image_a self.image_b = ContainerImage({ 'repository': 'repo_2', 'commit': '5678901', 'target': 'container-candidate', 'git_branch': 'test_branch', 'content_sets': ['image_b_content_set_1', 'image_b_content_set_2'], 'arches': 'x86_64', 'brew': { 'build': 'image-b-container-2.14-1', 'package': 'image-b-container' }, 'parent': self.image_a, 'parsed_data': { 'layers': [ 'sha512:f109', 'sha512:7890', 'sha512:5678', ] }, 'published': False, }) # image_c is an image unrelated to image_a and image_b # it also has no parent image. # image_c has the same name of image_a, that's why it has this name self.image_c = ContainerImage({ 'repository': 'repo_1', 'commit': '1234569', 'target': 'container-candidate', 'git_branch': 'test_branch', 'content_sets': ['image_a_content_set_1', 'image_a_content_set_2'], 'arches': 'x86_64', 'brew': { 'build': 'image-a-container-1.0-3', 'package': 'image-a-container', }, 'parent': None, 'parsed_data': { 'layers': [ 'sha512:7890', 'sha512:5678', ] }, 'published': False, }) # image_d is a child image of image_a, same as image_b # so image_d and image_b are unrelated, since they are sibilings self.image_d = ContainerImage({ 'repository': 'repo_2', 'commit': '5678906', 'target': 'container-candidate', 'git_branch': 'test_branch', 'content_sets': ['image_d_content_set_1', 'image_d_content_set_2'], 'arches': 'x86_64', 'brew': { 'build': 'image-d-container-3.3-1', 'package': 'image-d-container' }, 'parent': self.image_a, 'parsed_data': { 'layers': [ 'sha512:f109', ] }, 'published': False, }) # image_e is a child image of image_d self.image_e = ContainerImage({ 'repository': 'repo_2', 'commit': '5678906', 'target': 'container-candidate', 'git_branch': 'test_branch', 'content_sets': ['image_e_content_set_1', 'image_e_content_set_2'], 'arches': 'x86_64', 'brew': { 'build': 'image-e-container-3.3-1', 'package': 'image-e-container' }, 'parent': self.image_d, 'parsed_data': { 'layers': [ 'sha512:f109', ] }, 'published': False, }) self.image_f = ContainerImage({ 'architecture': 'arm64', 'brew': {'build': 's2i-core-container-1-147', 'completion_date': '20200603T12:00:24.000-0400', 'nvra': 's2i-core-container-1-147.arm64', 'package': 's2i-core-container'}, 'content_sets': ['rhel-8-for-x86_64-appstream-rpms', 'rhel-8-for-aarch64-baseos-rpms', 'rhel-8-for-x86_64-baseos-rpms', 'rhel-8-for-s390x-baseos-rpms', 'rhel-8-for-aarch64-appstream-rpms', 'rhel-8-for-ppc64le-appstream-rpms', 'rhel-8-for-ppc64le-baseos-rpms', 'rhel-8-for-s390x-appstream-rpms'], 'multi_arch_rpm_manifest': {}, 'parent_brew_build': 'ubi8-container-8.2-299', 'parsed_data': {}, 'repositories': [{'published': True, 'repository': 'rhel8/s2i-core', 'tags': [{'name': '1-147'}]}, {'published': True, 'repository': 'ubi8/s2i-core', 'tags': [{'name': '1-147'}]}] })
def _prepare_builds(self, db_event, to_rebuild_bundles): """ Prepare models.ArtifactBuild instance for every bundle that will be rebuilt :param models.Event db_event: database event that will contain builds :param list to_rebuild_bundles: bundles to rebuild :return: builds that already in database and ready to be submitted to brew :rtype: list """ builds = [] csv_mod_url = conf.freshmaker_root_url + "/api/2/pullspec_overrides/{}" for bundle in to_rebuild_bundles: # Reset context to db_event for each iteration before # the ArtifactBuild is created. self.set_context(db_event) rebuild_reason = RebuildReason.DIRECTLY_AFFECTED.value bundle_name = koji.parse_NVR(bundle["nvr"])["name"] build = self.record_build(db_event, bundle_name, ArtifactType.IMAGE, state=ArtifactBuildState.PLANNED.value, original_nvr=bundle["nvr"], rebuild_reason=rebuild_reason) # Set context to particular build so logging shows this build # in case of error. self.set_context(build) build.transition(ArtifactBuildState.PLANNED.value, "") additional_data = ContainerImage.get_additional_data_from_koji( bundle["nvr"]) build.build_args = json.dumps({ "repository": additional_data["repository"], "commit": additional_data["commit"], "target": additional_data["target"], "branch": additional_data["git_branch"], "arches": additional_data["arches"], # The build system always enforces that bundle images build from # "scratch", so there is no parent image. See: # https://osbs.readthedocs.io/en/latest/users.html?#operator-manifest-bundle-builds "original_parent": None, "operator_csv_modifications_url": csv_mod_url.format(build.id), }) build.bundle_pullspec_overrides = { "pullspec_replacements": bundle["pullspec_replacements"], "update": bundle["update"], } db.session.commit() builds.append(build) return builds