ContainerEngine .build .push default to returning strings (stream)
MODIFY
repo2docker/app.py
repo2docker/app.py
@@ -507,7 +507,12 @@ class Repo2Docker(Application):
progress_layers = {}
layers = {}
last_emit_time = time.time()
- for chunk in client.push(self.output_image_spec, stream=True):
+ for chunk in client.push(self.output_image_spec):
+ if client.string_output:
+ self.log.info(chunk, extra=dict(phase="pushing"))
+ continue
+ # else this is Docker output
+
# each chunk can be one or more lines of json events
# split lines here in case multiple are delivered at once
for line in chunk.splitlines():
@@ -770,7 +775,10 @@ class Repo2Docker(Application):
self.cache_from,
self.extra_build_kwargs,
):
- if "stream" in l:
+ if docker_client.string_output:
+ self.log.info(l, extra=dict(phase="building"))
+ # else this is Docker output
+ elif "stream" in l:
self.log.info(l["stream"], extra=dict(phase="building"))
elif "error" in l:
self.log.info(l["error"], extra=dict(phase="failure"))

MODIFY
repo2docker/docker.py
repo2docker/docker.py
@@ -13,7 +13,7 @@ class DockerContainer(Container):
def reload(self):
return self._c.reload()
- def logs(self, stream=False):
+ def logs(self, *, stream=False):
return self._c.logs(stream=stream)
def kill(self, *, signal="KILL"):
@@ -39,6 +39,8 @@ 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:
@@ -82,8 +84,8 @@ class DockerEngine(ContainerEngine):
def inspect_image(self, image):
return self._apiclient.inspect_image(image)
- def push(self, image_spec, *, stream=True):
- return self._apiclient.push(image_spec, stream=stream)
+ def push(self, image_spec):
+ return self._apiclient.push(image_spec, stream=True)
def run(
self,

MODIFY
repo2docker/engine.py
repo2docker/engine.py
@@ -21,19 +21,18 @@ class Container(ABC):
"""
@abstractmethod
- def logs(self, stream=False):
+ 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
+ If `True` return an iterator over the log lines, otherwise return all logs
Returns
-------
- str or iterator
+ str or generator of log strings
"""
@abstractmethod
@@ -115,6 +114,16 @@ class ContainerEngine(LoggingConfigurable):
Initialised with a reference to the parent so can also be configured using traitlets.
"""
+ string_output = True
+ """
+ Whether progress events should be strings or an object.
+
+ Originally Docker was the only container engine supported by repo2docker.
+ Some operations including build() and push() would return generators of events in a Docker specific format.
+ This format of events is not easily constructable with other engines so the default is to return strings and raise an exception if an error occurs.
+ If an engine returns docker style events set this variable to False.
+ """
+
def __init__(self, *, parent):
"""
Initialise the container engine
@@ -168,6 +177,13 @@ class ContainerEngine(LoggingConfigurable):
TODO: Specific to Docker, other clients can untar this to a tempdir
path : str
path to the Dockerfile
+
+ Returns
+ -------
+ A generator of strings. If an error occurs an exception must be thrown.
+
+ If `string_output=True` this should instead be whatever Docker returns:
+ https://github.com/jupyter/repo2docker/blob/0.11.0/repo2docker/app.py#L725-L735
"""
raise NotImplementedError("build not implemented")
@@ -198,7 +214,7 @@ class ContainerEngine(LoggingConfigurable):
"""
raise NotImplementedError("inspect_image not implemented")
- def push(self, image_spec, *, stream=True):
+ def push(self, image_spec):
"""
Push image to a registry
@@ -206,8 +222,13 @@ class ContainerEngine(LoggingConfigurable):
----------
image_spec : str
The repository spec to push to
- stream : bool
- If `True` return output logs as a generator
+
+ Returns
+ -------
+ A generator of strings. If an error occurs an exception must be thrown.
+
+ If `string_output=True` this should instead be whatever Docker returns:
+ https://github.com/jupyter/repo2docker/blob/0.11.0/repo2docker/app.py#L469-L495
"""
raise NotImplementedError("push not implemented")

ContainerEngine .build .push default to returning strings (stream)