From: Kedar Vidvans Date: Tue, 5 Jan 2016 14:49:03 +0000 (-0500) Subject: Filtering type extra-spec support to ZFSSA drivers X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=c64eda69e3688ae0d4a3e6da5f2d51d24f62d158;p=openstack-build%2Fcinder-build.git Filtering type extra-spec support to ZFSSA drivers 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 --- diff --git a/cinder/tests/unit/test_zfssa.py b/cinder/tests/unit/test_zfssa.py index 83709c493..8ce54e449 100644 --- a/cinder/tests/unit/test_zfssa.py +++ b/cinder/tests/unit/test_zfssa.py @@ -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() diff --git a/cinder/volume/drivers/zfssa/zfssaiscsi.py b/cinder/volume/drivers/zfssa/zfssaiscsi.py index a90d71def..3cb63178a 100644 --- a/cinder/volume/drivers/zfssa/zfssaiscsi.py +++ b/cinder/volume/drivers/zfssa/zfssaiscsi.py @@ -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): diff --git a/cinder/volume/drivers/zfssa/zfssanfs.py b/cinder/volume/drivers/zfssa/zfssanfs.py index 3cb3cd481..cb89a2c7b 100644 --- a/cinder/volume/drivers/zfssa/zfssanfs.py +++ b/cinder/volume/drivers/zfssa/zfssanfs.py @@ -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): diff --git a/cinder/volume/drivers/zfssa/zfssarest.py b/cinder/volume/drivers/zfssa/zfssarest.py index 2d07f166d..a49eb4d77 100644 --- a/cinder/volume/drivers/zfssa/zfssarest.py +++ b/cinder/volume/drivers/zfssa/zfssarest.py @@ -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"