]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Fallback to Quota Conf Driver if Quotas table is not defined
authorAkihiro MOTOKI <motoki@da.jp.nec.com>
Wed, 9 Oct 2013 10:50:35 +0000 (19:50 +0900)
committerAkihiro MOTOKI <motoki@da.jp.nec.com>
Wed, 9 Oct 2013 13:28:03 +0000 (22:28 +0900)
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

neutron/quota.py
neutron/tests/unit/test_quota_ext.py

index 908b256f2ce0d6179c1e428085126b4e7d1d39f2..411107864d0ceff4462514eb72bd16d18240b366 100644 (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):
index 3f572adf6d098f6f7d971360f5ec01a83e2e3558..085bd236620facda771420e29ea4bb89d9c1a4c2 100644 (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)