mirror of https://github.com/docker/docker-py.git
Update save / export methods to return data generators
Signed-off-by: Joffrey F <joffrey@docker.com>
This commit is contained in:
parent
deb8222d69
commit
388f291b13
|
@ -698,7 +698,7 @@ class ContainerApiMixin(object):
|
||||||
container (str): The container to export
|
container (str): The container to export
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
(str): The filesystem tar archive
|
(generator): The archived filesystem data stream
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
:py:class:`docker.errors.APIError`
|
:py:class:`docker.errors.APIError`
|
||||||
|
@ -707,8 +707,7 @@ class ContainerApiMixin(object):
|
||||||
res = self._get(
|
res = self._get(
|
||||||
self._url("/containers/{0}/export", container), stream=True
|
self._url("/containers/{0}/export", container), stream=True
|
||||||
)
|
)
|
||||||
self._raise_for_status(res)
|
return self._stream_raw_result(res)
|
||||||
return res.raw
|
|
||||||
|
|
||||||
@utils.check_resource('container')
|
@utils.check_resource('container')
|
||||||
@utils.minimum_version('1.20')
|
@utils.minimum_version('1.20')
|
||||||
|
@ -737,7 +736,7 @@ class ContainerApiMixin(object):
|
||||||
self._raise_for_status(res)
|
self._raise_for_status(res)
|
||||||
encoded_stat = res.headers.get('x-docker-container-path-stat')
|
encoded_stat = res.headers.get('x-docker-container-path-stat')
|
||||||
return (
|
return (
|
||||||
res.raw,
|
self._stream_raw_result(res),
|
||||||
utils.decode_json_header(encoded_stat) if encoded_stat else None
|
utils.decode_json_header(encoded_stat) if encoded_stat else None
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -21,8 +21,7 @@ class ImageApiMixin(object):
|
||||||
image (str): Image name to get
|
image (str): Image name to get
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
(urllib3.response.HTTPResponse object): The response from the
|
(generator): A stream of raw archive data.
|
||||||
daemon.
|
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
:py:class:`docker.errors.APIError`
|
:py:class:`docker.errors.APIError`
|
||||||
|
@ -30,14 +29,14 @@ class ImageApiMixin(object):
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
>>> image = cli.get_image("fedora:latest")
|
>>> image = cli.get_image("busybox:latest")
|
||||||
>>> f = open('/tmp/fedora-latest.tar', 'w')
|
>>> f = open('/tmp/busybox-latest.tar', 'w')
|
||||||
>>> f.write(image.data)
|
>>> for chunk in image:
|
||||||
|
>>> f.write(chunk)
|
||||||
>>> f.close()
|
>>> f.close()
|
||||||
"""
|
"""
|
||||||
res = self._get(self._url("/images/{0}/get", image), stream=True)
|
res = self._get(self._url("/images/{0}/get", image), stream=True)
|
||||||
self._raise_for_status(res)
|
return self._stream_raw_result(res)
|
||||||
return res.raw
|
|
||||||
|
|
||||||
@utils.check_resource('image')
|
@utils.check_resource('image')
|
||||||
def history(self, image):
|
def history(self, image):
|
||||||
|
|
|
@ -61,8 +61,7 @@ class Image(Model):
|
||||||
Get a tarball of an image. Similar to the ``docker save`` command.
|
Get a tarball of an image. Similar to the ``docker save`` command.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
(urllib3.response.HTTPResponse object): The response from the
|
(generator): A stream of raw archive data.
|
||||||
daemon.
|
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
:py:class:`docker.errors.APIError`
|
:py:class:`docker.errors.APIError`
|
||||||
|
@ -70,11 +69,10 @@ class Image(Model):
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
>>> image = cli.images.get("fedora:latest")
|
>>> image = cli.get_image("busybox:latest")
|
||||||
>>> resp = image.save()
|
>>> f = open('/tmp/busybox-latest.tar', 'w')
|
||||||
>>> f = open('/tmp/fedora-latest.tar', 'w')
|
>>> for chunk in image:
|
||||||
>>> for chunk in resp.stream():
|
>>> f.write(chunk)
|
||||||
>>> f.write(chunk)
|
|
||||||
>>> f.close()
|
>>> f.close()
|
||||||
"""
|
"""
|
||||||
return self.client.api.get_image(self.id)
|
return self.client.api.get_image(self.id)
|
||||||
|
|
|
@ -329,7 +329,7 @@ class PruneImagesTest(BaseAPIIntegrationTest):
|
||||||
img_id = self.client.inspect_image('hello-world')['Id']
|
img_id = self.client.inspect_image('hello-world')['Id']
|
||||||
result = self.client.prune_images()
|
result = self.client.prune_images()
|
||||||
assert img_id not in [
|
assert img_id not in [
|
||||||
img.get('Deleted') for img in result['ImagesDeleted']
|
img.get('Deleted') for img in result.get('ImagesDeleted') or []
|
||||||
]
|
]
|
||||||
result = self.client.prune_images({'dangling': False})
|
result = self.client.prune_images({'dangling': False})
|
||||||
assert result['SpaceReclaimed'] > 0
|
assert result['SpaceReclaimed'] > 0
|
||||||
|
@ -339,3 +339,25 @@ class PruneImagesTest(BaseAPIIntegrationTest):
|
||||||
assert img_id in [
|
assert img_id in [
|
||||||
img.get('Deleted') for img in result['ImagesDeleted']
|
img.get('Deleted') for img in result['ImagesDeleted']
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class SaveLoadImagesTest(BaseAPIIntegrationTest):
|
||||||
|
@requires_api_version('1.23')
|
||||||
|
def test_get_image_load_image(self):
|
||||||
|
with tempfile.TemporaryFile() as f:
|
||||||
|
stream = self.client.get_image(BUSYBOX)
|
||||||
|
for chunk in stream:
|
||||||
|
f.write(chunk)
|
||||||
|
|
||||||
|
f.seek(0)
|
||||||
|
result = self.client.load_image(f.read())
|
||||||
|
|
||||||
|
success = False
|
||||||
|
result_line = 'Loaded image: {}\n'.format(BUSYBOX)
|
||||||
|
for data in result:
|
||||||
|
print(data)
|
||||||
|
if 'stream' in data:
|
||||||
|
if data['stream'] == result_line:
|
||||||
|
success = True
|
||||||
|
break
|
||||||
|
assert success is True
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
import io
|
import io
|
||||||
|
import tempfile
|
||||||
|
|
||||||
import docker
|
import docker
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from .base import BaseIntegrationTest, TEST_API_VERSION
|
from .base import BaseIntegrationTest, BUSYBOX, TEST_API_VERSION
|
||||||
|
|
||||||
|
|
||||||
class ImageCollectionTest(BaseIntegrationTest):
|
class ImageCollectionTest(BaseIntegrationTest):
|
||||||
|
@ -76,6 +77,20 @@ class ImageCollectionTest(BaseIntegrationTest):
|
||||||
with pytest.raises(docker.errors.ImageLoadError):
|
with pytest.raises(docker.errors.ImageLoadError):
|
||||||
client.images.load('abc')
|
client.images.load('abc')
|
||||||
|
|
||||||
|
def test_save_and_load(self):
|
||||||
|
client = docker.from_env(version=TEST_API_VERSION)
|
||||||
|
image = client.images.get(BUSYBOX)
|
||||||
|
with tempfile.TemporaryFile() as f:
|
||||||
|
stream = image.save()
|
||||||
|
for chunk in stream:
|
||||||
|
f.write(chunk)
|
||||||
|
|
||||||
|
f.seek(0)
|
||||||
|
result = client.images.load(f.read())
|
||||||
|
|
||||||
|
assert len(result) == 1
|
||||||
|
assert result[0].id == image.id
|
||||||
|
|
||||||
|
|
||||||
class ImageTest(BaseIntegrationTest):
|
class ImageTest(BaseIntegrationTest):
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue