Skip to content

Commit 5e143c0

Browse files
committed
Check presence of errors in server response to image push
Fixes: docker#3277 Signed-off-by: Francesco Zardi <[email protected]>
1 parent a365202 commit 5e143c0

File tree

3 files changed

+36
-3
lines changed

3 files changed

+36
-3
lines changed

docker/api/image.py

+8-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import logging
22
import os
33

4+
from ..utils.json_stream import json_stream
45
from .. import auth, errors, utils
56
from ..constants import DEFAULT_DATA_CHUNK_SIZE
67

@@ -494,10 +495,14 @@ def push(self, repository, tag=None, stream=False, auth_config=None,
494495

495496
self._raise_for_status(response)
496497

497-
if stream:
498-
return self._stream_helper(response, decode=decode)
498+
for chunk in json_stream(self._stream_helper(response, decode=decode)):
499+
if 'error' in chunk:
500+
raise errors.APIError(chunk['error'], response=response)
501+
if stream:
502+
yield chunk
499503

500-
return self._result(response)
504+
if not stream:
505+
return response.text
501506

502507
@utils.check_resource('image')
503508
def remove_image(self, image, force=False, noprune=False):

tests/unit/api_image_test.py

+19
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,24 @@ def test_push_image(self):
227227
timeout=DEFAULT_TIMEOUT_SECONDS
228228
)
229229

230+
def test_push_image_bad_auth(self):
231+
with pytest.raises(docker.errors.APIError, match='you shall not pass'):
232+
with mock.patch('docker.auth.resolve_authconfig',
233+
fake_resolve_authconfig):
234+
self.client.push(fake_api.FAKE_IMAGE_NAME_BAD_AUTH)
235+
236+
fake_request.assert_called_with(
237+
'POST',
238+
f"{url_prefix}images/test_image_bad_auth/push",
239+
params={
240+
'tag': None
241+
},
242+
data='{}',
243+
headers={'Content-Type': 'application/json'},
244+
stream=False,
245+
timeout=DEFAULT_TIMEOUT_SECONDS
246+
)
247+
230248
def test_push_image_with_tag(self):
231249
with mock.patch('docker.auth.resolve_authconfig',
232250
fake_resolve_authconfig):
@@ -271,6 +289,7 @@ def test_push_image_with_auth(self):
271289
timeout=DEFAULT_TIMEOUT_SECONDS
272290
)
273291

292+
274293
def test_push_image_stream(self):
275294
with mock.patch('docker.auth.resolve_authconfig',
276295
fake_resolve_authconfig):

tests/unit/fake_api.py

+9
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
FAKE_EXEC_ID = 'b098ec855f10434b5c7c973c78484208223a83f663ddaefb0f02a242840cb1c7'
1010
FAKE_NETWORK_ID = '1999cfb42e414483841a125ade3c276c3cb80cb3269b14e339354ac63a31b02c'
1111
FAKE_IMAGE_NAME = 'test_image'
12+
FAKE_IMAGE_NAME_BAD_AUTH = 'test_image_bad_auth'
1213
FAKE_TARBALL_PATH = '/path/to/tarball'
1314
FAKE_REPO_NAME = 'repo'
1415
FAKE_TAG_NAME = 'tag'
@@ -359,6 +360,12 @@ def post_fake_push():
359360
return status_code, response
360361

361362

363+
def post_fake_push_bad_auth():
364+
status_code = 200
365+
response = [{'Id': FAKE_IMAGE_ID}, {'error':'you shall not pass'}]
366+
return status_code, response
367+
368+
362369
def post_fake_build_container():
363370
status_code = 200
364371
response = {'Id': FAKE_CONTAINER_ID}
@@ -603,6 +610,8 @@ def post_fake_config():
603610
get_fake_insert_image,
604611
f'{prefix}/{CURRENT_VERSION}/images/test_image/push':
605612
post_fake_push,
613+
f'{prefix}/{CURRENT_VERSION}/images/test_image_bad_auth/push':
614+
post_fake_push_bad_auth,
606615
f'{prefix}/{CURRENT_VERSION}/commit':
607616
post_fake_commit,
608617
f'{prefix}/{CURRENT_VERSION}/containers/create':

0 commit comments

Comments
 (0)