Esempio n. 1
0
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
Esempio n. 3
0
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
Esempio n. 4
0
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)