From 5be26e13ade3f33b98f551940ca39b25a5790c80 Mon Sep 17 00:00:00 2001 From: Mike Fedosin Date: Thu, 1 Oct 2015 18:28:48 +0300 Subject: [PATCH] Catch NotAuthenticated exception in import task If glance uses registry as data_api then it's possible that token may expire during image import task and Glance will have NotUauthenticated exception. This code adds a correct handling of this exception and allows Glance to remove stale chunks from store. Partial-Bug: #1498163 Change-Id: Ia6e1fe0d27b13b920ee7e728feb5305dec77e066 --- glance/common/scripts/image_import/main.py | 3 ++- .../common/scripts/image_import/test_main.py | 26 +++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/glance/common/scripts/image_import/main.py b/glance/common/scripts/image_import/main.py index b3f82ed232..e654095111 100644 --- a/glance/common/scripts/image_import/main.py +++ b/glance/common/scripts/image_import/main.py @@ -110,7 +110,8 @@ def import_image(image_repo, image_factory, task_input, task_id, uri): "processing.") % {"image_id": image_id, "task_id": task_id} raise exception.Conflict(msg) - except (exception.Conflict, exception.NotFound): + except (exception.Conflict, exception.NotFound, + exception.NotAuthenticated): with excutils.save_and_reraise_exception(): if new_image.locations: for location in new_image.locations: diff --git a/glance/tests/unit/common/scripts/image_import/test_main.py b/glance/tests/unit/common/scripts/image_import/test_main.py index 924756a92d..b4b14a4b49 100644 --- a/glance/tests/unit/common/scripts/image_import/test_main.py +++ b/glance/tests/unit/common/scripts/image_import/test_main.py @@ -16,7 +16,10 @@ import mock from six.moves import urllib +import glance.common.exception as exception from glance.common.scripts.image_import import main as image_import_script +from glance.common import store_utils + import glance.tests.utils as test_utils @@ -91,3 +94,26 @@ class TestImageImport(test_utils.BaseTestCase): image = mock.Mock() self.assertRaises(urllib.error.URLError, image_import_script.set_image_data, image, uri, None) + + @mock.patch.object(image_import_script, 'create_image') + @mock.patch.object(image_import_script, 'set_image_data') + @mock.patch.object(store_utils, 'delete_image_location_from_backend') + def test_import_image_failed_with_expired_token( + self, mock_delete_data, mock_set_img_data, mock_create_image): + image_id = mock.ANY + locations = ['location'] + image = mock.Mock(image_id=image_id, locations=locations) + image_repo = mock.Mock() + image_repo.get.side_effect = [image, exception.NotAuthenticated] + image_factory = mock.ANY + task_input = mock.Mock(image_properties=mock.ANY) + uri = mock.ANY + + mock_create_image.return_value = image + self.assertRaises(exception.NotAuthenticated, + image_import_script.import_image, + image_repo, image_factory, + task_input, None, uri) + self.assertEqual(1, mock_set_img_data.call_count) + mock_delete_data.assert_called_once_with( + mock_create_image().context, image_id, 'location')