diff --git a/doc/source/admin/interoperable-image-import.rst b/doc/source/admin/interoperable-image-import.rst index 621ae3a75c..4a56357f65 100644 --- a/doc/source/admin/interoperable-image-import.rst +++ b/doc/source/admin/interoperable-image-import.rst @@ -230,7 +230,9 @@ is already present in some of the available stores then those stores will be silently excluded from the list of all configured stores, whereas if ``all_stores`` is False, ``stores`` are specified in explicitly in request body and if image data is present in any of the specified store -then the request will be rejected. +then the request will be rejected. In case of ``all_stores`` is specified +in request body and cloud operator has also configured a read-only +``http`` store then it will be excluded explicitly. Image will be copied to staging area from one of the available locations and then import processing will be continued using import workflow as diff --git a/glance/common/utils.py b/glance/common/utils.py index 655c210f6d..f834da1a72 100644 --- a/glance/common/utils.py +++ b/glance/common/utils.py @@ -674,6 +674,10 @@ def _get_available_stores(): stores = [] # Remove reserved stores from the available stores list for store in available_stores: + # NOTE (abhishekk): http store is readonly and should be + # excluded from the list. + if available_stores[store] == 'http': + continue if store not in wsgi.RESERVED_STORES: stores.append(store) diff --git a/glance/tests/unit/common/test_utils.py b/glance/tests/unit/common/test_utils.py index 9d8fc0ebf0..ebbba9e3bd 100644 --- a/glance/tests/unit/common/test_utils.py +++ b/glance/tests/unit/common/test_utils.py @@ -521,6 +521,26 @@ class TestUtils(test_utils.BaseTestCase): mock_get_store.assert_any_call("ceph2") self.assertEqual(mock_get_store.call_count, 2) + def test_get_stores_from_request_excludes_readonly_store(self): + enabled_backends = { + "ceph1": "rbd", + "ceph2": "rbd", + "http": "http" + } + self.config(enabled_backends=enabled_backends) + store.register_store_opts(CONF) + 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.assertNotIn("http", result) + 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) + def test_get_stores_from_request_raises_bad_request_with_all_stores(self): enabled_backends = { "ceph1": "rbd", diff --git a/releasenotes/notes/bug-1881958-d0e16538f3c0ffaa.yaml b/releasenotes/notes/bug-1881958-d0e16538f3c0ffaa.yaml new file mode 100644 index 0000000000..0da178cd0a --- /dev/null +++ b/releasenotes/notes/bug-1881958-d0e16538f3c0ffaa.yaml @@ -0,0 +1,6 @@ +--- +fixes: + - | + Bug 1881958_: read-only http store should not be used if --all-stores specified for import/copy image workflow + + .. _1881958: https://bugs.launchpad.net/glance/+bug/1881958