def get_builds(self, number_of_builds: int = 3) -> None: """ Get specific number of latest builds from koji :param number_of_builds: int :return: None """ logger.info("\nLatest builds:") # https://github.com/fedora-infra/bodhi/issues/3058 from bodhi.client.bindings import BodhiClient b = BodhiClient() builds_d = b.latest_builds(self.dg.package_name) branches = self.dg.local_project.git_project.get_branches() branches.remove("master") # there is no master tag in koji for branch in branches: koji_tag = f"{branch}-updates-candidate" try: koji_builds = [builds_d[koji_tag]] # take last three builds koji_builds = (koji_builds[:number_of_builds] if len(koji_builds) > number_of_builds else koji_builds) koji_builds_str = "\n".join(f" - {b}" for b in koji_builds) logger.info(f"{branch}:\n{koji_builds_str}") except KeyError: logger.info(f"{branch}: No builds.")
def get_updates(self, number_of_updates: int = 3) -> List: """ Get specific number of latest updates in bodhi :param number_of_updates: int :return: None """ # https://github.com/fedora-infra/bodhi/issues/3058 from bodhi.client.bindings import BodhiClient b = BodhiClient() results = b.query( packages=self.dg.package_config.downstream_package_name)["updates"] logger.debug("Bodhi updates fetched.") stable_branches: Set[str] = set() all_updates = [[ result["title"], result["karma"], result["status"], result["release"]["branch"], ] for result in results] updates = [] for [update, karma, status, branch] in all_updates: # Don't return more than one stable update per branch if branch not in stable_branches or status != "stable": updates.append([update, karma, status]) if status == "stable": stable_branches.add(branch) if len(updates) == number_of_updates: break return updates
def _get_bodhi_history(username): """ Print the last action performed on bodhi by the given FAS user. :arg username, the fas username whose action is searched. """ from bodhi.client.bindings import BodhiClient bodhiclient = BodhiClient("https://bodhi.fedoraproject.org/") log.debug('Querying Bodhi for user: {0}'.format(username)) json_obj = bodhiclient.send_request( "updates/?user=%s" % username, verb='GET') def dategetter(field): def getter(item): return datetime.datetime.strptime(item[field], "%Y-%m-%d %H:%M:%S") return getter print('Last package update on bodhi:') if json_obj['updates']: latest = sorted(json_obj['updates'], key=dategetter("date_submitted") )[-1] print(' {0} on package {1}'.format( latest["date_submitted"], latest["title"])) else: print(' No activity found on bodhi')
def get_aliases() -> Dict[str, List[str]]: """ Function to automatically determine fedora-all, fedora-stable, fedora-development and epel-all aliases. Current data are fetched via bodhi client, with default base url `https://bodhi.fedoraproject.org/'. :return: dictionary containing aliases """ bodhi_client = BodhiClient() releases = bodhi_client.get_releases(exclude_archived=True) aliases = defaultdict(list) for release in releases.releases: if release.id_prefix == "FEDORA" and release.name != "ELN": name = release.long_name.lower().replace(" ", "-") if release.state == "current": aliases["fedora-stable"].append(name) elif release.state == "pending": aliases["fedora-development"].append(name) elif release.id_prefix == "FEDORA-EPEL": name = release.name.lower() aliases["epel-all"].append(name) if aliases.get("fedora-development"): aliases["fedora-development"].sort(key=lambda x: int(x.rsplit("-")[-1])) # The Fedora with the highest version is "rawhide", but # Bodhi always uses release names, and has no concept of "rawhide". aliases["fedora-development"][-1] = "fedora-rawhide" aliases["fedora-all"] = aliases["fedora-development"] + aliases["fedora-stable"] return aliases
def get_aliases() -> Dict[str, List[str]]: """ Function to automatically determine fedora-all, fedora-stable, fedora-development and epel-all aliases. Current data are fetched via bodhi client, with default base url `https://bodhi.fedoraproject.org/'. :return: dictionary containing aliases """ bodhi_client = BodhiClient() releases = bodhi_client.get_releases(exclude_archived=True) aliases = defaultdict(list) for release in releases.releases: if release.id_prefix == "FEDORA" and release.name != "ELN": name = release.long_name.lower().replace(" ", "-") aliases["fedora-all"].append(name) if release.state == "current": aliases["fedora-stable"].append(name) elif release.state == "pending": aliases["fedora-development"].append(name) elif release.id_prefix == "FEDORA-EPEL": name = release.name.lower() aliases["epel-all"].append(name) aliases["fedora-all"].append("fedora-rawhide") aliases["fedora-development"].append("fedora-rawhide") return aliases
def __init__(self, dry_run=False): self._client = BodhiClient() self._client.init_username() self._dry_run = dry_run self._log_prefix = '' if dry_run: self._log_prefix = 'dry run: '
def create_bodhi_update( self, dist_git_branch: str, update_type: str, update_notes: str, koji_builds: Sequence[str] = None, ): logger.debug( f"About to create a Bodhi update of type {update_type} from {dist_git_branch}" ) # https://github.com/fedora-infra/bodhi/issues/3058 from bodhi.client.bindings import BodhiClient, BodhiClientException if not self.package_name: raise PackitException("Package name is not set.") # bodhi will likely prompt for username and password if kerb ticket is not up b = BodhiClient() if not koji_builds: # alternatively we can call something like `koji latest-build rawhide sen` builds_d = b.latest_builds(self.package_name) builds_str = "\n".join(f" - {b}" for b in builds_d) logger.debug( f"Koji builds for package {self.package_name}: \n{builds_str}") koji_tag = f"{dist_git_branch}-updates-candidate" try: koji_builds = [builds_d[koji_tag]] koji_builds_str = "\n".join(f" - {b}" for b in koji_builds) logger.info( f"Koji builds for package {self.package_name} and koji tag {koji_tag}:" f"\n{koji_builds_str}") except KeyError: raise PackitException( f"There is no build for {self.package_name} in koji tag {koji_tag}" ) # I was thinking of verifying that the build is valid for a new bodhi update # but in the end it's likely a waste of resources since bodhi will tell us rendered_note = update_notes.format( version=self.specfile.get_version()) try: result = b.save(builds=koji_builds, notes=rendered_note, type=update_type) logger.debug(f"Bodhi response:\n{result}") logger.info(f"Bodhi update {result['alias']}:\n" f"- {result['url']}\n" f"- stable_karma: {result['stable_karma']}\n" f"- unstable_karma: {result['unstable_karma']}\n" f"- notes:\n{result['notes']}\n") if "caveats" in result: for cav in result["caveats"]: logger.info(f"- {cav['name']}: {cav['description']}\n") except BodhiClientException as ex: logger.error(ex) raise PackitException( f"There is a problem with creating the bodhi update:\n{ex}") return result["alias"]
def get_testing_updates(self, update_alias: Optional[str]) -> List: from bodhi.client.bindings import BodhiClient b = BodhiClient() results = b.query( alias=update_alias, packages=self.dg.package_config.downstream_package_name, status="testing", )["updates"] logger.debug("Bodhi updates with status 'testing' fetched.") return results
def push_bodhi_update(update_alias: str): from bodhi.client.bindings import BodhiClient, UpdateNotFound b = BodhiClient() try: response = b.request(update=update_alias, request="stable") logger.debug(f"Bodhi response:\n{response}") logger.info(f"Bodhi update {response['alias']} pushed to stable:\n" f"- {response['url']}\n" f"- stable_karma: {response['stable_karma']}\n" f"- unstable_karma: {response['unstable_karma']}\n" f"- notes:\n{response['notes']}\n") except UpdateNotFound: logger.error("Update was not found.")
def get_updates(self, number_of_updates: int = 3) -> List: """ Get specific number of latest updates in bodhi :param number_of_updates: int :return: None """ # https://github.com/fedora-infra/bodhi/issues/3058 from bodhi.client.bindings import BodhiClient b = BodhiClient() results = b.query(packages=self.dg.package_name)["updates"] if len(results) > number_of_updates: results = results[:number_of_updates] return [ [result["title"], result["karma"], result["status"]] for result in results ]
def get_updates(self, number_of_updates: int = 3) -> None: """ Get specific number of latest updates in bodhi :param number_of_updates: int :return: None """ logger.info("\nLatest bodhi updates:") # https://github.com/fedora-infra/bodhi/issues/3058 from bodhi.client.bindings import BodhiClient b = BodhiClient() results = b.query(packages=self.dg.package_name)["updates"] if len(results) > number_of_updates: results = results[:number_of_updates] table = [[result["title"], result["karma"], result["status"]] for result in results] logger.info(tabulate(table, headers=["Update", "Karma", "status"]))
def main(): module_args = dict( name=dict(type="str", required=True), long_name=dict(type="str", required=True), id_prefix=dict(type="str", required=True), version=dict(type="str", required=True), branch=dict(type="str", required=True), dist_tag=dict(type="str", required=True), stable_tag=dict(type="str", required=True), testing_tag=dict(type="str", required=True), candidate_tag=dict(type="str", required=True), pending_stable_tag=dict(type="str", required=True), pending_testing_tag=dict(type="str", required=True), pending_signing_tag=dict(type="str", required=False), override_tag=dict(type="str", required=True), state=dict(choice=["disabled", "pending", "current", "archived"], default="pending"), user=dict(type="str", required=True), mail_template=dict(type="str", required=False), composed_by_bodhi=dict(type="str", required=False), url=dict(type="str", required=False, default="https://bodhi.fedoraproject.org"), ) module = AnsibleModule(argument_spec=module_args, supports_check_mode=False) try: from bodhi.client.bindings import BodhiClient except ImportError: module.fail_json( msg="the bodhi python module not found on the target system") # Connect to bodhi client = BodhiClient( base_url=module.params["url"], username=module.params["user"], ) result = ensure_release(client, module, **module.params) module.exit_json(**result)
def search(self, query): """ Perform Bodhi query """ result = [] current_page = 1 original_query = query while current_page: log.debug("Bodhi query: {0}".format(query)) client = BodhiClient(self.url) data = client.send_request(query, verb='GET') objects = data['updates'] log.debug("Result: {0} fetched".format(listed( len(objects), "item"))) log.data(pretty(data)) result.extend(objects) if current_page < data['pages']: current_page = current_page + 1 query = f"{original_query}&page={current_page}" else: current_page = None return result
def get_builds(self, number_of_builds: int = 3) -> Dict: """ Get specific number of latest builds from koji :param number_of_builds: int :return: None """ # https://github.com/fedora-infra/bodhi/issues/3058 from bodhi.client.bindings import BodhiClient b = BodhiClient() builds_d = b.latest_builds(self.dg.package_name) branches = self.dg.local_project.git_project.get_branches() branches.remove("master") # there is no master tag in koji builds: Dict = {} for branch in branches: koji_tag = f"{branch}-updates-candidate" try: # take last three builds builds[branch] = builds_d[koji_tag][:number_of_builds] except KeyError: logger.info(f"There are no builds for branch {branch}") return builds
def get_builds(self, ) -> Dict: """ Get latest koji builds """ # https://github.com/fedora-infra/bodhi/issues/3058 from bodhi.client.bindings import BodhiClient b = BodhiClient() # { koji-target: "latest-build-nvr"} builds_d = b.latest_builds( self.dg.package_config.downstream_package_name) branches = self.dg.local_project.git_project.get_branches() logger.debug("Latest koji builds fetched.") builds: Dict = {} for branch in branches: # there is no master tag in koji if branch == "master": continue koji_tag = f"{branch}-updates-candidate" try: builds[branch] = builds_d[koji_tag] except KeyError: logger.info(f"There are no builds for branch {branch}") return builds
def create_bodhi_update( self, dist_git_branch: str, update_type: str, update_notes: str, koji_builds: Sequence[str] = None, bugzilla_ids: Optional[List[int]] = None, ): logger.debug( f"About to create a Bodhi update of type {update_type!r} from {dist_git_branch!r}" ) # bodhi will likely prompt for username and password if kerb ticket is not up b = BodhiClient() if not koji_builds: # alternatively we can call something like `koji latest-build rawhide sen` builds_d = b.latest_builds(self.package_config.downstream_package_name) builds_str = "\n".join(f" - {b}" for b in builds_d) logger.debug( "Koji builds for package " f"{self.package_config.downstream_package_name!r}: \n{builds_str}" ) # EPEL uses "testing-candidate" instead of "updates-candidate" prefix = "testing" if dist_git_branch.startswith("epel") else "updates" koji_tag = f"{dist_git_branch}-{prefix}-candidate" try: koji_builds = [builds_d[koji_tag]] koji_builds_str = "\n".join(f" - {b}" for b in koji_builds) logger.info( "Koji builds for package " f"{self.package_config.downstream_package_name!r} and koji tag {koji_tag}:" f"\n{koji_builds_str}" ) except KeyError: raise PackitException( f"There is no build for {self.package_config.downstream_package_name!r} " f"in koji tag {koji_tag}" ) # I was thinking of verifying that the build is valid for a new bodhi update # but in the end it's likely a waste of resources since bodhi will tell us rendered_note = update_notes.format(version=self.specfile.get_version()) try: save_kwargs = { "builds": koji_builds, "notes": rendered_note, "type": update_type, } if bugzilla_ids: save_kwargs["bugs"] = list(map(str, bugzilla_ids)) result = b.save(**save_kwargs) logger.debug(f"Bodhi response:\n{result}") logger.info( f"Bodhi update {result['alias']}:\n" f"- {result['url']}\n" f"- stable_karma: {result['stable_karma']}\n" f"- unstable_karma: {result['unstable_karma']}\n" f"- notes:\n{result['notes']}\n" ) if "caveats" in result: for cav in result["caveats"]: logger.info(f"- {cav['name']}: {cav['description']}\n") except BodhiClientException as ex: logger.error(ex) raise PackitException( f"There is a problem with creating the bodhi update:\n{ex}" ) return result["alias"]
#!/usr/bin/python3 """ Generate %patch, %source and %prep data about most patched Fedora spec files. """ import json import pathlib import re from typing import Dict, Tuple from bodhi.client.bindings import BodhiClient # rpm-specs-latest.tar.xz unpacked in /fedora-spec-files/rpm-specs/ RPM_SPECS = pathlib.Path("./rpm-specs") # process this many packages ordered by the amount of patches PROCESS_PACKAGE_COUNT = 50 bodhi = BodhiClient() def get_patch_stats() -> Dict[str, int]: """provide an ordered dict with package names as keys and number of patches as values""" patch_re = re.compile(r"\nPatch\d*:") result: Dict[str, int] = {} for spec in RPM_SPECS.iterdir(): spec_content = spec.read_text() match = patch_re.findall(spec_content) if match: result[spec.name[:-5]] = len(match) return dict(sorted(result.items(), key=lambda item: item[1], reverse=True)) def get_update_frequency(package_name: str, distro: str = "f34") -> int: """provide number of builds a package has in koji in a given distro""" return len(bodhi.koji_session.listTagged(distro, package=package_name))
def __init__(self, environ, request): super(BodhiConnector, self).__init__(environ, request) self._prod_url = config.get('fedoracommunity.connector.bodhi.produrl', 'https://bodhi.fedoraproject.org') self._bodhi_client = BodhiClient(self._base_url, insecure=self._insecure)