mirror of https://github.com/docker/docker-py.git
Merge 958049e01d
into 6e6a273573
This commit is contained in:
commit
1a8f65bcdd
|
@ -3,6 +3,7 @@ import os
|
|||
|
||||
from .. import auth, errors, utils
|
||||
from ..constants import DEFAULT_DATA_CHUNK_SIZE
|
||||
from ..types.image import Platform
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
@ -434,7 +435,7 @@ class ImageApiMixin:
|
|||
return self._result(response)
|
||||
|
||||
def push(self, repository, tag=None, stream=False, auth_config=None,
|
||||
decode=False):
|
||||
decode=False, platform=None):
|
||||
"""
|
||||
Push an image or a repository to the registry. Similar to the ``docker
|
||||
push`` command.
|
||||
|
@ -448,6 +449,7 @@ class ImageApiMixin:
|
|||
``username`` and ``password`` keys to be valid.
|
||||
decode (bool): Decode the JSON data from the server into dicts.
|
||||
Only applies with ``stream=True``
|
||||
platform (str): JSON-encoded OCI platform to select the platform-variant to push. If not provided, all available variants will attempt to be pushed.
|
||||
|
||||
Returns:
|
||||
(generator or str): The output from the server.
|
||||
|
@ -488,6 +490,13 @@ class ImageApiMixin:
|
|||
log.debug('Sending supplied auth config')
|
||||
headers['X-Registry-Auth'] = auth.encode_header(auth_config)
|
||||
|
||||
if platform is not None:
|
||||
if utils.version_lt(self._version, '1.46'):
|
||||
raise errors.InvalidVersion(
|
||||
'platform was only introduced in API version 1.46'
|
||||
)
|
||||
params['platform'] = Platform
|
||||
|
||||
response = self._post_json(
|
||||
u, None, headers=headers, stream=stream, params=params
|
||||
)
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
from .base import DictType
|
||||
|
||||
|
||||
class Platform(DictType):
|
||||
def __init__(self, **kwargs):
|
||||
architecture = kwargs.get('architecture', kwargs.get('Architecture'))
|
||||
os = kwargs.get('os', kwargs.get('OS'))
|
||||
|
||||
if architecture is None and os is None:
|
||||
raise ValueError("At least one of 'architecture' or 'os' must be provided")
|
||||
|
||||
|
||||
super().__init__({
|
||||
'Architecture': architecture,
|
||||
'OS': os,
|
||||
'OSVersion': kwargs.get('os_version', kwargs.get('OSVersion')),
|
||||
'OSFeatures': kwargs.get('os_features', kwargs.get('OSFeatures')),
|
||||
'Variant': kwargs.get('variant', kwargs.get('Variant'))
|
||||
})
|
||||
|
||||
@property
|
||||
def architecture(self):
|
||||
return self['Architecture']
|
||||
|
||||
@property
|
||||
def os(self):
|
||||
return self['OS']
|
||||
|
||||
@architecture.setter
|
||||
def architecture(self, value):
|
||||
self['Architecture'] = value
|
||||
|
||||
@os.setter
|
||||
def os(self, value):
|
||||
self['OS'] = value
|
|
@ -5,6 +5,7 @@ import pytest
|
|||
import docker
|
||||
from docker import auth
|
||||
|
||||
from ..helpers import requires_api_version
|
||||
from . import fake_api
|
||||
from .api_test import (
|
||||
DEFAULT_TIMEOUT_SECONDS,
|
||||
|
@ -271,6 +272,28 @@ class ImageTest(BaseAPIClientTest):
|
|||
timeout=DEFAULT_TIMEOUT_SECONDS
|
||||
)
|
||||
|
||||
@requires_api_version('1.46')
|
||||
def test_push_image_with_platform(self):
|
||||
with mock.patch('docker.auth.resolve_authconfig',
|
||||
fake_resolve_authconfig):
|
||||
self.client.push(
|
||||
fake_api.FAKE_IMAGE_NAME,
|
||||
platform=fake_api.FAKE_PLATFORM
|
||||
)
|
||||
|
||||
fake_request.assert_called_with(
|
||||
'POST',
|
||||
f"{url_prefix}images/test_image/push",
|
||||
params={
|
||||
'tag': None,
|
||||
'platform': fake_api.FAKE_PLATFORM
|
||||
},
|
||||
data='{}',
|
||||
headers={'Content-Type': 'application/json'},
|
||||
stream=False,
|
||||
timeout=DEFAULT_TIMEOUT_SECONDS
|
||||
)
|
||||
|
||||
def test_push_image_stream(self):
|
||||
with mock.patch('docker.auth.resolve_authconfig',
|
||||
fake_resolve_authconfig):
|
||||
|
|
|
@ -21,6 +21,7 @@ FAKE_SECRET_ID = 'epdyrw4tsi03xy3deu8g8ly6o'
|
|||
FAKE_SECRET_NAME = 'super_secret'
|
||||
FAKE_CONFIG_ID = 'sekvs771242jfdjnvfuds8232'
|
||||
FAKE_CONFIG_NAME = 'super_config'
|
||||
FAKE_PLATFORM = "{'os': 'linux','architecture': 'arm','variant': 'v5'}"
|
||||
|
||||
# Each method is prefixed with HTTP method (get, post...)
|
||||
# for clarity and readability
|
||||
|
|
Loading…
Reference in New Issue