From: Walter A. Boring IV Date: Fri, 3 May 2013 21:36:12 +0000 (-0700) Subject: Fix ability to add custom volume_backend_name X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=54a2ee48a4dc31cbf116b1e9d5add37efe66bc20;p=openstack-build%2Fcinder-build.git Fix ability to add custom volume_backend_name This patch fixes the ability to set the volume_backend_name for each driver. The original bug was filed against LeftHand and 3PAR, but several drivers exhibited a fixed backend name. Fixes: bug #1175222 bug #1172286 Change-Id: I4197f99bebd6ca8e4969795ae6edb537bc066c90 --- diff --git a/cinder/tests/test_hp3par.py b/cinder/tests/test_hp3par.py index c6d0c57a7..f73fbba33 100644 --- a/cinder/tests/test_hp3par.py +++ b/cinder/tests/test_hp3par.py @@ -492,9 +492,15 @@ class TestHP3PARFCDriver(HP3PARBaseDriver, test.TestCase): def test_get_volume_stats(self): self.flags(lock_path=self.tempdir) + + def fake_safe_get(*args): + return "HP3PARFCDriver" + + self.stubs.Set(self.driver.configuration, 'safe_get', fake_safe_get) stats = self.driver.get_volume_stats(True) self.assertEquals(stats['storage_protocol'], 'FC') - self.assertEquals(stats['volume_backend_name'], 'HP3PARFCDriver') + self.assertEquals(stats['total_capacity_gb'], 'infinite') + self.assertEquals(stats['free_capacity_gb'], 'infinite') class TestHP3PARISCSIDriver(HP3PARBaseDriver, test.TestCase): @@ -628,6 +634,12 @@ class TestHP3PARISCSIDriver(HP3PARBaseDriver, test.TestCase): def test_get_volume_stats(self): self.flags(lock_path=self.tempdir) + + def fake_safe_get(*args): + return "HP3PARFCDriver" + + self.stubs.Set(self.driver.configuration, 'safe_get', fake_safe_get) stats = self.driver.get_volume_stats(True) self.assertEquals(stats['storage_protocol'], 'iSCSI') - self.assertEquals(stats['volume_backend_name'], 'HP3PARISCSIDriver') + self.assertEquals(stats['total_capacity_gb'], 'infinite') + self.assertEquals(stats['free_capacity_gb'], 'infinite') diff --git a/cinder/tests/test_rbd.py b/cinder/tests/test_rbd.py index 8db544555..54b6ffffa 100644 --- a/cinder/tests/test_rbd.py +++ b/cinder/tests/test_rbd.py @@ -153,7 +153,12 @@ class RBDTestCase(test.TestCase): def test_update_volume_stats(self): def fake_stats(*args): return RADOS_DF_OUT, '' + + def fake_safe_get(*args): + return "RBD" + self.stubs.Set(self.driver, '_execute', fake_stats) + self.stubs.Set(self.driver.configuration, 'safe_get', fake_safe_get) expected = dict( volume_backend_name='RBD', vendor_name='Open Source', @@ -168,7 +173,12 @@ class RBDTestCase(test.TestCase): def test_update_volume_stats_error(self): def fake_exc(*args): raise exception.ProcessExecutionError() + + def fake_safe_get(*args): + return "RBD" + self.stubs.Set(self.driver, '_execute', fake_exc) + self.stubs.Set(self.driver.configuration, 'safe_get', fake_safe_get) expected = dict( volume_backend_name='RBD', vendor_name='Open Source', diff --git a/cinder/volume/drivers/coraid.py b/cinder/volume/drivers/coraid.py index ca7d674f8..0c251304b 100644 --- a/cinder/volume/drivers/coraid.py +++ b/cinder/volume/drivers/coraid.py @@ -392,13 +392,15 @@ class CoraidDriver(driver.VolumeDriver): def get_volume_stats(self, refresh=False): """Return Volume Stats.""" - return {'driver_version': '1.0', + data = {'driver_version': '1.0', 'free_capacity_gb': 'unknown', 'reserved_percentage': 0, 'storage_protocol': 'aoe', 'total_capacity_gb': 'unknown', - 'vendor_name': 'Coraid', - 'volume_backend_name': 'EtherCloud ESM'} + 'vendor_name': 'Coraid'} + backend_name = self.configuration.safe_get('volume_backend_name') + data['volume_backend_name'] = backend_name or 'EtherCloud ESM' + return data def local_path(self, volume): pass diff --git a/cinder/volume/drivers/emc/emc_smis_iscsi.py b/cinder/volume/drivers/emc/emc_smis_iscsi.py index d9c58a29a..25308c53a 100644 --- a/cinder/volume/drivers/emc/emc_smis_iscsi.py +++ b/cinder/volume/drivers/emc/emc_smis_iscsi.py @@ -240,6 +240,7 @@ class EMCSMISISCSIDriver(driver.ISCSIDriver): """Retrieve status info from volume group.""" LOG.debug(_("Updating volume status")) data = self.common.update_volume_status() - data['volume_backend_name'] = 'EMCSMISISCSIDriver' + backend_name = self.configuration.safe_get('volume_backend_name') + data['volume_backend_name'] = backend_name or 'EMCSMISISCSIDriver' data['storage_protocol'] = 'iSCSI' self._stats = data diff --git a/cinder/volume/drivers/huawei/huawei_iscsi.py b/cinder/volume/drivers/huawei/huawei_iscsi.py index 6eb4a957c..8b8ae6320 100644 --- a/cinder/volume/drivers/huawei/huawei_iscsi.py +++ b/cinder/volume/drivers/huawei/huawei_iscsi.py @@ -1501,7 +1501,8 @@ class HuaweiISCSIDriver(driver.ISCSIDriver): LOG.debug(_("Updating volume status")) data = {} - data['volume_backend_name'] = 'HuaweiISCSIDriver' + backend_name = self.configuration.safe_get('volume_backend_name') + data["volume_backend_name"] = backend_name or 'HuaweiISCSIDriver' data['vendor_name'] = 'Huawei' data['driver_version'] = '1.0' data['storage_protocol'] = 'iSCSI' diff --git a/cinder/volume/drivers/nexenta/volume.py b/cinder/volume/drivers/nexenta/volume.py index f657a0c7c..94b73fd3a 100644 --- a/cinder/volume/drivers/nexenta/volume.py +++ b/cinder/volume/drivers/nexenta/volume.py @@ -316,7 +316,10 @@ class NexentaDriver(driver.ISCSIDriver): # pylint: disable=R0921 LOG.debug(_("Updating volume status")) data = {} - data["volume_backend_name"] = self.__class__.__name__ + backend_name = self.__class__.__name__ + if self.configuration: + backend_name = self.configuration.safe_get('volume_backend_name') + data["volume_backend_name"] = backend_name or self.__class__.__name__ data["vendor_name"] = 'Nexenta' data["driver_version"] = VERSION data["storage_protocol"] = 'iSCSI' diff --git a/cinder/volume/drivers/rbd.py b/cinder/volume/drivers/rbd.py index c9016bf8b..6a8f5c044 100644 --- a/cinder/volume/drivers/rbd.py +++ b/cinder/volume/drivers/rbd.py @@ -54,14 +54,7 @@ class RBDDriver(driver.VolumeDriver): def __init__(self, *args, **kwargs): super(RBDDriver, self).__init__(*args, **kwargs) self.configuration.append_config_values(rbd_opts) - self._stats = dict( - volume_backend_name='RBD', - vendor_name='Open Source', - driver_version=VERSION, - storage_protocol='ceph', - total_capacity_gb='unknown', - free_capacity_gb='unknown', - reserved_percentage=0) + self._stats = {} def check_for_setup_error(self): """Returns an error if prerequisites aren't met""" @@ -73,9 +66,15 @@ class RBDDriver(driver.VolumeDriver): raise exception.VolumeBackendAPIException(data=exception_message) def _update_volume_stats(self): - stats = dict( - total_capacity_gb='unknown', - free_capacity_gb='unknown') + stats = {'vendor_name': 'Open Source', + 'driver_version': VERSION, + 'storage_protocol': 'ceph', + 'total_capacity_gb': 'unknown', + 'free_capacity_gb': 'unknown', + 'reserved_percentage': 0} + backend_name = self.configuration.safe_get('volume_backend_name') + stats['volume_backend_name'] = backend_name or 'RBD' + try: stdout, _err = self._execute('rados', 'df', '--format', 'json') new_stats = json.loads(stdout) @@ -86,7 +85,7 @@ class RBDDriver(driver.VolumeDriver): except exception.ProcessExecutionError: # just log and return unknown capacities LOG.exception(_('error refreshing volume stats')) - self._stats.update(stats) + self._stats = stats def get_volume_stats(self, refresh=False): """Return the current state of the volume service. If 'refresh' is diff --git a/cinder/volume/drivers/san/hp/hp_3par_common.py b/cinder/volume/drivers/san/hp/hp_3par_common.py index 31bbb7db7..bed8cc39d 100644 --- a/cinder/volume/drivers/san/hp/hp_3par_common.py +++ b/cinder/volume/drivers/san/hp/hp_3par_common.py @@ -95,13 +95,7 @@ hp3par_opts = [ class HP3PARCommon(): - stats = {'driver_version': '1.0', - 'free_capacity_gb': 'unknown', - 'reserved_percentage': 0, - 'storage_protocol': None, - 'total_capacity_gb': 'unknown', - 'vendor_name': 'Hewlett-Packard', - 'volume_backend_name': None} + stats = {} # Valid values for volume type extra specs # The first value in the list is the default value @@ -422,26 +416,42 @@ exit const = 0.0009765625 if refresh: - try: - cpg = client.getCPG(self.config.hp3par_cpg) - if 'limitMiB' not in cpg['SDGrowth']: - total_capacity = 'infinite' - free_capacity = 'infinite' - else: - total_capacity = int(cpg['SDGrowth']['limitMiB'] * const) - free_capacity = int((cpg['SDGrowth']['limitMiB'] - - cpg['UsrUsage']['usedMiB']) * const) - - self.stats['total_capacity_gb'] = total_capacity - self.stats['free_capacity_gb'] = free_capacity - except hpexceptions.HTTPNotFound: - err = (_("CPG (%s) doesn't exist on array") - % self.config.hp3par_cpg) - LOG.error(err) - raise exception.InvalidInput(reason=err) + self._update_volume_stats(client) return self.stats + def _update_volume_stats(self, client): + + # storage_protocol and volume_backend_name are + # set in the child classes + stats = {'driver_version': '1.0', + 'free_capacity_gb': 'unknown', + 'reserved_percentage': 0, + 'storage_protocol': None, + 'total_capacity_gb': 'unknown', + 'vendor_name': 'Hewlett-Packard', + 'volume_backend_name': None} + + try: + cpg = client.getCPG(self.config.hp3par_cpg) + if 'limitMiB' not in cpg['SDGrowth']: + total_capacity = 'infinite' + free_capacity = 'infinite' + else: + total_capacity = int(cpg['SDGrowth']['limitMiB'] * const) + free_capacity = int((cpg['SDGrowth']['limitMiB'] - + cpg['UsrUsage']['usedMiB']) * const) + + stats['total_capacity_gb'] = total_capacity + stats['free_capacity_gb'] = free_capacity + except hpexceptions.HTTPNotFound: + err = (_("CPG (%s) doesn't exist on array") + % self.config.hp3par_cpg) + LOG.error(err) + raise exception.InvalidInput(reason=err) + + self.stats = stats + def create_vlun(self, volume, host, client): """ In order to export a volume on a 3PAR box, we have to diff --git a/cinder/volume/drivers/san/hp/hp_3par_fc.py b/cinder/volume/drivers/san/hp/hp_3par_fc.py index 6eb6a3527..d5af46d3e 100644 --- a/cinder/volume/drivers/san/hp/hp_3par_fc.py +++ b/cinder/volume/drivers/san/hp/hp_3par_fc.py @@ -76,7 +76,8 @@ class HP3PARFCDriver(cinder.volume.driver.FibreChannelDriver): def get_volume_stats(self, refresh): stats = self.common.get_volume_stats(refresh, self.client) stats['storage_protocol'] = 'FC' - stats['volume_backend_name'] = 'HP3PARFCDriver' + backend_name = self.configuration.safe_get('volume_backend_name') + stats['volume_backend_name'] = backend_name or self.__class__.__name__ return stats def do_setup(self, context): diff --git a/cinder/volume/drivers/san/hp/hp_3par_iscsi.py b/cinder/volume/drivers/san/hp/hp_3par_iscsi.py index b740a2f57..fca9c2006 100644 --- a/cinder/volume/drivers/san/hp/hp_3par_iscsi.py +++ b/cinder/volume/drivers/san/hp/hp_3par_iscsi.py @@ -75,7 +75,8 @@ class HP3PARISCSIDriver(cinder.volume.driver.ISCSIDriver): def get_volume_stats(self, refresh): stats = self.common.get_volume_stats(refresh, self.client) stats['storage_protocol'] = 'iSCSI' - stats['volume_backend_name'] = 'HP3PARISCSIDriver' + backend_name = self.configuration.safe_get('volume_backend_name') + stats['volume_backend_name'] = backend_name or self.__class__.__name__ return stats def do_setup(self, context): diff --git a/cinder/volume/drivers/scality.py b/cinder/volume/drivers/scality.py index 31a41909f..b59fe26be 100644 --- a/cinder/volume/drivers/scality.py +++ b/cinder/volume/drivers/scality.py @@ -223,7 +223,6 @@ class ScalityDriver(driver.VolumeDriver): If 'refresh' is True, run the update first. """ stats = { - 'volume_backend_name': 'Scality_SOFS', 'vendor_name': 'Scality', 'driver_version': '1.0', 'storage_protocol': 'scality', @@ -231,6 +230,8 @@ class ScalityDriver(driver.VolumeDriver): 'free_capacity_gb': 'infinite', 'reserved_percentage': 0, } + backend_name = self.configuration.safe_get('volume_backend_name') + stats['volume_backend_name'] = backend_name or 'Scality_SOFS' return stats def copy_image_to_volume(self, context, volume, image_service, image_id): diff --git a/cinder/volume/drivers/sheepdog.py b/cinder/volume/drivers/sheepdog.py index d1916c7ad..a539ce181 100644 --- a/cinder/volume/drivers/sheepdog.py +++ b/cinder/volume/drivers/sheepdog.py @@ -33,16 +33,8 @@ class SheepdogDriver(driver.VolumeDriver): def __init__(self, *args, **kwargs): super(SheepdogDriver, self).__init__(*args, **kwargs) - self._stats = dict( - volume_backend_name='sheepdog', - vendor_name='Open Source', - dirver_version='1.0', - storage_protocol='sheepdog', - total_capacity_gb='unknown', - free_capacity_gb='unknown', - reserved_percentage=0, - QoS_support=False) self.stats_pattern = re.compile(r'[\w\s%]*Total\s(\d+)\s(\d+)*') + self._stats = {} def check_for_setup_error(self): """Returns an error if prerequisites aren't met""" @@ -118,6 +110,19 @@ class SheepdogDriver(driver.VolumeDriver): def _update_volume_stats(self): stats = {} + + backend_name = "sheepdog" + if self.configuration: + backend_name = self.configuration.safe_get('volume_backend_name') + stats["volume_backend_name"] = backend_name or 'sheepdog' + stats['vendor_name'] = 'Open Source' + stats['dirver_version'] = '1.0' + stats['storage_protocol'] = 'sheepdog' + stats['total_capacity_gb'] = 'unknown' + stats['free_capacity_gb'] = 'unknown' + stats['reserved_percentage'] = 0 + stats['QoS_support'] = False + try: stdout, _err = self._execute('collie', 'node', 'info', '-r') m = self.stats_pattern.match(stdout) @@ -127,7 +132,8 @@ class SheepdogDriver(driver.VolumeDriver): stats['free_capacity_gb'] = (total - used) / (1024 ** 3) except exception.ProcessExecutionError: LOG.exception(_('error refreshing volume stats')) - self._stats.update(stats) + + self._stats = stats def get_volume_stats(self, refresh=False): if refresh: diff --git a/cinder/volume/drivers/xenapi/sm.py b/cinder/volume/drivers/xenapi/sm.py index cc93af096..c1b64e2c9 100644 --- a/cinder/volume/drivers/xenapi/sm.py +++ b/cinder/volume/drivers/xenapi/sm.py @@ -245,14 +245,17 @@ class XenAPINFSDriver(driver.VolumeDriver): def get_volume_stats(self, refresh=False): if refresh or not self._stats: - self._stats = dict( - volume_backend_name='XenAPINFS', - vendor_name='Open Source', - driver_version='1.0', - storage_protocol='xensm', - total_capacity_gb='unknown', - free_capacity_gb='unknown', - reserved_percentage=0) + data = {} + + backend_name = self.configuration.safe_get('volume_backend_name') + data["volume_backend_name"] = backend_name or 'XenAPINFS', + data['vendor_name'] = 'Open Source', + data['driver_version'] = '1.0' + data['storage_protocol'] = 'xensm' + data['total_capacity_gb'] = 'unknown' + data['free_capacity_gb'] = 'unknown' + data['reserved_percentage'] = 0 + self._stats = data return self._stats