]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Eager load volume extra specs
authorLucian Petrut <lpetrut@cloudbasesolutions.com>
Wed, 25 Mar 2015 16:01:02 +0000 (18:01 +0200)
committerLucian Petrut <lpetrut@cloudbasesolutions.com>
Wed, 25 Mar 2015 20:32:08 +0000 (22:32 +0200)
The Linux SMBFS driver uses volume extra specs in order to determine
the according image format when creating new volumes.

Accessing the extra_specs attribute can raise DetachedInstanceError
as this attribute is lazy loaded and the session might close by the
time this attribute is accessed.

This can be avoided by simply eager loading the volume extra specs.

Change-Id: Iffdb160a4a968067261aa90638832782caed5ed0
Closes-Bug: #1436418

cinder/db/sqlalchemy/api.py
cinder/tests/test_db_api.py

index 5a88fccad1139cadd81035ca646f862dbdda112d..432f59c02f3c97548449d61988758e9110fd8101 100644 (file)
@@ -1232,6 +1232,7 @@ def _volume_get_query(context, session=None, project_only=False):
             options(joinedload('volume_metadata')).\
             options(joinedload('volume_admin_metadata')).\
             options(joinedload('volume_type')).\
+            options(joinedload('volume_type.extra_specs')).\
             options(joinedload('volume_attachment')).\
             options(joinedload('consistencygroup'))
     else:
@@ -1239,6 +1240,7 @@ def _volume_get_query(context, session=None, project_only=False):
                            project_only=project_only).\
             options(joinedload('volume_metadata')).\
             options(joinedload('volume_type')).\
+            options(joinedload('volume_type.extra_specs')).\
             options(joinedload('volume_attachment')).\
             options(joinedload('consistencygroup'))
 
index eb3e2adc7eb8ea523eea948f88cee78867d5a4f7..643721ecf13f5197fc3837bc4e43b393eb8d5694 100644 (file)
@@ -997,6 +997,25 @@ class DBAPIVolumeTypeTestCase(BaseTest):
                           self.ctxt,
                           {'name': 'n2', 'id': vt['id']})
 
+    def test_get_volume_type_extra_specs(self):
+        # Ensure that volume type extra specs can be accessed after
+        # the DB session is closed.
+        vt_extra_specs = {'mock_key': 'mock_value'}
+        vt = db.volume_type_create(self.ctxt,
+                                   {'name': 'n1',
+                                    'extra_specs': vt_extra_specs})
+        volume_ref = db.volume_create(self.ctxt, {'volume_type_id': vt.id})
+
+        session = sqlalchemy_api.get_session()
+        volume = sqlalchemy_api._volume_get(self.ctxt, volume_ref.id,
+                                            session=session)
+        session.close()
+
+        actual_specs = {}
+        for spec in volume.volume_type.extra_specs:
+            actual_specs[spec.key] = spec.value
+        self.assertEqual(vt_extra_specs, actual_specs)
+
 
 class DBAPIEncryptionTestCase(BaseTest):