Fallback to Quota Conf Driver if Quotas table is not defined

commit de15e0b9c5 enabled Quota DB driver default considering
production environments, but it breaks plugins without per-tenant
quota extension. In these plugin quotas tables is not loaded.

This commit fallbacks to ConfDriver if Quota model is not loaded by
checking neutron.db.quota_db which defines Quota model is imported.

Change-Id: Idaaaa9810598cfd3e5ce70020f498643b4819d16
Closes-Bug: #1236993
(cherry picked from commit 46495f4995)
This commit is contained in:
Akihiro MOTOKI 2013-10-09 19:50:35 +09:00 committed by Mark McClain
parent 1cb74d6311
commit 438b2ebfcd
2 changed files with 45 additions and 1 deletions

View File

@ -16,6 +16,8 @@
"""Quotas for instances, volumes, and floating ips."""
import sys
from oslo.config import cfg
import webob
@ -25,6 +27,10 @@ from neutron.openstack.common import importutils
from neutron.openstack.common import log as logging
LOG = logging.getLogger(__name__)
QUOTA_DB_MODULE = 'neutron.db.quota_db'
QUOTA_DB_DRIVER = 'neutron.db.quota_db.DbQuotaDriver'
QUOTA_CONF_DRIVER = 'neutron.quota.ConfDriver'
quota_opts = [
cfg.ListOpt('quota_items',
default=['network', 'subnet', 'port'],
@ -47,7 +53,7 @@ quota_opts = [
help=_('Number of ports allowed per tenant, minus for '
'unlimited')),
cfg.StrOpt('quota_driver',
default='neutron.db.quota_db.DbQuotaDriver',
default=QUOTA_DB_DRIVER,
help=_('Default driver to use for quota checks')),
]
# Register the configuration options
@ -217,9 +223,16 @@ class QuotaEngine(object):
if self._driver is None:
_driver_class = (self._driver_class or
cfg.CONF.QUOTAS.quota_driver)
if (_driver_class == QUOTA_DB_DRIVER and
QUOTA_DB_MODULE not in sys.modules):
# If quotas table is not loaded, force config quota driver.
_driver_class = QUOTA_CONF_DRIVER
LOG.info(_("ConfDriver is used as quota_driver because the "
"loaded plugin does not support 'quotas' table."))
if isinstance(_driver_class, basestring):
_driver_class = importutils.import_object(_driver_class)
self._driver = _driver_class
LOG.info(_('Loaded quota_driver: %s.'), _driver_class)
return self._driver
def __contains__(self, resource):

View File

@ -15,6 +15,8 @@
# License for the specific language governing permissions and limitations
# under the License.
import sys
import mock
from oslo.config import cfg
import testtools
@ -408,3 +410,32 @@ class TestDbQuotaDriver(base.BaseTestCase):
get_tenant_quotas.assert_called_once_with(ctx,
default_quotas,
target_tenant)
class TestQuotaDriverLoad(base.BaseTestCase):
def setUp(self):
super(TestQuotaDriverLoad, self).setUp()
# Make sure QuotaEngine is reinitialized in each test.
quota.QUOTAS._driver = None
def _test_quota_driver(self, cfg_driver, loaded_driver,
with_quota_db_module=True):
cfg.CONF.set_override('quota_driver', cfg_driver, group='QUOTAS')
with mock.patch.dict(sys.modules, {}):
if (not with_quota_db_module and
'neutron.db.quota_db' in sys.modules):
del sys.modules['neutron.db.quota_db']
driver = quota.QUOTAS.get_driver()
self.assertEqual(loaded_driver, driver.__class__.__name__)
def test_quota_db_driver_with_quotas_table(self):
self._test_quota_driver('neutron.db.quota_db.DbQuotaDriver',
'DbQuotaDriver', True)
def test_quota_db_driver_fallback_conf_driver(self):
self._test_quota_driver('neutron.db.quota_db.DbQuotaDriver',
'ConfDriver', False)
def test_quota_conf_driver(self):
self._test_quota_driver('neutron.quota.ConfDriver',
'ConfDriver', True)