Skip to content

Instantly share code, notes, and snippets.

@jhidding
Created February 3, 2017 10:03
Show Gist options
  • Save jhidding/859804fb1beb6e4e4ba98ae45857b2f1 to your computer and use it in GitHub Desktop.
Save jhidding/859804fb1beb6e4e4ba98ae45857b2f1 to your computer and use it in GitHub Desktop.
An easier interface to the Docker API
class DockerContainer(object):
"""Easy interface to Docker API.
This class encapsulates a part of the Docker API, with the goal
of making it easier to start a container, add some files, run a
few scripts, read the output, and then remove the container
again.
The object is a context manager for the created Docker container,
in that it starts the container upon entry and exterminates the
same container upon exit.
"""
client = docker.Client()
def __init__(self, image, working_dir=None):
self.image = image
self.working_dir = working_dir
container = self.client.create_container(
image=image, detach=True, stdin_open=True,
working_dir=working_dir)
self.container_id = container['Id']
def put_archive(self, archive, path="."):
"""Put the contents of an archive into the Docker container.
:param archive:
The `Archive` instance that contains the files that need
to be injected.
:type archive: Archive
:param path:
Where to extract the archive within the container.
:type path: str
"""
if self.working_dir is not None:
path = os.path.join(self.working_dir, path)
self.client.put_archive(
self.container_id, path, archive.buffer)
def get_archive(self, path):
"""Get a file or directory from the container and make it into
an `Archive` object."""
if self.working_dir is not None and not os.path.isabs(path):
path = os.path.join(self.working_dir, path)
strm, stat = self.client.get_archive(
self.container_id, path)
return Archive('r', strm.read())
def run(self, cmd, **kwargs):
"""Run a command.
:param cmd:
Command to be run and arguments as a list.
:type cmd: List[str]
:param kwargs:
Forwarded to Docker-py `exec_create` function call.
:return:
Output of command.
:rtype: bytes
"""
exe = self.client.exec_create(
container=self.container_id,
cmd=cmd, **kwargs)
return self.client.exec_start(exec_id=exe['Id'])
def start(self):
self.client.start(container=self.container_id)
def kill(self):
self.client.kill(self.container_id)
def remove(self, force=False):
self.client.remove_container(self.container_id, force=force)
def __enter__(self):
self.start()
return self
def __exit__(self, exc_type, exc_value, exc_st):
self.kill()
self.remove()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment