Fix scheduled share creation with generic driver

Generic driver uses separate module service_instance for handling of Nova VMs.
If service m-shr starts and there are existing scheduled shares for creation,
then concurrent issue appears between method 'do_setup', that is called once
on start of service and 'ensure_server', that uses stuff from do_setup.

Main error is in following:
- "Returning exception 'GenericShareDriver' object has no attribute
  'service_instance_manager' to caller"

Changes:
- moved definition of attr 'service_instance_manager' to __init__ method.
- removed attrs '_helpers' and 'share_networks_servers' from
  ServiceInstanceManager as they are redundant.
- updated unittests according to changes.
- used direct import of 'constants' submodule for neutron api,
  to be able to access it on driver init step.
- replaced generic driver with common driver interface for inheritance
  by fake driver for unittests.

Change-Id: I0fe7f097dc03eade5e0d4dfdbda0eb49588f4dde
Closes-Bug: #1362985
Related-Bug: #1330391
This commit is contained in:
Valeriy Ponomaryov 2014-08-29 05:53:59 -04:00 committed by vponomaryov
parent 27313d68a3
commit 73b874bd74
6 changed files with 15 additions and 16 deletions

View File

@ -22,6 +22,7 @@ from manila import context
from manila.db import base
from manila import exception
from manila.network import neutron
from manila.network.neutron import constants as neutron_constants
from manila.openstack.common import log as logging
neutron_opts = [
@ -190,7 +191,7 @@ class API(base.Base):
def _has_port_binding_extension(self):
if not self.extensions:
self.extensions = self.list_extensions()
return neutron.constants.PORTBINDING_EXT in self.extensions
return neutron_constants.PORTBINDING_EXT in self.extensions
def router_create(self, tenant_id, name):
router_req_body = {'router': {}}

View File

@ -110,6 +110,9 @@ class GenericShareDriver(driver.ExecuteMixin, driver.ShareDriver):
self.backend_name = self.configuration.safe_get(
'share_backend_name') or "Cinder_Volumes"
self.ssh_connections = {}
self.service_instance_manager = (
service_instance.ServiceInstanceManager(
self.db, driver_config=self.configuration))
def _ssh_exec(self, server, command):
connection = self.ssh_connections.get(server['instance_id'])
@ -141,11 +144,6 @@ class GenericShareDriver(driver.ExecuteMixin, driver.ShareDriver):
super(GenericShareDriver, self).do_setup(context)
self.compute_api = compute.API()
self.volume_api = volume.API()
self.service_instance_manager = service_instance.\
ServiceInstanceManager(self.db, self._helpers,
driver_config=self.configuration)
self.share_networks_servers = (
self.service_instance_manager.share_networks_servers)
self._setup_helpers()
def _setup_helpers(self):

View File

@ -123,7 +123,7 @@ class ServiceInstanceManager(object):
value = CONF.get(key)
return value
def __init__(self, db, _helpers, *args, **kwargs):
def __init__(self, db, *args, **kwargs):
"""Do initialization."""
super(ServiceInstanceManager, self).__init__()
self.driver_config = None
@ -136,7 +136,6 @@ class ServiceInstanceManager(object):
self._execute = utils.execute
self.compute_api = compute.API()
self.neutron_api = neutron.API()
self._helpers = _helpers
self.db = db
attempts = 5
while attempts:
@ -150,7 +149,6 @@ class ServiceInstanceManager(object):
else:
raise exception.ServiceInstanceException(_('Can not receive '
'service tenant id.'))
self.share_networks_servers = {}
self.service_network_id = self._get_service_network()
self.vif_driver = importutils.import_class(
self.get_config_option("interface_driver"))()

View File

@ -13,13 +13,14 @@
# under the License.
from manila.openstack.common import log as logging
from manila.share.drivers import generic
from manila.share import driver
LOG = logging.getLogger(__name__)
class FakeShareDriver(generic.GenericShareDriver):
class FakeShareDriver(driver.ShareDriver):
"""Logs calls instead of executing."""
def __init__(self, *args, **kwargs):
super(FakeShareDriver, self).__init__(execute=self.fake_execute,
*args, **kwargs)

View File

@ -22,7 +22,7 @@ LOG = logging.getLogger(__name__)
class FakeServiceInstanceManager(object):
def __init__(self):
def __init__(self, *args, **kwargs):
self.db = mock.Mock()
self._helpers = {
'CIFS': mock.Mock(),

View File

@ -88,6 +88,8 @@ class GenericShareDriverTestCase(test.TestCase):
self._helper_nfs = mock.Mock()
self.fake_conf = manila.share.configuration.Configuration(None)
self._db = mock.Mock()
generic.service_instance.ServiceInstanceManager = (
fake_service_instance.FakeServiceInstanceManager)
self._driver = generic.GenericShareDriver(self._db,
execute=self._execute,
configuration=self.fake_conf)
@ -134,12 +136,11 @@ class GenericShareDriverTestCase(test.TestCase):
def test_do_setup(self):
self.stubs.Set(volume, 'API', mock.Mock())
self.stubs.Set(compute, 'API', mock.Mock())
self.stubs.Set(generic, 'service_instance', mock.Mock())
self.stubs.Set(self._driver, '_setup_helpers', mock.Mock())
self._driver.do_setup(self._context)
volume.API.assert_called_once()
compute.API.assert_called_once()
self._driver._setup_helpers.assert_called_once()
volume.API.assert_called_once_with()
compute.API.assert_called_once_with()
self._driver._setup_helpers.assert_called_once_with()
def test_setup_helpers(self):
self._driver._helpers = {}