Propagate BadStoreConfiguration to library user

Propagate BadStoreConfiguration exceptions to library user on start up
(on create_stores call) instead of just logging them as ERRORs.

Until logic to handle runtime BadStoreConfiguration exceptions from
configure and get_store_from_schema is added to Glance we'll keep just
logging those exceptions at runtime.

Closes-Bug: #1422699
Depends-On: Ifc038874aa0388b036729790a883ae1e1efd323d
Change-Id: I1d4f95cba47d21f1eb7e580314d01ac8d3481586
This commit is contained in:
Gorka Eguileor
2015-03-16 13:20:02 +01:00
parent 84562f3578
commit 63fcfd55c0
9 changed files with 33 additions and 16 deletions

View File

@@ -392,7 +392,7 @@ class BaseStore(driver.Store):
def get_schemes(self):
return ('swift+https', 'swift', 'swift+http', 'swift+config')
def configure(self):
def configure(self, re_raise_bsc=False):
glance_conf = self.conf.glance_store
_obj_size = self._option_get('swift_store_large_object_size')
self.large_object_size = _obj_size * ONE_MB
@@ -406,7 +406,7 @@ class BaseStore(driver.Store):
self.insecure = glance_conf.swift_store_auth_insecure
self.ssl_compression = glance_conf.swift_store_ssl_compression
self.cacert = glance_conf.swift_store_cacert
super(BaseStore, self).configure()
super(BaseStore, self).configure(re_raise_bsc=re_raise_bsc)
def _get_object(self, location, connection=None, start=None, context=None):
if not connection:
@@ -715,8 +715,8 @@ class SingleTenantStore(BaseStore):
super(SingleTenantStore, self).__init__(conf)
self.ref_params = sutils.SwiftParams(self.conf).params
def configure(self):
super(SingleTenantStore, self).configure()
def configure(self, re_raise_bsc=False):
super(SingleTenantStore, self).configure(re_raise_bsc=re_raise_bsc)
self.auth_version = self._option_get('swift_store_auth_version')
def configure_add(self):

View File

@@ -311,7 +311,7 @@ class Store(glance_store.Store):
raise exceptions.BadStoreConfiguration(
store_name='vmware_datastore', reason=msg)
def configure(self):
def configure(self, re_raise_bsc=False):
self._sanity_check()
self.scheme = STORE_SCHEME
self.server_host = self._option_get('vmware_server_host')
@@ -321,7 +321,7 @@ class Store(glance_store.Store):
self.tpoll_interval = self.conf.glance_store.vmware_task_poll_interval
self.api_insecure = self.conf.glance_store.vmware_api_insecure
self.session = self.reset_session()
super(Store, self).configure()
super(Store, self).configure(re_raise_bsc=re_raise_bsc)
def _get_datacenter(self, datacenter_path):
search_index_moref = self.session.vim.service_content.searchIndex

View File

@@ -183,7 +183,7 @@ def create_stores(conf=CONF):
for (store_entry, store_instance) in _load_stores(conf):
try:
schemes = store_instance.get_schemes()
store_instance.configure()
store_instance.configure(re_raise_bsc=True)
except NotImplementedError:
continue
if not schemes:

View File

@@ -59,7 +59,7 @@ class Store(capabilities.StoreCapability):
except cfg.DuplicateOptError:
pass
def configure(self):
def configure(self, re_raise_bsc=False):
"""
Configure the store to use the stored configuration options
and initialize capabilities based on current configuration.
@@ -75,8 +75,10 @@ class Store(capabilities.StoreCapability):
msg = (_(u"Failed to configure store correctly: %s "
"Disabling add method.") % utils.exception_to_str(e))
LOG.warn(msg)
self.update_capabilities()
if re_raise_bsc:
raise
finally:
self.update_capabilities()
def get_schemes(self):
"""

View File

@@ -37,6 +37,7 @@ class StoreBaseTest(base.BaseTestCase):
self.conf = self._CONF
self.conf(args=[])
store.register_opts(self.conf)
self.config(stores=[])
# Ensure stores + locations cleared
location.SCHEME_TO_CLS_MAP = {}

View File

@@ -18,5 +18,5 @@ from glance_store import exceptions
class UnconfigurableStore(driver.Store):
def configure(self):
def configure(self, re_raise_bsc=False):
raise exceptions.BadStoreConfiguration()

View File

@@ -49,8 +49,10 @@ class TestStore(base.StoreBaseTest,
Store.READ_CHUNKSIZE = 10
self.store = Store(self.conf)
self.config(filesystem_store_datadir=self.test_dir,
stores=['glance.store.filesystem.Store'],
group="glance_store")
self.store.configure()
self.register_store_schemes(self.store, 'file')
def tearDown(self):
"""Clear the test environment."""

View File

@@ -32,6 +32,7 @@ class TestHttpStore(base.StoreBaseTest,
self.config(default_store='http', group='glance_store')
http.Store.READ_CHUNKSIZE = 2
self.store = http.Store(self.conf)
self.register_store_schemes(self.store, 'http')
def _mock_httplib(self):
"""Mock httplib connection object.
@@ -139,7 +140,7 @@ class TestHttpStore(base.StoreBaseTest,
self.store.add, None, None, None, None)
self.assertRaises(exceptions.StoreAddDisabled,
glance_store.add_to_backend, None, None,
None, None, 'file')
None, None, 'http')
def test_http_get_size_with_non_existent_image_raises_Not_Found(self):
self._mock_httplib()

View File

@@ -13,7 +13,10 @@
# License for the specific language governing permissions and limitations
# under the License.
import mock
import glance_store as store
from glance_store import backend
from glance_store.tests import base
@@ -23,7 +26,15 @@ class TestStoreBase(base.StoreBaseTest):
super(TestStoreBase, self).setUp()
self.config(default_store='file', group='glance_store')
def test_create_store_exclude_unconfigurable_drivers(self):
self.config(stores=["no_conf", "file"], group='glance_store')
count = store.create_stores(self.conf)
self.assertEqual(count, 1)
def test_raise_on_missing_driver_conf(self):
self.config(stores=['file'], group='glance_store')
self.assertRaises(store.BadStoreConfiguration,
store.create_stores,
self.conf)
@mock.patch.object(store.driver, 'LOG')
def test_configure_does_not_raise_on_missing_driver_conf(self, mock_log):
self.config(stores=['file'], group='glance_store')
for (__, store_instance) in backend._load_stores(self.conf):
store_instance.configure()
self.assertTrue(mock_log.warn.called)