]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Fix response when querying host detail by host name
authorwanghao <wanghao749@huawei.com>
Mon, 9 Mar 2015 10:49:31 +0000 (18:49 +0800)
committerwanghao <wanghao749@huawei.com>
Wed, 27 May 2015 02:06:47 +0000 (10:06 +0800)
When querying host detail by host name like
'wanghao-devstack-snapshot@lvmdriver-1'
returned by host list command, cinder returns
incorrect result in 'total' block.
"resource": {
        "volume_count": "0",
        "total_volume_gb": "0",
        "total_snapshot_gb": "0",
        "project": "(total)",
        "host": "wanghao-devstack-snapshot@lvmdriver-1",
        "snapshot_count": "0"
        }
This issue is caused by 'volume_data_get_for_host'
in sqlalchemy. This has nothing to do with multibackend,
this is due to the introduction of pool support for single
backend.
Fix this by querying volume filter by host or host name
like 'host#%' in volume_data_get_for_host.

Change-Id: I751a474677d50e552d87fe06fadfed45e3c1ddab
Closes-Bug: #1429787

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

index 17199ad99bbc036dd3d251ec4f76b8ac0674088f..bbf0cb07255554200763acddd8516d5f0d634b91 100644 (file)
@@ -1075,20 +1075,20 @@ def volume_create(context, values):
 
 @require_admin_context
 def volume_data_get_for_host(context, host, count_only=False):
+    host_attr = models.Volume.host
+    conditions = [host_attr == host, host_attr.op('LIKE')(host + '#%')]
     if count_only:
         result = model_query(context,
                              func.count(models.Volume.id),
-                             read_deleted="no").\
-            filter_by(host=host).\
-            first()
+                             read_deleted="no").filter(
+            or_(*conditions)).first()
         return result[0] or 0
     else:
         result = model_query(context,
                              func.count(models.Volume.id),
                              func.sum(models.Volume.size),
-                             read_deleted="no").\
-            filter_by(host=host).\
-            first()
+                             read_deleted="no").filter(
+            or_(*conditions)).first()
         # NOTE(vish): convert None to 0
         return (result[0] or 0, result[1] or 0)
 
index 85147ae9e8c391f3194d00b98d89a03f3792d684..082572cfc18090bee6c6c13f122dab7fbf31ee0e 100644 (file)
@@ -29,6 +29,10 @@ from cinder import test
 
 CONF = cfg.CONF
 
+THREE = 3
+THREE_HUNDREDS = 300
+ONE_HUNDREDS = 100
+
 
 def _quota_reserve(context, project_id):
     """Create sample Quota, QuotaUsage and Reservation objects.
@@ -264,23 +268,35 @@ class DBAPIVolumeTestCase(BaseTest):
         self.assertEqual(attachment['attached_host'], host_name)
 
     def test_volume_data_get_for_host(self):
-        for i in xrange(3):
-            for j in xrange(3):
-                db.volume_create(self.ctxt, {'host': 'h%d' % i, 'size': 100})
-        for i in xrange(3):
-            self.assertEqual((3, 300),
+        for i in xrange(THREE):
+            for j in xrange(THREE):
+                db.volume_create(self.ctxt, {'host': 'h%d' % i,
+                                             'size': ONE_HUNDREDS})
+        for i in xrange(THREE):
+            self.assertEqual((THREE, THREE_HUNDREDS),
                              db.volume_data_get_for_host(
                                  self.ctxt, 'h%d' % i))
 
+    def test_volume_data_get_for_host_for_multi_backend(self):
+        for i in xrange(THREE):
+            for j in xrange(THREE):
+                db.volume_create(self.ctxt, {'host':
+                                             'h%d@lvmdriver-1#lvmdriver-1' % i,
+                                             'size': ONE_HUNDREDS})
+        for i in xrange(THREE):
+            self.assertEqual((THREE, THREE_HUNDREDS),
+                             db.volume_data_get_for_host(
+                                 self.ctxt, 'h%d@lvmdriver-1' % i))
+
     def test_volume_data_get_for_project(self):
-        for i in xrange(3):
-            for j in xrange(3):
+        for i in xrange(THREE):
+            for j in xrange(THREE):
                 db.volume_create(self.ctxt, {'project_id': 'p%d' % i,
-                                             'size': 100,
+                                             'size': ONE_HUNDREDS,
                                              'host': 'h-%d-%d' % (i, j),
                                              })
-        for i in xrange(3):
-            self.assertEqual((3, 300),
+        for i in xrange(THREE):
+            self.assertEqual((THREE, THREE_HUNDREDS),
                              db.volume_data_get_for_project(
                                  self.ctxt, 'p%d' % i))