from typing import Text import docker import pydantic import requests from jeeves.core.objects import Result from .base import Action class DockerAction(Action): """ .. automethod:: _run_container """ id = "contrib/docker" verbose_name = "Execute docker container" class Parameters(pydantic.BaseModel): """ +----------------+------+-----------+----------------------------------------------+ | Parameter name | Type | Mandatory | Description | +================+======+===========+==============================================+ | ``image`` | text | no | Image to run (defaults to ``DEFAULT_IMAGE``) | | ``command`` | text | yes | The command to be executed | +----------------+------+-----------+----------------------------------------------+ """ image: Text = "alpine:latest" command: Text remove_container: bool = True def _run_container(self): """ """ pass def execute(self, **kwargs): workspace = kwargs.get("workspace") image = self.parameters.image command = self.parameters.command environment = {"WORKSPACE_PATH": "/workspace"} client = docker.from_env() self.logger.info("Pulling image...") try: client.images.get(image) except docker.errors.ImageNotFound: self.logger.error("Image does not exist") return Result(success=False) self.logger.info("Execute command in container...") container = client.containers.run( image=image, command=command, detach=True, environment=environment, volumes={"/workspace": {"bind": str(workspace.path), "mode": "rw"}}, ) try: result = container.wait(timeout=30, condition="not-running") logs = container.logs() success = result["StatusCode"] == 0 except requests.exceptions.ReadTimeout: success = False logs = container.logs() if self.parameters.remove_container: self.logger.info("Removing container") container.remove() return Result(success=success, output=logs)