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
This commit is contained in:
jiangpengcheng 2017-05-23 03:55:32 -04:00 committed by Hongbin Lu
parent 256c5e038a
commit 2b3331ad79
2 changed files with 15 additions and 28 deletions

View File

@ -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))

View File

@ -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):