]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Implement get_volume_stats in NFS driver
authorMehdi Abaakouk <mehdi.abaakouk@enovance.com>
Fri, 8 Mar 2013 12:01:57 +0000 (13:01 +0100)
committerJohn Griffith <john.griffith@solidfire.com>
Fri, 22 Mar 2013 04:04:38 +0000 (22:04 -0600)
Use the already existing code (ie: _get_available_capacity) to
implement get_volume_stats in the nfs driver

Change the netapp nfs driver to use this new implementation
instead of the dumb one.

Fixes bug #1152501

Change-Id: Ie16d9628ba4b096c60966b4aa6192fbdcb9a4f20
(cherry picked from commit c47bf9bc3835d4399185376ac07920ef903d79e8)

cinder/tests/test_nfs.py
cinder/volume/drivers/netapp/nfs.py
cinder/volume/drivers/nfs.py

index 302cd05f4bd52e75236b1ec8ebe6063f9c79eefc..ebeb0d1cdb1a2cd9868067c06a8888249cf95e0d 100644 (file)
@@ -20,6 +20,8 @@ import __builtin__
 import errno
 import os
 
+from oslo.config import cfg
+
 import mox as mox_lib
 from mox import IgnoreArg
 from mox import IsA
@@ -335,9 +337,11 @@ class NfsDriverTestCase(test.TestCase):
         mox = self._mox
         drv = self._driver
 
+        df_total_size = 2620544
         df_avail = 1490560
         df_head = 'Filesystem 1K-blocks Used Available Use% Mounted on\n'
-        df_data = 'nfs-host:/export 2620544 996864 %d 41%% /mnt' % df_avail
+        df_data = 'nfs-host:/export %d 996864 %d 41%% /mnt' % (df_total_size,
+                                                               df_avail)
         df_output = df_head + df_data
 
         self.configuration.nfs_disk_util = 'df'
@@ -352,7 +356,7 @@ class NfsDriverTestCase(test.TestCase):
 
         mox.ReplayAll()
 
-        self.assertEquals(df_avail,
+        self.assertEquals((df_avail, df_total_size),
                           drv._get_available_capacity(self.TEST_NFS_EXPORT1))
 
         mox.VerifyAll()
@@ -390,7 +394,7 @@ class NfsDriverTestCase(test.TestCase):
 
         mox.ReplayAll()
 
-        self.assertEquals(df_total_size - du_used,
+        self.assertEquals((df_total_size - du_used, df_total_size),
                           drv._get_available_capacity(self.TEST_NFS_EXPORT1))
 
         mox.VerifyAll()
@@ -474,7 +478,7 @@ class NfsDriverTestCase(test.TestCase):
         """do_setup should throw error if shares config is not configured."""
         drv = self._driver
 
-        nfs.FLAGS.nfs_shares_config = self.TEST_SHARES_CONFIG_FILE
+        cfg.CONF.nfs_shares_config = self.TEST_SHARES_CONFIG_FILE
 
         self.assertRaises(exception.NfsException,
                           drv.do_setup, IsA(context.RequestContext))
@@ -484,7 +488,7 @@ class NfsDriverTestCase(test.TestCase):
         mox = self._mox
         drv = self._driver
         self.configuration.nfs_shares_config = self.TEST_SHARES_CONFIG_FILE
-        nfs.FLAGS.nfs_shares_config = self.TEST_SHARES_CONFIG_FILE
+        cfg.CONF.nfs_shares_config = self.TEST_SHARES_CONFIG_FILE
 
         mox.StubOutWithMock(os.path, 'exists')
         os.path.exists(self.TEST_SHARES_CONFIG_FILE).AndReturn(True)
@@ -517,9 +521,9 @@ class NfsDriverTestCase(test.TestCase):
 
         mox.StubOutWithMock(drv, '_get_available_capacity')
         drv._get_available_capacity(self.TEST_NFS_EXPORT1).\
-            AndReturn(2 * self.ONE_GB_IN_BYTES)
+            AndReturn((2 * self.ONE_GB_IN_BYTES, 5 * self.ONE_GB_IN_BYTES))
         drv._get_available_capacity(self.TEST_NFS_EXPORT2).\
-            AndReturn(3 * self.ONE_GB_IN_BYTES)
+            AndReturn((3 * self.ONE_GB_IN_BYTES, 10 * self.ONE_GB_IN_BYTES))
 
         mox.ReplayAll()
 
@@ -537,9 +541,9 @@ class NfsDriverTestCase(test.TestCase):
 
         mox.StubOutWithMock(drv, '_get_available_capacity')
         drv._get_available_capacity(self.TEST_NFS_EXPORT1).\
-            AndReturn(0)
+            AndReturn((0, 5 * self.ONE_GB_IN_BYTES))
         drv._get_available_capacity(self.TEST_NFS_EXPORT2).\
-            AndReturn(0)
+            AndReturn((0, 10 * self.ONE_GB_IN_BYTES))
 
         mox.ReplayAll()
 
@@ -561,7 +565,7 @@ class NfsDriverTestCase(test.TestCase):
         drv = self._driver
         volume = self._simple_volume()
 
-        setattr(nfs.FLAGS, 'nfs_sparsed_volumes', True)
+        setattr(cfg.CONF, 'nfs_sparsed_volumes', True)
 
         mox.StubOutWithMock(drv, '_create_sparsed_file')
         mox.StubOutWithMock(drv, '_set_rw_permissions_for_all')
@@ -575,7 +579,7 @@ class NfsDriverTestCase(test.TestCase):
 
         mox.VerifyAll()
 
-        delattr(nfs.FLAGS, 'nfs_sparsed_volumes')
+        delattr(cfg.CONF, 'nfs_sparsed_volumes')
 
     def test_create_nonsparsed_volume(self):
         mox = self._mox
@@ -583,7 +587,7 @@ class NfsDriverTestCase(test.TestCase):
         self.configuration.nfs_sparsed_volumes = False
         volume = self._simple_volume()
 
-        setattr(nfs.FLAGS, 'nfs_sparsed_volumes', False)
+        setattr(cfg.CONF, 'nfs_sparsed_volumes', False)
 
         mox.StubOutWithMock(drv, '_create_regular_file')
         mox.StubOutWithMock(drv, '_set_rw_permissions_for_all')
@@ -597,7 +601,7 @@ class NfsDriverTestCase(test.TestCase):
 
         mox.VerifyAll()
 
-        delattr(nfs.FLAGS, 'nfs_sparsed_volumes')
+        delattr(cfg.CONF, 'nfs_sparsed_volumes')
 
     def test_create_volume_should_ensure_nfs_mounted(self):
         """create_volume ensures shares provided in config are mounted."""
@@ -729,3 +733,28 @@ class NfsDriverTestCase(test.TestCase):
         drv.delete_volume(volume)
 
         mox.VerifyAll()
+
+    def test_get_volume_stats(self):
+        """get_volume_stats must fill the correct values"""
+        mox = self._mox
+        drv = self._driver
+
+        drv._mounted_shares = [self.TEST_NFS_EXPORT1, self.TEST_NFS_EXPORT2]
+
+        mox.StubOutWithMock(drv, '_ensure_shares_mounted')
+        mox.StubOutWithMock(drv, '_get_available_capacity')
+
+        drv._ensure_shares_mounted()
+
+        drv._get_available_capacity(self.TEST_NFS_EXPORT1).\
+            AndReturn((2 * self.ONE_GB_IN_BYTES, 10 * self.ONE_GB_IN_BYTES))
+        drv._get_available_capacity(self.TEST_NFS_EXPORT2).\
+            AndReturn((3 * self.ONE_GB_IN_BYTES, 20 * self.ONE_GB_IN_BYTES))
+
+        mox.ReplayAll()
+
+        drv.get_volume_stats()
+        self.assertEqual(drv._stats['total_capacity_gb'], 30.0)
+        self.assertEqual(drv._stats['free_capacity_gb'], 5.0)
+
+        mox.VerifyAll()
index 60a9862227faf1cdb5047b6534a56b9bfd495022..1976beac07a9469e011a0b21a4e9239cfb383aab 100644 (file)
@@ -280,31 +280,15 @@ class NetAppNFSDriver(nfs.NfsDriver):
 
         return {'provider_location': share}
 
-    def get_volume_stats(self, refresh=False):
-        """Get volume status.
-
-        If 'refresh' is True, run update the stats first."""
-        if refresh:
-            self._update_volume_status()
-
-        return self._stats
-
     def _update_volume_status(self):
         """Retrieve status info from volume group."""
+        super(NetAppNFSDriver, self)._update_volume_status()
 
-        LOG.debug(_("Updating volume status"))
-        data = {}
         backend_name = self.configuration.safe_get('volume_backend_name')
-        data["volume_backend_name"] = backend_name or 'NetApp_NFS_7mode'
-        data["vendor_name"] = 'NetApp'
-        data["driver_version"] = '1.0'
-        data["storage_protocol"] = 'NFS'
-
-        data['total_capacity_gb'] = 'infinite'
-        data['free_capacity_gb'] = 'infinite'
-        data['reserved_percentage'] = 100
-        data['QoS_support'] = False
-        self._stats = data
+        self._stats["volume_backend_name"] = (backend_name or
+                                              'NetApp_NFS_7mode')
+        self._stats["vendor_name"] = 'NetApp'
+        self._stats["driver_version"] = '1.0'
 
 
 class NetAppCmodeNfsDriver (NetAppNFSDriver):
@@ -351,31 +335,15 @@ class NetAppCmodeNfsDriver (NetAppNFSDriver):
             password=self.configuration.netapp_password)
         return client
 
-    def get_volume_stats(self, refresh=False):
-        """Get volume status.
-
-        If 'refresh' is True, run update the stats first."""
-        if refresh:
-            self._update_volume_status()
-
-        return self._stats
-
     def _update_volume_status(self):
         """Retrieve status info from volume group."""
+        super(NetAppCmodeNfsDriver, self)._update_volume_status()
 
-        LOG.debug(_("Updating volume status"))
-        data = {}
         backend_name = self.configuration.safe_get('volume_backend_name')
-        data["volume_backend_name"] = backend_name or 'NetApp_NFS_Cluster'
-        data["vendor_name"] = 'NetApp'
-        data["driver_version"] = '1.0'
-        data["storage_protocol"] = 'NFS'
-
-        data['total_capacity_gb'] = 'infinite'
-        data['free_capacity_gb'] = 'infinite'
-        data['reserved_percentage'] = 100
-        data['QoS_support'] = False
-        self._stats = data
+        self._stats["volume_backend_name"] = (backend_name or
+                                              'NetApp_NFS_Cluster')
+        self._stats["vendor_name"] = 'NetApp'
+        self._stats["driver_version"] = '1.0'
 
 
 class NetAppDirectNfsDriver (NetAppNFSDriver):
@@ -525,32 +493,15 @@ class NetAppDirectCmodeNfsDriver (NetAppDirectNfsDriver):
             'destination-path': dest_path})
         self._invoke_successfully(clone_create, vserver)
 
-    def get_volume_stats(self, refresh=False):
-        """Get volume status.
-
-        If 'refresh' is True, run update the stats first."""
-        if refresh:
-            self._update_volume_status()
-
-        return self._stats
-
     def _update_volume_status(self):
         """Retrieve status info from volume group."""
+        super(NetAppDirectCmodeNfsDriver, self)._update_volume_status()
 
-        LOG.debug(_("Updating volume status"))
-        data = {}
         backend_name = self.configuration.safe_get('volume_backend_name')
-        data["volume_backend_name"] = (backend_name
-                                       or 'NetApp_NFS_cluster_direct')
-        data["vendor_name"] = 'NetApp'
-        data["driver_version"] = '1.0'
-        data["storage_protocol"] = 'NFS'
-
-        data['total_capacity_gb'] = 'infinite'
-        data['free_capacity_gb'] = 'infinite'
-        data['reserved_percentage'] = 100
-        data['QoS_support'] = False
-        self._stats = data
+        self._stats["volume_backend_name"] = (backend_name or
+                                              'NetApp_NFS_cluster_direct')
+        self._stats["vendor_name"] = 'NetApp'
+        self._stats["driver_version"] = '1.0'
 
 
 class NetAppDirect7modeNfsDriver (NetAppDirectNfsDriver):
@@ -655,29 +606,12 @@ class NetAppDirect7modeNfsDriver (NetAppDirectNfsDriver):
                 time.sleep(5)
             retry = retry - 1
 
-    def get_volume_stats(self, refresh=False):
-        """Get volume status.
-
-        If 'refresh' is True, run update the stats first."""
-        if refresh:
-            self._update_volume_status()
-
-        return self._stats
-
     def _update_volume_status(self):
         """Retrieve status info from volume group."""
+        super(NetAppDirect7modeNfsDriver, self)._update_volume_status()
 
-        LOG.debug(_("Updating volume status"))
-        data = {}
         backend_name = self.configuration.safe_get('volume_backend_name')
-        data["volume_backend_name"] = (backend_name
-                                       or 'NetApp_NFS_7mode_direct')
-        data["vendor_name"] = 'NetApp'
-        data["driver_version"] = '1.0'
-        data["storage_protocol"] = 'NFS'
-
-        data['total_capacity_gb'] = 'infinite'
-        data['free_capacity_gb'] = 'infinite'
-        data['reserved_percentage'] = 100
-        data['QoS_support'] = False
-        self._stats = data
+        self._stats["volume_backend_name"] = (backend_name or
+                                              'NetApp_NFS_7mode_direct')
+        self._stats["vendor_name"] = 'NetApp'
+        self._stats["driver_version"] = '1.0'
index 0c1df91daceb40386b52020a5dd4e58cb79a3c8d..74b3aecd412db2afdb9a8719b7de903804bcc91f 100755 (executable)
@@ -22,7 +22,6 @@ import os
 from oslo.config import cfg
 
 from cinder import exception
-from cinder import flags
 from cinder.openstack.common import log as logging
 from cinder.volume import driver
 
@@ -49,9 +48,6 @@ volume_opts = [
                     'of the nfs man page for details'),
 ]
 
-FLAGS = flags.FLAGS
-FLAGS.register_opts(volume_opts)
-
 
 class RemoteFsDriver(driver.VolumeDriver):
     """Common base for drivers that work like NFS."""
@@ -263,7 +259,7 @@ class NfsDriver(RemoteFsDriver):
         greatest_share = None
 
         for nfs_share in self._mounted_shares:
-            capacity = self._get_available_capacity(nfs_share)
+            capacity = self._get_available_capacity(nfs_share)[0]
             if capacity > greatest_size:
                 greatest_share = nfs_share
                 greatest_size = capacity
@@ -292,17 +288,17 @@ class NfsDriver(RemoteFsDriver):
 
         available = 0
 
+        size = int(out.split()[1])
         if self.configuration.nfs_disk_util == 'df':
             available = int(out.split()[3])
         else:
-            size = int(out.split()[1])
             out, _ = self._execute('du', '-sb', '--apparent-size',
                                    '--exclude', '*snapshot*', mount_point,
                                    run_as_root=True)
             used = int(out.split()[0])
             available = size - used
 
-        return available
+        return available, size
 
     def _mount_nfs(self, nfs_share, mount_path, ensure=False):
         """Mount NFS share to mount path"""
@@ -311,8 +307,8 @@ class NfsDriver(RemoteFsDriver):
 
         # Construct the NFS mount command.
         nfs_cmd = ['mount', '-t', 'nfs']
-        if FLAGS.nfs_mount_options is not None:
-            nfs_cmd.extend(['-o', FLAGS.nfs_mount_options])
+        if cfg.CONF.nfs_mount_options is not None:
+            nfs_cmd.extend(['-o', cfg.CONF.nfs_mount_options])
         nfs_cmd.extend([nfs_share, mount_path])
 
         try:
@@ -322,3 +318,38 @@ class NfsDriver(RemoteFsDriver):
                 LOG.warn(_("%s is already mounted"), nfs_share)
             else:
                 raise
+
+    def get_volume_stats(self, refresh=False):
+        """Get volume status.
+
+        If 'refresh' is True, run update the stats first."""
+        if refresh or not self._stats:
+            self._update_volume_status()
+
+        return self._stats
+
+    def _update_volume_status(self):
+        """Retrieve status info from volume group."""
+
+        LOG.debug(_("Updating volume status"))
+        data = {}
+        backend_name = self.configuration.safe_get('volume_backend_name')
+        data["volume_backend_name"] = backend_name or 'Generic_NFS'
+        data["vendor_name"] = 'Open Source'
+        data["driver_version"] = '1.0'
+        data["storage_protocol"] = 'nfs'
+
+        self._ensure_shares_mounted()
+
+        global_capacity = 0
+        global_free = 0
+        for nfs_share in self._mounted_shares:
+            free, capacity = self._get_available_capacity(nfs_share)
+            global_capacity += capacity
+            global_free += free
+
+        data['total_capacity_gb'] = global_capacity / 1024.0 ** 3
+        data['free_capacity_gb'] = global_free / 1024.0 ** 3
+        data['reserved_percentage'] = 0
+        data['QoS_support'] = False
+        self._stats = data