avocado-framework/avocado

View on GitHub
avocado/plugins/runners/podman_image.py

Summary

Maintainability
A
0 mins
Test Coverage
F
44%
import asyncio
import logging
import sys
import time
from multiprocessing import Process, SimpleQueue, set_start_method

from avocado.core.nrunner.app import BaseRunnerApp
from avocado.core.nrunner.runner import RUNNER_RUN_STATUS_INTERVAL, BaseRunner
from avocado.core.utils import messages
from avocado.utils.podman import AsyncPodman, PodmanException


class PodmanImageRunner(BaseRunner):
    """Runner for dependencies of type podman-image

    This runner handles download and verification.

    Runnable attributes usage:

     * kind: 'podman-image'

     * uri: the name of the image

     * args: not used
    """

    name = "podman-image"
    description = f"Runner for dependencies of type {name}"

    def _run_podman_pull(self, uri, queue):
        # Silence the podman utility from outputting messages into
        # the regular handler, which will go to stdout.  The
        # exceptions caught here still contain all the needed
        # information for debugging in case of errors.
        logging.getLogger("avocado.utils.podman").addHandler(logging.NullHandler())
        try:
            podman = AsyncPodman()
            loop = asyncio.get_event_loop()
            loop.run_until_complete(podman.execute("pull", uri))
            queue.put({"result": "pass"})
        except PodmanException as ex:
            queue.put(
                {"result": "fail", "fail_reason": f"Could not pull podman image: {ex}"}
            )

    def run(self, runnable):
        yield messages.StartedMessage.get()

        if not runnable.uri:
            reason = "uri identifying the podman image is required"
            yield messages.FinishedMessage.get("error", reason)
        else:
            queue = SimpleQueue()
            process = Process(target=self._run_podman_pull, args=(runnable.uri, queue))
            process.start()
            while queue.empty():
                time.sleep(RUNNER_RUN_STATUS_INTERVAL)
                yield messages.RunningMessage.get()

            output = queue.get()
            result = output.pop("result")
            yield messages.FinishedMessage.get(result, **output)


class RunnerApp(BaseRunnerApp):
    PROG_NAME = f"avocado-runner-{PodmanImageRunner.name}"
    PROG_DESCRIPTION = PodmanImageRunner.description
    RUNNABLE_KINDS_CAPABLE = [PodmanImageRunner.name]


def main():
    if sys.platform == "darwin":
        set_start_method("fork")
    app = RunnerApp(print)
    app.run()


if __name__ == "__main__":
    main()