From: Lucian Petrut Date: Wed, 25 Mar 2015 16:01:02 +0000 (+0200) Subject: Eager load volume extra specs X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=19f6b7703663e12836fd6805e8c20b5507ede098;p=openstack-build%2Fcinder-build.git Eager load volume extra specs 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 --- diff --git a/cinder/db/sqlalchemy/api.py b/cinder/db/sqlalchemy/api.py index 5a88fccad..432f59c02 100644 --- a/cinder/db/sqlalchemy/api.py +++ b/cinder/db/sqlalchemy/api.py @@ -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')) diff --git a/cinder/tests/test_db_api.py b/cinder/tests/test_db_api.py index eb3e2adc7..643721ecf 100644 --- a/cinder/tests/test_db_api.py +++ b/cinder/tests/test_db_api.py @@ -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):