kopia lustrzana https://github.com/jupyterhub/repo2docker
Add abstract interface for container engines
rodzic
ea90ae23d3
commit
cf35f51a38
|
@ -0,0 +1,245 @@
|
||||||
|
"""
|
||||||
|
Interface for a repo2docker container engine
|
||||||
|
"""
|
||||||
|
|
||||||
|
from abc import ABC, abstractmethod
|
||||||
|
|
||||||
|
|
||||||
|
# Based on https://docker-py.readthedocs.io/en/4.2.0/containers.html
|
||||||
|
|
||||||
|
|
||||||
|
class Container(ABC):
|
||||||
|
"""
|
||||||
|
Abstract container returned by repo2docker engines
|
||||||
|
"""
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def reload(self):
|
||||||
|
"""
|
||||||
|
Refresh container attributes
|
||||||
|
"""
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def logs(self, stream=False):
|
||||||
|
"""
|
||||||
|
Get the container logs.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
stream : bool
|
||||||
|
If `True` return an iterator over the log lines, otherwise return all
|
||||||
|
logs
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
str or iterator
|
||||||
|
"""
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def kill(self, *, signal="KILL"):
|
||||||
|
"""
|
||||||
|
Send a signal to the container
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
signal : str
|
||||||
|
The signal, default `KILL`
|
||||||
|
"""
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def remove(self):
|
||||||
|
"""
|
||||||
|
Remove the container
|
||||||
|
"""
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def stop(self, *, timeout=10):
|
||||||
|
"""
|
||||||
|
Stop the container
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
timeout : If the container doesn't gracefully stop after this timeout kill it
|
||||||
|
"""
|
||||||
|
|
||||||
|
@property
|
||||||
|
@abstractmethod
|
||||||
|
def status(self):
|
||||||
|
"""
|
||||||
|
The status of the container
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
str : The status of the container.
|
||||||
|
Values include `created` `running` `exited`.
|
||||||
|
|
||||||
|
TODO: Does Docker have a fixed list of these?
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class ContainerEngine(ABC):
|
||||||
|
"""
|
||||||
|
Abstract container engine
|
||||||
|
"""
|
||||||
|
|
||||||
|
# containers = Container
|
||||||
|
|
||||||
|
# Based on https://docker-py.readthedocs.io/en/4.2.0/api.html#module-docker.api.build
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def build(
|
||||||
|
self,
|
||||||
|
*,
|
||||||
|
buildargs={},
|
||||||
|
cache_from=[],
|
||||||
|
container_limits={},
|
||||||
|
forcerm=False,
|
||||||
|
rm=False,
|
||||||
|
tag="",
|
||||||
|
custom_context=False,
|
||||||
|
decode=False,
|
||||||
|
dockerfile="",
|
||||||
|
fileobj=None,
|
||||||
|
path="",
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Build a container
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
buildargs : dict
|
||||||
|
Dictionary of build arguments
|
||||||
|
cache_from : list[str]
|
||||||
|
List of images to chech for caching
|
||||||
|
container_limits : dict
|
||||||
|
Dictionary of resources limits. These keys are supported:
|
||||||
|
- `cpusetcpus`
|
||||||
|
- `cpushares`
|
||||||
|
- `memory`
|
||||||
|
- `memswap`
|
||||||
|
forcerm : bool
|
||||||
|
Always remove containers including unsuccessful builds
|
||||||
|
rm : bool
|
||||||
|
Remove intermediate containers
|
||||||
|
tag : str
|
||||||
|
Tag to add to the image
|
||||||
|
|
||||||
|
custom_context : bool
|
||||||
|
If `True` fileobj is a Tar file object containing the build context
|
||||||
|
TODO: Specific to Docker
|
||||||
|
decode : bool
|
||||||
|
If `True` decode responses into dicts
|
||||||
|
TODO: repo2docker sets this to True but it's not clear what other clients should return
|
||||||
|
dockerfile : str
|
||||||
|
Path to Dockerfile within the build context
|
||||||
|
fileobj : tarfile
|
||||||
|
A tar file-like object containing the build context
|
||||||
|
TODO: Specific to Docker, other clients can untar this to a tempdir
|
||||||
|
path : str
|
||||||
|
path to the Dockerfile
|
||||||
|
"""
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def images(self):
|
||||||
|
"""
|
||||||
|
List images
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
list[str] : List of images
|
||||||
|
"""
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def inspect_image(self, image):
|
||||||
|
"""
|
||||||
|
Get information about an image
|
||||||
|
|
||||||
|
TODO: This is specific to the engine, can we convert it to a standard format?
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
image : str
|
||||||
|
The image
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
dict
|
||||||
|
"""
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def push(self, image_spec, *, stream=True):
|
||||||
|
"""
|
||||||
|
Push image to a registry
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
image_spec : str
|
||||||
|
The repository spec to push to
|
||||||
|
stream : bool
|
||||||
|
If `True` return output logs as a generator
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Note this is different from the Docker client which has Client.containers.run
|
||||||
|
def run(
|
||||||
|
image_spec,
|
||||||
|
*,
|
||||||
|
command=[],
|
||||||
|
environment=[],
|
||||||
|
detach=False,
|
||||||
|
ports={},
|
||||||
|
publish_all_ports=False,
|
||||||
|
remove=False,
|
||||||
|
volumes={},
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Run a container
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
image_spec : str
|
||||||
|
The image to run
|
||||||
|
command : list[str]
|
||||||
|
The command to run
|
||||||
|
environment : list[str]
|
||||||
|
List of environment variables in the form `ENVVAR=value`
|
||||||
|
detach : bool
|
||||||
|
If `True` run container in background
|
||||||
|
ports : dict
|
||||||
|
Container port bindings in the format expected by the engine
|
||||||
|
TODO: Should we use a fixed format and convert to whatever's required by the engine?
|
||||||
|
publish_all_ports : bool
|
||||||
|
If `True` publish all ports to host
|
||||||
|
remove : bool
|
||||||
|
If `True` delete container when it completes
|
||||||
|
volumes : dict
|
||||||
|
Volume bindings in the format expected by the engine
|
||||||
|
TODO: Should we use a fixed format and convert to whatever's required by the engine?
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
Container : the running container
|
||||||
|
|
||||||
|
Raises
|
||||||
|
------
|
||||||
|
NotImplementedError
|
||||||
|
This engine does not support running containers
|
||||||
|
"""
|
||||||
|
raise NotImplementedError("Running containers not supported")
|
||||||
|
|
||||||
|
|
||||||
|
class ContainerEngineException(Exception):
|
||||||
|
"""
|
||||||
|
Base class for exceptions in the container engine
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class BuildError(ContainerEngineException):
|
||||||
|
"""
|
||||||
|
Container build error
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class ImageLoadError(ContainerEngineException):
|
||||||
|
"""
|
||||||
|
Container load/push error
|
||||||
|
"""
|
Ładowanie…
Reference in New Issue