Skip to content

Commit 7117855

Browse files
adw1nshin-
authored andcommitted
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 <[email protected]>
1 parent f9505da commit 7117855

File tree

4 files changed

+9
-4
lines changed

4 files changed

+9
-4
lines changed

docker/api/image.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,8 @@ def pull(self, repository, tag=None, stream=False, auth_config=None,
334334
Args:
335335
repository (str): The repository to pull
336336
tag (str): The tag to pull
337-
stream (bool): Stream the output as a generator
337+
stream (bool): Stream the output as a generator. Make sure to
338+
consume the generator, otherwise pull might get cancelled.
338339
auth_config (dict): Override the credentials that
339340
:py:meth:`~docker.api.daemon.DaemonApiMixin.login` has set for
340341
this request. ``auth_config`` should contain the ``username``

docker/models/images.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,7 @@ def pull(self, repository, tag=None, **kwargs):
425425
if not tag:
426426
repository, tag = parse_repository_tag(repository)
427427

428+
kwargs['stream'] = False
428429
self.client.api.pull(repository, tag=tag, **kwargs)
429430
if tag:
430431
return self.get('{0}{2}{1}'.format(

tests/unit/models_containers_test.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,8 @@ def test_run_pull(self):
232232
container = client.containers.run('alpine', 'sleep 300', detach=True)
233233

234234
assert container.id == FAKE_CONTAINER_ID
235-
client.api.pull.assert_called_with('alpine', platform=None, tag=None)
235+
client.api.pull.assert_called_with('alpine', platform=None, tag=None,
236+
stream=False)
236237

237238
def test_run_with_error(self):
238239
client = make_fake_client()

tests/unit/models_images_test.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,17 @@ def test_load(self):
4343
def test_pull(self):
4444
client = make_fake_client()
4545
image = client.images.pull('test_image:latest')
46-
client.api.pull.assert_called_with('test_image', tag='latest')
46+
client.api.pull.assert_called_with('test_image', tag='latest',
47+
stream=False)
4748
client.api.inspect_image.assert_called_with('test_image:latest')
4849
assert isinstance(image, Image)
4950
assert image.id == FAKE_IMAGE_ID
5051

5152
def test_pull_multiple(self):
5253
client = make_fake_client()
5354
images = client.images.pull('test_image')
54-
client.api.pull.assert_called_with('test_image', tag=None)
55+
client.api.pull.assert_called_with('test_image', tag=None,
56+
stream=False)
5557
client.api.images.assert_called_with(
5658
all=False, name='test_image', filters=None
5759
)

0 commit comments

Comments
 (0)