fmartingr
/
jeeves
Archived
1
0
Fork 0
This repository has been archived on 2021-02-14. You can view files and clone it, but cannot push or open issues or pull requests.
jeeves/jeeves/core/actions/docker.py

115 lines
3.8 KiB
Python

import os.path
from typing import Text, Optional
import docker
import pydantic
import requests
from jeeves.core.objects import Result
from .base import Action
class DockerBuildAction(Action):
"""
"""
id = "contrib/docker/build"
verbose_name = "Build docker image"
class Parameters(pydantic.BaseModel):
"""
"""
dockerfile_path: Text
image_name: Text
tag: Text = "latest"
def execute(self, **kwargs):
workspace = kwargs.get("workspace")
client = docker.from_env()
client.images.build(
path=workspace,
fileobj=os.path.join(workspace, self.parameters.dockerfile_path),
)
class DockerRunAction(Action):
"""
"""
id = "contrib/docker/run"
verbose_name = "Execute docker container"
class Parameters(pydantic.BaseModel):
"""
+----------------------+------+-----------+--------------------------------------------------------------+
| Parameter name | Type | Mandatory | Description |
+======================+======+===========+==============================================================+
| ``image`` | text | no | Image to run (defaults to ``alpine:latest``) |
| ``command`` | text | yes | The command to be executed |
| ``entrypoint`` | text | no | The entrypoint to use (defaults in image) |
| ``tty`` | bool | no | Allocate pseudo-tty (defaults to ``false``) |
| ``remove_container`` | text | no | Select to remove container after run (defaults to ``true`` ) |
+----------------------+------+-----------+--------------------------------------------------------------+
"""
image: Text = "alpine:latest"
command: Text
entrypoint: Optional[Text] = None
tty: bool = False
remove_container: bool = True
PARSE_WITH_ARGUMENTS = {"command", "image"}
def execute(self, **kwargs):
workspace = kwargs.get("workspace")
arguments = kwargs.get("arguments")
image = self.parameters.image
environment = {"WORKSPACE_PATH": "/workspace"}
# Add arguments as uppercase environment variables prefixed with JEEVES_
if arguments:
for key, value in arguments.items():
environment[f"JEEVES_{key.upper}"] = value
client = docker.from_env()
self.logger.info("Pulling image...")
try:
client.images.get(image)
except docker.errors.ImageNotFound:
self.logger.error(f"Image '{image}' does not exist")
return Result(success=False)
run_kwargs = dict(
image=image,
command=self.parsed_parameters["command"],
detach=True,
environment=environment,
tty=self.parameters.tty,
volumes={"/workspace": {"bind": str(workspace.path), "mode": "rw"}},
working_dir="/workspace",
)
if self.parameters.entrypoint:
run_kwargs["entrypoint"] = self.parameters.entrypoint
self.logger.info("Execute command in container...")
container = client.containers.run(**run_kwargs)
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)