Add driver mode interface
Implement driver mode interface for share driver, that will allow operator to switch share drivers to work in specific mode, like single or multi SVM. Add usage of driver mode interface to Generic driver as an example. To set driver mode use config option 'share_driver_mode'. Available values are specified within its help message. Partially Implements bp driver-modes Change-Id: I2744cccfbe2c09c3d942822f902793493cd9befb
This commit is contained in:
parent
7b588c86da
commit
28f311c9ad
@ -51,3 +51,11 @@ PING_PORTS = (
|
|||||||
|
|
||||||
SERVICE_INSTANCE_SECGROUP_DATA = (
|
SERVICE_INSTANCE_SECGROUP_DATA = (
|
||||||
CIFS_PORTS + NFS_PORTS + SSH_PORTS + PING_PORTS)
|
CIFS_PORTS + NFS_PORTS + SSH_PORTS + PING_PORTS)
|
||||||
|
|
||||||
|
SINGLE_SVM_MODE = 'single_svm'
|
||||||
|
MULTI_SVM_MODE = 'multi_svm'
|
||||||
|
|
||||||
|
VALID_SHARE_DRIVER_MODES = (
|
||||||
|
SINGLE_SVM_MODE,
|
||||||
|
MULTI_SVM_MODE,
|
||||||
|
)
|
||||||
|
@ -20,7 +20,9 @@ Drivers for shares.
|
|||||||
import time
|
import time
|
||||||
|
|
||||||
from oslo.config import cfg
|
from oslo.config import cfg
|
||||||
|
import six
|
||||||
|
|
||||||
|
from manila.common import constants
|
||||||
from manila import exception
|
from manila import exception
|
||||||
from manila.i18n import _LE
|
from manila.i18n import _LE
|
||||||
from manila import network
|
from manila import network
|
||||||
@ -51,6 +53,13 @@ share_opts = [
|
|||||||
"If not set, the share backend's config group will be used."
|
"If not set, the share backend's config group will be used."
|
||||||
"If an option is not found within provided group, then"
|
"If an option is not found within provided group, then"
|
||||||
"'DEFAULT' group will be used for search of option."),
|
"'DEFAULT' group will be used for search of option."),
|
||||||
|
cfg.ListOpt(
|
||||||
|
'share_driver_mode',
|
||||||
|
default=None,
|
||||||
|
help="One specific mode for driver to use. Available values: "
|
||||||
|
"%s. What modes are supported and can be used is "
|
||||||
|
"up to driver. If set None then default will be used." %
|
||||||
|
six.text_type(constants.VALID_SHARE_DRIVER_MODES)),
|
||||||
]
|
]
|
||||||
|
|
||||||
ssh_opts = [
|
ssh_opts = [
|
||||||
@ -76,11 +85,8 @@ CONF.register_opts(ssh_opts)
|
|||||||
class ExecuteMixin(object):
|
class ExecuteMixin(object):
|
||||||
"""Provides an executable functionality to a driver class."""
|
"""Provides an executable functionality to a driver class."""
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def init_execute_mixin(self, *args, **kwargs):
|
||||||
self.db = None
|
|
||||||
self.configuration = kwargs.get('configuration', None)
|
|
||||||
if self.configuration:
|
if self.configuration:
|
||||||
self.configuration.append_config_values(share_opts)
|
|
||||||
self.configuration.append_config_values(ssh_opts)
|
self.configuration.append_config_values(ssh_opts)
|
||||||
self.set_execute(kwargs.pop('execute', utils.execute))
|
self.set_execute(kwargs.pop('execute', utils.execute))
|
||||||
|
|
||||||
@ -115,10 +121,58 @@ class ShareDriver(object):
|
|||||||
self.configuration.append_config_values(share_opts)
|
self.configuration.append_config_values(share_opts)
|
||||||
network_config_group = (self.configuration.network_config_group or
|
network_config_group = (self.configuration.network_config_group or
|
||||||
self.configuration.config_group)
|
self.configuration.config_group)
|
||||||
|
self.mode = self.configuration.safe_get('share_driver_mode')
|
||||||
else:
|
else:
|
||||||
network_config_group = None
|
network_config_group = None
|
||||||
|
self.mode = CONF.share_driver_mode
|
||||||
|
|
||||||
|
if hasattr(self, 'init_execute_mixin'):
|
||||||
|
# Instance with 'ExecuteMixin'
|
||||||
|
self.init_execute_mixin(*args, **kwargs) # pylint: disable=E1101
|
||||||
self.network_api = network.API(config_group_name=network_config_group)
|
self.network_api = network.API(config_group_name=network_config_group)
|
||||||
|
|
||||||
|
def _validate_driver_mode(self, mode):
|
||||||
|
valid = constants.VALID_SHARE_DRIVER_MODES
|
||||||
|
if mode not in valid:
|
||||||
|
data = {'mode': mode, 'valid': valid}
|
||||||
|
msg = ("Provided unsupported driver mode '%(mode)s'. List of "
|
||||||
|
"valid driver modes is %(valid)s." % data)
|
||||||
|
LOG.error(msg)
|
||||||
|
raise exception.InvalidParameterValue(msg)
|
||||||
|
return mode
|
||||||
|
|
||||||
|
def get_driver_mode(self, supported_driver_modes):
|
||||||
|
"""Verify and return driver mode.
|
||||||
|
|
||||||
|
Call this method within share driver to get value for 'mode' attr,
|
||||||
|
|
||||||
|
:param supported_driver_modes: list of supported modes by share driver,
|
||||||
|
see list of available values in
|
||||||
|
manila.common.constants.VALID_SHARE_DRIVER_MODES
|
||||||
|
:returns: text_type -- name of enabled driver mode.
|
||||||
|
:raises: exception.InvalidParameterValue
|
||||||
|
"""
|
||||||
|
msg = None
|
||||||
|
if not len(supported_driver_modes):
|
||||||
|
msg = "At least one mode should be supported by share driver."
|
||||||
|
elif self.mode:
|
||||||
|
if self.mode not in supported_driver_modes:
|
||||||
|
data = {'mode': self.mode, 'supported': supported_driver_modes}
|
||||||
|
msg = ("Unsupported driver mode '%(mode)s' is provided. "
|
||||||
|
"List of supported is %(supported)s." % data)
|
||||||
|
else:
|
||||||
|
return self._validate_driver_mode(self.mode)
|
||||||
|
elif len(supported_driver_modes) > 1:
|
||||||
|
msg = ("Driver mode was not specified explicitly and amount of "
|
||||||
|
"supported driver modes %s is bigger than one, please "
|
||||||
|
"specify it using config option 'share_driver_mode'." %
|
||||||
|
six.text_type(supported_driver_modes))
|
||||||
|
|
||||||
|
if msg:
|
||||||
|
LOG.error(msg)
|
||||||
|
raise exception.InvalidParameterValue(msg)
|
||||||
|
return self._validate_driver_mode(supported_driver_modes[0])
|
||||||
|
|
||||||
def create_share(self, context, share, share_server=None):
|
def create_share(self, context, share, share_server=None):
|
||||||
"""Is called to create share."""
|
"""Is called to create share."""
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
@ -114,6 +114,7 @@ class GenericShareDriver(driver.ExecuteMixin, driver.ShareDriver):
|
|||||||
self.db = db
|
self.db = db
|
||||||
self.configuration.append_config_values(share_opts)
|
self.configuration.append_config_values(share_opts)
|
||||||
self.configuration.append_config_values(service_instance.server_opts)
|
self.configuration.append_config_values(service_instance.server_opts)
|
||||||
|
self.mode = self.get_driver_mode([const.MULTI_SVM_MODE, ])
|
||||||
self._helpers = {}
|
self._helpers = {}
|
||||||
self.backend_name = self.configuration.safe_get(
|
self.backend_name = self.configuration.safe_get(
|
||||||
'share_backend_name') or "Cinder_Volumes"
|
'share_backend_name') or "Cinder_Volumes"
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
import mock
|
import mock
|
||||||
|
|
||||||
|
from manila.common import constants
|
||||||
from manila.openstack.common import log as logging
|
from manila.openstack.common import log as logging
|
||||||
from manila.share import driver
|
from manila.share import driver
|
||||||
|
|
||||||
@ -28,6 +29,7 @@ class FakeShareDriver(driver.ShareDriver):
|
|||||||
super(FakeShareDriver, self).__init__(execute=self.fake_execute,
|
super(FakeShareDriver, self).__init__(execute=self.fake_execute,
|
||||||
*args, **kwargs)
|
*args, **kwargs)
|
||||||
self.db = mock.Mock()
|
self.db = mock.Mock()
|
||||||
|
self.mode = constants.MULTI_SVM_MODE
|
||||||
|
|
||||||
def share_network_update(*args, **kwargs):
|
def share_network_update(*args, **kwargs):
|
||||||
pass
|
pass
|
||||||
|
@ -878,6 +878,34 @@ class GenericShareDriverTestCase(test.TestCase):
|
|||||||
)
|
)
|
||||||
self.assertEqual(ssh_output, result)
|
self.assertEqual(ssh_output, result)
|
||||||
|
|
||||||
|
@mock.patch.object(
|
||||||
|
generic.service_instance, 'ServiceInstanceManager', mock.Mock())
|
||||||
|
def test_driver_mode_valid_value(self):
|
||||||
|
mode = const.MULTI_SVM_MODE
|
||||||
|
CONF.set_override('share_driver_mode', mode)
|
||||||
|
|
||||||
|
driver = generic.GenericShareDriver(
|
||||||
|
self._db, execute=self._execute, configuration=self.fake_conf)
|
||||||
|
|
||||||
|
self.assertEqual(mode, driver.mode)
|
||||||
|
generic.service_instance.ServiceInstanceManager.\
|
||||||
|
assert_called_once_with(self._db, driver_config=self.fake_conf)
|
||||||
|
|
||||||
|
def test_driver_mode_invalid_value(self):
|
||||||
|
mode = const.SINGLE_SVM_MODE
|
||||||
|
CONF.set_override('share_driver_mode', mode)
|
||||||
|
|
||||||
|
self.assertRaises(
|
||||||
|
exception.InvalidParameterValue,
|
||||||
|
generic.GenericShareDriver,
|
||||||
|
self._db,
|
||||||
|
execute=self._execute,
|
||||||
|
configuration=self.fake_conf)
|
||||||
|
|
||||||
|
def test_driver_mode_default_share_driver_modes(self):
|
||||||
|
mode = const.MULTI_SVM_MODE
|
||||||
|
self.assertEqual(mode, self._driver.mode)
|
||||||
|
|
||||||
|
|
||||||
class NFSHelperTestCase(test.TestCase):
|
class NFSHelperTestCase(test.TestCase):
|
||||||
"""Test case for NFS helper of generic driver."""
|
"""Test case for NFS helper of generic driver."""
|
||||||
|
@ -19,6 +19,7 @@ import time
|
|||||||
|
|
||||||
import mock
|
import mock
|
||||||
|
|
||||||
|
from manila.common import constants
|
||||||
from manila import exception
|
from manila import exception
|
||||||
from manila import network
|
from manila import network
|
||||||
from manila.share import configuration
|
from manila.share import configuration
|
||||||
@ -35,6 +36,10 @@ def fake_sleep(duration):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ShareDriverWithExecuteMixin(driver.ShareDriver, driver.ExecuteMixin):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class ShareDriverTestCase(test.TestCase):
|
class ShareDriverTestCase(test.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
@ -45,7 +50,7 @@ class ShareDriverTestCase(test.TestCase):
|
|||||||
self.stubs.Set(self.time, 'sleep', fake_sleep)
|
self.stubs.Set(self.time, 'sleep', fake_sleep)
|
||||||
|
|
||||||
def test__try_execute(self):
|
def test__try_execute(self):
|
||||||
execute_mixin = driver.ExecuteMixin(
|
execute_mixin = ShareDriverWithExecuteMixin(
|
||||||
configuration=configuration.Configuration(None))
|
configuration=configuration.Configuration(None))
|
||||||
self.assertRaises(exception.ProcessExecutionError,
|
self.assertRaises(exception.ProcessExecutionError,
|
||||||
execute_mixin._try_execute)
|
execute_mixin._try_execute)
|
||||||
@ -67,6 +72,8 @@ class ShareDriverTestCase(test.TestCase):
|
|||||||
else:
|
else:
|
||||||
network.API.assert_called_once_with(
|
network.API.assert_called_once_with(
|
||||||
config_group_name=config.config_group)
|
config_group_name=config.config_group)
|
||||||
|
self.assertTrue(hasattr(share_driver, 'mode'))
|
||||||
|
return share_driver
|
||||||
|
|
||||||
def test_instantiate_share_driver(self):
|
def test_instantiate_share_driver(self):
|
||||||
self._instantiate_share_driver(None)
|
self._instantiate_share_driver(None)
|
||||||
@ -81,3 +88,79 @@ class ShareDriverTestCase(test.TestCase):
|
|||||||
|
|
||||||
self.assertEqual(None, share_driver.configuration)
|
self.assertEqual(None, share_driver.configuration)
|
||||||
network.API.assert_called_once_with(config_group_name=None)
|
network.API.assert_called_once_with(config_group_name=None)
|
||||||
|
|
||||||
|
def test_get_driver_mode_empty_list(self):
|
||||||
|
share_driver = self._instantiate_share_driver(None)
|
||||||
|
self.assertRaises(
|
||||||
|
exception.InvalidParameterValue,
|
||||||
|
share_driver.get_driver_mode, [])
|
||||||
|
|
||||||
|
def test_get_driver_mode_one_value_in_list_mode_is_not_set(self):
|
||||||
|
share_driver = self._instantiate_share_driver(None)
|
||||||
|
share_driver.mode = None
|
||||||
|
|
||||||
|
mode = share_driver.get_driver_mode([constants.SINGLE_SVM_MODE, ])
|
||||||
|
|
||||||
|
self.assertEqual(constants.SINGLE_SVM_MODE, mode)
|
||||||
|
|
||||||
|
def test_get_driver_mode_one_value_in_list_mode_is_set_and_equal(self):
|
||||||
|
share_driver = self._instantiate_share_driver(None)
|
||||||
|
share_driver.mode = constants.SINGLE_SVM_MODE
|
||||||
|
|
||||||
|
mode = share_driver.get_driver_mode([constants.SINGLE_SVM_MODE, ])
|
||||||
|
|
||||||
|
self.assertEqual(constants.SINGLE_SVM_MODE, mode)
|
||||||
|
|
||||||
|
def test_get_driver_mode_one_value_in_list_mode_is_set_and_not_equal(self):
|
||||||
|
share_driver = self._instantiate_share_driver(None)
|
||||||
|
share_driver.mode = constants.SINGLE_SVM_MODE
|
||||||
|
|
||||||
|
self.assertRaises(
|
||||||
|
exception.InvalidParameterValue,
|
||||||
|
share_driver.get_driver_mode,
|
||||||
|
[constants.MULTI_SVM_MODE, ])
|
||||||
|
|
||||||
|
def test_get_driver_mode_two_values_in_list_mode_is_not_set(self):
|
||||||
|
share_driver = self._instantiate_share_driver(None)
|
||||||
|
share_driver.mode = None
|
||||||
|
|
||||||
|
self.assertRaises(
|
||||||
|
exception.InvalidParameterValue,
|
||||||
|
share_driver.get_driver_mode,
|
||||||
|
[constants.SINGLE_SVM_MODE, constants.MULTI_SVM_MODE])
|
||||||
|
|
||||||
|
def test_get_driver_mode_two_values_in_list_mode_is_set(self):
|
||||||
|
share_driver = self._instantiate_share_driver(None)
|
||||||
|
share_driver.mode = constants.MULTI_SVM_MODE
|
||||||
|
|
||||||
|
mode = share_driver.get_driver_mode(
|
||||||
|
[constants.SINGLE_SVM_MODE, constants.MULTI_SVM_MODE, ])
|
||||||
|
|
||||||
|
self.assertEqual(constants.MULTI_SVM_MODE, mode)
|
||||||
|
|
||||||
|
def test_get_driver_mode_one_invalid_value_in_list_mode_is_not_set(self):
|
||||||
|
share_driver = self._instantiate_share_driver(None)
|
||||||
|
share_driver.mode = None
|
||||||
|
|
||||||
|
self.assertRaises(
|
||||||
|
exception.InvalidParameterValue,
|
||||||
|
share_driver.get_driver_mode,
|
||||||
|
['fake', ])
|
||||||
|
|
||||||
|
def test_get_driver_mode_one_valid_value_in_list_mode_is_invalid(self):
|
||||||
|
share_driver = self._instantiate_share_driver(None)
|
||||||
|
share_driver.mode = 'fake'
|
||||||
|
|
||||||
|
self.assertRaises(
|
||||||
|
exception.InvalidParameterValue,
|
||||||
|
share_driver.get_driver_mode,
|
||||||
|
[constants.MULTI_SVM_MODE, ])
|
||||||
|
|
||||||
|
def test_get_driver_mode_two_values_in_list_invalid_mode_set(self):
|
||||||
|
share_driver = self._instantiate_share_driver(None)
|
||||||
|
share_driver.mode = 'fake'
|
||||||
|
|
||||||
|
self.assertRaises(
|
||||||
|
exception.InvalidParameterValue,
|
||||||
|
share_driver.get_driver_mode,
|
||||||
|
[constants.SINGLE_SVM_MODE, constants.MULTI_SVM_MODE, ])
|
||||||
|
Loading…
Reference in New Issue
Block a user