diff options
author | adw1n <adw1n@users.noreply.github.com> | 2018-09-03 05:54:12 +0200 |
---|---|---|
committer | Joffrey F <joffrey@docker.com> | 2018-11-28 11:27:04 -0800 |
commit | a74d546864b64ba03dce1e3407d3b0cd5badee9f (patch) | |
tree | f16e0972a72241f8e592fa5f230ebae0738b3637 | |
parent | e1e4048753aafc96571752cf54d96df7b24156d3 (diff) | |
download | docker-py-a74d546864b64ba03dce1e3407d3b0cd5badee9f.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.py | 3 | ||||
-rw-r--r-- | docker/models/images.py | 1 | ||||
-rw-r--r-- | tests/unit/models_containers_test.py | 3 | ||||
-rw-r--r-- | tests/unit/models_images_test.py | 6 |
4 files changed, 9 insertions, 4 deletions
diff --git a/docker/api/image.py b/docker/api/image.py index a9f801e..d3fed5c 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 ) |