Merge "Add driver interface checks"
This commit is contained in:
commit
ff6c00648e
@ -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,
|
||||
|
@ -39,6 +39,7 @@ from oslo_log import log as logging
|
||||
|
||||
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
|
||||
@ -50,6 +51,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