Make location URL compatible with cinder backend
While adding location to an image, cinder sends location url as `cinder://volume_id` for single as well as multistore which is incompatible with glance multistore and store throws InvalidLoctation error. Modifying the location url to be compatible with multistore as `cinder://store_id/volume_id` to avoid Invalid Location error. Related-Bug: #2054575 Change-Id: I5f791c58ae857f6c553276dd9808799c3db3aa4f
This commit is contained in:
parent
4dec531b0a
commit
1c523cf94e
@ -235,8 +235,12 @@ def _update_cinder_location_and_store_id(context, loc):
|
||||
return
|
||||
|
||||
|
||||
def get_updated_store_location(locations):
|
||||
def get_updated_store_location(locations, context=None):
|
||||
for loc in locations:
|
||||
if loc['url'].startswith("cinder://") and context:
|
||||
_update_cinder_location_and_store_id(context, loc)
|
||||
continue
|
||||
|
||||
store_id = _get_store_id_from_uri(loc['url'])
|
||||
if store_id:
|
||||
loc['metadata']['store'] = store_id
|
||||
|
@ -102,7 +102,8 @@ class TestCinderStoreUtils(base.MultiStoreClearingUnitTest):
|
||||
new_callable=mock.PropertyMock)
|
||||
def _test_update_cinder_store_in_location(self, mock_url_prefix,
|
||||
mock_associate_store,
|
||||
is_valid=True):
|
||||
is_valid=True,
|
||||
modify_source_url=False):
|
||||
volume_id = 'db457a25-8f16-4b2c-a644-eae8d17fe224'
|
||||
store_id = 'fast-cinder'
|
||||
expected = 'fast-cinder'
|
||||
@ -117,7 +118,11 @@ class TestCinderStoreUtils(base.MultiStoreClearingUnitTest):
|
||||
}]
|
||||
mock_url_prefix.return_value = 'cinder://%s' % store_id
|
||||
image.locations = locations
|
||||
store_utils.update_store_in_locations(context, image, image_repo)
|
||||
if modify_source_url:
|
||||
updated_location = store_utils.get_updated_store_location(
|
||||
locations, context=context)
|
||||
else:
|
||||
store_utils.update_store_in_locations(context, image, image_repo)
|
||||
|
||||
if is_valid:
|
||||
# This is the case where we found an image that has an
|
||||
@ -129,10 +134,18 @@ class TestCinderStoreUtils(base.MultiStoreClearingUnitTest):
|
||||
# format i.e. this is the case when store is valid and location
|
||||
# url, metadata are updated and image_repo.save is called
|
||||
expected_url = mock_url_prefix.return_value + '/' + volume_id
|
||||
self.assertEqual(expected_url, image.locations[0].get('url'))
|
||||
self.assertEqual(expected, image.locations[0]['metadata'].get(
|
||||
'store'))
|
||||
self.assertEqual(1, image_repo.save.call_count)
|
||||
if modify_source_url:
|
||||
# This is the case where location url is modified to be
|
||||
# compatible with multistore as below,
|
||||
# `cinder://store_id/volume_id` to avoid InvalidLocation error
|
||||
self.assertEqual(expected_url, updated_location[0].get('url'))
|
||||
self.assertEqual(expected,
|
||||
updated_location[0]['metadata'].get('store'))
|
||||
else:
|
||||
self.assertEqual(expected_url, image.locations[0].get('url'))
|
||||
self.assertEqual(expected, image.locations[0]['metadata'].get(
|
||||
'store'))
|
||||
self.assertEqual(1, image_repo.save.call_count)
|
||||
else:
|
||||
# Here, we've got an image backed by a volume which does
|
||||
# not have a corresponding store specifying the volume_type.
|
||||
@ -151,6 +164,15 @@ class TestCinderStoreUtils(base.MultiStoreClearingUnitTest):
|
||||
def test_update_cinder_store_location_invalid_type(self):
|
||||
self._test_update_cinder_store_in_location(is_valid=False)
|
||||
|
||||
def test_get_updated_cinder_store_location(self):
|
||||
"""
|
||||
Test if location url is modified to be compatible
|
||||
with multistore.
|
||||
"""
|
||||
|
||||
self._test_update_cinder_store_in_location(
|
||||
modify_source_url=True)
|
||||
|
||||
|
||||
class TestUtils(test_utils.BaseTestCase):
|
||||
"""Test routines in glance.utils"""
|
||||
|
Loading…
Reference in New Issue
Block a user