Skip to content

Commit a775ab9

Browse files
Zuulopenstack-gerrit
authored andcommitted
Merge "Fix LP#2054575" into stable/2024.1
2 parents 584accc + 5317526 commit a775ab9

File tree

4 files changed

+45
-10
lines changed

4 files changed

+45
-10
lines changed

glance/api/v2/images.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -673,7 +673,7 @@ def _do_add(self, req, image, api_pol, change):
673673
json_schema_version = change.get('json_schema_version', 10)
674674
if path_root == 'locations':
675675
api_pol.update_locations()
676-
self._do_add_locations(image, path[1], value)
676+
self._do_add_locations(image, path[1], value, req.context)
677677
else:
678678
api_pol.update_property(path_root, value)
679679
if ((hasattr(image, path_root) or
@@ -1042,7 +1042,7 @@ def _do_replace_locations(self, image, value):
10421042
raise webob.exc.HTTPBadRequest(
10431043
explanation=encodeutils.exception_to_unicode(ve))
10441044

1045-
def _do_add_locations(self, image, path_pos, value):
1045+
def _do_add_locations(self, image, path_pos, value, context):
10461046
if CONF.show_multiple_locations == False:
10471047
msg = _("It's not allowed to add locations if locations are "
10481048
"invisible.")
@@ -1058,7 +1058,7 @@ def _do_add_locations(self, image, path_pos, value):
10581058
updated_location = value
10591059
if CONF.enabled_backends:
10601060
updated_location = store_utils.get_updated_store_location(
1061-
[value])[0]
1061+
[value], context=context)[0]
10621062

10631063
pos = self._get_locations_op_pos(path_pos,
10641064
len(image.locations), True)

glance/common/store_utils.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,8 +238,12 @@ def _update_cinder_location_and_store_id(context, loc):
238238
"due to unknown issues."), uri)
239239

240240

241-
def get_updated_store_location(locations):
241+
def get_updated_store_location(locations, context=None):
242242
for loc in locations:
243+
if loc['url'].startswith("cinder://") and context:
244+
_update_cinder_location_and_store_id(context, loc)
245+
continue
246+
243247
store_id = _get_store_id_from_uri(loc['url'])
244248
if store_id:
245249
loc['metadata']['store'] = store_id

glance/tests/unit/common/test_utils.py

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,8 @@ class TestCinderStoreUtils(base.MultiStoreClearingUnitTest):
102102
new_callable=mock.PropertyMock)
103103
def _test_update_cinder_store_in_location(self, mock_url_prefix,
104104
mock_associate_store,
105-
is_valid=True):
105+
is_valid=True,
106+
modify_source_url=False):
106107
volume_id = 'db457a25-8f16-4b2c-a644-eae8d17fe224'
107108
store_id = 'fast-cinder'
108109
expected = 'fast-cinder'
@@ -117,7 +118,11 @@ def _test_update_cinder_store_in_location(self, mock_url_prefix,
117118
}]
118119
mock_url_prefix.return_value = 'cinder://%s' % store_id
119120
image.locations = locations
120-
store_utils.update_store_in_locations(context, image, image_repo)
121+
if modify_source_url:
122+
updated_location = store_utils.get_updated_store_location(
123+
locations, context=context)
124+
else:
125+
store_utils.update_store_in_locations(context, image, image_repo)
121126

122127
if is_valid:
123128
# This is the case where we found an image that has an
@@ -129,10 +134,18 @@ def _test_update_cinder_store_in_location(self, mock_url_prefix,
129134
# format i.e. this is the case when store is valid and location
130135
# url, metadata are updated and image_repo.save is called
131136
expected_url = mock_url_prefix.return_value + '/' + volume_id
132-
self.assertEqual(expected_url, image.locations[0].get('url'))
133-
self.assertEqual(expected, image.locations[0]['metadata'].get(
134-
'store'))
135-
self.assertEqual(1, image_repo.save.call_count)
137+
if modify_source_url:
138+
# This is the case where location url is modified to be
139+
# compatible with multistore as below,
140+
# `cinder://store_id/volume_id` to avoid InvalidLocation error
141+
self.assertEqual(expected_url, updated_location[0].get('url'))
142+
self.assertEqual(expected,
143+
updated_location[0]['metadata'].get('store'))
144+
else:
145+
self.assertEqual(expected_url, image.locations[0].get('url'))
146+
self.assertEqual(expected, image.locations[0]['metadata'].get(
147+
'store'))
148+
self.assertEqual(1, image_repo.save.call_count)
136149
else:
137150
# Here, we've got an image backed by a volume which does
138151
# not have a corresponding store specifying the volume_type.
@@ -151,6 +164,15 @@ def test_update_cinder_store_location_valid_type(self):
151164
def test_update_cinder_store_location_invalid_type(self):
152165
self._test_update_cinder_store_in_location(is_valid=False)
153166

167+
def test_get_updated_cinder_store_location(self):
168+
"""
169+
Test if location url is modified to be compatible
170+
with multistore.
171+
"""
172+
173+
self._test_update_cinder_store_in_location(
174+
modify_source_url=True)
175+
154176

155177
class TestUtils(test_utils.BaseTestCase):
156178
"""Test routines in glance.utils"""
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
fixes:
3+
- |
4+
`Bug #2054575 <https://bugs.launchpad.net/glance/+bug/2054575>`_:
5+
Fixed the issue when cinder uploads a volume to glance in the
6+
optimized path and glance rejects the request with invalid location.
7+
Now we convert the old location format sent by cinder into the new
8+
location format supported by multi store, hence allowing volumes to
9+
be uploaded in an optimized way.

0 commit comments

Comments
 (0)