-
Notifications
You must be signed in to change notification settings - Fork 362
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[MRG] Define an interface for Container engines #848
Merged
Merged
Changes from all commits
Commits
Show all changes
21 commits
Select commit
Hold shift + click to select a range
cf35f51
Add abstract interface for container engines
manics 0610edf
Add docker implementation of abstract engine
manics 2864b69
app: use DockerEngine
manics 9ac8a83
Handle attrs["State"]["ExitCode"]
manics c521c3c
Remove constant docker args
manics b6bead7
Python 3.5: can't have trailing , in function arg list
manics 787d1d3
Container engine is an entrypoint: repo2docker.engines
manics a73595c
Require image info in a fixed format
manics 4a06ef1
ContainerEngine is now LoggingConfigurable
manics 17af0c7
BuildError only takes positional params
manics 8215f0b
Remove commented engine.py code
manics 00df210
ContainerEngine .build .push default to returning strings (stream)
manics ad5701d
Remove unnecessary import
manics 4647dd0
Container .build .run need to support **kwargs
manics 52b672a
Docker: print helpful message if daemon not running
manics 5c2c8f7
Python 3.5: can't have trailing , in function arg list (again)
manics 4ed6685
Fix unit tests
manics 0e7e0f0
Use standard-ish image_inspect format
manics e32c7b0
describe ContainerEngine volume and port formats
manics 5778ed0
docker.py: remove workaround for old black
manics d47b744
Add Container.wait()
manics File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
""" | ||
Docker container engine for repo2docker | ||
""" | ||
|
||
import docker | ||
from .engine import Container, ContainerEngine, ContainerEngineException, Image | ||
|
||
|
||
class DockerContainer(Container): | ||
def __init__(self, container): | ||
self._c = container | ||
|
||
def reload(self): | ||
return self._c.reload() | ||
|
||
def logs(self, *, stream=False): | ||
return self._c.logs(stream=stream) | ||
|
||
def kill(self, *, signal="KILL"): | ||
return self._c.kill(signal=signal) | ||
|
||
def remove(self): | ||
return self._c.remove() | ||
|
||
def stop(self, *, timeout=10): | ||
return self._c.stop(timeout=timeout) | ||
|
||
def wait(self): | ||
return self._c.wait() | ||
|
||
@property | ||
def exitcode(self): | ||
return self._c.attrs["State"]["ExitCode"] | ||
|
||
@property | ||
def status(self): | ||
return self._c.status | ||
|
||
|
||
class DockerEngine(ContainerEngine): | ||
""" | ||
https://docker-py.readthedocs.io/en/4.2.0/api.html#module-docker.api.build | ||
""" | ||
|
||
string_output = False | ||
|
||
def __init__(self, *, parent): | ||
super().__init__(parent=parent) | ||
try: | ||
self._apiclient = docker.APIClient( | ||
version="auto", **docker.utils.kwargs_from_env() | ||
) | ||
except docker.errors.DockerException as e: | ||
raise ContainerEngineException("Check if docker is running on the host.", e) | ||
|
||
def build( | ||
self, | ||
*, | ||
buildargs=None, | ||
cache_from=None, | ||
container_limits=None, | ||
tag="", | ||
custom_context=False, | ||
dockerfile="", | ||
fileobj=None, | ||
path="", | ||
**kwargs, | ||
): | ||
return self._apiclient.build( | ||
buildargs=buildargs, | ||
cache_from=cache_from, | ||
container_limits=container_limits, | ||
forcerm=True, | ||
rm=True, | ||
tag=tag, | ||
custom_context=custom_context, | ||
decode=True, | ||
dockerfile=dockerfile, | ||
fileobj=fileobj, | ||
path=path, | ||
**kwargs, | ||
) | ||
|
||
def images(self): | ||
images = self._apiclient.images() | ||
return [Image(tags=image["RepoTags"]) for image in images] | ||
|
||
def inspect_image(self, image): | ||
image = self._apiclient.inspect_image(image) | ||
return Image(tags=image["RepoTags"], config=image["ContainerConfig"]) | ||
|
||
def push(self, image_spec): | ||
return self._apiclient.push(image_spec, stream=True) | ||
|
||
def run( | ||
self, | ||
image_spec, | ||
*, | ||
command=None, | ||
environment=None, | ||
ports=None, | ||
publish_all_ports=False, | ||
remove=False, | ||
volumes=None, | ||
**kwargs, | ||
): | ||
client = docker.from_env(version="auto") | ||
container = client.containers.run( | ||
image_spec, | ||
command=command, | ||
environment=(environment or []), | ||
detach=True, | ||
ports=(ports or {}), | ||
publish_all_ports=publish_all_ports, | ||
remove=remove, | ||
volumes=(volumes or {}), | ||
**kwargs, | ||
) | ||
return DockerContainer(container) |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a new dependency, but it's already used in other Jupyter projects such as jupyterhub for managing entrypoints:
https://github.com/jupyterhub/jupyterhub/blob/bc7bb5076ff2deabc7702c75dce208166d14568e/requirements.txt#L4