Created
May 5, 2016 23:31
-
-
Save patrick-east/afed6c0e68da1a11f1ab85f19a46cb34 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/cinder/volume/driver.py b/cinder/volume/driver.py | |
index 0da9e26..6e1f7a5 100644 | |
--- a/cinder/volume/driver.py | |
+++ b/cinder/volume/driver.py | |
@@ -30,6 +30,7 @@ from cinder.i18n import _, _LE, _LW | |
from cinder.image import image_utils | |
from cinder import objects | |
from cinder import utils | |
+from cinder.volume import driver_utils | |
from cinder.volume import rpcapi as volume_rpcapi | |
from cinder.volume import throttling | |
@@ -316,6 +317,9 @@ class BaseVD(object): | |
self.configuration.append_config_values(iser_opts) | |
utils.setup_tracing(self.configuration.safe_get('trace_flags')) | |
+ self.driver_utils = driver_utils.VolumeDriverUtils( | |
+ self._driver_data_namespace(), self.db) | |
+ | |
self._execute = execute | |
self._stats = {} | |
self._throttle = None | |
@@ -337,6 +341,11 @@ class BaseVD(object): | |
# set True by manager after successful check_for_setup | |
self._initialized = False | |
+ def _driver_data_namespace(self): | |
+ return (self.configuration.safe_get('driver_data_namespace') or | |
+ self.configuration.safe_get('volume_backend_name') or | |
+ self.__class__.__name__) | |
+ | |
def _is_non_recoverable(self, err, non_recoverable_list): | |
for item in non_recoverable_list: | |
if item in err: | |
@@ -1486,26 +1495,13 @@ class BaseVD(object): | |
return | |
@abc.abstractmethod | |
- def initialize_connection(self, volume, connector, initiator_data=None): | |
+ def initialize_connection(self, volume, connector): | |
"""Allow connection to connector and return connection info. | |
:param volume: The volume to be attached | |
:param connector: Dictionary containing information about what is being | |
connected to. | |
- :param initiator_data (optional): A dictionary of | |
- driver_initiator_data | |
- objects with key-value pairs that | |
- have been saved for this initiator | |
- by a driver in previous | |
- initialize_connection calls. | |
- :returns conn_info: A dictionary of connection information. This can | |
- optionally include a "initiator_updates" field. | |
- | |
- The "initiator_updates" field must be a dictionary containing a | |
- "set_values" and/or "remove_values" field. The "set_values" field must | |
- be a dictionary of key-value pairs to be set/updated in the db. The | |
- "remove_values" field must be a list of keys, previously set with | |
- "set_values", that will be deleted from the db. | |
+ :returns conn_info: A dictionary of connection information. | |
""" | |
return | |
diff --git a/cinder/volume/driver_utils.py b/cinder/volume/driver_utils.py | |
new file mode 100644 | |
index 0000000..3cc634a | |
--- /dev/null | |
+++ b/cinder/volume/driver_utils.py | |
@@ -0,0 +1,65 @@ | |
+# Copyright (c) 2014 Pure Storage, Inc. | |
+# All Rights Reserved. | |
+# | |
+# Licensed under the Apache License, Version 2.0 (the "License"); you may | |
+# not use this file except in compliance with the License. You may obtain | |
+# a copy of the License at | |
+# | |
+# http://www.apache.org/licenses/LICENSE-2.0 | |
+# | |
+# Unless required by applicable law or agreed to in writing, software | |
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |
+# License for the specific language governing permissions and limitations | |
+# under the License. | |
+ | |
+import six | |
+ | |
+from oslo_log import log as logging | |
+ | |
+from cinder import context | |
+from cinder import exception | |
+from cinder.i18n import _, _LE | |
+ | |
+LOG = logging.getLogger(__name__) | |
+ | |
+ | |
+class VolumeDriverUtils(object): | |
+ def __init__(self, namespace, db): | |
+ self._data_namespace = namespace | |
+ self._db = db | |
+ | |
+ @staticmethod | |
+ def _get_context(ctxt): | |
+ if not ctxt: | |
+ return context.get_admin_context() | |
+ return ctxt | |
+ | |
+ def get_driver_initiator_data(self,initiator, ctxt=None): | |
+ try: | |
+ return self._db.driver_initiator_data_get( | |
+ self._get_context(ctxt), | |
+ initiator, | |
+ self._data_namespace | |
+ ) | |
+ except exception.CinderException: | |
+ LOG.exception(_LE("Failed to get driver initiator data for" | |
+ " initiator %(initiator)s and namespace" | |
+ " %(namespace)s"), | |
+ {'initiator': initiator, | |
+ 'namespace': self._data_namespace}) | |
+ raise | |
+ | |
+ def save_driver_initiator_data(self, initiator, model_update, ctxt=None): | |
+ try: | |
+ self._db.driver_initiator_data_update(ctxt, | |
+ initiator, | |
+ self._data_namespace, | |
+ model_update) | |
+ except exception.CinderException: | |
+ LOG.exception(_LE("Failed to update initiator data for" | |
+ " initiator %(initiator)s and backend" | |
+ " %(backend)s"), | |
+ {'initiator': initiator, | |
+ 'backend': self._data_namespace}) | |
+ raise | |
diff --git a/cinder/volume/drivers/pure.py b/cinder/volume/drivers/pure.py | |
index d6bbed9..a4496cb 100644 | |
--- a/cinder/volume/drivers/pure.py | |
+++ b/cinder/volume/drivers/pure.py | |
@@ -408,7 +408,7 @@ class PureBaseVolumeDriver(san.SanDriver): | |
def create_export(self, context, volume, connector): | |
pass | |
- def initialize_connection(self, volume, connector, initiator_data=None): | |
+ def initialize_connection(self, volume, connector): | |
"""Connect the volume to the specified initiator in Purity. | |
This implementation is specific to the host type (iSCSI, FC, etc). | |
@@ -1493,9 +1493,9 @@ class PureISCSIDriver(PureBaseVolumeDriver, san.SanISCSIDriver): | |
return None | |
@pure_driver_debug_trace | |
- def initialize_connection(self, volume, connector, initiator_data=None): | |
+ def initialize_connection(self, volume, connector): | |
"""Allow connection to connector and return connection info.""" | |
- connection = self._connect(volume, connector, initiator_data) | |
+ connection = self._connect(volume, connector) | |
target_ports = self._get_target_iscsi_ports() | |
multipath = connector.get("multipath", False) | |
@@ -1557,8 +1557,8 @@ class PureISCSIDriver(PureBaseVolumeDriver, san.SanISCSIDriver): | |
def _generate_chap_secret(): | |
return volume_utils.generate_password() | |
- @classmethod | |
- def _get_chap_credentials(cls, host, data): | |
+ def _get_chap_credentials(self, host): | |
+ data = self.driver_utils.get_driver_initator_data(host) | |
initiator_updates = None | |
username = host | |
password = None | |
@@ -1568,22 +1568,25 @@ class PureISCSIDriver(PureBaseVolumeDriver, san.SanISCSIDriver): | |
password = d["value"] | |
break | |
if not password: | |
- password = cls._generate_chap_secret() | |
+ password = self._generate_chap_secret() | |
initiator_updates = { | |
"set_values": { | |
CHAP_SECRET_KEY: password | |
} | |
} | |
- return username, password, initiator_updates | |
+ if initiator_updates: | |
+ self.driver_utils.save_driver_initiator_data(host, | |
+ initiator_updates) | |
+ return username, password | |
@utils.synchronized(CONNECT_LOCK_NAME, external=True) | |
- def _connect(self, volume, connector, initiator_data): | |
+ def _connect(self, volume, connector): | |
"""Connect the host and volume; return dict describing connection.""" | |
iqn = connector["initiator"] | |
if self.configuration.use_chap_auth: | |
- (chap_username, chap_password, initiator_update) = \ | |
- self._get_chap_credentials(connector['host'], initiator_data) | |
+ (chap_username, chap_password) = \ | |
+ self._get_chap_credentials(connector['host']) | |
current_array = self._get_current_array() | |
vol_name = self._get_vol_name(volume) | |
@@ -1663,7 +1666,7 @@ class PureFCDriver(PureBaseVolumeDriver, driver.FibreChannelDriver): | |
@fczm_utils.AddFCZone | |
@pure_driver_debug_trace | |
- def initialize_connection(self, volume, connector, initiator_data=None): | |
+ def initialize_connection(self, volume, connector): | |
"""Allow connection to connector and return connection info.""" | |
current_array = self._get_current_array() | |
connection = self._connect(volume, connector) | |
diff --git a/cinder/volume/drivers/solidfire.py b/cinder/volume/drivers/solidfire.py | |
index 4c93661..da771e4 100644 | |
--- a/cinder/volume/drivers/solidfire.py | |
+++ b/cinder/volume/drivers/solidfire.py | |
@@ -1650,14 +1650,12 @@ class SolidFireDriver(san.SanISCSIDriver): | |
results['thinProvisioningPercent']) | |
self.cluster_stats = data | |
- def initialize_connection(self, volume, connector, initiator_data=None): | |
+ def initialize_connection(self, volume, connector): | |
"""Initialize the connection and return connection info. | |
Optionally checks and utilizes volume access groups. | |
""" | |
- properties = self._sf_initialize_connection(volume, | |
- connector, | |
- initiator_data) | |
+ properties = self._sf_initialize_connection(volume, connector) | |
properties['data']['discard'] = True | |
return properties | |
@@ -1979,8 +1977,7 @@ class SolidFireISCSI(iscsi_driver.SanISCSITarget): | |
def terminate_connection(self, volume, connector, **kwargs): | |
pass | |
- def _sf_initialize_connection(self, volume, connector, | |
- initiator_data=None): | |
+ def _sf_initialize_connection(self, volume, connector): | |
"""Initialize the connection and return connection info. | |
Optionally checks and utilizes volume access groups. | |
diff --git a/cinder/volume/manager.py b/cinder/volume/manager.py | |
index aaf9ef9..03844b1 100644 | |
--- a/cinder/volume/manager.py | |
+++ b/cinder/volume/manager.py | |
@@ -1353,50 +1353,6 @@ class VolumeManager(manager.SchedulerDependentManager): | |
exc_info=True, resource={'type': 'image', | |
'id': image_id}) | |
- def _driver_data_namespace(self): | |
- return self.driver.configuration.safe_get('driver_data_namespace') \ | |
- or self.driver.configuration.safe_get('volume_backend_name') \ | |
- or self.driver.__class__.__name__ | |
- | |
- def _get_driver_initiator_data(self, context, connector): | |
- data = None | |
- initiator = connector.get('initiator', False) | |
- if initiator: | |
- if not isinstance(initiator, six.string_types): | |
- msg = _('Invalid initiator value received') | |
- raise exception.InvalidInput(reason=msg) | |
- namespace = self._driver_data_namespace() | |
- try: | |
- data = self.db.driver_initiator_data_get( | |
- context, | |
- initiator, | |
- namespace | |
- ) | |
- except exception.CinderException: | |
- LOG.exception(_LE("Failed to get driver initiator data for" | |
- " initiator %(initiator)s and namespace" | |
- " %(namespace)s"), | |
- {'initiator': initiator, | |
- 'namespace': namespace}) | |
- raise | |
- return data | |
- | |
- def _save_driver_initiator_data(self, context, connector, model_update): | |
- if connector.get('initiator', False) and model_update: | |
- namespace = self._driver_data_namespace() | |
- try: | |
- self.db.driver_initiator_data_update(context, | |
- connector['initiator'], | |
- namespace, | |
- model_update) | |
- except exception.CinderException: | |
- LOG.exception(_LE("Failed to update initiator data for" | |
- " initiator %(initiator)s and backend" | |
- " %(backend)s"), | |
- {'initiator': connector['initiator'], | |
- 'backend': namespace}) | |
- raise | |
- | |
def initialize_connection(self, context, volume_id, connector): | |
"""Prepare volume for connection from host represented by connector. | |
@@ -1467,15 +1423,8 @@ class VolumeManager(manager.SchedulerDependentManager): | |
LOG.exception(_LE("Model update failed."), resource=volume) | |
raise exception.ExportFailure(reason=six.text_type(ex)) | |
- initiator_data = self._get_driver_initiator_data(context, connector) | |
try: | |
- if initiator_data: | |
- conn_info = self.driver.initialize_connection(volume, | |
- connector, | |
- initiator_data) | |
- else: | |
- conn_info = self.driver.initialize_connection(volume, | |
- connector) | |
+ conn_info = self.driver.initialize_connection(volume, connector) | |
except Exception as err: | |
err_msg = (_("Driver initialize connection failed " | |
"(error: %(err)s).") % {'err': six.text_type(err)}) | |
@@ -1485,12 +1434,6 @@ class VolumeManager(manager.SchedulerDependentManager): | |
raise exception.VolumeBackendAPIException(data=err_msg) | |
- initiator_update = conn_info.get('initiator_update', None) | |
- if initiator_update: | |
- self._save_driver_initiator_data(context, connector, | |
- initiator_update) | |
- del conn_info['initiator_update'] | |
- | |
# Add qos_specs to connection info | |
typeid = volume['volume_type_id'] | |
specs = None |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment