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

pull/848/head
Simon Li 2020-02-14 16:20:55 +00:00
rodzic 8215f0b065
commit 00df21069e
3 zmienionych plików z 43 dodań i 12 usunięć

Wyświetl plik

@ -507,7 +507,12 @@ class Repo2Docker(Application):
progress_layers = {} progress_layers = {}
layers = {} layers = {}
last_emit_time = time.time() 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 # each chunk can be one or more lines of json events
# split lines here in case multiple are delivered at once # split lines here in case multiple are delivered at once
for line in chunk.splitlines(): for line in chunk.splitlines():
@ -770,7 +775,10 @@ class Repo2Docker(Application):
self.cache_from, self.cache_from,
self.extra_build_kwargs, 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")) self.log.info(l["stream"], extra=dict(phase="building"))
elif "error" in l: elif "error" in l:
self.log.info(l["error"], extra=dict(phase="failure")) self.log.info(l["error"], extra=dict(phase="failure"))

Wyświetl plik

@ -13,7 +13,7 @@ class DockerContainer(Container):
def reload(self): def reload(self):
return self._c.reload() return self._c.reload()
def logs(self, stream=False): def logs(self, *, stream=False):
return self._c.logs(stream=stream) return self._c.logs(stream=stream)
def kill(self, *, signal="KILL"): 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 https://docker-py.readthedocs.io/en/4.2.0/api.html#module-docker.api.build
""" """
string_output = False
def __init__(self, *, parent): def __init__(self, *, parent):
super().__init__(parent=parent) super().__init__(parent=parent)
try: try:
@ -82,8 +84,8 @@ class DockerEngine(ContainerEngine):
def inspect_image(self, image): def inspect_image(self, image):
return self._apiclient.inspect_image(image) return self._apiclient.inspect_image(image)
def push(self, image_spec, *, stream=True): def push(self, image_spec):
return self._apiclient.push(image_spec, stream=stream) return self._apiclient.push(image_spec, stream=True)
def run( def run(
self, self,

Wyświetl plik

@ -21,19 +21,18 @@ class Container(ABC):
""" """
@abstractmethod @abstractmethod
def logs(self, stream=False): def logs(self, *, stream=False):
""" """
Get the container logs. Get the container logs.
Parameters Parameters
---------- ----------
stream : bool stream : bool
If `True` return an iterator over the log lines, otherwise return all If `True` return an iterator over the log lines, otherwise return all logs
logs
Returns Returns
------- -------
str or iterator str or generator of log strings
""" """
@abstractmethod @abstractmethod
@ -115,6 +114,16 @@ class ContainerEngine(LoggingConfigurable):
Initialised with a reference to the parent so can also be configured using traitlets. 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): def __init__(self, *, parent):
""" """
Initialise the container engine Initialise the container engine
@ -168,6 +177,13 @@ class ContainerEngine(LoggingConfigurable):
TODO: Specific to Docker, other clients can untar this to a tempdir TODO: Specific to Docker, other clients can untar this to a tempdir
path : str path : str
path to the Dockerfile 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") raise NotImplementedError("build not implemented")
@ -198,7 +214,7 @@ class ContainerEngine(LoggingConfigurable):
""" """
raise NotImplementedError("inspect_image not implemented") raise NotImplementedError("inspect_image not implemented")
def push(self, image_spec, *, stream=True): def push(self, image_spec):
""" """
Push image to a registry Push image to a registry
@ -206,8 +222,13 @@ class ContainerEngine(LoggingConfigurable):
---------- ----------
image_spec : str image_spec : str
The repository spec to push to 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") raise NotImplementedError("push not implemented")