]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Add call to retrieve image metadata for volumes in bulk
authorLuis A. Garcia <luis@linux.vnet.ibm.com>
Tue, 5 Nov 2013 02:19:02 +0000 (02:19 +0000)
committerLuis A. Garcia <luis@linux.vnet.ibm.com>
Mon, 11 Nov 2013 18:51:35 +0000 (18:51 +0000)
When using the GET volume details REST API call, the image metadata API
contribution is making an individual db call for each of the available
volumes. When the number of volumes is large the details call can take
several minutes.

This patch adds a call to the volume.API to retrieve image metadata in
bulk, very similar to the one used to retrieve individual volume image
metadata.

Change-Id: Ic3aa721016704c72b7564cc5ceff71676806a24a
Partial-Bug: #1197612

cinder/db/api.py
cinder/db/sqlalchemy/api.py
cinder/tests/test_volume_glance_metadata.py
cinder/volume/api.py

index 0648ead86a51eaf89809d82bab98dcf5120b9294..966dbdae3f9eca13c8f7b8113ccf56329cb6f774 100644 (file)
@@ -549,6 +549,11 @@ def volume_glance_metadata_create(context, volume_id, key, value):
                                               value)
 
 
+def volume_glance_metadata_get_all(context):
+    """Return the glance metadata for all volumes."""
+    return IMPL.volume_glance_metadata_get_all(context)
+
+
 def volume_glance_metadata_get(context, volume_id):
     """Return the glance metadata for a volume."""
     return IMPL.volume_glance_metadata_get(context, volume_id)
index e872bce3373dcda311b5338231af750a4f2633cb..ceef717805fae3398a1c71e4c68d8beb3d8c0876 100644 (file)
@@ -2289,6 +2289,25 @@ def volume_encryption_metadata_get(context, volume_id, session=None):
 ####################
 
 
+@require_context
+def _volume_glance_metadata_get_all(context, session=None):
+    rows = model_query(context,
+                       models.VolumeGlanceMetadata,
+                       project_only=True,
+                       session=session).\
+        filter_by(deleted=False).\
+        all()
+
+    return rows
+
+
+@require_context
+def volume_glance_metadata_get_all(context):
+    """Return the Glance metadata for all volumes."""
+
+    return _volume_glance_metadata_get_all(context)
+
+
 @require_context
 @require_volume_exists
 def _volume_glance_metadata_get(context, volume_id, session=None):
index 0a8cf7c5250135dff52121edcf6f200d39e41e63..ec44d3c1c8b3c193ef72e4047543b0b27245a1fb 100644 (file)
@@ -82,6 +82,26 @@ class VolumeGlanceMetadataTestCase(test.TestCase):
         for key, value in expected_metadata_1.items():
             self.assertEqual(metadata[0][key], value)
 
+    def test_vols_get_glance_metadata(self):
+        ctxt = context.get_admin_context()
+        db.volume_create(ctxt, {'id': '1'})
+        db.volume_create(ctxt, {'id': '2'})
+        db.volume_create(ctxt, {'id': '3'})
+        db.volume_glance_metadata_create(ctxt, '1', 'key1', 'value1')
+        db.volume_glance_metadata_create(ctxt, '2', 'key2', 'value2')
+        db.volume_glance_metadata_create(ctxt, '2', 'key22', 'value22')
+
+        metadata = db.volume_glance_metadata_get_all(ctxt)
+        self.assertEqual(len(metadata), 3)
+        self._assert_metadata_equals('1', 'key1', 'value1', metadata[0])
+        self._assert_metadata_equals('2', 'key2', 'value2', metadata[1])
+        self._assert_metadata_equals('2', 'key22', 'value22', metadata[2])
+
+    def _assert_metadata_equals(self, volume_id, key, value, observed):
+        self.assertEqual(volume_id, observed.volume_id)
+        self.assertEqual(key, observed.key)
+        self.assertEqual(value, observed.value)
+
     def test_vol_delete_glance_metadata(self):
         ctxt = context.get_admin_context()
         db.volume_create(ctxt, {'id': 1})
index 15bf95467a86f40c9dd58233840ddf41434be5bd..a1398d4d8e6bfce0f812ef6d319c5a17c804f1f9 100644 (file)
@@ -21,6 +21,7 @@ Handles all requests relating to volumes.
 """
 
 
+import collections
 import functools
 
 from oslo.config import cfg
@@ -700,6 +701,15 @@ class API(base.Base):
     def get_snapshot_metadata_value(self, snapshot, key):
         pass
 
+    def get_volumes_image_metadata(self, context):
+        check_policy(context, 'get_volumes_image_metadata')
+        db_data = self.db.volume_glance_metadata_get_all(context)
+        results = collections.defaultdict(dict)
+        for meta_entry in db_data:
+            results[meta_entry['volume_id']].update({meta_entry['key']:
+                                                     meta_entry['value']})
+        return results
+
     @wrap_check_policy
     def get_volume_image_metadata(self, context, volume):
         db_data = self.db.volume_glance_metadata_get(context, volume['id'])