def handle_srpm_end(self): url = get_srpm_build_info_url(self.build.id) if self.copr_event.status != COPR_API_SUCC_STATE: failed_msg = "SRPM build failed, check the logs for details." self.copr_build_helper.report_status_to_all( state=BaseCommitStatus.failure, description=failed_msg, url=url, ) self.build.set_status(PG_BUILD_STATUS_FAILURE) self.copr_build_helper.monitor_not_submitted_copr_builds( len(self.copr_build_helper.build_targets), "srpm_failure") return TaskResults(success=False, details={"msg": failed_msg}) for build in CoprBuildModel.get_all_by_build_id( str(self.copr_event.build_id)): # from waiting_for_srpm to pending build.set_status("pending") self.build.set_status(PG_BUILD_STATUS_SUCCESS) self.copr_build_helper.report_status_to_all( state=BaseCommitStatus.running, description= "SRPM build succeeded. Waiting for RPM build to start...", url=url, ) msg = "SRPM build in Copr has finished." logger.debug(msg) return TaskResults(success=True, details={"msg": msg})
def check_copr_build(build_id: int) -> bool: """ Check the copr_build with given id and refresh the status if needed. Used in the babysit task. :param build_id: id of the copr_build (CoprBuildModel.build.id) :return: True if in case of successful run, False when we need to retry """ logger.debug(f"Getting copr build ID {build_id} from DB.") builds = CoprBuildModel.get_all_by_build_id(build_id) if not builds: logger.warning(f"Copr build {build_id} not in DB.") return True copr_client = CoprClient.create_from_config_file() build_copr = copr_client.build_proxy.get(build_id) if not build_copr.ended_on: logger.info("The copr build is still in progress.") return False logger.info(f"The status is {build_copr.state!r}.") for build in builds: if build.status != "pending": logger.info(f"DB state says {build.status!r}, " "things were taken care of already, skipping.") continue chroot_build = copr_client.build_chroot_proxy.get( build_id, build.target) event = CoprBuildEvent( topic=FedmsgTopic.copr_build_finished.value, build_id=build_id, build=build, chroot=build.target, status=(COPR_API_SUCC_STATE if chroot_build.state == COPR_SUCC_STATE else COPR_API_FAIL_STATE), owner=build.owner, project_name=build.project_name, pkg=build_copr.source_package.get( "name", ""), # this seems to be the SRPM name timestamp=chroot_build.ended_on, ) job_configs = get_config_for_handler_kls( handler_kls=CoprBuildEndHandler, event=event, package_config=event.get_package_config(), ) for job_config in job_configs: CoprBuildEndHandler( package_config=event.package_config, job_config=job_config, data=EventData.from_event_dict(event.get_dict()), copr_event=event, ).run() return True
def get(self): """ List all Copr builds. """ # Return relevant info thats concise # Usecases like the packit-dashboard copr-builds table result = [] checklist = [] first, last = indices() for build in islice(CoprBuildModel.get_all(), first, last): if int(build.build_id) not in checklist: build_dict = { "project": build.project_name, "owner": build.owner, "build_id": build.build_id, "status": build.status, # Legacy, remove later. "status_per_chroot": {}, "chroots": [], "build_submitted_time": optional_time(build.build_submitted_time), "web_url": build.web_url, } project = build.get_project() if project: build_dict["repo_namespace"] = project.namespace build_dict["repo_name"] = project.repo_name # same_buildid_builds are copr builds created due to the same trigger # multiple identical builds are created which differ only in target # so we merge them into one same_buildid_builds = CoprBuildModel.get_all_by_build_id( str(build.build_id)) for sbid_build in same_buildid_builds: build_dict["chroots"].append(sbid_build.target) # Get status per chroot as well build_dict["status_per_chroot"][ sbid_build.target] = sbid_build.status checklist.append(int(build.build_id)) result.append(build_dict) resp = make_response(dumps(result), HTTPStatus.PARTIAL_CONTENT) resp.headers[ "Content-Range"] = f"copr-builds {first + 1}-{last}/{len(result)}" resp.headers["Content-Type"] = "application/json" return resp
def get(self, id): """A specific copr build details. From copr_build hash, filled by worker.""" builds_list = CoprBuildModel.get_all_by_build_id(str(id)) if bool(builds_list.first()): build = builds_list[0] build_dict = { "project": build.project_name, "owner": build.owner, "build_id": build.build_id, "status": build.status, # Legacy, remove later. "status_per_chroot": {}, "chroots": [], "build_submitted_time": optional_time(build.build_submitted_time), "build_start_time": optional_time(build.build_start_time), "build_finished_time": optional_time(build.build_finished_time), "commit_sha": build.commit_sha, "web_url": build.web_url, "srpm_logs": build.srpm_build.logs if build.srpm_build else None, # For backwards compatability with the old redis based API "ref": build.commit_sha, } project = build.get_project() if project: build_dict["repo_namespace"] = project.namespace build_dict["repo_name"] = project.repo_name build_dict[ "git_repo"] = f"https://github.com/{project.namespace}/{project.repo_name}" build_dict[ "https_url"] = f"https://github.com/{project.namespace}/{project.repo_name}.git" build_dict["pr_id"] = build.get_pr_id() # merge chroots into one for sbid_build in builds_list: build_dict["chroots"].append(sbid_build.target) # Get status per chroot as well build_dict["status_per_chroot"][ sbid_build.target] = sbid_build.status build = make_response(dumps(build_dict)) build.headers["Content-Type"] = "application/json" build.headers["Access-Control-Allow-Origin"] = "*" return build if build else ("", HTTPStatus.NO_CONTENT) else: return "", HTTPStatus.NO_CONTENT
def check_copr_build(build_id: int) -> bool: """ Check the copr_build with given id and refresh the status if needed. Used in the babysit task. Args: build_id (int): ID of the copr build to check. Returns: bool: Whether the run was successful, False signals the need to retry. """ logger.debug(f"Getting copr build ID {build_id} from DB.") builds = CoprBuildModel.get_all_by_build_id(build_id) if not builds: logger.warning(f"Copr build {build_id} not in DB.") return True return update_copr_builds(build_id, builds)
def get(self, id): """A specific copr build details. From copr_build hash, filled by worker.""" builds_list = CoprBuildModel.get_all_by_build_id(str(id)) if not bool(builds_list.first()): return response_maker( {"error": "No info about build stored in DB"}, status=HTTPStatus.NOT_FOUND.value, ) build = builds_list[0] build_dict = { "project": build.project_name, "owner": build.owner, "build_id": build.build_id, "status": build.status, # Legacy, remove later. "status_per_chroot": {}, "chroots": [], "build_submitted_time": optional_time(build.build_submitted_time), "build_start_time": optional_time(build.build_start_time), "build_finished_time": optional_time(build.build_finished_time), "commit_sha": build.commit_sha, "web_url": build.web_url, "srpm_logs": build.srpm_build.logs if build.srpm_build else None, # For backwards compatability with the old redis based API "ref": build.commit_sha, } project = build.get_project() if project: build_dict["repo_namespace"] = project.namespace build_dict["repo_name"] = project.repo_name build_dict["git_repo"] = project.project_url build_dict["pr_id"] = build.get_pr_id() build_dict["branch_name"] = build.get_branch_name() # merge chroots into one for sbid_build in builds_list: build_dict["chroots"].append(sbid_build.target) # Get status per chroot as well build_dict["status_per_chroot"][ sbid_build.target] = sbid_build.status return response_maker(build_dict)
def copr_build_helper(self) -> CoprBuildJobHelper: # when reporting state of SRPM build built in Copr targets_override = ({ build.target for build in CoprBuildModel.get_all_by_build_id( str(self.copr_event.build_id)) } if self.copr_event.chroot == COPR_SRPM_CHROOT else None) if not self._copr_build_helper: self._copr_build_helper = CoprBuildJobHelper( service_config=self.service_config, package_config=self.package_config, project=self.project, metadata=self.data, db_trigger=self.db_trigger, job_config=self.job_config, pushgateway=self.pushgateway, targets_override=targets_override, ) return self._copr_build_helper
def babysit_copr_build(self, build_id: int): """ check status of a copr build and update it in DB """ logger.debug(f"getting copr build ID {build_id} from DB") builds = CoprBuildModel.get_all_by_build_id(build_id) if builds: copr_client = CoprClient.create_from_config_file() build_copr = copr_client.build_proxy.get(build_id) if not build_copr.ended_on: logger.info("The copr build is still in progress") self.retry() logger.info(f"The status is {build_copr.state}") for build in builds: if build.status != "pending": logger.info(f"DB state says {build.status}, " "things were taken care of already, skipping.") continue chroot_build = copr_client.build_chroot_proxy.get( build_id, build.target) event = CoprBuildEvent( topic=FedmsgTopic.copr_build_finished.value, build_id=build_id, build=build, chroot=build.target, status=(COPR_API_SUCC_STATE if chroot_build.state == COPR_SUCC_STATE else COPR_API_FAIL_STATE), owner=build.owner, project_name=build.project_name, pkg=build_copr.source_package.get( "name", ""), # this seems to be the SRPM name ) CoprBuildEndHandler(ServiceConfig.get_service_config(), job_config=None, event=event).run() else: logger.warning(f"Copr build {build_id} not in DB.")
def test_get_all_build_id(clean_before_and_after, multiple_copr_builds): builds_list = list(CoprBuildModel.get_all_by_build_id(str(123456))) assert len(builds_list) == 2 # both should have the same project_name assert builds_list[1].project_name == builds_list[0].project_name assert builds_list[1].project_name == "the-project-name"
def test_get_all_build_id(clean_before_and_after, multiple_copr_builds): builds_list = CoprBuildModel.get_all_by_build_id(str(123456)) assert len(list(builds_list)) == 2 # both should have the same project_name assert builds_list[1].project_name == builds_list[0].project_name assert builds_list[1].project_name == "SomeUser-hello-world-9"