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

Add methods for /distribution/<name>/json endpoint

Signed-off-by: 's avatarJoffrey F <joffrey@docker.com>
üst f39c0dc1
......@@ -245,6 +245,27 @@ class ImageApiMixin(object):
self._get(self._url("/images/{0}/json", image)), True
)
@utils.minimum_version('1.30')
@utils.check_resource('image')
def inspect_distribution(self, image):
"""
Get image digest and platform information by contacting the registry.
Args:
image (str): The image name to inspect
Returns:
(dict): A dict containing distribution data
Raises:
:py:class:`docker.errors.APIError`
If the server returns an error.
"""
return self._result(
self._get(self._url("/distribution/{0}/json", image)), True
)
def load_image(self, data, quiet=None):
"""
Load an image that was previously saved using
......
......@@ -5,7 +5,7 @@ import six
from ..api import APIClient
from ..constants import DEFAULT_DATA_CHUNK_SIZE
from ..errors import BuildError, ImageLoadError
from ..errors import BuildError, ImageLoadError, InvalidArgument
from ..utils import parse_repository_tag
from ..utils.json_stream import json_stream
from .resource import Collection, Model
......@@ -105,6 +105,81 @@ class Image(Model):
return self.client.api.tag(self.id, repository, tag=tag, **kwargs)
class RegistryData(Model):
"""
Image metadata stored on the registry, including available platforms.
"""
def __init__(self, image_name, *args, **kwargs):
super(RegistryData, self).__init__(*args, **kwargs)
self.image_name = image_name
@property
def id(self):
"""
The ID of the object.
"""
return self.attrs['Descriptor']['digest']
@property
def short_id(self):
"""
The ID of the image truncated to 10 characters, plus the ``sha256:``
prefix.
"""
return self.id[:17]
def pull(self, platform=None):
"""
Pull the image digest.
Args:
platform (str): The platform to pull the image for.
Default: ``None``
Returns:
(:py:class:`Image`): A reference to the pulled image.
"""
repository, _ = parse_repository_tag(self.image_name)
return self.collection.pull(repository, tag=self.id, platform=platform)
def has_platform(self, platform):
"""
Check whether the given platform identifier is available for this
digest.
Args:
platform (str or dict): A string using the ``os[/arch[/variant]]``
format, or a platform dictionary.
Returns:
(bool): ``True`` if the platform is recognized as available,
``False`` otherwise.
Raises:
:py:class:`docker.errors.InvalidArgument`
If the platform argument is not a valid descriptor.
"""
if platform and not isinstance(platform, dict):
parts = platform.split('/')
if len(parts) > 3 or len(parts) < 1:
raise InvalidArgument(
'"{0}" is not a valid platform descriptor'.format(platform)
)
platform = {'os': parts[0]}
if len(parts) > 2:
platform['variant'] = parts[2]
if len(parts) > 1:
platform['architecture'] = parts[1]
return normalize_platform(
platform, self.client.version()
) in self.attrs['Platforms']
def reload(self):
self.attrs = self.client.api.inspect_distribution(self.image_name)
reload.__doc__ = Model.reload.__doc__
class ImageCollection(Collection):
model = Image
......@@ -219,6 +294,26 @@ class ImageCollection(Collection):
"""
return self.prepare_model(self.client.api.inspect_image(name))
def get_registry_data(self, name):
"""
Gets the registry data for an image.
Args:
name (str): The name of the image.
Returns:
(:py:class:`RegistryData`): The data object.
Raises:
:py:class:`docker.errors.APIError`
If the server returns an error.
"""
return RegistryData(
image_name=name,
attrs=self.client.api.inspect_distribution(name),
client=self.client,
collection=self,
)
def list(self, name=None, all=False, filters=None):
"""
List images on the server.
......@@ -336,3 +431,13 @@ class ImageCollection(Collection):
def prune(self, filters=None):
return self.client.api.prune_images(filters=filters)
prune.__doc__ = APIClient.prune_images.__doc__
def normalize_platform(platform, engine_info):
if platform is None:
platform = {}
if 'os' not in platform:
platform['os'] = engine_info['Os']
if 'architecture' not in platform:
platform['architecture'] = engine_info['Arch']
return platform
......@@ -12,6 +12,7 @@ Methods available on ``client.images``:
.. automethod:: build
.. automethod:: get
.. automethod:: get_registry_data
.. automethod:: list(**kwargs)
.. automethod:: load
.. automethod:: prune
......@@ -41,3 +42,21 @@ Image objects
.. automethod:: reload
.. automethod:: save
.. automethod:: tag
RegistryData objects
--------------------
.. autoclass:: RegistryData()
.. py:attribute:: attrs
The raw representation of this object from the server.
.. autoattribute:: id
.. autoattribute:: short_id
.. automethod:: has_platform
.. automethod:: pull
.. automethod:: reload
......@@ -357,3 +357,12 @@ class SaveLoadImagesTest(BaseAPIIntegrationTest):
success = True
break
assert success is True
@requires_api_version('1.30')
class InspectDistributionTest(BaseAPIIntegrationTest):
def test_inspect_distribution(self):
data = self.client.inspect_distribution('busybox:latest')
assert data is not None
assert 'Platforms' in data
assert {'os': 'linux', 'architecture': 'amd64'} in data['Platforms']
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