def test_get_nvr(self): lst = [{"nvr": "foo-1-10"}, {"nvr": "foo-1-2"}, {"nvr": "foo-1-1"}] expected = [{ "nvr": "foo-1-1" }, { "nvr": "foo-1-2" }, { "nvr": "foo-1-10" }] ret = sorted_by_nvr(lst, lambda x: x["nvr"]) self.assertEqual(ret, expected)
def test_names_not_equal_reverse(self): lst = ["foo-1-10", "bar-1-2", "foo-1-1"] expected = ["bar-1-2", "foo-1-1", "foo-1-10"] ret = sorted_by_nvr(lst, reverse=True) self.assertEqual(ret, list(reversed(expected)))
def test_names_not_equal(self): lst = ["foo-1-10", "bar-1-2", "foo-1-1"] expected = ["bar-1-2", "foo-1-1", "foo-1-10"] ret = sorted_by_nvr(lst) self.assertEqual(ret, expected)
def test_simple_list_reverse(self): lst = ["foo-1-1", "foo-1-2", "foo-1-10"] expected = ["foo-1-10", "foo-1-2", "foo-1-1"] ret = sorted_by_nvr(lst, reverse=True) self.assertEqual(ret, expected)
def filter_images_based_on_dist_git_branch(self, images, db_event): """ Filter images based on the dist-git branch requested by the user. If the images were never be built for that branch, let's skip the build. The input images are all the images matching a specific name. In this method we also select the images with higher NVR for the same name (package). :param images list: images to rebuild. :param db_event Event: event object in the db. :return: list of images to rebuild. If the event gets skipped, return empty list. :rtype: list """ with koji_service(conf.koji_profile, log, dry_run=conf.dry_run, login=False) as session: # Sort images by nvr images = sorted_by_nvr(images, reverse=True) # Use a dict to map a package (name) to the highest NVR image. For example: # {"ubi8-container": ContainerImage<nvr=ubi8-container-8.1-100>, # "nodejs-12-container": ContainerImage<nvr=nodejs12-container-1.0-101>)} images_to_rebuild = {} # In case the user requested to build ['s2i-core-container', 'cnv-libvirt-container'] # lightblue will return a bunch of NVRs for each name, example: # * s2i-core-container-1-127 # * s2i-core-container-1-126 # * ... # * cnv-libvirt-container-1.3-1 # * cnv-libvirt-container-1.2-4 # * ... # Since `images` is a list of sorted NVRs, we just need to select the first NVR for # each package (name). for image in images: build = None git_branch = None package = image['brew']['package'] # if package is already in images_to_rebuild we don't need to keep searching # since the images were sorted by NVR in the beginning if package not in images_to_rebuild: # Let's get the branch for this image build = session.get_build(image.nvr) task_id = build.get("extra", {}).get("container_koji_task_id") if task_id: task = session.get_task_request(task_id) # The task_info should always be in the 3rd element task_info = task[2] git_branch = task_info.get("git_branch") if len( task_info) else None if (build and task_id and git_branch and self.event.dist_git_branch == git_branch): images_to_rebuild[package] = image if not images_to_rebuild or len(images_to_rebuild) < len( self.event.container_images): # If we didn't find images to rebuild, or we found less than what the user asked # it means that some of those images were never been built before for the requested # branch. In this case we need to throw an error because we won't build something # that was never built before. # We cannot return to the API with an error, because the request already completed # at this point. Let's mark this build as FAILED then. msg = ( "One or more of the requested image was never built before for the " f"requested branch: {self.event.dist_git_branch}. " "Cannot build it, please change your request.") missing_images = set(self.event.container_images) - set( images_to_rebuild.keys()) if missing_images: msg += f" Problematic images are {missing_images}" db_event.transition(EventState.FAILED, msg) db.session.commit() self.log_info(msg) return [] # The result needs to be a list return list(images_to_rebuild.values())