summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoradw1n <adw1n@users.noreply.github.com>2018-09-03 05:54:12 +0200
committerJoffrey F <joffrey@docker.com>2018-11-28 11:56:28 -0800
commit7117855f6e577678ba47536d860d193fcb131a75 (patch)
treee2507d5e1d8748f814b680ee0e4c70b49ac592bf
parentf9505da1d604f2c4046b8116a80e62efe5937e87 (diff)
downloaddocker-py-7117855f6e577678ba47536d860d193fcb131a75.tar.gz
Fix pulling images with `stream=True`
Pulling an image with option `stream=True` like this: ``` client.api.pull('docker.io/user/repo_name', tag='latest', stream=True) ``` without consuming the generator oftentimes results in premature drop of the connection. Docker daemon tries to send progress of pulling the image to the client, but it encounters an error (broken pipe) and therefore cancells the pull action: ``` Thread 1 "dockerd-dev" received signal SIGPIPE, Broken pipe. ERRO[2018-09-03T05:12:35.746497638+02:00] Not continuing with pull after error: context canceled ``` As described in issue #2116, even though client receives response with status code 200, image is not pulled. Closes #2116 Signed-off-by: Przemysław Adamek <adw1n@users.noreply.github.com>
-rw-r--r--docker/api/image.py3
-rw-r--r--docker/models/images.py1
-rw-r--r--tests/unit/models_containers_test.py3
-rw-r--r--tests/unit/models_images_test.py6
4 files changed, 9 insertions, 4 deletions
diff --git a/docker/api/image.py b/docker/api/image.py
index e9e61db..5a6537e 100644
--- a/docker/api/image.py
+++ b/docker/api/image.py
@@ -334,7 +334,8 @@ class ImageApiMixin(object):
Args:
repository (str): The repository to pull
tag (str): The tag to pull
- stream (bool): Stream the output as a generator
+ stream (bool): Stream the output as a generator. Make sure to
+ consume the generator, otherwise pull might get cancelled.
auth_config (dict): Override the credentials that
:py:meth:`~docker.api.daemon.DaemonApiMixin.login` has set for
this request. ``auth_config`` should contain the ``username``
diff --git a/docker/models/images.py b/docker/models/images.py
index 4578c0b..f8b842a 100644
--- a/docker/models/images.py
+++ b/docker/models/images.py
@@ -425,6 +425,7 @@ class ImageCollection(Collection):
if not tag:
repository, tag = parse_repository_tag(repository)
+ kwargs['stream'] = False
self.client.api.pull(repository, tag=tag, **kwargs)
if tag:
return self.get('{0}{2}{1}'.format(
diff --git a/tests/unit/models_containers_test.py b/tests/unit/models_containers_test.py
index 22dd241..957035a 100644
--- a/tests/unit/models_containers_test.py
+++ b/tests/unit/models_containers_test.py
@@ -232,7 +232,8 @@ class ContainerCollectionTest(unittest.TestCase):
container = client.containers.run('alpine', 'sleep 300', detach=True)
assert container.id == FAKE_CONTAINER_ID
- client.api.pull.assert_called_with('alpine', platform=None, tag=None)
+ client.api.pull.assert_called_with('alpine', platform=None, tag=None,
+ stream=False)
def test_run_with_error(self):
client = make_fake_client()
diff --git a/tests/unit/models_images_test.py b/tests/unit/models_images_test.py
index 6783279..ef81a15 100644
--- a/tests/unit/models_images_test.py
+++ b/tests/unit/models_images_test.py
@@ -43,7 +43,8 @@ class ImageCollectionTest(unittest.TestCase):
def test_pull(self):
client = make_fake_client()
image = client.images.pull('test_image:latest')
- client.api.pull.assert_called_with('test_image', tag='latest')
+ client.api.pull.assert_called_with('test_image', tag='latest',
+ stream=False)
client.api.inspect_image.assert_called_with('test_image:latest')
assert isinstance(image, Image)
assert image.id == FAKE_IMAGE_ID
@@ -51,7 +52,8 @@ class ImageCollectionTest(unittest.TestCase):
def test_pull_multiple(self):
client = make_fake_client()
images = client.images.pull('test_image')
- client.api.pull.assert_called_with('test_image', tag=None)
+ client.api.pull.assert_called_with('test_image', tag=None,
+ stream=False)
client.api.images.assert_called_with(
all=False, name='test_image', filters=None
)