Kaydet (Commit) a74d5468 authored tarafından adw1n's avatar adw1n Kaydeden (comit) Joffrey F

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: 's avatarPrzemysław Adamek <adw1n@users.noreply.github.com>
üst e1e40487
......@@ -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``
......
......@@ -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(
......
......@@ -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()
......
......@@ -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
)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment