]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
ZFSSA driver to return project 'available' space
authorAbhiram Moturi <abhiram.moturi@oracle.com>
Mon, 10 Aug 2015 14:23:09 +0000 (14:23 +0000)
committerAbhiram Moturi <abhiram.moturi@oracle.com>
Thu, 3 Sep 2015 12:44:58 +0000 (12:44 +0000)
This fix allows the iSCSI driver to return the 'available' space
property at project level instead of the pool level which is more
accurate in cases when storage is not thin provisioned.

Change-Id: I52dec5e527eab393fd464fbc7f4f910fafb67268
Closes-Bug: #1479342

cinder/tests/unit/test_zfssa.py
cinder/volume/drivers/zfssa/zfssaiscsi.py
cinder/volume/drivers/zfssa/zfssarest.py

index 719bb80255a3d3a9fad36418b1a28630c936d5c7..a6ec506dca2444f069144f21b2cb56eb384e9955 100644 (file)
@@ -460,10 +460,13 @@ class TestZFSSAISCSIDriver(test.TestCase):
             '')
 
     def test_get_volume_stats(self):
-        self.drv.zfssa.get_pool_stats.return_value = 2 * units.Gi, 3 * units.Gi
+        self.drv.zfssa.get_project_stats.return_value = 2 * units.Gi,\
+            3 * units.Gi
         lcfg = self.configuration
         stats = self.drv.get_volume_stats(refresh=True)
-        self.drv.zfssa.get_pool_stats.assert_called_once_with(lcfg.zfssa_pool)
+        self.drv.zfssa.get_project_stats.assert_called_once_with(
+            lcfg.zfssa_pool,
+            lcfg.zfssa_project)
         self.assertEqual('Oracle', stats['vendor_name'])
         self.assertEqual(self.configuration.volume_backend_name,
                          stats['volume_backend_name'])
@@ -1174,6 +1177,27 @@ class TestZFSSAApi(test.TestCase):
                         'nodestroy': True}
         self.zfssa.rclient.put.assert_called_with(expected_svc, expected_arg)
 
+    def test_get_project_stats(self):
+        ret_val = json.dumps({"project": {"name": self.project,
+                                          "space_available": 15754895360,
+                                          "space_total": 25754895360,
+                                          "dedup": False,
+                                          "logbias": "latency",
+                                          "encryption": "off"}})
+        self.zfssa.rclient.get.return_value = self._create_response(
+            client.Status.OK, ret_val)
+        self.zfssa.get_project_stats(self.pool, self.project)
+        expected_svc = '/api/storage/v1/pools/' + self.pool + '/projects/' + \
+            self.project
+        self.zfssa.rclient.get.assert_called_with(expected_svc)
+
+        self.zfssa.rclient.get.return_value = self._create_response(
+            client.Status.NOT_FOUND)
+        self.assertRaises(exception.VolumeBackendAPIException,
+                          self.zfssa.get_project_stats,
+                          self.pool,
+                          self.project)
+
 
 class TestZFSSANfsApi(test.TestCase):
 
index 642b85fe51167aacef2adf39dd7207837a504f29..f446f924cab99fd4aa0bcba3e40bf8ac08d3cb28 100644 (file)
@@ -393,7 +393,8 @@ class ZFSSAISCSIDriver(driver.ISCSIDriver):
         data["storage_protocol"] = self.protocol
 
         lcfg = self.configuration
-        (avail, total) = self.zfssa.get_pool_stats(lcfg.zfssa_pool)
+        (avail, total) = self.zfssa.get_project_stats(lcfg.zfssa_pool,
+                                                      lcfg.zfssa_project)
         if avail is None or total is None:
             return
 
index de1c5d9ff95a8460c85f2c11762fcc4441491496..2d07f166d36ce0942310841ccf0d76a53e84018e 100644 (file)
@@ -352,35 +352,30 @@ class ZFSSAApi(object):
             LOG.error(exception_msg)
             raise exception.VolumeBackendAPIException(data=exception_msg)
 
-    def get_pool_stats(self, pool):
-        """Get pool stats.
+    def get_project_stats(self, pool, project):
+        """Get project stats.
 
-        Get space available and total properties of a pool
-        returns (avail, total).
+           Get available space and total space of a project
+           returns (avail, total).
         """
-        svc = '/api/storage/v1/pools/' + pool
+        svc = '/api/storage/v1/pools/%s/projects/%s' % (pool, project)
         ret = self.rclient.get(svc)
         if ret.status != restclient.Status.OK:
-            exception_msg = (_('Error Getting Pool Stats: '
+            exception_msg = (_('Error Getting Project Stats: '
                                'Pool: %(pool)s '
+                               'Project: %(project)s '
                                'Return code: %(ret.status)d '
                                'Message: %(ret.data)s.')
                              % {'pool': pool,
+                                'project': project,
                                 'ret.status': ret.status,
                                 'ret.data': ret.data})
             LOG.error(exception_msg)
-            raise exception.InvalidVolume(reason=exception_msg)
+            raise exception.VolumeBackendAPIException(data=exception_msg)
 
         val = json.loads(ret.data)
-
-        if not self._is_pool_owned(val):
-            LOG.error(_LE('Error Pool ownership: Pool %(pool)s is not owned '
-                          'by %(host)s.'),
-                      {'pool': pool, 'host': self.host})
-            raise exception.InvalidInput(reason=pool)
-
-        avail = val['pool']['usage']['available']
-        total = val['pool']['usage']['total']
+        avail = val['project']['space_available']
+        total = avail + val['project']['space_total']
 
         return avail, total