]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Be sure to check deleted types on quota update.
authorJohn Griffith <john.griffith@solidfire.com>
Fri, 12 Jul 2013 23:43:27 +0000 (17:43 -0600)
committerJohn Griffith <john.griffith@solidfire.com>
Tue, 16 Jul 2013 18:45:11 +0000 (12:45 -0600)
If a volume-type is deleted, and later a volume
that's assigned that type is deleted the quota
update will fail and result in a trace for
VolumeTypeNotFound exception.

The volume is succesfully deleted, however the
quota information for the volume-type let alone
the other quota items for the volume are not
updated.

Fixes bug: 1200709

Change-Id: Idd687514be9d622df84aad54b1b33ddc6615851b

cinder/db/api.py
cinder/db/sqlalchemy/api.py
cinder/quota.py

index 0cd60c1c04e3fa08180ce367f994b6da31ba2b0e..28e349f36e9897466dc836a37e0f36d335ab882a 100644 (file)
@@ -384,9 +384,9 @@ def volume_type_get_all(context, inactive=False):
     return IMPL.volume_type_get_all(context, inactive)
 
 
-def volume_type_get(context, id):
+def volume_type_get(context, id, inactive=False):
     """Get volume type by id."""
-    return IMPL.volume_type_get(context, id)
+    return IMPL.volume_type_get(context, id, inactive)
 
 
 def volume_type_get_by_name(context, name):
index 7259db9a20dd653be88118bd6405b98844f29f29..10d053f4934dc09c13b67b47b2538b1ebdf21b44 100644 (file)
@@ -1607,8 +1607,12 @@ def volume_type_get_all(context, inactive=False, filters=None):
 
 
 @require_context
-def _volume_type_get(context, id, session=None):
-    result = model_query(context, models.VolumeTypes, session=session).\
+def _volume_type_get(context, id, session=None, inactive=False):
+    read_deleted = "yes" if inactive else "no"
+    result = model_query(context,
+                         models.VolumeTypes,
+                         session=session,
+                         read_deleted=read_deleted).\
         options(joinedload('extra_specs')).\
         filter_by(id=id).\
         first()
@@ -1620,10 +1624,10 @@ def _volume_type_get(context, id, session=None):
 
 
 @require_context
-def volume_type_get(context, id):
+def volume_type_get(context, id, inactive=False):
     """Returns a dict describing specific volume_type"""
 
-    return _volume_type_get(context, id)
+    return _volume_type_get(context, id, None, inactive)
 
 
 @require_context
index 16f77a5107a180f6bbf51425b3c14b4cf383285f..f5bcccb7c96685d10c604002470923c69e122bd0 100644 (file)
@@ -879,7 +879,12 @@ class QuotaEngine(object):
         """
         if not volume_type_id:
             return
-        volume_type = db.volume_type_get(context, volume_type_id)
+
+        # NOTE(jdg): set inactive to True in volume_type_get, as we
+        # may be operating on a volume that was created with a type
+        # that has since been deleted.
+        volume_type = db.volume_type_get(context, volume_type_id, True)
+
         for quota in ('volumes', 'gigabytes', 'snapshots'):
             if quota in opts:
                 vtype_quota = "%s_%s" % (quota, volume_type['name'])
@@ -911,7 +916,10 @@ class VolumeTypeQuotaEngine(QuotaEngine):
             result[resource.name] = resource
 
         # Volume type quotas.
-        volume_types = db.volume_type_get_all(context.get_admin_context())
+        # NOTE(jdg): We also want to check deleted types here as well
+        # if we don't the _get_quotas resource len check on will fail
+        volume_types = db.volume_type_get_all(context.get_admin_context(),
+                                              True)
         for volume_type in volume_types.values():
             for part_name in ('volumes', 'gigabytes', 'snapshots'):
                 resource = VolumeTypeResource(part_name, volume_type)