From a9c25274ab9085738cf35a4f7c1639b9af35c4e5 Mon Sep 17 00:00:00 2001 From: Ponomaryov Valeriy Date: Sun, 28 Dec 2014 21:17:33 +0200 Subject: [PATCH] Add driver mode attr definition for all drivers Driver mode functionality was implemented to be able to specify how driver should work and filter backends scheduling share creation based on this. Add to all drivers update of attr 'mode' based on its current behavior. Set 'share_driver_mode' extra spec to volume/share type with one of available values. Scheduler will use it for host filtering. Implements blueprint driver-modes-for-scheduler Change-Id: Ida644f630ee07c51c02aea5d6280980b5d704c2f --- manila/share/driver.py | 1 + manila/share/drivers/emc/driver.py | 2 ++ manila/share/drivers/emc/plugins/base.py | 2 ++ .../drivers/emc/plugins/vnx/connection.py | 2 ++ manila/share/drivers/generic.py | 3 ++- manila/share/drivers/glusterfs.py | 3 +++ manila/share/drivers/glusterfs_native.py | 3 +++ manila/share/drivers/ibm/gpfs.py | 3 +++ manila/share/drivers/netapp/cluster_mode.py | 3 +++ manila/share/drivers/zfssa/zfssashare.py | 3 +++ manila/tests/share/drivers/emc/test_driver.py | 3 +++ manila/tests/share/drivers/ibm/test_gpfs.py | 22 ++++++++++++++++ .../share/drivers/netapp/test_cluster_mode.py | 3 ++- manila/tests/share/drivers/test_generic.py | 24 +++++++++++++++++ manila/tests/share/drivers/test_glusterfs.py | 1 + .../share/drivers/test_glusterfs_native.py | 1 + .../share/drivers/zfssa/test_zfssashare.py | 6 +++++ manila/tests/share/test_driver.py | 26 +++++++++++++++++++ 18 files changed, 109 insertions(+), 2 deletions(-) diff --git a/manila/share/driver.py b/manila/share/driver.py index f20cef97b3..627cb6a7fa 100644 --- a/manila/share/driver.py +++ b/manila/share/driver.py @@ -318,6 +318,7 @@ class ShareDriver(object): # each driver may define these values in its own config options # or fetch from driver specific configuration file. data["share_backend_name"] = backend_name or 'Generic_NFS' + data["share_driver_mode"] = self.mode data["vendor_name"] = 'Open Source' data["driver_version"] = '1.0' data["storage_protocol"] = None diff --git a/manila/share/drivers/emc/driver.py b/manila/share/drivers/emc/driver.py index 08ed081925..f63f542746 100644 --- a/manila/share/drivers/emc/driver.py +++ b/manila/share/drivers/emc/driver.py @@ -125,6 +125,7 @@ class EMCShareDriver(driver.ShareDriver): backend_name = self.configuration.safe_get('emc_share_backend') self.plugin = self.plugin_manager.load_plugin(backend_name, LOG) + self.mode = self.get_driver_mode(self.plugin.supported_driver_modes) self.plugin.connect(self, context) @@ -136,6 +137,7 @@ class EMCShareDriver(driver.ShareDriver): backend_name = self.configuration.safe_get( 'share_backend_name') or "EMC_NAS_Storage" data["share_backend_name"] = backend_name + data["share_driver_mode"] = self.mode data["vendor_name"] = 'EMC' data["driver_version"] = '1.0' data["storage_protocol"] = 'NFS_CIFS' diff --git a/manila/share/drivers/emc/plugins/base.py b/manila/share/drivers/emc/plugins/base.py index af66a2f8fb..f25bb1714c 100644 --- a/manila/share/drivers/emc/plugins/base.py +++ b/manila/share/drivers/emc/plugins/base.py @@ -25,6 +25,8 @@ class StorageConnection(object): def __init__(self, logger): self.logger = logger + # NOTE(vponomaryov): redefine 'supported_driver_modes' within plugin. + self.supported_driver_modes = None @abc.abstractmethod def create_share(self, emc_share_driver, context, share, share_server): diff --git a/manila/share/drivers/emc/plugins/vnx/connection.py b/manila/share/drivers/emc/plugins/vnx/connection.py index 89a2ce031d..b140b6af26 100644 --- a/manila/share/drivers/emc/plugins/vnx/connection.py +++ b/manila/share/drivers/emc/plugins/vnx/connection.py @@ -17,6 +17,7 @@ from oslo.utils import excutils from oslo.utils import units import six +from manila.common import constants as const from manila import db as manila_db from manila import exception from manila.i18n import _ @@ -47,6 +48,7 @@ class VNXStorageConnection(driver.StorageConnection): self._pool_name = None self._pool = None self._filesystems = {} + self.supported_driver_modes = const.MULTI_SVM_MODE def create_share(self, emc_share_driver, context, share, share_server=None): diff --git a/manila/share/drivers/generic.py b/manila/share/drivers/generic.py index 9fa3bf659b..f0acbeb304 100644 --- a/manila/share/drivers/generic.py +++ b/manila/share/drivers/generic.py @@ -114,7 +114,7 @@ class GenericShareDriver(driver.ExecuteMixin, driver.ShareDriver): self.db = db self.configuration.append_config_values(share_opts) self.configuration.append_config_values(service_instance.server_opts) - self.mode = self.get_driver_mode([const.MULTI_SVM_MODE, ]) + self.mode = self.get_driver_mode(const.MULTI_SVM_MODE) self._helpers = {} self.backend_name = self.configuration.safe_get( 'share_backend_name') or "Cinder_Volumes" @@ -455,6 +455,7 @@ class GenericShareDriver(driver.ExecuteMixin, driver.ShareDriver): data = {} data["share_backend_name"] = self.backend_name + data["share_driver_mode"] = self.mode data["vendor_name"] = 'Open Source' data["driver_version"] = '1.0' data["storage_protocol"] = 'NFS_CIFS' diff --git a/manila/share/drivers/glusterfs.py b/manila/share/drivers/glusterfs.py index 0f6d90282a..1eb02ac82e 100644 --- a/manila/share/drivers/glusterfs.py +++ b/manila/share/drivers/glusterfs.py @@ -32,6 +32,7 @@ import xml.etree.cElementTree as etree from oslo.config import cfg import six +from manila.common import constants as const from manila import exception from manila.i18n import _ from manila.i18n import _LE @@ -99,6 +100,7 @@ class GlusterfsShareDriver(driver.ExecuteMixin, driver.ShareDriver): self.configuration.append_config_values(GlusterfsManilaShare_opts) self.backend_name = self.configuration.safe_get( 'share_backend_name') or 'GlusterFS' + self.mode = self.get_driver_mode(const.SINGLE_SVM_MODE) def do_setup(self, context): """Native mount the GlusterFS volume and tune it.""" @@ -267,6 +269,7 @@ class GlusterfsShareDriver(driver.ExecuteMixin, driver.ShareDriver): data = {} data["share_backend_name"] = self.backend_name + data["share_driver_mode"] = self.mode data["vendor_name"] = 'Red Hat' data["driver_version"] = '1.0' data["storage_protocol"] = 'NFS' diff --git a/manila/share/drivers/glusterfs_native.py b/manila/share/drivers/glusterfs_native.py index eed20afa63..3140b6b168 100644 --- a/manila/share/drivers/glusterfs_native.py +++ b/manila/share/drivers/glusterfs_native.py @@ -33,6 +33,7 @@ import tempfile from oslo.config import cfg import six +from manila.common import constants as const from manila import exception from manila.i18n import _ from manila.i18n import _LI @@ -84,6 +85,7 @@ class GlusterfsNativeShareDriver(driver.ExecuteMixin, driver.ShareDriver): glusterfs_native_manila_share_opts) self.backend_name = self.configuration.safe_get( 'share_backend_name') or 'GlusterFS-Native' + self.mode = self.get_driver_mode(const.SINGLE_SVM_MODE) def do_setup(self, context): """Setup the GlusterFS volumes.""" @@ -505,6 +507,7 @@ class GlusterfsNativeShareDriver(driver.ExecuteMixin, driver.ShareDriver): data = {} data["share_backend_name"] = self.backend_name + data["share_driver_mode"] = self.mode data["vendor_name"] = 'Red Hat' data["driver_version"] = '1.1' data["storage_protocol"] = 'glusterfs' diff --git a/manila/share/drivers/ibm/gpfs.py b/manila/share/drivers/ibm/gpfs.py index 139cf4e279..fdb1dcb9bb 100644 --- a/manila/share/drivers/ibm/gpfs.py +++ b/manila/share/drivers/ibm/gpfs.py @@ -43,6 +43,7 @@ from oslo.utils import units from oslo_concurrency import processutils import six +from manila.common import constants as const from manila import exception from manila.i18n import _, _LE, _LI from manila.openstack.common import log as logging @@ -129,6 +130,7 @@ class GPFSShareDriver(driver.ExecuteMixin, driver.GaneshaMixin, self.configuration.append_config_values(gpfs_share_opts) self.backend_name = self.configuration.safe_get( 'share_backend_name') or "IBM Storage System" + self.mode = self.get_driver_mode(const.SINGLE_SVM_MODE) self.sshpool = None self.ssh_connections = {} self._gpfs_execute = None @@ -501,6 +503,7 @@ class GPFSShareDriver(driver.ExecuteMixin, driver.GaneshaMixin, data = {} data["share_backend_name"] = self.backend_name + data["share_driver_mode"] = self.mode data["vendor_name"] = 'IBM' data["driver_version"] = '1.0' data["storage_protocol"] = 'NFS' diff --git a/manila/share/drivers/netapp/cluster_mode.py b/manila/share/drivers/netapp/cluster_mode.py index 3ba35f7774..01d2d5b8d7 100644 --- a/manila/share/drivers/netapp/cluster_mode.py +++ b/manila/share/drivers/netapp/cluster_mode.py @@ -28,6 +28,7 @@ from oslo.utils import excutils from oslo.utils import units import six +from manila.common import constants as const from manila import context from manila import exception from manila.i18n import _ @@ -144,6 +145,7 @@ class NetAppClusteredShareDriver(driver.ShareDriver): self.api_version = (1, 15) self.backend_name = self.configuration.safe_get( 'share_backend_name') or "NetApp_Cluster_Mode" + self.mode = self.get_driver_mode(const.MULTI_SVM_MODE) def do_setup(self, context): """Prepare once the driver. @@ -194,6 +196,7 @@ class NetAppClusteredShareDriver(driver.ShareDriver): LOG.debug("Updating share stats") data = {} data["share_backend_name"] = self.backend_name + data["share_driver_mode"] = self.mode data["vendor_name"] = 'NetApp' data["driver_version"] = '1.0' data["storage_protocol"] = 'NFS_CIFS' diff --git a/manila/share/drivers/zfssa/zfssashare.py b/manila/share/drivers/zfssa/zfssashare.py index 0629060da0..ac167b5d1b 100644 --- a/manila/share/drivers/zfssa/zfssashare.py +++ b/manila/share/drivers/zfssa/zfssashare.py @@ -20,6 +20,7 @@ import base64 from oslo.config import cfg from oslo.utils import units +from manila.common import constants as const from manila import exception from manila.i18n import _ from manila.i18n import _LE @@ -121,6 +122,7 @@ class ZFSSAShareDriver(driver.ShareDriver): 'quota_snap': self.configuration.zfssa_nas_quota_snap, 'reservation_snap': self.configuration.zfssa_nas_quota_snap, } + self.mode = self.get_driver_mode(const.SINGLE_SVM_MODE) def do_setup(self, context): """Login, create project, no sharing option enabled.""" @@ -305,6 +307,7 @@ class ZFSSAShareDriver(driver.ShareDriver): data = {} backend_name = self.configuration.safe_get('share_backend_name') data["share_backend_name"] = backend_name or self.__class__.__name__ + data["share_driver_mode"] = self.mode data["vendor_name"] = 'Oracle' data["driver_version"] = self.VERSION data["storage_protocol"] = self.PROTOCOL diff --git a/manila/tests/share/drivers/emc/test_driver.py b/manila/tests/share/drivers/emc/test_driver.py index 09dc639369..11ea4e1b39 100644 --- a/manila/tests/share/drivers/emc/test_driver.py +++ b/manila/tests/share/drivers/emc/test_driver.py @@ -16,6 +16,7 @@ import mock from stevedore import extension +from manila.common import constants as const from manila.openstack.common import log as logging from manila.share import configuration as conf from manila.share.drivers.emc import driver as emcdriver @@ -28,6 +29,7 @@ LOG = logging.getLogger(__name__) class FakeConnection(base.StorageConnection): def __init__(self, logger): self.logger = logger + self.supported_driver_modes = const.MULTI_SVM_MODE def create_share(self, emc_share_driver, context, share, share_server): """Is called to create share.""" @@ -123,6 +125,7 @@ class EMCShareFrameworkTestCase(test.TestCase): self.driver.plugin = mock.Mock() self.driver._update_share_stats() data["share_backend_name"] = FAKE_BACKEND + data["share_driver_mode"] = self.driver.mode data["vendor_name"] = 'EMC' data["driver_version"] = '1.0' data["storage_protocol"] = 'NFS_CIFS' diff --git a/manila/tests/share/drivers/ibm/test_gpfs.py b/manila/tests/share/drivers/ibm/test_gpfs.py index 1b2d14a65c..b4b4f0ec1d 100644 --- a/manila/tests/share/drivers/ibm/test_gpfs.py +++ b/manila/tests/share/drivers/ibm/test_gpfs.py @@ -128,6 +128,28 @@ class GPFSShareDriverTestCase(test.TestCase): ['127.0.0.1', self.local_ip]) )) + def test_get_share_stats_refresh_false(self): + self._driver._stats = {'fake_key': 'fake_value'} + result = self._driver.get_share_stats(False) + self.assertEqual(self._driver._stats, result) + + def test_get_share_stats_refresh_true(self): + self.stubs.Set( + self._driver, '_get_available_capacity', + mock.Mock(return_value=(11111.0, 12345.0))) + result = self._driver.get_share_stats(True) + expected_keys = [ + 'QoS_support', 'driver_version', 'share_backend_name', + 'free_capacity_gb', 'share_driver_mode', 'total_capacity_gb', + 'reserved_percentage', 'vendor_name', 'storage_protocol', + ] + for key in expected_keys: + self.assertIn(key, result) + self.assertEqual(self._driver.mode, result['share_driver_mode']) + self.assertEqual('IBM', result['vendor_name']) + self._driver._get_available_capacity.assert_called_once_with( + self._driver.configuration.gpfs_mount_point_base) + def test_do_setup(self): self.stubs.Set(self._driver, '_setup_helpers', mock.Mock()) self._driver.do_setup(self._context) diff --git a/manila/tests/share/drivers/netapp/test_cluster_mode.py b/manila/tests/share/drivers/netapp/test_cluster_mode.py index a75c4ac00e..90a1259d6b 100644 --- a/manila/tests/share/drivers/netapp/test_cluster_mode.py +++ b/manila/tests/share/drivers/netapp/test_cluster_mode.py @@ -140,6 +140,7 @@ class NetAppClusteredDrvTestCase(test.TestCase): expected = {} expected["share_backend_name"] = self.driver.backend_name + expected["share_driver_mode"] = self.driver.mode expected["vendor_name"] = 'NetApp' expected["driver_version"] = '1.0' expected["storage_protocol"] = 'NFS_CIFS' @@ -147,7 +148,7 @@ class NetAppClusteredDrvTestCase(test.TestCase): expected['free_capacity_gb'] = 3 expected['reserved_percentage'] = 0 expected['QoS_support'] = False - self.assertDictMatch(res, expected) + self.assertDictMatch(expected, res) def test_setup_server(self): self.driver._vserver_create_if_not_exists = mock.Mock( diff --git a/manila/tests/share/drivers/test_generic.py b/manila/tests/share/drivers/test_generic.py index d02d4e68c5..c1c0dbffaf 100644 --- a/manila/tests/share/drivers/test_generic.py +++ b/manila/tests/share/drivers/test_generic.py @@ -932,6 +932,30 @@ class GenericShareDriverTestCase(test.TestCase): ) self.assertEqual(ssh_output, result) + def test_get_share_stats_refresh_false(self): + self._driver._stats = {'fake_key': 'fake_value'} + + result = self._driver.get_share_stats(False) + + self.assertEqual(self._driver._stats, result) + + def test_get_share_stats_refresh_true(self): + fake_stats = {'fake_key': 'fake_value'} + self._driver._stats = fake_stats + expected_keys = [ + 'QoS_support', 'driver_version', 'share_backend_name', + 'free_capacity_gb', 'share_driver_mode', 'total_capacity_gb', + 'reserved_percentage', 'vendor_name', 'storage_protocol', + ] + + result = self._driver.get_share_stats(True) + + self.assertNotEqual(fake_stats, result) + for key in expected_keys: + self.assertIn(key, result) + self.assertEqual(self._driver.mode, result['share_driver_mode']) + self.assertEqual('Open Source', result['vendor_name']) + @mock.patch.object( generic.service_instance, 'ServiceInstanceManager', mock.Mock()) def test_driver_mode_valid_value(self): diff --git a/manila/tests/share/drivers/test_glusterfs.py b/manila/tests/share/drivers/test_glusterfs.py index 08997ca3b2..d994b9a94f 100644 --- a/manila/tests/share/drivers/test_glusterfs.py +++ b/manila/tests/share/drivers/test_glusterfs.py @@ -447,6 +447,7 @@ class GlusterfsShareDriverTestCase(test.TestCase): def test_update_share_stats(self): test_data = { 'share_backend_name': 'GlusterFS', + 'share_driver_mode': self._driver.mode, 'vendor_name': 'Red Hat', 'driver_version': '1.0', 'storage_protocol': 'NFS', diff --git a/manila/tests/share/drivers/test_glusterfs_native.py b/manila/tests/share/drivers/test_glusterfs_native.py index 899031ec13..b2b29c7b60 100644 --- a/manila/tests/share/drivers/test_glusterfs_native.py +++ b/manila/tests/share/drivers/test_glusterfs_native.py @@ -792,6 +792,7 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase): def test_update_share_stats(self): test_data = { 'share_backend_name': 'GlusterFS-Native', + 'share_driver_mode': self._driver.mode, 'vendor_name': 'Red Hat', 'driver_version': '1.1', 'storage_protocol': 'glusterfs', diff --git a/manila/tests/share/drivers/zfssa/test_zfssashare.py b/manila/tests/share/drivers/zfssa/test_zfssashare.py index 7f1cb77e36..51d5f7262c 100644 --- a/manila/tests/share/drivers/zfssa/test_zfssashare.py +++ b/manila/tests/share/drivers/zfssa/test_zfssashare.py @@ -17,6 +17,7 @@ Unit tests for Oracle's ZFSSA Manila driver. import mock from oslo.config import cfg +from manila.common import constants as const from manila import context from manila import exception from manila.share import configuration as conf @@ -70,7 +71,11 @@ class ZFSSAShareDriverTestCase(test.TestCase): self._driver.do_setup(self._context) def _create_fake_config(self): + def _safe_get(opt): + return getattr(self.configuration, opt) + self.configuration = mock.Mock(spec=conf.Configuration) + self.configuration.safe_get = mock.Mock(side_effect=_safe_get) self.configuration.zfssa_host = '1.1.1.1' self.configuration.zfssa_data_ip = '1.1.1.1' self.configuration.zfssa_auth_user = 'user' @@ -86,6 +91,7 @@ class ZFSSAShareDriverTestCase(test.TestCase): self.configuration.zfssa_nas_quota_snap = 'true' self.configuration.zfssa_rest_timeout = 60 self.configuration.network_config_group = 'fake_network_config_group' + self.configuration.share_driver_mode = const.SINGLE_SVM_MODE def test_create_share(self): self.stubs.Set(self._driver.zfssa, 'create_share', mock.Mock()) diff --git a/manila/tests/share/test_driver.py b/manila/tests/share/test_driver.py index b9cc336cdd..546e2d5428 100644 --- a/manila/tests/share/test_driver.py +++ b/manila/tests/share/test_driver.py @@ -111,6 +111,32 @@ class ShareDriverTestCase(test.TestCase): self.assertEqual(None, share_driver.configuration) network.API.assert_called_once_with(config_group_name=None) + def test_get_share_stats_refresh_false(self): + share_driver = driver.ShareDriver(configuration=None) + share_driver._stats = {'fake_key': 'fake_value'} + + result = share_driver.get_share_stats(False) + + self.assertEqual(share_driver._stats, result) + + def test_get_share_stats_refresh_true(self): + conf = configuration.Configuration(None) + expected_keys = [ + 'QoS_support', 'driver_version', 'share_backend_name', + 'free_capacity_gb', 'share_driver_mode', 'total_capacity_gb', + 'reserved_percentage', 'vendor_name', 'storage_protocol', + ] + share_driver = driver.ShareDriver(configuration=conf) + fake_stats = {'fake_key': 'fake_value'} + share_driver._stats = fake_stats + + result = share_driver.get_share_stats(True) + + self.assertNotEqual(fake_stats, result) + for key in expected_keys: + self.assertIn(key, result) + self.assertEqual('Open Source', result['vendor_name']) + @ddt.data( '', 'v1', 'v2', 'fake1', None, [], ['v1'], ['v2'], ['v1', 'v2'], ['fake1'], ['fake1', 'fake2'],