def _handle_solved_message(Configuration): # noqa: N803 """Handle all the messages for which Kebechet needs to run on if the sovler type matches the os type.""" solver_string = os.environ["THOTH_SOLVER_NAME"] # ex - solver-fedora-31-py38 if not solver_string: raise ValueError( "SolverMessageType has been provided to the MESSAGE_TYPE env variable. \ but solver name is missing." ) solver_dict = OpenShift.parse_python_solver_name(solver_string) os_name, os_version, python_version = ( solver_dict["os_name"], solver_dict["os_version"], solver_dict["python_version"], ) repositories: Dict[str, Dict] = GRAPH.get_kebechet_github_installations_info_for_python_package_version( package_name=Configuration.PACKAGE_NAME, index_url=Configuration.PACKAGE_INDEX, os_name=os_name, os_version=os_version, python_version=python_version, ) # We query without the package_version. for key in repositories.keys(): repo_info = repositories[key] # Construct the message input if repo_info.get("private"): continue # We skip for private repo's. if semver.compare(repo_info.get("package_version"), Configuration.PACKAGE_VERSION): continue # We dont schedule, if the package version > version of the solved package version. message_input = KebechetRunUrlMessageContents( component_name=__COMPONENT_NAME__, service_version=__service_version__, url=_URL_PREFIX + key, service_name="github", installation_id=repo_info.get("installation_id"), metadata={ "message_justification": _JUSTIFICATION_MAPPING[Configuration.MESSAGE_TYPE], "package_name": Configuration.PACKAGE_NAME, "package_version": Configuration.PACKAGE_VERSION, "package_index": Configuration.PACKAGE_INDEX, }, ).dict() # We store the message to put in the output file here. output_messages.append( {"topic_name": kebechet_run_url_trigger_message.base_name, "message_contents": message_input} )
def should_include( cls, builder_context: "PipelineBuilderContext" ) -> Generator[Dict[str, Any], None, None]: """Register self if users use runtime environments not matching solvers in the configmap.""" if not cls._SOLVERS_CONFIGURED or builder_context.is_included(cls): yield from () return None runtime_environment = ( builder_context.project.runtime_environment.operating_system.name, normalize_os_version( builder_context.project.runtime_environment.operating_system. name, builder_context.project.runtime_environment.operating_system. version, ), builder_context.project.python_version, ) for solver_name in cls._SOLVERS_CONFIGURED.splitlines(): solver_name = solver_name.strip() if not solver_name: continue try: solver_info = OpenShift.parse_python_solver_name(solver_name) except SolverNameParseError: _LOGGER.exception( "Please report this error to Thoth service administrator") yield from () return None if runtime_environment == ( solver_info["os_name"], solver_info["os_version"], solver_info["python_version"], ): break else: yield {} return None yield from () return None
def do_solve(package_name: str, package_version: str) -> List[Dict[str, Any]]: """Obtain dependent packages for the given package, respect registered solvers in Thoth.""" graph = GraphDatabase() graph.connect() openshift = OpenShift() result = [] for solver_name in openshift.get_solver_names(): _LOGGER.info( "Obtaining dependencies for environment used by solver %r", solver_name) solver_info = openshift.parse_python_solver_name(solver_name) start_offset = 0 while True: dependents = graph.get_python_package_version_dependents_all( package_name=package_name, os_name=solver_info["os_name"], os_version=solver_info["os_version"], python_version=solver_info["python_version"], start_offset=start_offset, count=_QUERY_COUNT, ) for dependent in dependents: if (dependent["version_range"] and dependent["version_range"] != "*" and package_version not in PackageVersion.parse_semantic_version( dependent["version_range"])): _LOGGER.info( "Package %r in version %r from %r ignored, not matching version specifier %r in environment %r", dependent["package_name"], dependent["package_version"], dependent["index_url"], package_version, solver_name, ) continue _LOGGER.info( "Found dependent %r in version %r from %r in environment %r", dependent["package_name"], dependent["package_version"], dependent["index_url"], solver_name, ) result.append({ "os_name": solver_info["os_name"], "os_version": solver_info["os_version"], "python_version": solver_info["python_version"], "solver_name": solver_name, **dependent, }) if len(dependents) < int(_QUERY_COUNT): break # Adjust for the next round. start_offset += int(_QUERY_COUNT) return result
def _handle_solved_message(Configuration): # noqa: N803 """Handle all the messages for which Kebechet needs to run on if the sovler type matches the os type.""" solver_string = Configuration.get( "THOTH_SOLVER_NAME") # ex - solver-fedora-31-py38 if not solver_string: raise ValueError( "SolverMessageType has been provided to the MESSAGE_TYPE env variable. \ but solver name is missing.") solver_dict = OpenShift.parse_python_solver_name(solver_string) os_name, os_version, python_version = ( solver_dict["os_name"], solver_dict["os_version"], solver_dict["python_version"], ) repositories: Dict[ str, Dict] = GRAPH.get_kebechet_github_installations_info_for_python_package_version( package_name=Configuration.PACKAGE_NAME, index_url=Configuration.PACKAGE_INDEX, os_name=os_name, os_version=os_version, python_version=python_version, ) # We query without the package_version. for key in repositories.keys(): repo_info = repositories[key] # Construct the message input if repo_info.get("private"): continue # We skip for private repo's. if semver.compare(repo_info.get("package_version"), Configuration.PACKAGE_VERSION): continue # We dont schedule, if the package version > version of the solved package version. message_input = { "component_name": { "type": "str", "value": __COMPONENT_NAME__ }, "service_version": { "type": "str", "value": __service_version__ }, "url": { "type": "str", "value": _URL_PREFIX + key }, "service_name": { "type": "str", "value": "github" }, "installation_id": { "type": "str", "value": repo_info.get("installation_id") }, } # We store the message to put in the output file here. output_messages.append({ "topic_name": "thoth.kebechet-run-url-trigger", "message_contents": message_input })
def run(self) -> None: """Check for version clash in packages.""" if self.context.graph.solved_software_environment_exists( os_name=self.context.project.runtime_environment. operating_system.name, os_version=self.context.project.runtime_environment. operating_system.version, python_version=self.context.project.runtime_environment. python_version, ): return runtime_environment = self.context.project.runtime_environment msg = ( f"No observations found for {runtime_environment.operating_system.name!r} in " f"version {runtime_environment.operating_system.version!r} using " f"Python {runtime_environment.python_version!r}") self.context.stack_info.append({ "type": "ERROR", "message": msg, "link": self._JUSTIFICATION_LINK, }) _LOGGER.warning("%s - %s", msg, self._JUSTIFICATION_LINK) _LOGGER.warning("Available configurations:") configurations = [] solvers = self._THOTH_ADVISER_DEPLOYMENT_CONFIGURED_SOLVERS.split() for solver in solvers: solver = solver.strip() if not solver: continue item = OpenShift.parse_python_solver_name(solver) configurations.append(item) if item["os_name"] == "rhel": # Duplicate entry as we can also guide on the same UBI environment. UBI and RHEL are binary compatible. other_item = dict(item) other_item["os_name"] = "ubi" configurations.append(other_item) _LOGGER.warning("{:<16} {:<16} {:<8}".format("OS name", "OS version", "Python version")) for conf in sorted( configurations, key=lambda i: (i["os_name"], i["os_version"], i["python_version"]), ): self.context.stack_info.append({ "message": f"Consider using {conf['os_name']!r} in version {conf['os_version']!r} " f"with Python {conf['python_version']}", "type": "ERROR", "link": self._JUSTIFICATION_LINK, }) _LOGGER.warning("{:<16} {:<16} {:<8}".format( conf["os_name"], conf["os_version"], conf["python_version"])) raise NotAcceptable(msg)