Multiple import fails if "all_stores" specified as "true"

Newly added multiple import fails if user passes "all_stores" as "true"
in the request. The reason is if all_stores is specified then we are getting
stores using CONF.enabled_backends and unfortunately we are injecting
reserved stores 'os_glance_staging_store' and 'os_glance_tasks_store'
runtime. As a result import job tries to import the image in the
'os_glance_staging_store' store as well where it fails as that image
is already staged in this staging store.

Made a provision to exclude available reserved stores if "all_stores"
is specified.

Change-Id: If2616c275a969cdad5649e2cb0851275e5d0c7d2
Closes-Bug: #1863879
This commit is contained in:
Abhishek Kekane 2020-02-19 12:03:58 +00:00
parent 0035ab2538
commit d7de7ccbd6
3 changed files with 42 additions and 1 deletions

View File

@ -163,6 +163,11 @@ Currently, there are two reserved stores:
import process. It replaces the use of the DEPRECATED configuration
option ``[DEFAULT]/node_staging_uri``.
.. note::
If end user wants to retrieve all the available stores using
``CONF.enabled_backeds`` then he needs to remove reserved
stores from that list explicitly.
Configuration
~~~~~~~~~~~~~

View File

@ -44,6 +44,7 @@ from webob import exc
from glance.common import exception
from glance.common import timeutils
from glance.common import wsgi
from glance.i18n import _, _LE
CONF = cfg.CONF
@ -671,6 +672,17 @@ def evaluate_filter_op(value, operator, threshold):
raise exception.InvalidFilterOperatorValue(msg)
def _get_available_stores():
available_stores = CONF.enabled_backends
stores = []
# Remove reserved stores from the available stores list
for store in available_stores:
if store not in wsgi.RESERVED_STORES:
stores.append(store)
return stores
def get_stores_from_request(req, body):
"""Processes a supplied request and extract stores from it
@ -685,7 +697,7 @@ def get_stores_from_request(req, body):
msg = _("All_stores parameter can't be used with "
"x-image-meta-store header or stores parameter")
raise exc.HTTPBadRequest(explanation=msg)
stores = list(CONF.enabled_backends)
stores = _get_available_stores()
else:
try:
stores = body['stores']

View File

@ -480,6 +480,30 @@ class TestUtils(test_utils.BaseTestCase):
utils.get_stores_from_request, req, body)
def test_get_stores_from_request_returns_all_stores(self):
enabled_backends = {
"ceph1": "rbd",
"ceph2": "rbd"
}
reserved_stores = {
'os_glance_staging_store': 'file',
'os_glance_tasks_store': 'file'
}
self.config(enabled_backends=enabled_backends)
store.register_store_opts(CONF, reserved_stores=reserved_stores)
self.config(default_backend="ceph1", group="glance_store")
body = {"all_stores": True}
req = webob.Request.blank("/some_request")
mp = "glance.common.utils.glance_store.get_store_from_store_identifier"
with mock.patch(mp) as mock_get_store:
result = sorted(utils.get_stores_from_request(req, body))
self.assertEqual(["ceph1", "ceph2"], result)
mock_get_store.assert_any_call("ceph1")
mock_get_store.assert_any_call("ceph2")
self.assertEqual(mock_get_store.call_count, 2)
self.assertNotIn('os_glance_staging_store', result)
self.assertNotIn('os_glance_tasks_store', result)
def test_get_stores_from_request_excludes_reserved_stores(self):
enabled_backends = {
"ceph1": "rbd",
"ceph2": "rbd"