]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Filtering type extra-spec support to ZFSSA drivers
authorKedar Vidvans <kedar.vidvans@oracle.com>
Tue, 5 Jan 2016 14:49:03 +0000 (09:49 -0500)
committerKedar Vidvans <kedar.vidvans@oracle.com>
Fri, 29 Jan 2016 15:59:20 +0000 (10:59 -0500)
This change adds filtering type of extra specs to the ZFSSA drivers. It will
enable admins to create volume-types with the set of capabilities added by
this change.
Extra specs being added the ZFSSA iSCSI driver are: zfssa_poolprofile,
zfssa_volblocksize, zfssa_sparse, zfssa_compression, zfssa_logbias
Extra specs being added the ZFSSA NFS driver are: zfssa_poolprofile,
zfssa_sparse, zfssa_compression, zfssa_logbias, zfssa_encryption

Change-Id: I9167a50111f96921480dc30b350899035bf676bb
Implements: blueprint oracle-zfssa-extra-specs

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

index 83709c493dc76515bbf33697a5d50e412c8e1a7a..8ce54e449303b509caf9097b3ce5d7197e28b0fc 100644 (file)
@@ -469,11 +469,15 @@ class TestZFSSAISCSIDriver(test.TestCase):
     def test_get_volume_stats(self):
         self.drv.zfssa.get_project_stats.return_value = 2 * units.Gi,\
             3 * units.Gi
+        self.drv.zfssa.get_pool_details.return_value = \
+            {"profile": "mirror:log_stripe"}
         lcfg = self.configuration
         stats = self.drv.get_volume_stats(refresh=True)
         self.drv.zfssa.get_project_stats.assert_called_once_with(
             lcfg.zfssa_pool,
             lcfg.zfssa_project)
+        self.drv.zfssa.get_pool_details.assert_called_once_with(
+            lcfg.zfssa_pool)
         self.assertEqual('Oracle', stats['vendor_name'])
         self.assertEqual(self.configuration.volume_backend_name,
                          stats['volume_backend_name'])
@@ -483,6 +487,15 @@ class TestZFSSAISCSIDriver(test.TestCase):
         self.assertFalse(stats['QoS_support'])
         self.assertEqual(3, stats['total_capacity_gb'])
         self.assertEqual(2, stats['free_capacity_gb'])
+        self.assertEqual('mirror:log_stripe', stats['zfssa_poolprofile'])
+        self.assertEqual('8k', stats['zfssa_volblocksize'])
+        self.assertEqual('false', stats['zfssa_sparse'])
+        self.assertEqual('off', stats['zfssa_compression'])
+        self.assertEqual('latency', stats['zfssa_logbias'])
+
+        self.drv.zfssa.get_pool_details.return_value = {"profile": "raidz2"}
+        stats = self.drv.get_volume_stats(refresh=True)
+        self.assertEqual('raidz2', stats['zfssa_poolprofile'])
 
     def test_extend_volume(self):
         lcfg = self.configuration
@@ -770,6 +783,7 @@ class TestZFSSANFSDriver(test.TestCase):
         self.configuration.nfs_used_ratio = 1
         self.configuration.zfssa_enable_local_cache = True
         self.configuration.zfssa_cache_directory = zfssa_cache_dir
+        self.configuration.nfs_sparsed_volumes = 'true'
 
     def test_migrate_volume(self):
         self.drv.zfssa.get_asn.return_value = (
@@ -859,15 +873,38 @@ class TestZFSSANFSDriver(test.TestCase):
                                     method='COPY')
 
     def test_get_volume_stats(self):
+        lcfg = self.configuration
         self.drv._mounted_shares = ['nfs_share']
         with mock.patch.object(self.drv, '_ensure_shares_mounted'):
             with mock.patch.object(self.drv, '_get_share_capacity_info') as \
                     mock_get_share_capacity_info:
                 mock_get_share_capacity_info.return_value = (1073741824,
                                                              9663676416)
+                self.drv.zfssa.get_pool_details.return_value = \
+                    {"profile": "mirror:log_stripe"}
+                self.drv.zfssa.get_share.return_value = {"compression": "lzjb",
+                                                         "encryption": "off",
+                                                         "logbias": "latency"}
                 stats = self.drv.get_volume_stats(refresh=True)
+                self.drv.zfssa.get_pool_details.assert_called_once_with(
+                    lcfg.zfssa_nfs_pool)
+                self.drv.zfssa.get_share.assert_called_with(
+                    lcfg.zfssa_nfs_pool, lcfg.zfssa_nfs_project,
+                    lcfg.zfssa_nfs_share)
+
                 self.assertEqual(1, stats['free_capacity_gb'])
                 self.assertEqual(10, stats['total_capacity_gb'])
+                self.assertEqual('mirror:log_stripe',
+                                 stats['zfssa_poolprofile'])
+                self.assertEqual('lzjb', stats['zfssa_compression'])
+                self.assertEqual('true', stats['zfssa_sparse'])
+                self.assertEqual('off', stats['zfssa_encryption'])
+                self.assertEqual('latency', stats['zfssa_logbias'])
+
+                self.drv.zfssa.get_pool_details.return_value = \
+                    {"profile": "mirror3"}
+                stats = self.drv.get_volume_stats(refresh=True)
+                self.assertEqual('mirror3', stats['zfssa_poolprofile'])
 
     def tearDown(self):
         super(TestZFSSANFSDriver, self).tearDown()
index a90d71def0996757988c43f88bddb22d07618c76..3cb63178a93ba32c59feddda06790469bd6b7ff0 100644 (file)
@@ -415,6 +415,14 @@ class ZFSSAISCSIDriver(driver.ISCSIDriver):
         data['free_capacity_gb'] = int(avail) / units.Gi
         data['reserved_percentage'] = 0
         data['QoS_support'] = False
+
+        pool_details = self.zfssa.get_pool_details(lcfg.zfssa_pool)
+        data['zfssa_poolprofile'] = pool_details['profile']
+        data['zfssa_volblocksize'] = lcfg.zfssa_lun_volblocksize
+        data['zfssa_sparse'] = six.text_type(lcfg.zfssa_lun_sparse)
+        data['zfssa_compression'] = lcfg.zfssa_lun_compression
+        data['zfssa_logbias'] = lcfg.zfssa_lun_logbias
+
         self._stats = data
 
     def get_volume_stats(self, refresh=False):
index 3cb3cd4815d5bacf84b8ef87a0f77255ffb0776e..cb89a2c7b5f5d94d27c3698254a49fd3ab5afecd 100644 (file)
@@ -558,6 +558,17 @@ class ZFSSANFSDriver(nfs.NfsDriver):
         data['total_capacity_gb'] = float(capacity) / units.Gi
         data['free_capacity_gb'] = float(free) / units.Gi
 
+        share_details = self.zfssa.get_share(lcfg.zfssa_nfs_pool,
+                                             lcfg.zfssa_nfs_project,
+                                             lcfg.zfssa_nfs_share)
+        pool_details = self.zfssa.get_pool_details(lcfg.zfssa_nfs_pool)
+
+        data['zfssa_compression'] = share_details['compression']
+        data['zfssa_encryption'] = share_details['encryption']
+        data['zfssa_logbias'] = share_details['logbias']
+        data['zfssa_poolprofile'] = pool_details['profile']
+        data['zfssa_sparse'] = six.text_type(lcfg.nfs_sparsed_volumes)
+
         self._stats = data
 
     def migrate_volume(self, ctxt, volume, host):
index 2d07f166d36ce0942310841ccf0d76a53e84018e..a49eb4d7700a0859bcbe027007a3b58df08f9987 100644 (file)
@@ -62,6 +62,33 @@ class ZFSSAApi(object):
         return vdata['version']['asn'] == pdata['pool']['asn'] and \
             vdata['version']['nodename'] == pdata['pool']['owner']
 
+    def get_pool_details(self, pool):
+        """Get properties of a pool."""
+        svc = '/api/storage/v1/pools/%s' % pool
+        ret = self.rclient.get(svc)
+        if ret.status != restclient.Status.OK:
+            exception_msg = (_('Error Getting Pool Stats: '
+                               'Pool: %(pool)s '
+                               'Return code: %(status)d '
+                               'Message: %(data)s.')
+                             % {'pool': pool,
+                                'status': ret.status,
+                                'data': ret.data})
+            LOG.error(exception_msg)
+            raise exception.VolumeBackendAPIException(data=exception_msg)
+
+        val = json.loads(ret.data)
+
+        if not self._is_pool_owned(val):
+            exception_msg = (_('Error Pool ownership: '
+                               'Pool %(pool)s is not owned '
+                               'by %(host)s.')
+                             % {'pool': pool,
+                                'host': self.host})
+            LOG.error(exception_msg)
+            raise exception.InvalidInput(reason=exception_msg)
+        return val['pool']
+
     def set_host(self, host, timeout=None):
         self.host = host
         self.url = "https://" + self.host + ":215"