From 2b3331ad7990d48061ea8606605b1fcbe015f7ca Mon Sep 17 00:00:00 2001 From: jiangpengcheng Date: Tue, 23 May 2017 03:55:32 -0400 Subject: [PATCH] Raise ImageNotFound when image not found in docker The docker library will raise an NotFound exception when image's repo is not found,instead of returning an error message containg "not found". so the docker driver will raise a ZunException when image is not found in docker repo, which differs from the glance driver. Closes-Bug: #1693060 Change-Id: Id7bb5b37c912bf32d95a6e0ba94121097611cc61 --- zun/image/docker/driver.py | 15 ++++-------- zun/tests/unit/image/docker/test_driver.py | 28 ++++++++-------------- 2 files changed, 15 insertions(+), 28 deletions(-) diff --git a/zun/image/docker/driver.py b/zun/image/docker/driver.py index 6f4f52a07..15eb8e9b2 100644 --- a/zun/image/docker/driver.py +++ b/zun/image/docker/driver.py @@ -14,7 +14,7 @@ # limitations under the License. from docker import errors -import json +import six from oslo_log import log as logging from oslo_utils import excutils @@ -47,13 +47,10 @@ class DockerDriver(driver.ContainerImageDriver): def _pull_image(self, repo, tag): with docker_utils.docker_client() as docker: - for line in docker.pull(repo, tag=tag, stream=True): - error = json.loads(line).get('errorDetail') - if error: - if "not found" in error['message']: - raise exception.ImageNotFound(error['message']) - else: - raise exception.DockerError(error['message']) + try: + docker.pull(repo, tag=tag) + except errors.NotFound as e: + raise exception.ImageNotFound(message=six.text_type(e)) def pull_image(self, context, repo, tag, image_pull_policy): image_loaded = True @@ -81,8 +78,6 @@ class DockerDriver(driver.ContainerImageDriver): LOG.error( 'Docker API error occurred during downloading\ image %s' % repo) - except errors.APIError as api_error: - raise exception.ZunException(str(api_error)) except Exception as e: msg = _('Cannot download image from docker: {0}') raise exception.ZunException(msg.format(e)) diff --git a/zun/tests/unit/image/docker/test_driver.py b/zun/tests/unit/image/docker/test_driver.py index d9a7db68d..4de4f9ada 100644 --- a/zun/tests/unit/image/docker/test_driver.py +++ b/zun/tests/unit/image/docker/test_driver.py @@ -69,8 +69,7 @@ class TestDriver(base.BaseTestCase): self.assertEqual(({'image': 'test_image', 'path': None}, True), ret) self.mock_docker.pull.assert_called_once_with( 'test_image', - tag='latest', - stream=True) + tag='latest') @mock.patch('zun.common.utils.parse_image_name') @mock.patch.object(driver.DockerDriver, @@ -89,8 +88,7 @@ class TestDriver(base.BaseTestCase): None, 'repo', 'tag', 'always') self.mock_docker.pull.assert_called_once_with( 'repo', - tag='tag', - stream=True) + tag='tag') self.assertEqual(1, mock_init.call_count) @mock.patch('zun.common.utils.parse_image_name') @@ -102,18 +100,15 @@ class TestDriver(base.BaseTestCase): mock_should_pull_image.return_value = True mock_search.return_value = {'image': 'nginx', 'path': 'xyz'} mock_parse_image.return_value = ('repo', 'tag') - pull_return_value = '{"errorDetail":{"message":'\ - '"Error: image library/repo not found"},'\ - '"error":"Error: image library/repo not found"}' with mock.patch.object(self.mock_docker, 'pull', - return_value=[pull_return_value]) as mock_pull: + side_effect=exception.ImageNotFound('Error') + ) as mock_pull: self.assertRaises(exception.ImageNotFound, self.driver.pull_image, None, 'repo', 'tag', 'always') self.mock_docker.pull.assert_called_once_with( 'repo', - tag='tag', - stream=True) + tag='tag') self.assertEqual(1, mock_pull.call_count) @mock.patch('zun.common.utils.parse_image_name') @@ -125,18 +120,15 @@ class TestDriver(base.BaseTestCase): mock_should_pull_image.return_value = True mock_search.return_value = {'image': 'nginx', 'path': 'xyz'} mock_parse_image.return_value = ('repo', 'tag') - pull_return_value = '{"errorDetail":{"message":'\ - '"Error: image library/repo not"},'\ - '"error":"Error: image library/repo"}' with mock.patch.object(self.mock_docker, 'pull', - return_value=[pull_return_value]) as mock_pull: + side_effect=exception.DockerError('Error') + ) as mock_pull: self.assertRaises(exception.DockerError, self.driver.pull_image, None, 'repo', 'tag', 'always') self.mock_docker.pull.assert_called_once_with( 'repo', - tag='tag', - stream=True) + tag='tag') self.assertEqual(1, mock_pull.call_count) @mock.patch('zun.common.utils.parse_image_name') @@ -148,6 +140,7 @@ class TestDriver(base.BaseTestCase): mock_should_pull_image.return_value = True mock_search.return_value = {'image': 'nginx', 'path': 'xyz'} mock_parse_image.return_value = ('repo', 'tag') + with mock.patch.object(TempException, '__str__', return_value='hit error') as mock_init: self.mock_docker.pull = mock.Mock( @@ -156,8 +149,7 @@ class TestDriver(base.BaseTestCase): None, 'repo', 'tag', 'always') self.mock_docker.pull.assert_called_once_with( 'repo', - tag='tag', - stream=True) + tag='tag') self.assertEqual(1, mock_init.call_count) def test_search_image_success(self):