Update EMC Manila driver framework using stevedore

Alternative way of registering plugins in EMC Manila driver framework
using the module *stevedore*.

Change-Id: I3c38a2dbc9575a81c83e64180cd37916abe68334
Implements: blueprint register-emc-manila-plugin-with-stevedore
This commit is contained in:
Jay Xu 2014-12-10 01:01:31 -05:00
parent 5433fdafc7
commit e8709c8005
6 changed files with 60 additions and 53 deletions

View File

@ -24,10 +24,7 @@ from oslo.config import cfg
from manila.openstack.common import log
from manila.share import driver
from manila.share.drivers.emc.plugins import \
registry as emc_plugins_registry
# TODO(jay.xu): Implement usage of stevedore for plugins.
from manila.share.drivers.emc.plugins.vnx import connection # noqa
from manila.share.drivers.emc import plugin_manager as manager
LOG = log.getLogger(__name__)
@ -71,11 +68,14 @@ class EMCShareDriver(driver.ShareDriver):
if self.configuration:
self.configuration.append_config_values(EMC_NAS_OPTS)
self._storage_conn = None
self.plugin_manager = manager.EMCPluginManager(
namespace='manila.share.drivers.emc.plugins')
self.plugin = None
def create_share(self, context, share, share_server=None):
"""Is called to create share."""
location = self._storage_conn.create_share(self, context, share,
location = self.plugin.create_share(self, context, share,
share_server)
return location
@ -83,37 +83,37 @@ class EMCShareDriver(driver.ShareDriver):
def create_share_from_snapshot(self, context, share, snapshot,
share_server=None):
"""Is called to create share from snapshot."""
location = self._storage_conn.create_share_from_snapshot(
location = self.plugin.create_share_from_snapshot(
self, context, share, snapshot, share_server)
return location
def create_snapshot(self, context, snapshot, share_server=None):
"""Is called to create snapshot."""
self._storage_conn.create_snapshot(self, context, snapshot,
self.plugin.create_snapshot(self, context, snapshot,
share_server)
def delete_share(self, context, share, share_server=None):
"""Is called to remove share."""
self._storage_conn.delete_share(self, context, share, share_server)
self.plugin.delete_share(self, context, share, share_server)
def delete_snapshot(self, context, snapshot, share_server=None):
"""Is called to remove snapshot."""
self._storage_conn.delete_snapshot(self, context, snapshot,
self.plugin.delete_snapshot(self, context, snapshot,
share_server)
def ensure_share(self, context, share, share_server=None):
"""Invoked to sure that share is exported."""
self._storage_conn.ensure_share(self, context, share, share_server)
self.plugin.ensure_share(self, context, share, share_server)
def allow_access(self, context, share, access, share_server=None):
"""Allow access to the share."""
self._storage_conn.allow_access(self, context, share, access,
self.plugin.allow_access(self, context, share, access,
share_server)
def deny_access(self, context, share, access, share_server=None):
"""Deny access to the share."""
self._storage_conn.deny_access(self, context, share, access,
self.plugin.deny_access(self, context, share, access,
share_server)
def check_for_setup_error(self):
@ -122,9 +122,11 @@ class EMCShareDriver(driver.ShareDriver):
def do_setup(self, context):
"""Any initialization the share driver does while starting."""
self._storage_conn = emc_plugins_registry.create_storage_connection(
self.configuration.safe_get('emc_share_backend'), LOG)
self._storage_conn.connect(self, context)
backend_name = self.configuration.safe_get('emc_share_backend')
self.plugin = self.plugin_manager.load_plugin(backend_name, LOG)
self.plugin.connect(self, context)
def get_share_stats(self, refresh=False):
"""Get share stats.
@ -152,19 +154,19 @@ class EMCShareDriver(driver.ShareDriver):
data['free_capacity_gb'] = 'infinite'
data['reserved_percentage'] = 0
data['QoS_support'] = False
self._storage_conn.update_share_stats(data)
self.plugin.update_share_stats(data)
self._stats = data
def get_network_allocations_number(self):
"""Returns number of network allocations for creating VIFs."""
return self._storage_conn.get_network_allocations_number(self)
return self.plugin.get_network_allocations_number(self)
def setup_server(self, network_info, metadata=None):
"""Set up and configures share server with given network parameters."""
return self._storage_conn.setup_server(self, network_info, metadata)
return self.plugin.setup_server(self, network_info, metadata)
def teardown_server(self, server_details, security_services=None):
"""Teardown share server."""
return self._storage_conn.teardown_server(self,
return self.plugin.teardown_server(self,
server_details,
security_services)

View File

@ -12,20 +12,20 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""EMC Share Driver Plugin Framework."""
g_registered_storage_backends = {}
from stevedore import extension
def register_storage_backend(share_backend_name, storage_conn_class):
"""register a backend storage plugins."""
g_registered_storage_backends[
share_backend_name.upper()] = storage_conn_class
class EMCPluginManager(object):
def __init__(self, namespace):
self.namespace = namespace
self.extension_manager = extension.ExtensionManager(namespace)
def create_storage_connection(share_backend_name, logger):
"""create an instance of plugins."""
storage_conn_class = g_registered_storage_backends[
share_backend_name.upper()]
return storage_conn_class(logger)
def load_plugin(self, name, logger=None):
for ext in self.extension_manager.extensions:
if ext.name == name:
storage_conn = ext.plugin(logger)
return storage_conn
return None

View File

@ -24,7 +24,6 @@ from manila.i18n import _LE
from manila.i18n import _LW
from manila.openstack.common import log
from manila.share.drivers.emc.plugins import base as driver
from manila.share.drivers.emc.plugins import registry
from manila.share.drivers.emc.plugins.vnx import constants
from manila.share.drivers.emc.plugins.vnx import helper
from manila.share.drivers.emc.plugins.vnx import utils as vnx_utils
@ -918,6 +917,3 @@ class VNXStorageConnection(driver.StorageConnection):
msg = _("Only single security service with "
"type 'active_directory' supported")
raise exception.EMCVnxXMLAPIError(err=msg)
registry.register_storage_backend("vnx", VNXStorageConnection)

View File

@ -14,13 +14,12 @@
# under the License.
import mock
from stevedore import extension
from manila.openstack.common import log as logging
from manila.share import configuration as conf
from manila.share.drivers.emc import driver as emcdriver
from manila.share.drivers.emc.plugins import base
from manila.share.drivers.emc.plugins import \
registry as emc_plugins_registry
from manila import test
LOG = logging.getLogger(__name__)
@ -89,8 +88,20 @@ class FakeConnection(base.StorageConnection):
FAKE_BACKEND = 'fake_backend'
class FakeEMCExtensionManager():
def __init__(self):
self.extensions = []
self.extensions.append(
extension.Extension(name=FAKE_BACKEND,
plugin=FakeConnection,
entry_point=None,
obj=None))
class EMCShareFrameworkTestCase(test.TestCase):
@mock.patch('stevedore.extension.ExtensionManager',
mock.Mock(return_value=FakeEMCExtensionManager()))
def setUp(self):
super(EMCShareFrameworkTestCase, self).setUp()
self.configuration = conf.Configuration(None)
@ -101,18 +112,15 @@ class EMCShareFrameworkTestCase(test.TestCase):
configuration=self.configuration)
def test_driver_setup(self):
emc_plugins_registry.register_storage_backend(
FAKE_BACKEND, FakeConnection)
FakeConnection.connect = mock.Mock()
self.driver.do_setup(None)
self.assertIsInstance(self.driver._storage_conn, FakeConnection,
self.assertIsInstance(self.driver.plugin, FakeConnection,
"Not an instance of FakeConnection")
FakeConnection.connect.assert_called_with(self.driver, None)
def test_update_share_stats(self):
data = {}
self.driver._storage_conn = mock.Mock()
self.driver.plugin = mock.Mock()
self.driver._update_share_stats()
data["share_backend_name"] = FAKE_BACKEND
data["vendor_name"] = 'EMC'
@ -122,8 +130,7 @@ class EMCShareFrameworkTestCase(test.TestCase):
data['free_capacity_gb'] = 'infinite'
data['reserved_percentage'] = 0
data['QoS_support'] = False
self.driver._storage_conn.\
update_share_stats.assert_called_with(data)
self.driver.plugin.update_share_stats.assert_called_with(data)
def _fake_safe_get(self, value):
if value in ['emc_share_backend', 'share_backend_name']:

View File

@ -1201,7 +1201,7 @@ class EMCShareDriverVNXTestCase(test.TestCase):
]
helper.XMLAPIConnector.request.assert_has_calls(expected_calls)
helper.XMLAPIConnector.do_setup.assert_called_once_with()
pool_id = self.driver._storage_conn._pool['id']
pool_id = self.driver.plugin._pool['id']
self.assertEqual(pool_id, TD.storage_pool_id_default,
"Storage pool id parse error")

View File

@ -52,6 +52,8 @@ oslo.messaging.notify.drivers =
manila.openstack.common.notifier.test_notifier = oslo.messaging.notify._impl_test:TestDriver
oslo.config.opts =
manila = manila.opts:list_opts
manila.share.drivers.emc.plugins =
vnx = manila.share.drivers.emc.plugins.vnx.connection:VNXStorageConnection
[build_sphinx]
all_files = 1