Add driver interface checks
This is the start of an effort to both validate that drivers fully implement the expected minimum requirements as well as to create a clear place for driver developers to learn what needs to be implemented and get documentation explaining what is expected for each method. This also enables us to create tooling for documenting the available drivers and their capabilities, to some degree. A follow up patch will show some of what I'm thinking there, but it will make it possible to write scripts for different needs. This is somewhat a cleanup attempt to the ABC work that was started a while back. This does not aim to replace that effort, but give a mechanism for some of the things expected out of that effort that ended up not being possible with how it evolved. In most cases we do not really care if a driver is inherited from a certain base class, just that it conforms to the given interface. The interface/inheritance work really centers around two separate things: * Ensuring drivers conform to an expected interface * Allowing code reuse and common implementation This is really for the first item. Additional work is needed to complete the ABC work we've done, but that really focuses on the second item, and is out of scope for the intent of this patch. Change-Id: I4168225126fe88c31712d94f0a130e9e7ede3446
This commit is contained in:
parent
0f72ff555d
commit
e7b40242f8
@ -58,6 +58,7 @@ from six.moves import range
|
||||
from cinder.backup import driver
|
||||
from cinder import exception
|
||||
from cinder.i18n import _, _LE, _LI, _LW
|
||||
from cinder import interface
|
||||
from cinder import utils
|
||||
import cinder.volume.drivers.rbd as rbd_driver
|
||||
|
||||
@ -152,6 +153,7 @@ class VolumeMetadataBackup(object):
|
||||
self.name)
|
||||
|
||||
|
||||
@interface.backupdriver
|
||||
class CephBackupDriver(driver.BackupDriver):
|
||||
"""Backup Cinder volumes to Ceph Object Store.
|
||||
|
||||
|
@ -24,6 +24,7 @@ from oslo_config import cfg
|
||||
|
||||
from cinder.backup.drivers import posix
|
||||
from cinder import exception
|
||||
from cinder import interface
|
||||
from cinder import utils
|
||||
|
||||
|
||||
@ -41,6 +42,7 @@ CONF = cfg.CONF
|
||||
CONF.register_opts(glusterfsbackup_service_opts)
|
||||
|
||||
|
||||
@interface.backupdriver
|
||||
class GlusterfsBackupDriver(posix.PosixBackupDriver):
|
||||
"""Provides backup, restore and delete using GlusterFS repository."""
|
||||
|
||||
|
@ -42,6 +42,7 @@ import six
|
||||
from cinder.backup import chunkeddriver
|
||||
from cinder import exception
|
||||
from cinder.i18n import _
|
||||
from cinder import interface
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
@ -110,6 +111,7 @@ def gcs_logger(func):
|
||||
return func_wrapper
|
||||
|
||||
|
||||
@interface.backupdriver
|
||||
class GoogleBackupDriver(chunkeddriver.ChunkedBackupDriver):
|
||||
"""Provides backup, restore and delete of backup objects within GCS."""
|
||||
|
||||
|
@ -23,6 +23,7 @@ from oslo_log import log as logging
|
||||
from cinder.backup.drivers import posix
|
||||
from cinder import exception
|
||||
from cinder.i18n import _
|
||||
from cinder import interface
|
||||
from cinder import utils
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
@ -44,6 +45,7 @@ CONF = cfg.CONF
|
||||
CONF.register_opts(nfsbackup_service_opts)
|
||||
|
||||
|
||||
@interface.backupdriver
|
||||
class NFSBackupDriver(posix.PosixBackupDriver):
|
||||
"""Provides backup, restore and delete using NFS supplied repository."""
|
||||
|
||||
|
@ -26,6 +26,7 @@ from oslo_log import log as logging
|
||||
|
||||
from cinder.backup import chunkeddriver
|
||||
from cinder import exception
|
||||
from cinder import interface
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
@ -63,6 +64,7 @@ CONF = cfg.CONF
|
||||
CONF.register_opts(posixbackup_service_opts)
|
||||
|
||||
|
||||
@interface.backupdriver
|
||||
class PosixBackupDriver(chunkeddriver.ChunkedBackupDriver):
|
||||
"""Provides backup, restore and delete using a Posix file system."""
|
||||
|
||||
|
@ -56,6 +56,7 @@ from cinder.backup import chunkeddriver
|
||||
from cinder import exception
|
||||
from cinder.i18n import _
|
||||
from cinder.i18n import _LE
|
||||
from cinder import interface
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
@ -138,6 +139,7 @@ CONF = cfg.CONF
|
||||
CONF.register_opts(swiftbackup_service_opts)
|
||||
|
||||
|
||||
@interface.backupdriver
|
||||
class SwiftBackupDriver(chunkeddriver.ChunkedBackupDriver):
|
||||
"""Provides backup, restore and delete of backup objects within Swift."""
|
||||
|
||||
|
@ -36,6 +36,7 @@ from oslo_log import log as logging
|
||||
from cinder.backup import driver
|
||||
from cinder import exception
|
||||
from cinder.i18n import _LE, _
|
||||
from cinder import interface
|
||||
from cinder import utils
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
@ -259,6 +260,7 @@ def _cleanup_device_hardlink(hardlink_path, volume_path, volume_id):
|
||||
'err': exc.stderr})
|
||||
|
||||
|
||||
@interface.backupdriver
|
||||
class TSMBackupDriver(driver.BackupDriver):
|
||||
"""Provides backup, restore and delete of volumes backup for TSM."""
|
||||
|
||||
|
37
cinder/interface/__init__.py
Normal file
37
cinder/interface/__init__.py
Normal file
@ -0,0 +1,37 @@
|
||||
# Copyright 2016 Dell 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.
|
||||
#
|
||||
|
||||
_volume_register = []
|
||||
_backup_register = []
|
||||
_fczm_register = []
|
||||
|
||||
|
||||
def volumedriver(cls):
|
||||
"""Decorator for concrete volume driver implementations."""
|
||||
_volume_register.append(cls)
|
||||
return cls
|
||||
|
||||
|
||||
def backupdriver(cls):
|
||||
"""Decorator for concrete backup driver implementations."""
|
||||
_backup_register.append(cls)
|
||||
return cls
|
||||
|
||||
|
||||
def fczmdriver(cls):
|
||||
"""Decorator for concrete fibre channel zone manager drivers."""
|
||||
_fczm_register.append(cls)
|
||||
return cls
|
79
cinder/interface/backup_chunked_driver.py
Normal file
79
cinder/interface/backup_chunked_driver.py
Normal file
@ -0,0 +1,79 @@
|
||||
# Copyright 2016 Dell 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.
|
||||
#
|
||||
|
||||
"""
|
||||
Backup driver with 'chunked' backup operations.
|
||||
"""
|
||||
|
||||
from cinder.interface import backup_driver
|
||||
|
||||
|
||||
class BackupDriverWithVerify(backup_driver.BackupDriver):
|
||||
"""Backup driver that supports 'chunked' backups."""
|
||||
|
||||
def put_container(self, container):
|
||||
"""Create the container if needed. No failure if it pre-exists.
|
||||
|
||||
:param container: The container to write into.
|
||||
"""
|
||||
|
||||
def get_container_entries(self, container, prefix):
|
||||
"""Get container entry names.
|
||||
|
||||
:param container: The container from which to get entries.
|
||||
:param prefix: The prefix used to match entries.
|
||||
"""
|
||||
|
||||
def get_object_writer(self, container, object_name, extra_metadata=None):
|
||||
"""Returns a writer which stores the chunk data in backup repository.
|
||||
|
||||
:param container: The container to write to.
|
||||
:param object_name: The object name to write.
|
||||
:param extra_metadata: Extra metadata to be included.
|
||||
:returns: A context handler that can be used in a "with" context.
|
||||
"""
|
||||
|
||||
def get_object_reader(self, container, object_name, extra_metadata=None):
|
||||
"""Returns a reader object for the backed up chunk.
|
||||
|
||||
:param container: The container to read from.
|
||||
:param object_name: The object name to read.
|
||||
:param extra_metadata: Extra metadata to be included.
|
||||
"""
|
||||
|
||||
def delete_object(self, container, object_name):
|
||||
"""Delete object from container.
|
||||
|
||||
:param container: The container to modify.
|
||||
:param object_name: The object name delete.
|
||||
"""
|
||||
|
||||
def update_container_name(self, backup, container):
|
||||
"""Allows sub-classes to override container name.
|
||||
|
||||
This method exists so that sub-classes can override the container name
|
||||
as it comes in to the driver in the backup object. Implementations
|
||||
should return None if no change to the container name is desired.
|
||||
"""
|
||||
|
||||
def get_extra_metadata(self, backup, volume):
|
||||
"""Return extra metadata to use in prepare_backup.
|
||||
|
||||
This method allows for collection of extra metadata in prepare_backup()
|
||||
which will be passed to get_object_reader() and get_object_writer().
|
||||
Subclass extensions can use this extra information to optimize
|
||||
data transfers. Return a json serializable object.
|
||||
"""
|
111
cinder/interface/backup_driver.py
Normal file
111
cinder/interface/backup_driver.py
Normal file
@ -0,0 +1,111 @@
|
||||
# Copyright 2016 Dell 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.
|
||||
#
|
||||
|
||||
"""
|
||||
Core backup driver interface.
|
||||
|
||||
All backup drivers should support this interface as a bare minimum.
|
||||
"""
|
||||
|
||||
from cinder.interface import base
|
||||
|
||||
|
||||
class BackupDriver(base.CinderInterface):
|
||||
"""Backup driver required interface."""
|
||||
|
||||
def get_metadata(self, volume_id):
|
||||
"""Get volume metadata.
|
||||
|
||||
Returns a json-encoded dict containing all metadata and the restore
|
||||
version i.e. the version used to decide what actually gets restored
|
||||
from this container when doing a backup restore.
|
||||
|
||||
Typically best to use py:class:`BackupMetadataAPI` for this.
|
||||
|
||||
:param volume_id: The ID of the volume.
|
||||
:returns: json-encoded dict of metadata.
|
||||
"""
|
||||
|
||||
def put_metadata(self, volume_id, json_metadata):
|
||||
"""Set volume metadata.
|
||||
|
||||
Typically best to use py:class:`BackupMetadataAPI` for this.
|
||||
|
||||
:param volume_id: The ID of the volume.
|
||||
:param json_metadata: The json-encoded dict of metadata.
|
||||
"""
|
||||
|
||||
def backup(self, backup, volume_file, backup_metadata=False):
|
||||
"""Start a backup of a specified volume.
|
||||
|
||||
If backup['parent_id'] is given, then an incremental backup
|
||||
should be performed is supported.
|
||||
|
||||
If the parent backup is a different size, a full backup should be
|
||||
performed to ensure all data is included.
|
||||
|
||||
TODO(smcginnis) Document backup variable structure.
|
||||
|
||||
:param backup: The backup information.
|
||||
:param volume_file: The volume or file to write the backup to.
|
||||
:param backup_metadata: Whether to include volume metadata in the
|
||||
backup.
|
||||
"""
|
||||
|
||||
def restore(self, backup, volume_id, volume_file):
|
||||
"""Restore data from a backup.
|
||||
|
||||
:param backup: The backup information.
|
||||
:param volume_id: The volume to be restored.
|
||||
:param volume_file: The volume or file to read the data from.
|
||||
"""
|
||||
|
||||
def delete(self, backup):
|
||||
"""Delete a backup from the backup store.
|
||||
|
||||
:param backup: The backup to be deleted.
|
||||
"""
|
||||
|
||||
def export_record(self, backup):
|
||||
"""Export driver specific backup record information.
|
||||
|
||||
If backup backend needs additional driver specific information to
|
||||
import backup record back into the system it must overwrite this method
|
||||
and return it here as a dictionary so it can be serialized into a
|
||||
string.
|
||||
|
||||
Default backup driver implementation has no extra information.
|
||||
|
||||
:param backup: backup object to export
|
||||
:returns: driver_info - dictionary with extra information
|
||||
"""
|
||||
|
||||
def import_record(self, backup, driver_info):
|
||||
"""Import driver specific backup record information.
|
||||
|
||||
If backup backend needs additional driver specific information to
|
||||
import backup record back into the system it must overwrite this method
|
||||
since it will be called with the extra information that was provided by
|
||||
export_record when exporting the backup.
|
||||
|
||||
Default backup driver implementation does nothing since it didn't
|
||||
export any specific data in export_record.
|
||||
|
||||
:param backup: backup object to export
|
||||
:param driver_info: dictionary with driver specific backup record
|
||||
information
|
||||
:returns: nothing
|
||||
"""
|
38
cinder/interface/backup_verify_driver.py
Normal file
38
cinder/interface/backup_verify_driver.py
Normal file
@ -0,0 +1,38 @@
|
||||
# Copyright 2016 Dell 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.
|
||||
#
|
||||
|
||||
"""
|
||||
Backup driver with verification interface.
|
||||
|
||||
Used for backup drivers that support the option to verify the backup after
|
||||
completion.
|
||||
"""
|
||||
|
||||
from cinder.interface import backup_driver
|
||||
|
||||
|
||||
class BackupDriverWithVerify(backup_driver.BackupDriver):
|
||||
"""Backup driver that supports the optional verification."""
|
||||
|
||||
def verify(self, backup):
|
||||
"""Verify that the backup exists on the backend.
|
||||
|
||||
Verify that the backup is OK, possibly following an import record
|
||||
operation.
|
||||
|
||||
:param backup: Backup id of the backup to verify.
|
||||
:raises: InvalidBackup, NotImplementedError
|
||||
"""
|
105
cinder/interface/base.py
Normal file
105
cinder/interface/base.py
Normal file
@ -0,0 +1,105 @@
|
||||
# Copyright 2016 Dell 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 abc
|
||||
import inspect
|
||||
|
||||
import six
|
||||
|
||||
|
||||
def _get_arg_count(method):
|
||||
"""Get the number of args for a method.
|
||||
|
||||
:param method: The method to check.
|
||||
:returns: The number of args for the method.
|
||||
"""
|
||||
if not method:
|
||||
return 0
|
||||
|
||||
arg_spec = inspect.getargspec(method)
|
||||
return len(arg_spec[0])
|
||||
|
||||
|
||||
def _get_method_info(cls):
|
||||
"""Get all methods defined in a class.
|
||||
|
||||
Note: This will only return public methods and their associated arg count.
|
||||
|
||||
:param cls: The class to inspect.
|
||||
:returns: `Dict` of method names with a tuple of the method and their arg
|
||||
counts.
|
||||
"""
|
||||
result = {}
|
||||
|
||||
methods = inspect.getmembers(cls, inspect.ismethod)
|
||||
for (name, method) in methods:
|
||||
if name.startswith('_'):
|
||||
# Skip non-public methods
|
||||
continue
|
||||
result[name] = (method, _get_arg_count(method))
|
||||
|
||||
return result
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class CinderInterface(object):
|
||||
"""Interface base class for Cinder.
|
||||
|
||||
Cinder interfaces should inherit from this class to support indirect
|
||||
inheritance evaluation.
|
||||
|
||||
This can be used to validate compliance to an interface without requiring
|
||||
that the class actually be inherited from the same base class.
|
||||
"""
|
||||
|
||||
_method_cache = None
|
||||
|
||||
@classmethod
|
||||
def _get_methods(cls):
|
||||
if not cls._method_cache:
|
||||
cls._method_cache = _get_method_info(cls)
|
||||
return cls._method_cache
|
||||
|
||||
@classmethod
|
||||
def __subclasshook__(cls, other_cls):
|
||||
"""Custom class inheritance evaluation.
|
||||
|
||||
:param cls: The CinderInterface to check against.
|
||||
:param other_cls: The class to be checked if it implements
|
||||
our interface.
|
||||
"""
|
||||
interface_methods = cls._get_methods()
|
||||
driver_methods = _get_method_info(other_cls)
|
||||
|
||||
interface_keys = interface_methods.keys()
|
||||
driver_keys = driver_methods.keys()
|
||||
|
||||
matching_count = len(set(interface_keys) & set(driver_keys))
|
||||
if matching_count != len(interface_keys):
|
||||
# Missing some methods, does not implement this interface or is
|
||||
# missing something.
|
||||
return NotImplemented
|
||||
|
||||
# TODO(smcginnis) Add method signature checking.
|
||||
# We know all methods are there, now make sure they look right.
|
||||
# Unfortunately the methods can be obfuscated by certain decorators,
|
||||
# so we need to find a better way to pull out the real method
|
||||
# signatures.
|
||||
# driver_methods[method_name][0].func_closure.cell_contents works
|
||||
# for most cases but not all.
|
||||
# AST might work instead of using introspect.
|
||||
|
||||
return True
|
78
cinder/interface/fczm_driver.py
Normal file
78
cinder/interface/fczm_driver.py
Normal file
@ -0,0 +1,78 @@
|
||||
# Copyright 2016 Dell 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.
|
||||
#
|
||||
|
||||
"""
|
||||
Core fibre channel zone manager driver interface.
|
||||
|
||||
All fczm drivers should support this interface as a bare minimum.
|
||||
"""
|
||||
|
||||
from cinder.interface import base
|
||||
|
||||
|
||||
class FibreChannelZoneManagerDriver(base.CinderInterface):
|
||||
"""FCZM driver required interface."""
|
||||
|
||||
def add_connection(self, fabric, initiator_target_map, host_name=None,
|
||||
storage_system=None):
|
||||
"""Add a new initiator<>target connection.
|
||||
|
||||
All implementing drivers should provide concrete implementation
|
||||
for this API.
|
||||
|
||||
:param fabric: Fabric name from cinder.conf file
|
||||
:param initiator_target_map: Mapping of initiator to list of targets
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
Example initiator_target_map:
|
||||
|
||||
{
|
||||
'10008c7cff523b01': ['20240002ac000a50', '20240002ac000a40']
|
||||
}
|
||||
|
||||
Note that WWPN can be in lower or upper case and can be ':'
|
||||
separated strings.
|
||||
"""
|
||||
|
||||
def delete_connection(self, fabric, initiator_target_map, host_name=None,
|
||||
storage_system=None):
|
||||
"""Delete an initiator<>target connection.
|
||||
|
||||
:param fabric: Fabric name from cinder.conf file
|
||||
:param initiator_target_map: Mapping of initiator to list of targets
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
Example initiator_target_map:
|
||||
|
||||
{
|
||||
'10008c7cff523b01': ['20240002ac000a50', '20240002ac000a40']
|
||||
}
|
||||
|
||||
Note that WWPN can be in lower or upper case and can be ':'
|
||||
separated strings.
|
||||
"""
|
||||
|
||||
def get_san_context(self, target_wwn_list):
|
||||
"""Get SAN context for end devices.
|
||||
|
||||
:param target_wwn_list: Mapping of initiator to list of targets
|
||||
|
||||
Example initiator_target_map: ['20240002ac000a50', '20240002ac000a40']
|
||||
Note that WWPN can be in lower or upper case and can be
|
||||
':' separated strings.
|
||||
"""
|
78
cinder/interface/util.py
Normal file
78
cinder/interface/util.py
Normal file
@ -0,0 +1,78 @@
|
||||
# Copyright 2016 Dell 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 fnmatch
|
||||
import inspect
|
||||
import os
|
||||
|
||||
from cinder import interface
|
||||
|
||||
|
||||
def _ensure_loaded(start_path):
|
||||
"""Loads everything in a given path.
|
||||
|
||||
This will make sure all classes have been loaded and therefore all
|
||||
decorators have registered class.
|
||||
|
||||
:param start_path: The starting path to load.
|
||||
"""
|
||||
for root, folder, files in os.walk(start_path):
|
||||
for phile in fnmatch.filter(files, '*.py'):
|
||||
path = os.path.join(root, phile)
|
||||
try:
|
||||
__import__(
|
||||
path.replace('/', '.')[:-3], globals(), locals())
|
||||
except Exception:
|
||||
# Really don't care here
|
||||
pass
|
||||
|
||||
|
||||
def get_volume_drivers():
|
||||
"""Get a list of all volume drivers."""
|
||||
_ensure_loaded('cinder/volume/drivers')
|
||||
return [DriverInfo(x) for x in interface._volume_register]
|
||||
|
||||
|
||||
def get_backup_drivers():
|
||||
"""Get a list of all backup drivers."""
|
||||
_ensure_loaded('cinder/backup/drivers')
|
||||
return [DriverInfo(x) for x in interface._backup_register]
|
||||
|
||||
|
||||
def get_fczm_drivers():
|
||||
"""Get a list of all fczm drivers."""
|
||||
_ensure_loaded('cinder/zonemanager/drivers')
|
||||
return [DriverInfo(x) for x in interface._fczm_register]
|
||||
|
||||
|
||||
class DriverInfo(object):
|
||||
"""Information about driver implementations."""
|
||||
|
||||
def __init__(self, cls):
|
||||
self.cls = cls
|
||||
self.desc = cls.__doc__
|
||||
self.class_name = cls.__name__
|
||||
self.class_fqn = '{}.{}'.format(inspect.getmodule(cls).__name__,
|
||||
self.class_name)
|
||||
self.version = getattr(cls, 'VERSION', None)
|
||||
|
||||
def __str__(self):
|
||||
return self.class_name
|
||||
|
||||
def __repr__(self):
|
||||
return self.class_fqn
|
||||
|
||||
def __hash__(self):
|
||||
return hash(self.class_fqn)
|
231
cinder/interface/volume_consistencygroup_driver.py
Normal file
231
cinder/interface/volume_consistencygroup_driver.py
Normal file
@ -0,0 +1,231 @@
|
||||
# Copyright 2016 Dell 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.
|
||||
#
|
||||
|
||||
"""
|
||||
Consistency group volume driver interface.
|
||||
"""
|
||||
|
||||
from cinder.interface import base
|
||||
|
||||
|
||||
class VolumeConsistencyGroupDriver(base.CinderInterface):
|
||||
"""Interface for drivers that support consistency groups."""
|
||||
|
||||
def create_consistencygroup(self, context, group):
|
||||
"""Creates a consistencygroup.
|
||||
|
||||
:param context: the context of the caller.
|
||||
:param group: the dictionary of the consistency group to be created.
|
||||
:returns: model_update
|
||||
|
||||
model_update will be in this format: {'status': xxx, ......}.
|
||||
|
||||
If the status in model_update is 'error', the manager will throw
|
||||
an exception and it will be caught in the try-except block in the
|
||||
manager. If the driver throws an exception, the manager will also
|
||||
catch it in the try-except block. The group status in the db will
|
||||
be changed to 'error'.
|
||||
|
||||
For a successful operation, the driver can either build the
|
||||
model_update and return it or return None. The group status will
|
||||
be set to 'available'.
|
||||
"""
|
||||
|
||||
def create_consistencygroup_from_src(self, context, group, volumes,
|
||||
cgsnapshot=None, snapshots=None,
|
||||
source_cg=None, source_vols=None):
|
||||
"""Creates a consistencygroup from source.
|
||||
|
||||
:param context: the context of the caller.
|
||||
:param group: the dictionary of the consistency group to be created.
|
||||
:param volumes: a list of volume dictionaries in the group.
|
||||
:param cgsnapshot: the dictionary of the cgsnapshot as source.
|
||||
:param snapshots: a list of snapshot dictionaries in the cgsnapshot.
|
||||
:param source_cg: the dictionary of a consistency group as source.
|
||||
:param source_vols: a list of volume dictionaries in the source_cg.
|
||||
:returns: model_update, volumes_model_update
|
||||
|
||||
The source can be cgsnapshot or a source cg.
|
||||
|
||||
param volumes is retrieved directly from the db. It is a list of
|
||||
cinder.db.sqlalchemy.models.Volume to be precise. It cannot be
|
||||
assigned to volumes_model_update. volumes_model_update is a list of
|
||||
dictionaries. It has to be built by the driver. An entry will be
|
||||
in this format: {'id': xxx, 'status': xxx, ......}. model_update
|
||||
will be in this format: {'status': xxx, ......}.
|
||||
|
||||
To be consistent with other volume operations, the manager will
|
||||
assume the operation is successful if no exception is thrown by
|
||||
the driver. For a successful operation, the driver can either build
|
||||
the model_update and volumes_model_update and return them or
|
||||
return None, None.
|
||||
"""
|
||||
|
||||
def delete_consistencygroup(self, context, group, volumes):
|
||||
"""Deletes a consistency group.
|
||||
|
||||
:param context: the context of the caller.
|
||||
:param group: the dictionary of the consistency group to be deleted.
|
||||
:param volumes: a list of volume dictionaries in the group.
|
||||
:returns: model_update, volumes_model_update
|
||||
|
||||
param volumes is retrieved directly from the db. It is a list of
|
||||
cinder.db.sqlalchemy.models.Volume to be precise. It cannot be
|
||||
assigned to volumes_model_update. volumes_model_update is a list of
|
||||
dictionaries. It has to be built by the driver. An entry will be
|
||||
in this format: {'id': xxx, 'status': xxx, ......}. model_update
|
||||
will be in this format: {'status': xxx, ......}.
|
||||
|
||||
The driver should populate volumes_model_update and model_update
|
||||
and return them.
|
||||
|
||||
The manager will check volumes_model_update and update db accordingly
|
||||
for each volume. If the driver successfully deleted some volumes
|
||||
but failed to delete others, it should set statuses of the volumes
|
||||
accordingly so that the manager can update db correctly.
|
||||
|
||||
If the status in any entry of volumes_model_update is 'error_deleting'
|
||||
or 'error', the status in model_update will be set to the same if it
|
||||
is not already 'error_deleting' or 'error'.
|
||||
|
||||
If the status in model_update is 'error_deleting' or 'error', the
|
||||
manager will raise an exception and the status of the group will be
|
||||
set to 'error' in the db. If volumes_model_update is not returned by
|
||||
the driver, the manager will set the status of every volume in the
|
||||
group to 'error' in the except block.
|
||||
|
||||
If the driver raises an exception during the operation, it will be
|
||||
caught by the try-except block in the manager. The statuses of the
|
||||
group and all volumes in it will be set to 'error'.
|
||||
|
||||
For a successful operation, the driver can either build the
|
||||
model_update and volumes_model_update and return them or
|
||||
return None, None. The statuses of the group and all volumes
|
||||
will be set to 'deleted' after the manager deletes them from db.
|
||||
"""
|
||||
|
||||
def update_consistencygroup(self, context, group,
|
||||
add_volumes=None, remove_volumes=None):
|
||||
"""Updates a consistency group.
|
||||
|
||||
:param context: the context of the caller.
|
||||
:param group: the dictionary of the consistency group to be updated.
|
||||
:param add_volumes: a list of volume dictionaries to be added.
|
||||
:param remove_volumes: a list of volume dictionaries to be removed.
|
||||
:returns: model_update, add_volumes_update, remove_volumes_update
|
||||
|
||||
model_update is a dictionary that the driver wants the manager
|
||||
to update upon a successful return. If None is returned, the manager
|
||||
will set the status to 'available'.
|
||||
|
||||
add_volumes_update and remove_volumes_update are lists of dictionaries
|
||||
that the driver wants the manager to update upon a successful return.
|
||||
Note that each entry requires a {'id': xxx} so that the correct
|
||||
volume entry can be updated. If None is returned, the volume will
|
||||
remain its original status. Also note that you cannot directly
|
||||
assign add_volumes to add_volumes_update as add_volumes is a list of
|
||||
cinder.db.sqlalchemy.models.Volume objects and cannot be used for
|
||||
db update directly. Same with remove_volumes.
|
||||
|
||||
If the driver throws an exception, the status of the group as well as
|
||||
those of the volumes to be added/removed will be set to 'error'.
|
||||
"""
|
||||
|
||||
def create_cgsnapshot(self, context, cgsnapshot, snapshots):
|
||||
"""Creates a cgsnapshot.
|
||||
|
||||
:param context: the context of the caller.
|
||||
:param cgsnapshot: the dictionary of the cgsnapshot to be created.
|
||||
:param snapshots: a list of snapshot dictionaries in the cgsnapshot.
|
||||
:returns: model_update, snapshots_model_update
|
||||
|
||||
param snapshots is retrieved directly from the db. It is a list of
|
||||
cinder.db.sqlalchemy.models.Snapshot to be precise. It cannot be
|
||||
assigned to snapshots_model_update. snapshots_model_update is a list
|
||||
of dictionaries. It has to be built by the driver. An entry will be
|
||||
in this format: {'id': xxx, 'status': xxx, ......}. model_update
|
||||
will be in this format: {'status': xxx, ......}.
|
||||
|
||||
The driver should populate snapshots_model_update and model_update
|
||||
and return them.
|
||||
|
||||
The manager will check snapshots_model_update and update db accordingly
|
||||
for each snapshot. If the driver successfully deleted some snapshots
|
||||
but failed to delete others, it should set statuses of the snapshots
|
||||
accordingly so that the manager can update db correctly.
|
||||
|
||||
If the status in any entry of snapshots_model_update is 'error', the
|
||||
status in model_update will be set to the same if it is not already
|
||||
'error'.
|
||||
|
||||
If the status in model_update is 'error', the manager will raise an
|
||||
exception and the status of cgsnapshot will be set to 'error' in the
|
||||
db. If snapshots_model_update is not returned by the driver, the
|
||||
manager will set the status of every snapshot to 'error' in the except
|
||||
block.
|
||||
|
||||
If the driver raises an exception during the operation, it will be
|
||||
caught by the try-except block in the manager and the statuses of
|
||||
cgsnapshot and all snapshots will be set to 'error'.
|
||||
|
||||
For a successful operation, the driver can either build the
|
||||
model_update and snapshots_model_update and return them or
|
||||
return None, None. The statuses of cgsnapshot and all snapshots
|
||||
will be set to 'available' at the end of the manager function.
|
||||
"""
|
||||
|
||||
def delete_cgsnapshot(self, context, cgsnapshot, snapshots):
|
||||
"""Deletes a cgsnapshot.
|
||||
|
||||
:param context: the context of the caller.
|
||||
:param cgsnapshot: the dictionary of the cgsnapshot to be deleted.
|
||||
:param snapshots: a list of snapshot dictionaries in the cgsnapshot.
|
||||
:returns: model_update, snapshots_model_update
|
||||
|
||||
param snapshots is retrieved directly from the db. It is a list of
|
||||
cinder.db.sqlalchemy.models.Snapshot to be precise. It cannot be
|
||||
assigned to snapshots_model_update. snapshots_model_update is a list
|
||||
of dictionaries. It has to be built by the driver. An entry will be
|
||||
in this format: {'id': xxx, 'status': xxx, ......}. model_update
|
||||
will be in this format: {'status': xxx, ......}.
|
||||
|
||||
The driver should populate snapshots_model_update and model_update
|
||||
and return them.
|
||||
|
||||
The manager will check snapshots_model_update and update db accordingly
|
||||
for each snapshot. If the driver successfully deleted some snapshots
|
||||
but failed to delete others, it should set statuses of the snapshots
|
||||
accordingly so that the manager can update db correctly.
|
||||
|
||||
If the status in any entry of snapshots_model_update is
|
||||
'error_deleting' or 'error', the status in model_update will be set to
|
||||
the same if it is not already 'error_deleting' or 'error'.
|
||||
|
||||
If the status in model_update is 'error_deleting' or 'error', the
|
||||
manager will raise an exception and the status of cgsnapshot will be
|
||||
set to 'error' in the db. If snapshots_model_update is not returned by
|
||||
the driver, the manager will set the status of every snapshot to
|
||||
'error' in the except block.
|
||||
|
||||
If the driver raises an exception during the operation, it will be
|
||||
caught by the try-except block in the manager and the statuses of
|
||||
cgsnapshot and all snapshots will be set to 'error'.
|
||||
|
||||
For a successful operation, the driver can either build the
|
||||
model_update and snapshots_model_update and return them or
|
||||
return None, None. The statuses of cgsnapshot and all snapshots
|
||||
will be set to 'deleted' after the manager deletes them from db.
|
||||
"""
|
247
cinder/interface/volume_driver.py
Normal file
247
cinder/interface/volume_driver.py
Normal file
@ -0,0 +1,247 @@
|
||||
# Copyright 2016 Dell 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.
|
||||
#
|
||||
|
||||
"""
|
||||
Core backend volume driver interface.
|
||||
|
||||
All backend drivers should support this interface as a bare minimum.
|
||||
"""
|
||||
|
||||
from cinder.interface import base
|
||||
|
||||
|
||||
class VolumeDriverCore(base.CinderInterface):
|
||||
"""Core backend driver required interface."""
|
||||
|
||||
def do_setup(self, context):
|
||||
"""Any initialization the volume driver needs to do while starting.
|
||||
|
||||
Called once by the manager after the driver is loaded.
|
||||
Can be used to set up clients, check licenses, set up protocol
|
||||
specific helpers, etc.
|
||||
|
||||
:param context: The admin context.
|
||||
"""
|
||||
|
||||
def check_for_setup_error(self):
|
||||
"""Validate there are no issues with the driver configuration.
|
||||
|
||||
Called after do_setup(). Driver initialization can occur there or in
|
||||
this call, but must be complete by the time this returns.
|
||||
|
||||
If this method raises an exception, the driver will be left in an
|
||||
"uninitialized" state by the volume manager, which means that it will
|
||||
not be sent requests for volume operations.
|
||||
|
||||
This method typically checks things like whether the configured
|
||||
credentials can be used to log in the storage backend, and whether any
|
||||
external dependencies are present and working.
|
||||
|
||||
:raises: VolumeBackendAPIException in case of setup error.
|
||||
"""
|
||||
|
||||
def get_volume_stats(self, refresh=False):
|
||||
"""Collects volume backend stats.
|
||||
|
||||
The get_volume_stats method is used by the volume manager to collect
|
||||
information from the driver instance related to information about the
|
||||
driver, available and used space, and driver/backend capabilities.
|
||||
|
||||
It returns a dict with the following required fields:
|
||||
|
||||
* volume_backend_name
|
||||
This is an identifier for the backend taken from cinder.conf.
|
||||
Useful when using multi-backend.
|
||||
* vendor_name
|
||||
Vendor/author of the driver who serves as the contact for the
|
||||
driver's development and support.
|
||||
* driver_version
|
||||
The driver version is logged at cinder-volume startup and is useful
|
||||
for tying volume service logs to a specific release of the code.
|
||||
There are currently no rules for how or when this is updated, but
|
||||
it tends to follow typical major.minor.revision ideas.
|
||||
* storage_protocol
|
||||
The protocol used to connect to the storage, this should be a short
|
||||
string such as: "iSCSI", "FC", "nfs", "ceph", etc.
|
||||
* total_capacity_gb
|
||||
The total capacity in gigabytes (GiB) of the storage backend being
|
||||
used to store Cinder volumes.
|
||||
* free_capacity_gb
|
||||
The free capacity in gigabytes (GiB).
|
||||
|
||||
And the following optional fields:
|
||||
|
||||
* reserved_percentage (integer)
|
||||
Percentage of backend capacity which is not used by the scheduler.
|
||||
* location_info (string)
|
||||
Driver-specific information used by the driver and storage backend
|
||||
to correlate Cinder volumes and backend LUNs/files.
|
||||
* QoS_support (Boolean)
|
||||
Whether the backend supports quality of service.
|
||||
* provisioned_capacity_gb
|
||||
The total provisioned capacity on the storage backend, in gigabytes
|
||||
(GiB), including space consumed by any user other than Cinder
|
||||
itself.
|
||||
* max_over_subscription_ratio
|
||||
The maximum amount a backend can be over subscribed.
|
||||
* thin_provisioning_support (Boolean)
|
||||
Whether the backend is capable of allocating thinly provisioned
|
||||
volumes.
|
||||
* thick_provisioning_support (Boolean)
|
||||
Whether the backend is capable of allocating thick provisioned
|
||||
volumes. (Typically True.)
|
||||
* total_volumes (integer)
|
||||
Total number of volumes on the storage backend. This can be used in
|
||||
custom driver filter functions.
|
||||
* filter_function (string)
|
||||
A custom function used by the scheduler to determine whether a
|
||||
volume should be allocated to this backend or not. Example:
|
||||
|
||||
capabilities.total_volumes < 10
|
||||
|
||||
* goodness_function (string)
|
||||
Similar to filter_function, but used to weigh multiple volume
|
||||
backends. Example:
|
||||
|
||||
capabilities.capacity_utilization < 0.6 ? 100 : 25
|
||||
|
||||
* multiattach (Boolean)
|
||||
Whether the backend supports multiattach or not. Defaults to False.
|
||||
* sparse_copy_volume (Boolean)
|
||||
Whether copies performed by the volume manager for operations such
|
||||
as migration should attempt to preserve sparseness.
|
||||
|
||||
The returned dict may also contain a list, "pools", which has a similar
|
||||
dict for each pool being used with the backend.
|
||||
|
||||
:param refresh: Whether to discard any cached values and force a full
|
||||
refresh of stats.
|
||||
:returns: dict of appropriate values (see above).
|
||||
"""
|
||||
|
||||
def create_volume(self, volume):
|
||||
"""Create a new volume on the backend.
|
||||
|
||||
This method is responsible only for storage allocation on the backend.
|
||||
It should not export a LUN or actually make this storage available for
|
||||
use, this is done in a later call.
|
||||
|
||||
# TODO(smcginnis) - Add example data structure of volume object.
|
||||
:param volume: Volume object containing specifics to create.
|
||||
:returns: (Optional) dict of database updates for the new volume.
|
||||
:raises: VolumeBackendAPIException if creation failed.
|
||||
"""
|
||||
|
||||
def delete_volume(self, volume):
|
||||
"""Delete a volume from the backend.
|
||||
|
||||
If the driver can talk to the backend and detects that the volume is no
|
||||
longer present, this call should succeed and allow Cinder to complete
|
||||
the process of deleting the volume.
|
||||
|
||||
:param volume: The volume to delete.
|
||||
:raises: VolumeIsBusy if the volume is still attached or has snapshots.
|
||||
VolumeBackendAPIException on error.
|
||||
"""
|
||||
|
||||
def initialize_connection(self, volume, connector, initiator_data=None):
|
||||
"""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: 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.
|
||||
|
||||
May be called multiple times to get connection information after a
|
||||
volume has already been attached.
|
||||
"""
|
||||
|
||||
def attach_volume(self, context, volume, instance_uuid, host_name,
|
||||
mountpoint):
|
||||
"""Lets the driver know Nova has attached the volume to an instance.
|
||||
|
||||
:param context: Security/policy info for the request.
|
||||
:param volume: Volume being attached.
|
||||
:param instance_uuid: ID of the instance being attached to.
|
||||
:param host_name: The host name.
|
||||
:param mountpoint: Device mount point on the instance.
|
||||
"""
|
||||
|
||||
def terminate_connection(self, volume, connector):
|
||||
"""Remove access to a volume.
|
||||
|
||||
:param volume: The volume to remove.
|
||||
:param connector: The Dictionary containing information about the
|
||||
connection.
|
||||
"""
|
||||
|
||||
def detach_volume(self, context, volume, attachment=None):
|
||||
"""Detach volume from an instance.
|
||||
|
||||
:param context: Security/policy info for the request.
|
||||
:param volume: Volume being detached.
|
||||
:param attachment: (Optional) Attachment information.
|
||||
"""
|
||||
|
||||
def clone_image(self, volume, image_location, image_id, image_metadata,
|
||||
image_service):
|
||||
"""Clone an image to a volume.
|
||||
|
||||
:param volume: The volume to create.
|
||||
:param image_location: Where to pull the image from.
|
||||
:param image_id: The image identifier.
|
||||
:param image_metadata: Information about the image.
|
||||
:param image_service: The image service to use.
|
||||
:returns: Model updates.
|
||||
"""
|
||||
|
||||
def copy_image_to_volume(self, context, volume, image_service, image_id):
|
||||
"""Fetch the image from image_service and write it to the volume.
|
||||
|
||||
:param context: Security/policy info for the request.
|
||||
:param volume: The volume to create.
|
||||
:param image_service: The image service to use.
|
||||
:param image_id: The image identifier.
|
||||
:returns: Model updates.
|
||||
"""
|
||||
|
||||
def copy_volume_to_image(self, context, volume, image_service, image_meta):
|
||||
"""Copy the volume to the specified image.
|
||||
|
||||
:param context: Security/policy info for the request.
|
||||
:param volume: The volume to copy.
|
||||
:param image_service: The image service to use.
|
||||
:param image_meta: Information about the image.
|
||||
:returns: Model updates.
|
||||
"""
|
||||
|
||||
def extend_volume(self, volume, new_size):
|
||||
"""Extend the size of a volume.
|
||||
|
||||
:param volume: The volume to extend.
|
||||
:param new_size: The new desired size of the volume.
|
||||
"""
|
81
cinder/interface/volume_management_driver.py
Normal file
81
cinder/interface/volume_management_driver.py
Normal file
@ -0,0 +1,81 @@
|
||||
# Copyright 2016 Dell 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.
|
||||
#
|
||||
|
||||
"""
|
||||
Manage/unmanage existing volume driver interface.
|
||||
"""
|
||||
|
||||
from cinder.interface import base
|
||||
|
||||
|
||||
class VolumeManagementDriver(base.CinderInterface):
|
||||
"""Interface for drivers that support managing existing volumes."""
|
||||
|
||||
def manage_existing(self, volume, existing_ref):
|
||||
"""Brings an existing backend storage object under Cinder management.
|
||||
|
||||
existing_ref is passed straight through from the API request's
|
||||
manage_existing_ref value, and it is up to the driver how this should
|
||||
be interpreted. It should be sufficient to identify a storage object
|
||||
that the driver should somehow associate with the newly-created cinder
|
||||
volume structure.
|
||||
|
||||
There are two ways to do this:
|
||||
|
||||
1. Rename the backend storage object so that it matches the,
|
||||
volume['name'] which is how drivers traditionally map between a
|
||||
cinder volume and the associated backend storage object.
|
||||
|
||||
2. Place some metadata on the volume, or somewhere in the backend, that
|
||||
allows other driver requests (e.g. delete, clone, attach, detach...)
|
||||
to locate the backend storage object when required.
|
||||
|
||||
If the existing_ref doesn't make sense, or doesn't refer to an existing
|
||||
backend storage object, raise a ManageExistingInvalidReference
|
||||
exception.
|
||||
|
||||
The volume may have a volume_type, and the driver can inspect that and
|
||||
compare against the properties of the referenced backend storage
|
||||
object. If they are incompatible, raise a
|
||||
ManageExistingVolumeTypeMismatch, specifying a reason for the failure.
|
||||
|
||||
:param volume: Cinder volume to manage
|
||||
:param existing_ref: Driver-specific information used to identify a
|
||||
volume
|
||||
"""
|
||||
|
||||
def manage_existing_get_size(self, volume, existing_ref):
|
||||
"""Return size of volume to be managed by manage_existing.
|
||||
|
||||
When calculating the size, round up to the next GB.
|
||||
|
||||
:param volume: Cinder volume to manage
|
||||
:param existing_ref: Driver-specific information used to identify a
|
||||
volume
|
||||
"""
|
||||
|
||||
def unmanage(self, volume):
|
||||
"""Removes the specified volume from Cinder management.
|
||||
|
||||
Does not delete the underlying backend storage object.
|
||||
|
||||
For most drivers, this will not need to do anything. However, some
|
||||
drivers might use this call as an opportunity to clean up any
|
||||
Cinder-specific configuration that they have associated with the
|
||||
backend storage object.
|
||||
|
||||
:param volume: Cinder volume to unmanage
|
||||
"""
|
57
cinder/interface/volume_snapshot_driver.py
Normal file
57
cinder/interface/volume_snapshot_driver.py
Normal file
@ -0,0 +1,57 @@
|
||||
# Copyright 2016 Dell 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.
|
||||
#
|
||||
|
||||
"""
|
||||
Snapshot capable volume driver interface.
|
||||
"""
|
||||
|
||||
from cinder.interface import base
|
||||
|
||||
|
||||
class VolumeSnapshotDriver(base.CinderInterface):
|
||||
"""Interface for drivers that support snapshots.
|
||||
|
||||
TODO(smcginnis) Merge into VolumeDriverBase once NFS driver supports
|
||||
snapshots.
|
||||
"""
|
||||
|
||||
def create_snapshot(self, snapshot):
|
||||
"""Creates a snapshot.
|
||||
|
||||
:param snapshot: Information for the snapshot to be created.
|
||||
"""
|
||||
|
||||
def delete_snapshot(self, snapshot):
|
||||
"""Deletes a snapshot.
|
||||
|
||||
:param snapshot: The snapshot to delete.
|
||||
"""
|
||||
|
||||
def create_volume_from_snapshot(self, volume, snapshot):
|
||||
"""Creates a volume from a snapshot.
|
||||
|
||||
If volume_type extra specs includes 'replication: <is> True'
|
||||
the driver needs to create a volume replica (secondary),
|
||||
and setup replication between the newly created volume and
|
||||
the secondary volume.
|
||||
|
||||
An optional larger size for the new snapshot can be specified. Drivers
|
||||
should check this value and create or expand the new volume to match.
|
||||
|
||||
:param volume: The volume to be created.
|
||||
:param snapshot: The snapshot from which to create the volume.
|
||||
:returns: A dict of database updates for the new volume.
|
||||
"""
|
73
cinder/interface/volume_snapshotmanagement_driver.py
Normal file
73
cinder/interface/volume_snapshotmanagement_driver.py
Normal file
@ -0,0 +1,73 @@
|
||||
# Copyright 2016 Dell 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.
|
||||
#
|
||||
|
||||
"""
|
||||
Manage/unmanage existing volume snapshots driver interface.
|
||||
"""
|
||||
|
||||
from cinder.interface import base
|
||||
|
||||
|
||||
class VolumeSnapshotManagementDriver(base.CinderInterface):
|
||||
"""Interface for drivers that support managing existing snapshots."""
|
||||
|
||||
def manage_existing_snapshot(self, snapshot, existing_ref):
|
||||
"""Brings an existing backend storage object under Cinder management.
|
||||
|
||||
existing_ref is passed straight through from the API request's
|
||||
manage_existing_ref value, and it is up to the driver how this should
|
||||
be interpreted. It should be sufficient to identify a storage object
|
||||
that the driver should somehow associate with the newly-created cinder
|
||||
snapshot structure.
|
||||
|
||||
There are two ways to do this:
|
||||
|
||||
1. Rename the backend storage object so that it matches the
|
||||
snapshot['name'] which is how drivers traditionally map between a
|
||||
cinder snapshot and the associated backend storage object.
|
||||
|
||||
2. Place some metadata on the snapshot, or somewhere in the backend,
|
||||
that allows other driver requests (e.g. delete) to locate the
|
||||
backend storage object when required.
|
||||
|
||||
:param snapshot: The snapshot to manage.
|
||||
:param existing_ref: A reference to the existing snap.
|
||||
:raises: ManageExistingInvalidReference If the existing_ref doesn't
|
||||
make sense, or doesn't refer to an existing backend storage
|
||||
object.
|
||||
"""
|
||||
|
||||
def manage_existing_snapshot_get_size(self, snapshot, existing_ref):
|
||||
"""Return size of snapshot to be managed by manage_existing.
|
||||
|
||||
When calculating the size, round up to the next GB.
|
||||
|
||||
:param snapshot: The snapshot.
|
||||
:param existing_ref: A reference to the existing snap.
|
||||
"""
|
||||
|
||||
def unmanage_snapshot(self, snapshot):
|
||||
"""Removes the specified snapshot from Cinder management.
|
||||
|
||||
Does not delete the underlying backend storage object.
|
||||
|
||||
For most drivers, this will not need to do anything. However, some
|
||||
drivers might use this call as an opportunity to clean up any
|
||||
Cinder-specific configuration that they have associated with the
|
||||
backend storage object.
|
||||
|
||||
:param snapshot: The snapshot to unmanage.
|
||||
"""
|
0
cinder/tests/compliance/__init__.py
Normal file
0
cinder/tests/compliance/__init__.py
Normal file
45
cinder/tests/compliance/test_backup_drivers.py
Normal file
45
cinder/tests/compliance/test_backup_drivers.py
Normal file
@ -0,0 +1,45 @@
|
||||
# Copyright 2016 Dell 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 ddt
|
||||
|
||||
from cinder.interface import backup_driver
|
||||
from cinder.interface import util
|
||||
from cinder import test
|
||||
|
||||
BACKUP_DRIVERS = util.get_backup_drivers()
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class TestBackupDrivers(test.TestCase):
|
||||
|
||||
def test_backup_driver_decorator(self):
|
||||
"""Sanity check on the decorator.
|
||||
|
||||
The interface code is somewhat implicitly tested. We don't need unit
|
||||
tests for all of that code, but as a minimum we should make sure it
|
||||
returns at least one registered driver, else the compliance test will
|
||||
never even run.
|
||||
"""
|
||||
self.assertTrue(len(BACKUP_DRIVERS) > 0)
|
||||
|
||||
@ddt.data(*BACKUP_DRIVERS)
|
||||
def test_backup_driver_compliance(self, driver):
|
||||
"""Makes sure all backup drivers support the minimum requirements."""
|
||||
self.assertTrue(
|
||||
issubclass(driver.cls, backup_driver.BackupDriver),
|
||||
"Driver {} does not conform to minimum backup driver "
|
||||
"requirements!".format(driver.class_fqn))
|
45
cinder/tests/compliance/test_fczm_drivers.py
Normal file
45
cinder/tests/compliance/test_fczm_drivers.py
Normal file
@ -0,0 +1,45 @@
|
||||
# Copyright 2016 Dell 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 ddt
|
||||
|
||||
from cinder.interface import fczm_driver
|
||||
from cinder.interface import util
|
||||
from cinder import test
|
||||
|
||||
FCZM_DRIVERS = util.get_fczm_drivers()
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class TestFibreChannelZoneManagerDrivers(test.TestCase):
|
||||
|
||||
def test_fczm_driver_decorator(self):
|
||||
"""Sanity check on the decorator.
|
||||
|
||||
The interface code is somewhat implicitly tested. We don't need unit
|
||||
tests for all of that code, but as a minimum we should make sure it
|
||||
returns at least one registered driver, else the compliance test will
|
||||
never even run.
|
||||
"""
|
||||
self.assertTrue(len(FCZM_DRIVERS) > 0)
|
||||
|
||||
@ddt.data(*FCZM_DRIVERS)
|
||||
def test_fczm_driver_compliance(self, driver):
|
||||
"""Makes sure all fczm drivers support the minimum requirements."""
|
||||
self.assertTrue(
|
||||
issubclass(driver.cls, fczm_driver.FibreChannelZoneManagerDriver),
|
||||
"Driver {} does not conform to minimum fczm driver "
|
||||
"requirements!".format(driver.class_fqn))
|
44
cinder/tests/compliance/test_volume_drivers.py
Normal file
44
cinder/tests/compliance/test_volume_drivers.py
Normal file
@ -0,0 +1,44 @@
|
||||
# Copyright 2016 Dell 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 ddt
|
||||
|
||||
from cinder.interface import util
|
||||
from cinder.interface import volume_driver
|
||||
from cinder import test
|
||||
|
||||
VOLUME_DRIVERS = util.get_volume_drivers()
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class TestVolumeDrivers(test.TestCase):
|
||||
|
||||
def test_volume_driver_decorator(self):
|
||||
"""Sanity check on the decorator.
|
||||
|
||||
The interface code is somewhat implicitly tested. We don't need unit
|
||||
tests for all of that code, but as a minimum we should make sure it
|
||||
returns at least one registered driver, else the compliance test will
|
||||
never even run.
|
||||
"""
|
||||
self.assertTrue(len(VOLUME_DRIVERS) > 0)
|
||||
|
||||
@ddt.data(*VOLUME_DRIVERS)
|
||||
def test_volume_driver_compliance(self, driver):
|
||||
self.assertTrue(
|
||||
issubclass(driver.cls, volume_driver.VolumeDriverCore),
|
||||
"Driver {} does not conform to minimum volume driver "
|
||||
"requirements!".format(driver.class_fqn))
|
@ -24,6 +24,7 @@ from cinder import context
|
||||
from cinder import exception
|
||||
from cinder.i18n import _, _LI, _LW
|
||||
from cinder.image import image_utils
|
||||
from cinder import interface
|
||||
from cinder import objects
|
||||
from cinder import utils
|
||||
from cinder.volume import driver
|
||||
@ -42,6 +43,7 @@ CONF = cfg.CONF
|
||||
CONF.register_opts(volume_opts)
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class BlockDeviceDriver(driver.BaseVD, driver.LocalVD,
|
||||
driver.CloneableImageVD, driver.TransferVD):
|
||||
VERSION = '2.2.0'
|
||||
|
@ -29,6 +29,7 @@ from six.moves import urllib
|
||||
from cinder import context
|
||||
from cinder import exception
|
||||
from cinder.i18n import _
|
||||
from cinder import interface
|
||||
from cinder.volume import driver
|
||||
from cinder.volume import utils as volume_utils
|
||||
|
||||
@ -168,6 +169,7 @@ class BlockbridgeAPIClient(object):
|
||||
return rsp_data
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class BlockbridgeISCSIDriver(driver.ISCSIDriver):
|
||||
"""Manages volumes hosted on Blockbridge EPS."""
|
||||
|
||||
|
@ -26,6 +26,7 @@ from six.moves import urllib
|
||||
from cinder import context
|
||||
from cinder import exception
|
||||
from cinder.i18n import _, _LE, _LI
|
||||
from cinder import interface
|
||||
from cinder.volume.drivers.cloudbyte import options
|
||||
from cinder.volume.drivers.san import san
|
||||
from cinder.volume import qos_specs
|
||||
@ -34,6 +35,7 @@ from cinder.volume import volume_types
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class CloudByteISCSIDriver(san.SanISCSIDriver):
|
||||
"""CloudByte ISCSI Driver.
|
||||
|
||||
|
@ -25,6 +25,7 @@ from random import randint
|
||||
|
||||
from cinder import exception
|
||||
from cinder.i18n import _
|
||||
from cinder import interface
|
||||
from cinder import utils
|
||||
from cinder.volume.drivers import nfs
|
||||
|
||||
@ -292,6 +293,7 @@ CONF = cfg.CONF
|
||||
CONF.register_opts(coho_opts)
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class CohoDriver(nfs.NfsDriver):
|
||||
"""Coho Data NFS based cinder driver.
|
||||
|
||||
|
@ -29,6 +29,7 @@ import six
|
||||
from cinder import context
|
||||
from cinder import exception
|
||||
from cinder.i18n import _, _LE, _LI
|
||||
from cinder import interface
|
||||
from cinder import utils
|
||||
from cinder.volume.drivers.san import san
|
||||
from cinder.volume import qos_specs
|
||||
@ -111,6 +112,7 @@ def _authenticated(func):
|
||||
return func_wrapper
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
@six.add_metaclass(utils.TraceWrapperWithABCMetaclass)
|
||||
class DateraDriver(san.SanISCSIDriver):
|
||||
|
||||
|
@ -19,6 +19,7 @@ from oslo_utils import excutils
|
||||
|
||||
from cinder import exception
|
||||
from cinder.i18n import _, _LE
|
||||
from cinder import interface
|
||||
from cinder.volume import driver
|
||||
from cinder.volume.drivers.dell import dell_storagecenter_common
|
||||
from cinder.zonemanager import utils as fczm_utils
|
||||
@ -26,6 +27,7 @@ from cinder.zonemanager import utils as fczm_utils
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class DellStorageCenterFCDriver(dell_storagecenter_common.DellCommonDriver,
|
||||
driver.FibreChannelDriver):
|
||||
|
||||
|
@ -19,11 +19,13 @@ from oslo_utils import excutils
|
||||
|
||||
from cinder import exception
|
||||
from cinder.i18n import _, _LE, _LI
|
||||
from cinder import interface
|
||||
from cinder.volume import driver
|
||||
from cinder.volume.drivers.dell import dell_storagecenter_common
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class DellStorageCenterISCSIDriver(dell_storagecenter_common.DellCommonDriver,
|
||||
driver.ISCSIDriver):
|
||||
|
||||
|
@ -31,6 +31,7 @@ from cinder.db.sqlalchemy import api
|
||||
from cinder import exception
|
||||
from cinder.i18n import _
|
||||
from cinder.image import image_utils
|
||||
from cinder import interface
|
||||
from cinder import utils
|
||||
from cinder.volume import driver
|
||||
|
||||
@ -82,6 +83,7 @@ CONF.register_opts(disco_opts)
|
||||
|
||||
|
||||
# Driver to communicate with DISCO storage solution
|
||||
@interface.volumedriver
|
||||
class DiscoDriver(driver.VolumeDriver):
|
||||
"""Execute commands related to DISCO Volumes."""
|
||||
|
||||
|
@ -14,12 +14,14 @@
|
||||
# under the License.
|
||||
#
|
||||
|
||||
from cinder import interface
|
||||
import cinder.volume.driver
|
||||
from cinder.volume.drivers.dothill import dothill_common
|
||||
from cinder.volume.drivers.san import san
|
||||
from cinder.zonemanager import utils as fczm_utils
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class DotHillFCDriver(cinder.volume.driver.FibreChannelDriver):
|
||||
"""OpenStack Fibre Channel cinder drivers for DotHill Arrays.
|
||||
|
||||
|
@ -18,6 +18,7 @@ from oslo_log import log as logging
|
||||
|
||||
from cinder import exception
|
||||
from cinder.i18n import _
|
||||
from cinder import interface
|
||||
import cinder.volume.driver
|
||||
from cinder.volume.drivers.dothill import dothill_common as dothillcommon
|
||||
from cinder.volume.drivers.san import san
|
||||
@ -27,6 +28,7 @@ DEFAULT_ISCSI_PORT = "3260"
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class DotHillISCSIDriver(cinder.volume.driver.ISCSIDriver):
|
||||
"""OpenStack iSCSI cinder drivers for DotHill Arrays.
|
||||
|
||||
|
@ -38,6 +38,7 @@ from oslo_utils import units
|
||||
|
||||
from cinder import exception
|
||||
from cinder.i18n import _, _LW, _LI, _LE
|
||||
from cinder import interface
|
||||
from cinder.volume import driver
|
||||
|
||||
try:
|
||||
@ -758,7 +759,7 @@ class DrbdManageBaseDriver(driver.VolumeDriver):
|
||||
|
||||
|
||||
# Class with iSCSI interface methods
|
||||
|
||||
@interface.volumedriver
|
||||
class DrbdManageIscsiDriver(DrbdManageBaseDriver):
|
||||
"""Cinder driver that uses the iSCSI protocol. """
|
||||
|
||||
@ -820,6 +821,7 @@ DrbdManageDriver = DrbdManageIscsiDriver
|
||||
|
||||
|
||||
# Class with DRBD transport mode
|
||||
@interface.volumedriver
|
||||
class DrbdManageDrbdDriver(DrbdManageBaseDriver):
|
||||
"""Cinder driver that uses the DRBD protocol. """
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
from oslo_log import log as logging
|
||||
|
||||
from cinder import interface
|
||||
from cinder.volume import driver
|
||||
from cinder.volume.drivers.emc import emc_vnx_cli
|
||||
from cinder.zonemanager import utils as zm_utils
|
||||
@ -24,6 +25,7 @@ from cinder.zonemanager import utils as zm_utils
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class EMCCLIFCDriver(driver.FibreChannelDriver):
|
||||
"""EMC FC Driver for VNX using CLI.
|
||||
|
||||
|
@ -16,12 +16,14 @@
|
||||
|
||||
from oslo_log import log as logging
|
||||
|
||||
from cinder import interface
|
||||
from cinder.volume import driver
|
||||
from cinder.volume.drivers.emc import emc_vnx_cli
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class EMCCLIISCSIDriver(driver.ISCSIDriver):
|
||||
"""EMC ISCSI Drivers for VNX using CLI.
|
||||
|
||||
|
@ -20,6 +20,7 @@ import six
|
||||
|
||||
from cinder import context
|
||||
from cinder.i18n import _LW
|
||||
from cinder import interface
|
||||
from cinder.volume import driver
|
||||
from cinder.volume.drivers.emc import emc_vmax_common
|
||||
from cinder.zonemanager import utils as fczm_utils
|
||||
@ -27,6 +28,7 @@ from cinder.zonemanager import utils as fczm_utils
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class EMCVMAXFCDriver(driver.FibreChannelDriver):
|
||||
"""EMC FC Drivers for VMAX using SMI-S.
|
||||
|
||||
|
@ -24,6 +24,7 @@ import six
|
||||
from cinder import context
|
||||
from cinder import exception
|
||||
from cinder.i18n import _, _LE, _LI
|
||||
from cinder import interface
|
||||
from cinder.volume import driver
|
||||
from cinder.volume.drivers.emc import emc_vmax_common
|
||||
|
||||
@ -33,6 +34,7 @@ LOG = logging.getLogger(__name__)
|
||||
CINDER_CONF = '/etc/cinder/cinder.conf'
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class EMCVMAXISCSIDriver(driver.ISCSIDriver):
|
||||
"""EMC ISCSI Drivers for VMAX using SMI-S.
|
||||
|
||||
|
@ -32,6 +32,7 @@ from cinder import context
|
||||
from cinder import exception
|
||||
from cinder.i18n import _, _LI, _LW, _LE
|
||||
from cinder.image import image_utils
|
||||
from cinder import interface
|
||||
from cinder import utils
|
||||
from cinder.volume import driver
|
||||
from cinder.volume.drivers.san import san
|
||||
@ -88,6 +89,7 @@ VOLUME_NOT_MAPPED_ERROR = 84
|
||||
VOLUME_ALREADY_MAPPED_ERROR = 81
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class ScaleIODriver(driver.VolumeDriver):
|
||||
"""EMC ScaleIO Driver."""
|
||||
|
||||
|
@ -44,6 +44,7 @@ import six
|
||||
from cinder import context
|
||||
from cinder import exception
|
||||
from cinder.i18n import _, _LE, _LI, _LW
|
||||
from cinder import interface
|
||||
from cinder import objects
|
||||
from cinder.objects import fields
|
||||
from cinder import utils
|
||||
@ -774,6 +775,7 @@ class XtremIOVolumeDriver(san.SanDriver):
|
||||
(data=_("Failed to create IG, %s") % name))
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class XtremIOISCSIDriver(XtremIOVolumeDriver, driver.ISCSIDriver):
|
||||
"""Executes commands relating to ISCSI volumes.
|
||||
|
||||
@ -918,6 +920,7 @@ class XtremIOISCSIDriver(XtremIOVolumeDriver, driver.ISCSIDriver):
|
||||
return connector['initiator']
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class XtremIOFibreChannelDriver(XtremIOVolumeDriver,
|
||||
driver.FibreChannelDriver):
|
||||
|
||||
|
@ -30,6 +30,7 @@ from six.moves import range
|
||||
|
||||
from cinder import exception
|
||||
from cinder.i18n import _, _LE, _LW, _LI
|
||||
from cinder import interface
|
||||
from cinder import ssh_utils
|
||||
from cinder import utils
|
||||
from cinder.volume.drivers import san
|
||||
@ -102,6 +103,7 @@ def with_timeout(f):
|
||||
return __inner
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class DellEQLSanISCSIDriver(san.SanISCSIDriver):
|
||||
"""Implements commands for Dell EqualLogic SAN ISCSI management.
|
||||
|
||||
|
@ -22,6 +22,7 @@ FibreChannel Cinder Volume driver for Fujitsu ETERNUS DX S3 series.
|
||||
from oslo_log import log as logging
|
||||
import six
|
||||
|
||||
from cinder import interface
|
||||
from cinder.volume import driver
|
||||
from cinder.volume.drivers.fujitsu import eternus_dx_common
|
||||
from cinder.zonemanager import utils as fczm_utils
|
||||
@ -29,6 +30,7 @@ from cinder.zonemanager import utils as fczm_utils
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class FJDXFCDriver(driver.FibreChannelDriver):
|
||||
"""FC Cinder Volume Driver for Fujitsu ETERNUS DX S3 series."""
|
||||
|
||||
|
@ -22,6 +22,7 @@ iSCSI Cinder Volume driver for Fujitsu ETERNUS DX S3 series.
|
||||
import six
|
||||
|
||||
from cinder.i18n import _LI
|
||||
from cinder import interface
|
||||
from cinder.volume import driver
|
||||
from cinder.volume.drivers.fujitsu import eternus_dx_common
|
||||
from oslo_log import log as logging
|
||||
@ -29,6 +30,7 @@ from oslo_log import log as logging
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class FJDXISCSIDriver(driver.ISCSIDriver):
|
||||
"""iSCSI Cinder Volume Driver for Fujitsu ETERNUS DX S3 series."""
|
||||
|
||||
|
@ -27,6 +27,7 @@ from oslo_utils import units
|
||||
from cinder import exception
|
||||
from cinder.i18n import _, _LE, _LI, _LW
|
||||
from cinder.image import image_utils
|
||||
from cinder import interface
|
||||
from cinder import utils
|
||||
from cinder.volume import driver
|
||||
from cinder.volume.drivers import remotefs as remotefs_drv
|
||||
@ -47,6 +48,7 @@ CONF = cfg.CONF
|
||||
CONF.register_opts(volume_opts)
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class GlusterfsDriver(remotefs_drv.RemoteFSSnapDriver,
|
||||
driver.ExtendVD):
|
||||
"""Gluster based cinder driver.
|
||||
|
@ -38,6 +38,7 @@ from cinder.i18n import _
|
||||
from cinder.i18n import _LE
|
||||
from cinder.i18n import _LW
|
||||
from cinder.image import image_utils
|
||||
from cinder import interface
|
||||
from cinder.volume import driver
|
||||
from cinder.volume import utils as volutils
|
||||
|
||||
@ -70,6 +71,7 @@ CONF = cfg.CONF
|
||||
CONF.register_opts(hgst_opts)
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class HGSTDriver(driver.VolumeDriver):
|
||||
"""This is the Class to set in cinder.conf (volume_driver).
|
||||
|
||||
|
@ -26,6 +26,7 @@ import six
|
||||
|
||||
from cinder import exception
|
||||
from cinder.i18n import _LI, _LW
|
||||
from cinder import interface
|
||||
from cinder import utils
|
||||
import cinder.volume.driver
|
||||
from cinder.volume.drivers.hitachi import hbsd_basiclib as basic_lib
|
||||
@ -44,6 +45,7 @@ CONF = cfg.CONF
|
||||
CONF.register_opts(volume_opts)
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class HBSDFCDriver(cinder.volume.driver.FibreChannelDriver):
|
||||
VERSION = common.VERSION
|
||||
|
||||
|
@ -25,6 +25,7 @@ import six
|
||||
|
||||
from cinder import exception
|
||||
from cinder.i18n import _LE, _LI
|
||||
from cinder import interface
|
||||
from cinder import utils
|
||||
import cinder.volume.driver
|
||||
from cinder.volume.drivers.hitachi import hbsd_basiclib as basic_lib
|
||||
@ -52,6 +53,7 @@ CONF = cfg.CONF
|
||||
CONF.register_opts(volume_opts)
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class HBSDISCSIDriver(cinder.volume.driver.ISCSIDriver):
|
||||
VERSION = common.VERSION
|
||||
|
||||
|
@ -30,6 +30,7 @@ from oslo_utils import units
|
||||
|
||||
from cinder import exception
|
||||
from cinder.i18n import _, _LE, _LI, _LW
|
||||
from cinder import interface
|
||||
from cinder import utils as cinder_utils
|
||||
from cinder.volume import driver
|
||||
from cinder.volume.drivers.hitachi import hnas_backend
|
||||
@ -164,6 +165,7 @@ def _read_config(xml_config_file):
|
||||
return config
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class HDSISCSIDriver(driver.ISCSIDriver):
|
||||
"""HDS HNAS volume driver.
|
||||
|
||||
|
@ -33,6 +33,7 @@ from oslo_utils import units
|
||||
from cinder import exception
|
||||
from cinder.i18n import _, _LE, _LI
|
||||
from cinder.image import image_utils
|
||||
from cinder import interface
|
||||
from cinder import utils as cutils
|
||||
from cinder.volume.drivers.hitachi import hnas_backend
|
||||
from cinder.volume.drivers import nfs
|
||||
@ -150,6 +151,7 @@ def factory_bend(drv_config):
|
||||
return hnas_backend.HnasBackend(drv_config)
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class HDSNFSDriver(nfs.NfsDriver):
|
||||
"""Base class for Hitachi NFS driver.
|
||||
|
||||
|
@ -38,6 +38,7 @@ from oslo_log import log as logging
|
||||
|
||||
from cinder import exception
|
||||
from cinder.i18n import _, _LI, _LW
|
||||
from cinder import interface
|
||||
from cinder.volume import driver
|
||||
from cinder.volume.drivers.hpe import hpe_3par_common as hpecommon
|
||||
from cinder.volume.drivers.san import san
|
||||
@ -46,6 +47,7 @@ from cinder.zonemanager import utils as fczm_utils
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class HPE3PARFCDriver(driver.TransferVD,
|
||||
driver.ManageableVD,
|
||||
driver.ExtendVD,
|
||||
|
@ -40,6 +40,7 @@ import six
|
||||
|
||||
from cinder import exception
|
||||
from cinder.i18n import _, _LE, _LW
|
||||
from cinder import interface
|
||||
from cinder.volume import driver
|
||||
from cinder.volume.drivers.hpe import hpe_3par_common as hpecommon
|
||||
from cinder.volume.drivers.san import san
|
||||
@ -51,6 +52,7 @@ CHAP_USER_KEY = "HPQ-cinder-CHAP-name"
|
||||
CHAP_PASS_KEY = "HPQ-cinder-CHAP-secret"
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class HPE3PARISCSIDriver(driver.TransferVD,
|
||||
driver.ManageableVD,
|
||||
driver.ExtendVD,
|
||||
|
@ -44,6 +44,7 @@ from oslo_utils import units
|
||||
from cinder import context
|
||||
from cinder import exception
|
||||
from cinder.i18n import _, _LE, _LI, _LW
|
||||
from cinder import interface
|
||||
from cinder.objects import fields
|
||||
from cinder.volume import driver
|
||||
from cinder.volume.drivers.san import san
|
||||
@ -120,6 +121,7 @@ extra_specs_value_map = {
|
||||
}
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class HPELeftHandISCSIDriver(driver.ISCSIDriver):
|
||||
"""Executes REST commands relating to HPE/LeftHand SAN ISCSI volumes.
|
||||
|
||||
|
@ -18,6 +18,7 @@ Fibre channel Cinder volume driver for Hewlett Packard Enterprise storage.
|
||||
|
||||
from oslo_utils import importutils
|
||||
|
||||
from cinder import interface
|
||||
from cinder.volume import driver
|
||||
from cinder.volume.drivers.hpe import hpe_xp_opts as opts
|
||||
from cinder.zonemanager import utils as fczm_utils
|
||||
@ -26,6 +27,7 @@ _DRIVER_DIR = 'cinder.volume.drivers.hpe'
|
||||
_DRIVER_CLASS = 'hpe_xp_horcm_fc.HPEXPHORCMFC'
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class HPEXPFCDriver(driver.FibreChannelDriver):
|
||||
"""OpenStack Fibre Channel driver to enable HPE XP storage."""
|
||||
|
||||
|
@ -26,6 +26,7 @@ from oslo_utils import units
|
||||
from cinder import context
|
||||
from cinder import exception
|
||||
from cinder.i18n import _, _LE, _LI, _LW
|
||||
from cinder import interface
|
||||
from cinder import utils
|
||||
from cinder.volume import driver
|
||||
from cinder.volume.drivers.huawei import constants
|
||||
@ -1586,6 +1587,7 @@ class HuaweiBaseDriver(driver.VolumeDriver):
|
||||
return secondary_id, volumes_update
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class HuaweiISCSIDriver(HuaweiBaseDriver, driver.ISCSIDriver):
|
||||
"""ISCSI driver for Huawei storage arrays.
|
||||
|
||||
@ -1777,6 +1779,7 @@ class HuaweiISCSIDriver(HuaweiBaseDriver, driver.ISCSIDriver):
|
||||
self.client.delete_mapping_view(view_id)
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class HuaweiFCDriver(HuaweiBaseDriver, driver.FibreChannelDriver):
|
||||
"""FC driver for Huawei OceanStor storage arrays.
|
||||
|
||||
|
@ -33,6 +33,7 @@ import six
|
||||
|
||||
from cinder import exception
|
||||
from cinder.i18n import _, _LE, _LI, _LW
|
||||
from cinder import interface
|
||||
from cinder import utils
|
||||
import cinder.volume.driver
|
||||
from cinder.volume.drivers.ibm import flashsystem_common as fscommon
|
||||
@ -53,6 +54,7 @@ CONF = cfg.CONF
|
||||
CONF.register_opts(flashsystem_fc_opts)
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class FlashSystemFCDriver(fscommon.FlashSystemDriver,
|
||||
cinder.volume.driver.FibreChannelDriver):
|
||||
"""IBM FlashSystem FC volume driver.
|
||||
|
@ -33,6 +33,7 @@ import six
|
||||
|
||||
from cinder import exception
|
||||
from cinder.i18n import _, _LE, _LW
|
||||
from cinder import interface
|
||||
from cinder import utils
|
||||
import cinder.volume.driver
|
||||
from cinder.volume.drivers.ibm import flashsystem_common as fscommon
|
||||
@ -51,6 +52,7 @@ CONF = cfg.CONF
|
||||
CONF.register_opts(flashsystem_iscsi_opts)
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class FlashSystemISCSIDriver(fscommon.FlashSystemDriver,
|
||||
cinder.volume.driver.ISCSIDriver):
|
||||
"""IBM FlashSystem iSCSI volume driver.
|
||||
|
@ -31,6 +31,7 @@ from cinder import context
|
||||
from cinder import exception
|
||||
from cinder.i18n import _, _LE, _LI
|
||||
from cinder.image import image_utils
|
||||
from cinder import interface
|
||||
from cinder.objects import fields
|
||||
from cinder import utils
|
||||
from cinder.volume import driver
|
||||
@ -105,6 +106,7 @@ def _sizestr(size_in_g):
|
||||
return '%sG' % size_in_g
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class GPFSDriver(driver.ConsistencyGroupVD, driver.ExtendVD,
|
||||
driver.LocalVD, driver.TransferVD,
|
||||
driver.CloneableImageVD, driver.SnapshotVD,
|
||||
@ -1240,6 +1242,7 @@ class GPFSDriver(driver.ConsistencyGroupVD, driver.ExtendVD,
|
||||
return model_update, snapshots_model_update
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class GPFSNFSDriver(GPFSDriver, nfs.NfsDriver, san.SanDriver):
|
||||
"""GPFS cinder driver extension.
|
||||
|
||||
|
@ -40,6 +40,7 @@ from oslo_utils import excutils
|
||||
|
||||
from cinder import exception
|
||||
from cinder.i18n import _, _LE, _LI, _LW
|
||||
from cinder import interface
|
||||
from cinder import utils
|
||||
from cinder.volume.drivers.ibm.storwize_svc import (
|
||||
storwize_svc_common as storwize_common)
|
||||
@ -58,6 +59,7 @@ CONF = cfg.CONF
|
||||
CONF.register_opts(storwize_svc_fc_opts)
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class StorwizeSVCFCDriver(storwize_common.StorwizeSVCCommonDriver):
|
||||
"""IBM Storwize V7000 and SVC FC volume driver.
|
||||
|
||||
|
@ -40,6 +40,7 @@ from oslo_utils import excutils
|
||||
|
||||
from cinder import exception
|
||||
from cinder.i18n import _, _LE, _LW
|
||||
from cinder import interface
|
||||
from cinder import utils
|
||||
|
||||
from cinder.volume.drivers.ibm.storwize_svc import (
|
||||
@ -58,6 +59,7 @@ CONF = cfg.CONF
|
||||
CONF.register_opts(storwize_svc_iscsi_opts)
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class StorwizeSVCISCSIDriver(storwize_common.StorwizeSVCCommonDriver):
|
||||
"""IBM Storwize V7000 and SVC iSCSI volume driver.
|
||||
|
||||
|
@ -27,6 +27,7 @@ from oslo_log import log as logging
|
||||
from oslo_utils import importutils
|
||||
|
||||
from cinder import exception
|
||||
from cinder import interface
|
||||
from cinder.volume import driver
|
||||
from cinder.volume.drivers.san import san
|
||||
|
||||
@ -58,6 +59,7 @@ CONF.register_opts(xiv_ds8k_opts)
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class XIVDS8KDriver(san.SanDriver,
|
||||
driver.ManageableVD,
|
||||
driver.ExtendVD,
|
||||
|
@ -19,6 +19,7 @@ Fibre Channel Driver for Infortrend Eonstor based on CLI.
|
||||
|
||||
from oslo_log import log as logging
|
||||
|
||||
from cinder import interface
|
||||
from cinder.volume import driver
|
||||
from cinder.volume.drivers.infortrend.eonstor_ds_cli import common_cli
|
||||
from cinder.zonemanager import utils as fczm_utils
|
||||
@ -26,6 +27,7 @@ from cinder.zonemanager import utils as fczm_utils
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class InfortrendCLIFCDriver(driver.FibreChannelDriver):
|
||||
|
||||
"""Infortrend Fibre Channel Driver for Eonstor DS using CLI.
|
||||
|
@ -18,12 +18,14 @@ iSCSI Driver for Infortrend Eonstor based on CLI.
|
||||
|
||||
from oslo_log import log as logging
|
||||
|
||||
from cinder import interface
|
||||
from cinder.volume import driver
|
||||
from cinder.volume.drivers.infortrend.eonstor_ds_cli import common_cli
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class InfortrendCLIISCSIDriver(driver.ISCSIDriver):
|
||||
|
||||
"""Infortrend iSCSI Driver for Eonstor DS using CLI.
|
||||
|
@ -14,10 +14,12 @@
|
||||
# under the License.
|
||||
#
|
||||
|
||||
from cinder import interface
|
||||
from cinder.volume.drivers.dothill import dothill_fc
|
||||
from cinder.volume.drivers.lenovo import lenovo_common
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class LenovoFCDriver(dothill_fc.DotHillFCDriver):
|
||||
"""OpenStack Fibre Channel cinder drivers for Lenovo Storage arrays.
|
||||
|
||||
|
@ -14,10 +14,12 @@
|
||||
# under the License.
|
||||
#
|
||||
|
||||
from cinder import interface
|
||||
from cinder.volume.drivers.dothill import dothill_iscsi
|
||||
from cinder.volume.drivers.lenovo import lenovo_common
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class LenovoISCSIDriver(dothill_iscsi.DotHillISCSIDriver):
|
||||
"""OpenStack iSCSI cinder drivers for Lenovo Storage arrays.
|
||||
|
||||
|
@ -31,6 +31,7 @@ from cinder.brick.local_dev import lvm as lvm
|
||||
from cinder import exception
|
||||
from cinder.i18n import _, _LE, _LI, _LW
|
||||
from cinder.image import image_utils
|
||||
from cinder import interface
|
||||
from cinder import objects
|
||||
from cinder import utils
|
||||
from cinder.volume import driver
|
||||
@ -75,6 +76,7 @@ CONF = cfg.CONF
|
||||
CONF.register_opts(volume_opts)
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class LVMVolumeDriver(driver.VolumeDriver):
|
||||
"""Executes commands relating to Volumes."""
|
||||
|
||||
|
@ -16,11 +16,13 @@
|
||||
Volume driver for NetApp Data ONTAP (7-mode) FibreChannel storage systems.
|
||||
"""
|
||||
|
||||
from cinder import interface
|
||||
from cinder.volume import driver
|
||||
from cinder.volume.drivers.netapp.dataontap import block_7mode
|
||||
from cinder.zonemanager import utils as fczm_utils
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class NetApp7modeFibreChannelDriver(driver.BaseVD,
|
||||
driver.ConsistencyGroupVD,
|
||||
driver.ManageableVD,
|
||||
|
@ -16,11 +16,13 @@
|
||||
Volume driver for NetApp Data ONTAP (C-mode) FibreChannel storage systems.
|
||||
"""
|
||||
|
||||
from cinder import interface
|
||||
from cinder.volume import driver
|
||||
from cinder.volume.drivers.netapp.dataontap import block_cmode
|
||||
from cinder.zonemanager import utils as fczm_utils
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class NetAppCmodeFibreChannelDriver(driver.BaseVD,
|
||||
driver.ConsistencyGroupVD,
|
||||
driver.ManageableVD,
|
||||
|
@ -16,10 +16,12 @@
|
||||
Volume driver for NetApp Data ONTAP (7-mode) iSCSI storage systems.
|
||||
"""
|
||||
|
||||
from cinder import interface
|
||||
from cinder.volume import driver
|
||||
from cinder.volume.drivers.netapp.dataontap import block_7mode
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class NetApp7modeISCSIDriver(driver.BaseVD,
|
||||
driver.ConsistencyGroupVD,
|
||||
driver.ManageableVD,
|
||||
|
@ -16,10 +16,12 @@
|
||||
Volume driver for NetApp Data ONTAP (C-mode) iSCSI storage systems.
|
||||
"""
|
||||
|
||||
from cinder import interface
|
||||
from cinder.volume import driver
|
||||
from cinder.volume.drivers.netapp.dataontap import block_cmode
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class NetAppCmodeISCSIDriver(driver.BaseVD,
|
||||
driver.ConsistencyGroupVD,
|
||||
driver.ManageableVD,
|
||||
|
@ -28,6 +28,7 @@ import six
|
||||
|
||||
from cinder import exception
|
||||
from cinder.i18n import _
|
||||
from cinder import interface
|
||||
from cinder import utils
|
||||
from cinder.volume.drivers.netapp.dataontap.client import client_7mode
|
||||
from cinder.volume.drivers.netapp.dataontap import nfs_base
|
||||
@ -40,6 +41,7 @@ LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@six.add_metaclass(utils.TraceWrapperWithABCMetaclass)
|
||||
@interface.volumedriver
|
||||
class NetApp7modeNfsDriver(nfs_base.NetAppNfsDriver):
|
||||
"""NetApp NFS driver for Data ONTAP (7-mode)."""
|
||||
|
||||
|
@ -32,6 +32,7 @@ import six
|
||||
from cinder import exception
|
||||
from cinder.i18n import _, _LE, _LI, _LW
|
||||
from cinder.image import image_utils
|
||||
from cinder import interface
|
||||
from cinder import utils
|
||||
from cinder.volume.drivers.netapp.dataontap.client import client_cmode
|
||||
from cinder.volume.drivers.netapp.dataontap import nfs_base
|
||||
@ -47,6 +48,7 @@ LOG = logging.getLogger(__name__)
|
||||
QOS_CLEANUP_INTERVAL_SECONDS = 60
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
@six.add_metaclass(utils.TraceWrapperWithABCMetaclass)
|
||||
class NetAppCmodeNfsDriver(nfs_base.NetAppNfsDriver):
|
||||
"""NetApp NFS driver for Data ONTAP (Cluster-mode)."""
|
||||
|
@ -16,12 +16,14 @@
|
||||
Volume driver for NetApp E-Series FibreChannel storage systems.
|
||||
"""
|
||||
|
||||
from cinder import interface
|
||||
from cinder.volume import driver
|
||||
from cinder.volume.drivers.netapp.eseries import library
|
||||
from cinder.volume.drivers.netapp import utils as na_utils
|
||||
from cinder.zonemanager import utils as fczm_utils
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class NetAppEseriesFibreChannelDriver(driver.BaseVD,
|
||||
driver.ManageableVD,
|
||||
driver.ExtendVD,
|
||||
|
@ -18,11 +18,13 @@
|
||||
Volume driver for NetApp E-Series iSCSI storage systems.
|
||||
"""
|
||||
|
||||
from cinder import interface
|
||||
from cinder.volume import driver
|
||||
from cinder.volume.drivers.netapp.eseries import library
|
||||
from cinder.volume.drivers.netapp import utils as na_utils
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class NetAppEseriesISCSIDriver(driver.BaseVD,
|
||||
driver.ManageableVD,
|
||||
driver.ExtendVD,
|
||||
|
@ -20,6 +20,7 @@ from oslo_utils import excutils
|
||||
from cinder import context
|
||||
from cinder import exception
|
||||
from cinder.i18n import _, _LE, _LI, _LW
|
||||
from cinder import interface
|
||||
from cinder.volume import driver
|
||||
from cinder.volume.drivers.nexenta import jsonrpc
|
||||
from cinder.volume.drivers.nexenta import options
|
||||
@ -29,6 +30,7 @@ VERSION = '1.3.0.1'
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class NexentaISCSIDriver(driver.ISCSIDriver):
|
||||
"""Executes volume driver commands on Nexenta Appliance.
|
||||
|
||||
|
@ -21,6 +21,7 @@ from oslo_utils import units
|
||||
|
||||
from cinder import exception
|
||||
from cinder.i18n import _, _LE, _LI
|
||||
from cinder import interface
|
||||
from cinder.volume import driver
|
||||
from cinder.volume.drivers.nexenta.nexentaedge import jsonrpc
|
||||
from cinder.volume.drivers.nexenta import options
|
||||
@ -29,6 +30,7 @@ from cinder.volume.drivers.nexenta import options
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class NexentaEdgeISCSIDriver(driver.ISCSIDriver):
|
||||
"""Executes volume driver commands on NexentaEdge cluster.
|
||||
|
||||
|
@ -26,6 +26,7 @@ from cinder import context
|
||||
from cinder import db
|
||||
from cinder import exception
|
||||
from cinder.i18n import _, _LE, _LI, _LW
|
||||
from cinder import interface
|
||||
from cinder.volume.drivers.nexenta import jsonrpc
|
||||
from cinder.volume.drivers.nexenta import options
|
||||
from cinder.volume.drivers.nexenta import utils
|
||||
@ -35,6 +36,7 @@ VERSION = '1.3.0'
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class NexentaNfsDriver(nfs.NfsDriver): # pylint: disable=R0921
|
||||
"""Executes volume driver commands on Nexenta Appliance.
|
||||
|
||||
|
@ -20,6 +20,7 @@ from cinder import context
|
||||
from cinder import db
|
||||
from cinder import exception
|
||||
from cinder.i18n import _, _LI, _LE, _LW
|
||||
from cinder import interface
|
||||
from cinder.volume import driver
|
||||
from cinder.volume.drivers.nexenta.ns5 import jsonrpc
|
||||
from cinder.volume.drivers.nexenta import options
|
||||
@ -29,6 +30,7 @@ VERSION = '1.0.0'
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class NexentaISCSIDriver(driver.ISCSIDriver): # pylint: disable=R0921
|
||||
"""Executes volume driver commands on Nexenta Appliance.
|
||||
|
||||
|
@ -22,6 +22,7 @@ from cinder import context
|
||||
from cinder import db
|
||||
from cinder import exception
|
||||
from cinder.i18n import _, _LE, _LI, _LW
|
||||
from cinder import interface
|
||||
from cinder.volume.drivers.nexenta.ns5 import jsonrpc
|
||||
from cinder.volume.drivers.nexenta import options
|
||||
from cinder.volume.drivers.nexenta import utils
|
||||
@ -31,6 +32,7 @@ VERSION = '1.0.0'
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class NexentaNfsDriver(nfs.NfsDriver): # pylint: disable=R0921
|
||||
"""Executes volume driver commands on Nexenta Appliance.
|
||||
|
||||
|
@ -27,6 +27,7 @@ import six
|
||||
from cinder import exception
|
||||
from cinder.i18n import _, _LE, _LI, _LW
|
||||
from cinder.image import image_utils
|
||||
from cinder import interface
|
||||
from cinder import utils
|
||||
from cinder.volume import driver
|
||||
from cinder.volume.drivers import remotefs
|
||||
@ -63,6 +64,7 @@ CONF = cfg.CONF
|
||||
CONF.register_opts(nfs_opts)
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class NfsDriver(driver.ExtendVD, remotefs.RemoteFSDriver):
|
||||
"""NFS based cinder driver.
|
||||
|
||||
|
@ -33,6 +33,7 @@ from suds import client
|
||||
|
||||
from cinder import exception
|
||||
from cinder.i18n import _, _LE, _LI, _LW
|
||||
from cinder import interface
|
||||
from cinder.objects import volume
|
||||
from cinder.volume.drivers.san import san
|
||||
from cinder.volume import volume_types
|
||||
@ -84,6 +85,7 @@ class NimbleAPIException(exception.VolumeBackendAPIException):
|
||||
message = _("Unexpected response from Nimble API")
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class NimbleISCSIDriver(san.SanISCSIDriver):
|
||||
|
||||
"""OpenStack driver to enable Nimble Controller.
|
||||
|
@ -19,6 +19,7 @@ from oslo_log import log as logging
|
||||
|
||||
from cinder import exception
|
||||
from cinder.i18n import _, _LE, _LI
|
||||
from cinder import interface
|
||||
from cinder.volume import driver
|
||||
from cinder.volume.drivers.prophetstor import dplcommon
|
||||
from cinder.zonemanager import utils as fczm_utils
|
||||
@ -26,6 +27,7 @@ from cinder.zonemanager import utils as fczm_utils
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class DPLFCDriver(dplcommon.DPLCOMMONDriver,
|
||||
driver.FibreChannelDriver):
|
||||
def __init__(self, *args, **kwargs):
|
||||
|
@ -19,12 +19,14 @@ from oslo_log import log as logging
|
||||
|
||||
from cinder import exception
|
||||
from cinder.i18n import _, _LI, _LW
|
||||
from cinder import interface
|
||||
import cinder.volume.driver
|
||||
from cinder.volume.drivers.prophetstor import dplcommon
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class DPLISCSIDriver(dplcommon.DPLCOMMONDriver,
|
||||
cinder.volume.driver.ISCSIDriver):
|
||||
def __init__(self, *args, **kwargs):
|
||||
|
@ -18,6 +18,7 @@ Volume driver for Pure Storage FlashArray storage system.
|
||||
This driver requires Purity version 4.0.0 or later.
|
||||
"""
|
||||
|
||||
import functools
|
||||
import math
|
||||
import platform
|
||||
import re
|
||||
@ -32,6 +33,7 @@ import six
|
||||
from cinder import context
|
||||
from cinder import exception
|
||||
from cinder.i18n import _, _LE, _LI, _LW
|
||||
from cinder import interface
|
||||
from cinder.objects import fields
|
||||
from cinder import utils
|
||||
from cinder.volume import driver
|
||||
@ -119,6 +121,7 @@ def pure_driver_debug_trace(f):
|
||||
This should only be used on VolumeDriver class methods. It depends on
|
||||
having a 'self' argument that is a PureBaseVolumeDriver.
|
||||
"""
|
||||
@functools.wraps(f)
|
||||
def wrapper(*args, **kwargs):
|
||||
driver = args[0] # self
|
||||
cls_name = driver.__class__.__name__
|
||||
@ -1470,6 +1473,7 @@ class PureBaseVolumeDriver(san.SanDriver):
|
||||
self._array = array
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class PureISCSIDriver(PureBaseVolumeDriver, san.SanISCSIDriver):
|
||||
|
||||
VERSION = "4.0.0"
|
||||
@ -1632,6 +1636,7 @@ class PureISCSIDriver(PureBaseVolumeDriver, san.SanISCSIDriver):
|
||||
return connection
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class PureFCDriver(PureBaseVolumeDriver, driver.FibreChannelDriver):
|
||||
|
||||
VERSION = "2.0.0"
|
||||
|
@ -26,6 +26,7 @@ from cinder import compute
|
||||
from cinder import exception
|
||||
from cinder.i18n import _, _LI, _LW
|
||||
from cinder.image import image_utils
|
||||
from cinder import interface
|
||||
from cinder import utils
|
||||
from cinder.volume.drivers import remotefs as remotefs_drv
|
||||
|
||||
@ -57,6 +58,7 @@ CONF = cfg.CONF
|
||||
CONF.register_opts(volume_opts)
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class QuobyteDriver(remotefs_drv.RemoteFSSnapDriver):
|
||||
"""Cinder driver for Quobyte USP.
|
||||
|
||||
|
@ -30,6 +30,7 @@ from six.moves import urllib
|
||||
from cinder import exception
|
||||
from cinder.i18n import _, _LE, _LI, _LW
|
||||
from cinder.image import image_utils
|
||||
from cinder import interface
|
||||
from cinder import utils
|
||||
from cinder.volume import driver
|
||||
|
||||
@ -261,6 +262,7 @@ class RADOSClient(object):
|
||||
return int(features)
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class RBDDriver(driver.TransferVD, driver.ExtendVD,
|
||||
driver.CloneableImageVD, driver.SnapshotVD,
|
||||
driver.MigrateVD, driver.ManageableVD, driver.BaseVD):
|
||||
|
@ -14,10 +14,12 @@
|
||||
# under the License.
|
||||
#
|
||||
|
||||
from cinder import interface
|
||||
from cinder.volume.drivers.dothill import dothill_fc
|
||||
from cinder.volume.drivers.san.hp import hpmsa_common
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class HPMSAFCDriver(dothill_fc.DotHillFCDriver):
|
||||
"""OpenStack Fibre Channel cinder drivers for HPMSA arrays.
|
||||
|
||||
|
@ -14,10 +14,12 @@
|
||||
# under the License.
|
||||
#
|
||||
|
||||
from cinder import interface
|
||||
from cinder.volume.drivers.dothill import dothill_iscsi
|
||||
from cinder.volume.drivers.san.hp import hpmsa_common
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class HPMSAISCSIDriver(dothill_iscsi.DotHillISCSIDriver):
|
||||
"""OpenStack iSCSI cinder drivers for HPMSA arrays.
|
||||
|
||||
|
@ -31,6 +31,7 @@ from six.moves import urllib
|
||||
from cinder import exception
|
||||
from cinder.i18n import _, _LI
|
||||
from cinder.image import image_utils
|
||||
from cinder import interface
|
||||
from cinder import utils
|
||||
from cinder.volume.drivers import remotefs as remotefs_drv
|
||||
from cinder.volume import utils as volume_utils
|
||||
@ -53,6 +54,7 @@ CONF = cfg.CONF
|
||||
CONF.register_opts(volume_opts)
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class ScalityDriver(remotefs_drv.RemoteFSSnapDriver):
|
||||
"""Scality SOFS cinder driver.
|
||||
|
||||
|
@ -34,6 +34,7 @@ from oslo_utils import units
|
||||
from cinder import exception
|
||||
from cinder.i18n import _, _LE, _LW
|
||||
from cinder.image import image_utils
|
||||
from cinder import interface
|
||||
from cinder import utils
|
||||
from cinder.volume import driver
|
||||
|
||||
@ -423,6 +424,7 @@ class SheepdogIOWrapper(io.RawIOBase):
|
||||
raise IOError(_("fileno is not supported by SheepdogIOWrapper"))
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class SheepdogDriver(driver.VolumeDriver):
|
||||
"""Executes commands relating to Sheepdog Volumes."""
|
||||
|
||||
|
@ -29,6 +29,7 @@ from oslo_utils import units
|
||||
from cinder import exception
|
||||
from cinder.i18n import _, _LI, _LW
|
||||
from cinder.image import image_utils
|
||||
from cinder import interface
|
||||
from cinder import utils
|
||||
from cinder.volume.drivers import remotefs as remotefs_drv
|
||||
|
||||
@ -97,6 +98,7 @@ def update_allocation_data(delete=False):
|
||||
return wrapper
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class SmbfsDriver(remotefs_drv.RemoteFSSnapDriver):
|
||||
"""SMBFS based cinder volume driver."""
|
||||
|
||||
|
@ -35,6 +35,7 @@ from cinder import context
|
||||
from cinder import exception
|
||||
from cinder.i18n import _, _LE, _LW
|
||||
from cinder.image import image_utils
|
||||
from cinder import interface
|
||||
from cinder.objects import fields
|
||||
from cinder.volume.drivers.san import san
|
||||
from cinder.volume import qos_specs
|
||||
@ -133,6 +134,7 @@ def retry(exc_tuple, tries=5, delay=1, backoff=2):
|
||||
return retry_dec
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class SolidFireDriver(san.SanISCSIDriver):
|
||||
"""OpenStack driver to enable SolidFire cluster.
|
||||
|
||||
|
@ -28,6 +28,7 @@ import six
|
||||
from cinder import exception
|
||||
from cinder import utils
|
||||
from cinder.i18n import _, _LI, _LW
|
||||
from cinder import interface
|
||||
from cinder.volume import driver
|
||||
from cinder.volume.drivers.san import san
|
||||
from cinder.volume import utils as volume_utils
|
||||
@ -472,6 +473,7 @@ class TegileIntelliFlashVolumeDriver(san.SanDriver):
|
||||
'set.') % {'attr': attr})
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class TegileISCSIDriver(TegileIntelliFlashVolumeDriver, san.SanISCSIDriver):
|
||||
"""Tegile ISCSI Driver."""
|
||||
|
||||
@ -584,6 +586,7 @@ class TegileISCSIDriver(TegileIntelliFlashVolumeDriver, san.SanISCSIDriver):
|
||||
'provider_auth': provider_auth})
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class TegileFCDriver(TegileIntelliFlashVolumeDriver,
|
||||
driver.FibreChannelDriver):
|
||||
"""Tegile FC driver."""
|
||||
|
@ -34,6 +34,7 @@ from cinder import exception
|
||||
from cinder import utils
|
||||
from cinder.i18n import _, _LE, _LI, _LW
|
||||
from cinder.image import image_utils
|
||||
from cinder import interface
|
||||
from cinder.volume import driver
|
||||
from cinder.volume.drivers import nfs
|
||||
|
||||
@ -65,6 +66,7 @@ CONF = cfg.CONF
|
||||
CONF.register_opts(tintri_opts)
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class TintriDriver(driver.ManageableVD,
|
||||
driver.CloneableImageVD,
|
||||
driver.SnapshotVD,
|
||||
|
@ -39,6 +39,7 @@ from oslo_log import log as logging
|
||||
|
||||
from cinder import exception
|
||||
from cinder.i18n import _, _LE, _LI
|
||||
from cinder import interface
|
||||
from cinder import utils
|
||||
from cinder.volume import driver
|
||||
from cinder.volume.drivers.san import san
|
||||
@ -50,6 +51,7 @@ import socket
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class V7000FCPDriver(driver.FibreChannelDriver):
|
||||
"""Executes commands relating to fibre channel based Violin Memory arrays.
|
||||
|
||||
|
@ -43,6 +43,7 @@ import six
|
||||
|
||||
from cinder import exception
|
||||
from cinder.i18n import _, _LE, _LI, _LW
|
||||
from cinder import interface
|
||||
from cinder.volume import driver
|
||||
from cinder.volume.drivers.vmware import datastore as hub
|
||||
from cinder.volume.drivers.vmware import exceptions as vmdk_exceptions
|
||||
@ -207,6 +208,7 @@ class ImageDiskType(object):
|
||||
extra_spec_disk_type)
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class VMwareVcVmdkDriver(driver.VolumeDriver):
|
||||
"""Manage volumes on VMware vCenter server."""
|
||||
|
||||
|
@ -27,6 +27,7 @@ from oslo_utils import units
|
||||
from cinder import exception
|
||||
from cinder.i18n import _, _LI
|
||||
from cinder.image import image_utils
|
||||
from cinder import interface
|
||||
from cinder import utils
|
||||
from cinder.volume.drivers import remotefs as remotefs_drv
|
||||
|
||||
@ -62,6 +63,7 @@ CONF = cfg.CONF
|
||||
CONF.register_opts(vzstorage_opts)
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class VZStorageDriver(remotefs_drv.RemoteFSSnapDriver):
|
||||
"""Cinder driver for Virtuozzo Storage.
|
||||
|
||||
|
@ -26,6 +26,7 @@ from oslo_utils import units
|
||||
from cinder import exception
|
||||
from cinder.i18n import _, _LI
|
||||
from cinder.image import image_utils
|
||||
from cinder import interface
|
||||
from cinder.volume.drivers import remotefs as remotefs_drv
|
||||
from cinder.volume.drivers import smbfs
|
||||
from cinder.volume.drivers.windows import remotefs
|
||||
@ -42,6 +43,7 @@ CONF.set_default('smbfs_mount_point_base', r'C:\OpenStack\_mnt')
|
||||
CONF.set_default('smbfs_default_volume_format', 'vhd')
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class WindowsSmbfsDriver(smbfs.SmbfsDriver):
|
||||
VERSION = VERSION
|
||||
_MINIMUM_QEMU_IMG_VERSION = '1.6'
|
||||
|
@ -23,6 +23,7 @@ from six.moves import urllib
|
||||
from cinder import context
|
||||
from cinder import exception
|
||||
from cinder.i18n import _LE, _LI, _LW
|
||||
from cinder import interface
|
||||
from cinder.volume import driver
|
||||
from cinder.volume.drivers.san import san
|
||||
from cinder.volume import qos_specs
|
||||
@ -1380,6 +1381,7 @@ class XIOISEDriver(object):
|
||||
# Protocol specific classes for entry. They are wrappers around base class
|
||||
# above and every external API resuslts in a call to common function in base
|
||||
# class.
|
||||
@interface.volumedriver
|
||||
class XIOISEISCSIDriver(driver.ISCSIDriver):
|
||||
|
||||
"""Requires ISE Running FW version 3.1.0 or higher"""
|
||||
@ -1506,6 +1508,7 @@ class XIOISEISCSIDriver(driver.ISCSIDriver):
|
||||
return self.driver.remove_export(context, volume)
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class XIOISEFCDriver(driver.FibreChannelDriver):
|
||||
|
||||
"""Requires ISE Running FW version 2.8.0 or higher"""
|
||||
|
@ -28,6 +28,7 @@ from cinder import exception
|
||||
from cinder import utils
|
||||
from cinder.i18n import _, _LE, _LI, _LW
|
||||
from cinder.image import image_utils
|
||||
from cinder import interface
|
||||
from cinder.volume import driver
|
||||
from cinder.volume.drivers.san import san
|
||||
from cinder.volume.drivers.zfssa import zfssarest
|
||||
@ -105,6 +106,7 @@ def factory_zfssa():
|
||||
return zfssarest.ZFSSAApi()
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class ZFSSAISCSIDriver(driver.ISCSIDriver):
|
||||
"""ZFSSA Cinder iSCSI volume driver.
|
||||
|
||||
@ -224,10 +226,10 @@ class ZFSSAISCSIDriver(driver.ISCSIDriver):
|
||||
|
||||
# Parse interfaces
|
||||
interfaces = []
|
||||
for interface in lcfg.zfssa_target_interfaces.split(','):
|
||||
if interface == '':
|
||||
for intrface in lcfg.zfssa_target_interfaces.split(','):
|
||||
if intrface == '':
|
||||
continue
|
||||
interfaces.append(interface)
|
||||
interfaces.append(intrface)
|
||||
|
||||
# Setup target and target group
|
||||
iqn = self.zfssa.create_target(
|
||||
|
@ -30,6 +30,7 @@ from cinder import exception
|
||||
from cinder import utils
|
||||
from cinder.i18n import _, _LE, _LI
|
||||
from cinder.image import image_utils
|
||||
from cinder import interface
|
||||
from cinder.volume.drivers import nfs
|
||||
from cinder.volume.drivers.san import san
|
||||
from cinder.volume.drivers.zfssa import zfssarest
|
||||
@ -76,6 +77,7 @@ def factory_zfssa():
|
||||
return zfssarest.ZFSSANfsApi()
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class ZFSSANFSDriver(nfs.NfsDriver):
|
||||
"""ZFSSA Cinder NFS volume driver.
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user