Merge "Move require_driver_initialized / log_unsupp to volume_utils"

This commit is contained in:
Zuul 2021-07-09 13:17:46 +00:00 committed by Gerrit Code Review
commit 7a9a914df1
8 changed files with 100 additions and 131 deletions

View File

@ -108,16 +108,6 @@ class GenericUtilsTestCase(test.TestCase):
unit=False, unit=False,
pretty_keys=False) pretty_keys=False)
def test_require_driver_intialized(self):
driver = mock.Mock()
driver.initialized = True
utils.require_driver_initialized(driver)
driver.initialized = False
self.assertRaises(exception.DriverNotInitialized,
utils.require_driver_initialized,
driver)
def test_hostname_unicode_sanitization(self): def test_hostname_unicode_sanitization(self):
hostname = u"\u7684.test.example.com" hostname = u"\u7684.test.example.com"
self.assertEqual("test.example.com", self.assertEqual("test.example.com",

View File

@ -1232,6 +1232,16 @@ class VolumeUtilsTestCase(test.TestCase):
mock_configuration.assert_called_with(driver.volume_opts, mock_configuration.assert_called_with(driver.volume_opts,
config_group='backendA') config_group='backendA')
def test_require_driver_initialized(self):
driver = mock.Mock()
driver.initialized = True
volume_utils.require_driver_initialized(driver)
driver.initialized = False
self.assertRaises(exception.DriverNotInitialized,
volume_utils.require_driver_initialized,
driver)
@ddt.ddt @ddt.ddt
class LogTracingTestCase(test.TestCase): class LogTracingTestCase(test.TestCase):

View File

@ -663,8 +663,10 @@ class ReplicationTestCase(base.BaseVolumeTestCase):
[], [], [], [], [], [],
self.manager.FAILBACK_SENTINEL) self.manager.FAILBACK_SENTINEL)
@mock.patch('cinder.utils.log_unsupported_driver_warning', mock.Mock()) @mock.patch('cinder.volume.volume_utils.log_unsupported_driver_warning',
@mock.patch('cinder.utils.require_driver_initialized', mock.Mock()) mock.Mock())
@mock.patch('cinder.volume.volume_utils.require_driver_initialized',
mock.Mock())
def test_init_host_with_rpc_clustered_replication(self): def test_init_host_with_rpc_clustered_replication(self):
# These are not OVOs but ORM instances # These are not OVOs but ORM instances
cluster = utils.create_cluster(self.context) cluster = utils.create_cluster(self.context)

View File

@ -27,7 +27,7 @@ from cinder.volume import manager as vol_manager
class VolumeManagerTestCase(base.BaseVolumeTestCase): class VolumeManagerTestCase(base.BaseVolumeTestCase):
@mock.patch('cinder.message.api.API.create') @mock.patch('cinder.message.api.API.create')
@mock.patch('cinder.utils.require_driver_initialized') @mock.patch('cinder.volume.volume_utils.require_driver_initialized')
@mock.patch('cinder.volume.manager.VolumeManager.' @mock.patch('cinder.volume.manager.VolumeManager.'
'_notify_about_snapshot_usage') '_notify_about_snapshot_usage')
def test_create_snapshot_driver_not_initialized_generates_user_message( def test_create_snapshot_driver_not_initialized_generates_user_message(
@ -54,7 +54,7 @@ class VolumeManagerTestCase(base.BaseVolumeTestCase):
detail=message_field.Detail.SNAPSHOT_CREATE_ERROR) detail=message_field.Detail.SNAPSHOT_CREATE_ERROR)
@mock.patch('cinder.message.api.API.create') @mock.patch('cinder.message.api.API.create')
@mock.patch('cinder.utils.require_driver_initialized') @mock.patch('cinder.volume.volume_utils.require_driver_initialized')
@mock.patch('cinder.volume.manager.VolumeManager.' @mock.patch('cinder.volume.manager.VolumeManager.'
'_notify_about_snapshot_usage') '_notify_about_snapshot_usage')
def test_create_snapshot_metadata_update_failure_generates_user_message( def test_create_snapshot_metadata_update_failure_generates_user_message(
@ -92,7 +92,7 @@ class VolumeManagerTestCase(base.BaseVolumeTestCase):
detail=message_field.Detail.SNAPSHOT_UPDATE_METADATA_FAILED) detail=message_field.Detail.SNAPSHOT_UPDATE_METADATA_FAILED)
@mock.patch('cinder.message.api.API.create') @mock.patch('cinder.message.api.API.create')
@mock.patch('cinder.utils.require_driver_initialized') @mock.patch('cinder.volume.volume_utils.require_driver_initialized')
@mock.patch('cinder.volume.manager.VolumeManager.' @mock.patch('cinder.volume.manager.VolumeManager.'
'_notify_about_snapshot_usage') '_notify_about_snapshot_usage')
def test_delete_snapshot_when_busy_generates_user_message( def test_delete_snapshot_when_busy_generates_user_message(
@ -116,7 +116,7 @@ class VolumeManagerTestCase(base.BaseVolumeTestCase):
exception=fake_exp) exception=fake_exp)
@mock.patch('cinder.message.api.API.create') @mock.patch('cinder.message.api.API.create')
@mock.patch('cinder.utils.require_driver_initialized') @mock.patch('cinder.volume.volume_utils.require_driver_initialized')
@mock.patch('cinder.volume.manager.VolumeManager.' @mock.patch('cinder.volume.manager.VolumeManager.'
'_notify_about_snapshot_usage') '_notify_about_snapshot_usage')
def test_delete_snapshot_general_exception_generates_user_message( def test_delete_snapshot_general_exception_generates_user_message(

View File

@ -23,8 +23,8 @@ from unittest import mock
from cinder.tests import fake_driver from cinder.tests import fake_driver
from cinder.tests.unit import test from cinder.tests.unit import test
from cinder import utils
from cinder.volume import configuration as conf from cinder.volume import configuration as conf
from cinder.volume import volume_utils
from cinder.zonemanager.drivers.brocade import brcd_fc_zone_driver from cinder.zonemanager.drivers.brocade import brcd_fc_zone_driver
from cinder.zonemanager import fc_zone_manager from cinder.zonemanager import fc_zone_manager
@ -44,7 +44,7 @@ class TestVolumeDriver(test.TestCase):
super(TestVolumeDriver, self).__init__(*args, **kwargs) super(TestVolumeDriver, self).__init__(*args, **kwargs)
@mock.patch('oslo_config.cfg._is_opt_registered', return_value=False) @mock.patch('oslo_config.cfg._is_opt_registered', return_value=False)
@mock.patch.object(utils, 'require_driver_initialized') @mock.patch.object(volume_utils, 'require_driver_initialized')
def test_initialize_connection_with_decorator(self, utils_mock, opt_mock): def test_initialize_connection_with_decorator(self, utils_mock, opt_mock):
utils_mock.return_value = True utils_mock.return_value = True
with mock.patch.object(fc_zone_manager.ZoneManager, 'add_connection')\ with mock.patch.object(fc_zone_manager.ZoneManager, 'add_connection')\
@ -57,7 +57,7 @@ class TestVolumeDriver(test.TestCase):
@mock.patch('cinder.zonemanager.utils.create_zone_manager') @mock.patch('cinder.zonemanager.utils.create_zone_manager')
@mock.patch('oslo_config.cfg._is_opt_registered', return_value=False) @mock.patch('oslo_config.cfg._is_opt_registered', return_value=False)
@mock.patch.object(utils, 'require_driver_initialized') @mock.patch.object(volume_utils, 'require_driver_initialized')
def test_initialize_connection_with_decorator_and_empty_map( def test_initialize_connection_with_decorator_and_empty_map(
self, utils_mock, opt_mock, zm_create_mock): self, utils_mock, opt_mock, zm_create_mock):
utils_mock.return_value = True utils_mock.return_value = True
@ -67,7 +67,7 @@ class TestVolumeDriver(test.TestCase):
zm_create_mock.assert_not_called() zm_create_mock.assert_not_called()
add_zone_mock.assert_not_called() add_zone_mock.assert_not_called()
@mock.patch.object(utils, 'require_driver_initialized') @mock.patch.object(volume_utils, 'require_driver_initialized')
def test_initialize_connection_no_decorator(self, utils_mock): def test_initialize_connection_no_decorator(self, utils_mock):
utils_mock.return_value = True utils_mock.return_value = True
with mock.patch.object(fc_zone_manager.ZoneManager, 'add_connection')\ with mock.patch.object(fc_zone_manager.ZoneManager, 'add_connection')\
@ -79,7 +79,7 @@ class TestVolumeDriver(test.TestCase):
add_zone_mock.assert_not_called() add_zone_mock.assert_not_called()
@mock.patch('oslo_config.cfg._is_opt_registered', return_value=False) @mock.patch('oslo_config.cfg._is_opt_registered', return_value=False)
@mock.patch.object(utils, 'require_driver_initialized') @mock.patch.object(volume_utils, 'require_driver_initialized')
def test_terminate_connection_with_decorator(self, utils_mock, opt_mock): def test_terminate_connection_with_decorator(self, utils_mock, opt_mock):
utils_mock.return_value = True utils_mock.return_value = True
with mock.patch.object(fc_zone_manager.ZoneManager, with mock.patch.object(fc_zone_manager.ZoneManager,
@ -92,7 +92,7 @@ class TestVolumeDriver(test.TestCase):
@mock.patch('cinder.zonemanager.utils.create_zone_manager') @mock.patch('cinder.zonemanager.utils.create_zone_manager')
@mock.patch('oslo_config.cfg._is_opt_registered', return_value=False) @mock.patch('oslo_config.cfg._is_opt_registered', return_value=False)
@mock.patch.object(utils, 'require_driver_initialized') @mock.patch.object(volume_utils, 'require_driver_initialized')
def test_terminate_connection_with_decorator_and_empty_map( def test_terminate_connection_with_decorator_and_empty_map(
self, utils_mock, opt_mock, zm_create_mock): self, utils_mock, opt_mock, zm_create_mock):
utils_mock.return_value = True utils_mock.return_value = True
@ -102,7 +102,7 @@ class TestVolumeDriver(test.TestCase):
zm_create_mock.assert_not_called() zm_create_mock.assert_not_called()
remove_zone_mock.assert_not_called() remove_zone_mock.assert_not_called()
@mock.patch.object(utils, 'require_driver_initialized') @mock.patch.object(volume_utils, 'require_driver_initialized')
def test_terminate_connection_no_decorator(self, utils_mock): def test_terminate_connection_no_decorator(self, utils_mock):
utils_mock.return_value = True utils_mock.return_value = True
with mock.patch.object(fc_zone_manager.ZoneManager, with mock.patch.object(fc_zone_manager.ZoneManager,

View File

@ -15,7 +15,15 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
"""Utilities and helper functions.""" """Utilities and helper functions for all Cinder code.
This file is for utilities useful in all of Cinder,
including cinder-manage, the api service, the scheduler,
etc.
Code related to volume drivers and connecting to volumes
should be placed in volume_utils instead.
"""
from collections import OrderedDict from collections import OrderedDict
import contextlib import contextlib
@ -424,36 +432,6 @@ def get_root_helper() -> str:
return 'sudo cinder-rootwrap %s' % CONF.rootwrap_config return 'sudo cinder-rootwrap %s' % CONF.rootwrap_config
def require_driver_initialized(driver) -> None:
"""Verifies if `driver` is initialized
If the driver is not initialized, an exception will be raised.
:params driver: The driver instance.
:raises: `exception.DriverNotInitialized`
"""
# we can't do anything if the driver didn't init
if not driver.initialized:
driver_name = driver.__class__.__name__
LOG.error("Volume driver %s not initialized", driver_name)
raise exception.DriverNotInitialized()
else:
log_unsupported_driver_warning(driver)
def log_unsupported_driver_warning(driver) -> None:
"""Annoy the log about unsupported drivers."""
if not driver.supported:
# Check to see if the driver is flagged as supported.
LOG.warning("Volume driver (%(driver_name)s %(version)s) is "
"currently unsupported and may be removed in the "
"next release of OpenStack. Use at your own risk.",
{'driver_name': driver.__class__.__name__,
'version': driver.get_version()},
resource={'type': 'driver',
'id': driver.__class__.__name__})
def get_file_mode(path: str) -> int: def get_file_mode(path: str) -> int:
"""This primarily exists to make unit testing easier.""" """This primarily exists to make unit testing easier."""
return stat.S_IMODE(os.stat(path).st_mode) return stat.S_IMODE(os.stat(path).st_mode)

View File

@ -74,7 +74,6 @@ from cinder.objects import cgsnapshot
from cinder.objects import consistencygroup from cinder.objects import consistencygroup
from cinder.objects import fields from cinder.objects import fields
from cinder import quota from cinder import quota
from cinder import utils
from cinder import volume as cinder_volume from cinder import volume as cinder_volume
from cinder.volume import configuration as config from cinder.volume import configuration as config
from cinder.volume.flows.manager import create_volume from cinder.volume.flows.manager import create_volume
@ -443,7 +442,7 @@ class VolumeManager(manager.CleanableManager,
**kwargs) -> None: **kwargs) -> None:
"""Perform any required initialization.""" """Perform any required initialization."""
if not self.driver.supported: if not self.driver.supported:
utils.log_unsupported_driver_warning(self.driver) volume_utils.log_unsupported_driver_warning(self.driver)
if not self.configuration.enable_unsupported_driver: if not self.configuration.enable_unsupported_driver:
LOG.error("Unsupported drivers are disabled." LOG.error("Unsupported drivers are disabled."
@ -607,8 +606,8 @@ class VolumeManager(manager.CleanableManager,
try: try:
# Make sure the driver is initialized first # Make sure the driver is initialized first
utils.log_unsupported_driver_warning(self.driver) volume_utils.log_unsupported_driver_warning(self.driver)
utils.require_driver_initialized(self.driver) volume_utils.require_driver_initialized(self.driver)
except exception.DriverNotInitialized: except exception.DriverNotInitialized:
LOG.error("Cannot complete RPC initialization because " LOG.error("Cannot complete RPC initialization because "
"driver isn't initialized properly.", "driver isn't initialized properly.",
@ -701,7 +700,7 @@ class VolumeManager(manager.CleanableManager,
allow_reschedule=True) -> ovo_fields.UUIDField: allow_reschedule=True) -> ovo_fields.UUIDField:
"""Creates the volume.""" """Creates the volume."""
# Log about unsupported drivers # Log about unsupported drivers
utils.log_unsupported_driver_warning(self.driver) volume_utils.log_unsupported_driver_warning(self.driver)
# Make sure the host in the DB matches our own when clustered # Make sure the host in the DB matches our own when clustered
self._set_resource_host(volume) self._set_resource_host(volume)
@ -894,10 +893,7 @@ class VolumeManager(manager.CleanableManager,
if not is_temp_vol: if not is_temp_vol:
self._notify_about_volume_usage(context, volume, notification) self._notify_about_volume_usage(context, volume, notification)
try: try:
# NOTE(flaper87): Verify the driver is enabled volume_utils.require_driver_initialized(self.driver)
# before going forward. The exception will be caught
# and the volume status updated.
utils.require_driver_initialized(self.driver)
self.driver.remove_export(context, volume) self.driver.remove_export(context, volume)
if unmanage_only: if unmanage_only:
@ -1159,10 +1155,7 @@ class VolumeManager(manager.CleanableManager,
context, snapshot, "create.start") context, snapshot, "create.start")
try: try:
# NOTE(flaper87): Verify the driver is enabled volume_utils.require_driver_initialized(self.driver)
# before going forward. The exception will be caught
# and the snapshot status updated.
utils.require_driver_initialized(self.driver)
# Pass context so that drivers that want to use it, can, # Pass context so that drivers that want to use it, can,
# but it is not a requirement for all drivers. # but it is not a requirement for all drivers.
@ -1241,10 +1234,7 @@ class VolumeManager(manager.CleanableManager,
context, snapshot, "delete.start") context, snapshot, "delete.start")
try: try:
# NOTE(flaper87): Verify the driver is enabled volume_utils.require_driver_initialized(self.driver)
# before going forward. The exception will be caught
# and the snapshot status updated.
utils.require_driver_initialized(self.driver)
# Pass context so that drivers that want to use it, can, # Pass context so that drivers that want to use it, can,
# but it is not a requirement for all drivers. # but it is not a requirement for all drivers.
@ -1373,10 +1363,7 @@ class VolumeManager(manager.CleanableManager,
if volume_metadata.get('readonly') == 'True' and mode != 'ro': if volume_metadata.get('readonly') == 'True' and mode != 'ro':
raise exception.InvalidVolumeAttachMode(mode=mode, raise exception.InvalidVolumeAttachMode(mode=mode,
volume_id=volume.id) volume_id=volume.id)
# NOTE(flaper87): Verify the driver is enabled volume_utils.require_driver_initialized(self.driver)
# before going forward. The exception will be caught
# and the volume status updated.
utils.require_driver_initialized(self.driver)
LOG.info('Attaching volume %(volume_id)s to instance ' LOG.info('Attaching volume %(volume_id)s to instance '
'%(instance)s at mountpoint %(mount)s on host ' '%(instance)s at mountpoint %(mount)s on host '
@ -1460,10 +1447,7 @@ class VolumeManager(manager.CleanableManager,
self._notify_about_volume_usage(context, volume, "detach.start") self._notify_about_volume_usage(context, volume, "detach.start")
try: try:
# NOTE(flaper87): Verify the driver is enabled volume_utils.require_driver_initialized(self.driver)
# before going forward. The exception will be caught
# and the volume status updated.
utils.require_driver_initialized(self.driver)
LOG.info('Detaching volume %(volume_id)s from instance ' LOG.info('Detaching volume %(volume_id)s from instance '
'%(instance)s.', '%(instance)s.',
@ -1486,7 +1470,7 @@ class VolumeManager(manager.CleanableManager,
# We're going to remove the export here # We're going to remove the export here
# (delete the iscsi target) # (delete the iscsi target)
try: try:
utils.require_driver_initialized(self.driver) volume_utils.require_driver_initialized(self.driver)
self.driver.remove_export(context.elevated(), volume) self.driver.remove_export(context.elevated(), volume)
except exception.DriverNotInitialized: except exception.DriverNotInitialized:
with excutils.save_and_reraise_exception(): with excutils.save_and_reraise_exception():
@ -1692,10 +1676,7 @@ class VolumeManager(manager.CleanableManager,
try: try:
volume = objects.Volume.get_by_id(context, volume_id) volume = objects.Volume.get_by_id(context, volume_id)
# NOTE(flaper87): Verify the driver is enabled volume_utils.require_driver_initialized(self.driver)
# before going forward. The exception will be caught
# and the volume status updated.
utils.require_driver_initialized(self.driver)
image_service, image_id = \ image_service, image_id = \
glance.get_remote_image_service(context, image_meta['id']) glance.get_remote_image_service(context, image_meta['id'])
@ -1868,12 +1849,8 @@ class VolumeManager(manager.CleanableManager,
various places, so it should not contain any non-json data types. various places, so it should not contain any non-json data types.
""" """
# NOTE(flaper87): Verify the driver is enabled
# before going forward. The exception will be caught
# and the volume status updated.
# TODO(jdg): Add deprecation warning # TODO(jdg): Add deprecation warning
utils.require_driver_initialized(self.driver) volume_utils.require_driver_initialized(self.driver)
try: try:
self.driver.validate_connector(connector) self.driver.validate_connector(connector)
except exception.InvalidConnectorException as err: except exception.InvalidConnectorException as err:
@ -1924,7 +1901,7 @@ class VolumeManager(manager.CleanableManager,
ctxt, ctxt,
snapshot_id: ovo_fields.UUIDField, snapshot_id: ovo_fields.UUIDField,
connector: dict) -> dict: connector: dict) -> dict:
utils.require_driver_initialized(self.driver) volume_utils.require_driver_initialized(self.driver)
snapshot = objects.Snapshot.get_by_id(ctxt, snapshot_id) snapshot = objects.Snapshot.get_by_id(ctxt, snapshot_id)
try: try:
self.driver.validate_connector(connector) self.driver.validate_connector(connector)
@ -1990,10 +1967,7 @@ class VolumeManager(manager.CleanableManager,
The format of connector is the same as for initialize_connection. The format of connector is the same as for initialize_connection.
""" """
# NOTE(flaper87): Verify the driver is enabled volume_utils.require_driver_initialized(self.driver)
# before going forward. The exception will be caught
# and the volume status updated.
utils.require_driver_initialized(self.driver)
volume_ref = self.db.volume_get(context, volume_id) volume_ref = self.db.volume_get(context, volume_id)
try: try:
@ -2012,7 +1986,7 @@ class VolumeManager(manager.CleanableManager,
snapshot_id: ovo_fields.UUIDField, snapshot_id: ovo_fields.UUIDField,
connector: dict, connector: dict,
force=False) -> None: force=False) -> None:
utils.require_driver_initialized(self.driver) volume_utils.require_driver_initialized(self.driver)
snapshot = objects.Snapshot.get_by_id(ctxt, snapshot_id) snapshot = objects.Snapshot.get_by_id(ctxt, snapshot_id)
try: try:
@ -2028,7 +2002,7 @@ class VolumeManager(manager.CleanableManager,
def remove_export(self, context, volume_id: ovo_fields.UUIDField) -> None: def remove_export(self, context, volume_id: ovo_fields.UUIDField) -> None:
"""Removes an export for a volume.""" """Removes an export for a volume."""
utils.require_driver_initialized(self.driver) volume_utils.require_driver_initialized(self.driver)
volume_ref = self.db.volume_get(context, volume_id) volume_ref = self.db.volume_get(context, volume_id)
try: try:
self.driver.remove_export(context, volume_ref) self.driver.remove_export(context, volume_ref)
@ -2044,7 +2018,7 @@ class VolumeManager(manager.CleanableManager,
ctxt, ctxt,
snapshot_id: ovo_fields.UUIDField) -> None: snapshot_id: ovo_fields.UUIDField) -> None:
"""Removes an export for a snapshot.""" """Removes an export for a snapshot."""
utils.require_driver_initialized(self.driver) volume_utils.require_driver_initialized(self.driver)
snapshot = objects.Snapshot.get_by_id(ctxt, snapshot_id) snapshot = objects.Snapshot.get_by_id(ctxt, snapshot_id)
try: try:
self.driver.remove_export_snapshot(ctxt, snapshot) self.driver.remove_export_snapshot(ctxt, snapshot)
@ -2058,10 +2032,7 @@ class VolumeManager(manager.CleanableManager,
def accept_transfer(self, context, volume_id, new_user, new_project, def accept_transfer(self, context, volume_id, new_user, new_project,
no_snapshots=False) -> dict: no_snapshots=False) -> dict:
# NOTE(flaper87): Verify the driver is enabled volume_utils.require_driver_initialized(self.driver)
# before going forward. The exception will be caught
# and the volume status updated.
utils.require_driver_initialized(self.driver)
# NOTE(jdg): need elevated context as we haven't "given" the vol # NOTE(jdg): need elevated context as we haven't "given" the vol
# yet # yet
@ -2410,10 +2381,7 @@ class VolumeManager(manager.CleanableManager,
new_volume, new_volume,
error=False) -> ovo_fields.UUIDField: error=False) -> ovo_fields.UUIDField:
try: try:
# NOTE(flaper87): Verify the driver is enabled volume_utils.require_driver_initialized(self.driver)
# before going forward. The exception will be caught
# and the migration status updated.
utils.require_driver_initialized(self.driver)
except exception.DriverNotInitialized: except exception.DriverNotInitialized:
with excutils.save_and_reraise_exception(): with excutils.save_and_reraise_exception():
volume.migration_status = 'error' volume.migration_status = 'error'
@ -2584,10 +2552,7 @@ class VolumeManager(manager.CleanableManager,
diff=None) -> None: diff=None) -> None:
"""Migrate the volume to the specified host (called on source host).""" """Migrate the volume to the specified host (called on source host)."""
try: try:
# NOTE(flaper87): Verify the driver is enabled volume_utils.require_driver_initialized(self.driver)
# before going forward. The exception will be caught
# and the migration status updated.
utils.require_driver_initialized(self.driver)
except exception.DriverNotInitialized: except exception.DriverNotInitialized:
with excutils.save_and_reraise_exception(): with excutils.save_and_reraise_exception():
volume.migration_status = 'error' volume.migration_status = 'error'
@ -2868,10 +2833,7 @@ class VolumeManager(manager.CleanableManager,
new_size: int, new_size: int,
reservations) -> None: reservations) -> None:
try: try:
# NOTE(flaper87): Verify the driver is enabled volume_utils.require_driver_initialized(self.driver)
# before going forward. The exception will be caught
# and the volume status updated.
utils.require_driver_initialized(self.driver)
except exception.DriverNotInitialized: except exception.DriverNotInitialized:
with excutils.save_and_reraise_exception(): with excutils.save_and_reraise_exception():
volume.status = 'error_extending' volume.status = 'error_extending'
@ -2975,10 +2937,7 @@ class VolumeManager(manager.CleanableManager,
project_id = context.project_id project_id = context.project_id
try: try:
# NOTE(flaper87): Verify the driver is enabled volume_utils.require_driver_initialized(self.driver)
# before going forward. The exception will be caught
# and the volume status updated.
utils.require_driver_initialized(self.driver)
except exception.DriverNotInitialized: except exception.DriverNotInitialized:
with excutils.save_and_reraise_exception(): with excutils.save_and_reraise_exception():
# NOTE(flaper87): Other exceptions in this method don't # NOTE(flaper87): Other exceptions in this method don't
@ -3210,7 +3169,7 @@ class VolumeManager(manager.CleanableManager,
def get_manageable_volumes(self, ctxt, marker, limit, offset, sort_keys, def get_manageable_volumes(self, ctxt, marker, limit, offset, sort_keys,
sort_dirs, want_objects=False): sort_dirs, want_objects=False):
try: try:
utils.require_driver_initialized(self.driver) volume_utils.require_driver_initialized(self.driver)
except exception.DriverNotInitialized: except exception.DriverNotInitialized:
with excutils.save_and_reraise_exception(): with excutils.save_and_reraise_exception():
LOG.exception("Listing manageable volumes failed, due " LOG.exception("Listing manageable volumes failed, due "
@ -3247,7 +3206,7 @@ class VolumeManager(manager.CleanableManager,
self._notify_about_group_usage(context, group, "create.start") self._notify_about_group_usage(context, group, "create.start")
try: try:
utils.require_driver_initialized(self.driver) volume_utils.require_driver_initialized(self.driver)
LOG.info("Group %s: creating", group.name) LOG.info("Group %s: creating", group.name)
@ -3376,7 +3335,7 @@ class VolumeManager(manager.CleanableManager,
self._notify_about_group_usage( self._notify_about_group_usage(
context, group, "create.start") context, group, "create.start")
utils.require_driver_initialized(self.driver) volume_utils.require_driver_initialized(self.driver)
try: try:
model_update, volumes_model_update = ( model_update, volumes_model_update = (
@ -3658,7 +3617,7 @@ class VolumeManager(manager.CleanableManager,
volumes_model_update = None volumes_model_update = None
model_update = None model_update = None
try: try:
utils.require_driver_initialized(self.driver) volume_utils.require_driver_initialized(self.driver)
try: try:
model_update, volumes_model_update = ( model_update, volumes_model_update = (
@ -3905,7 +3864,7 @@ class VolumeManager(manager.CleanableManager,
context, group, "update.start") context, group, "update.start")
try: try:
utils.require_driver_initialized(self.driver) volume_utils.require_driver_initialized(self.driver)
try: try:
model_update, add_volumes_update, remove_volumes_update = ( model_update, add_volumes_update, remove_volumes_update = (
@ -4004,7 +3963,7 @@ class VolumeManager(manager.CleanableManager,
snapshots_model_update = None snapshots_model_update = None
model_update = None model_update = None
try: try:
utils.require_driver_initialized(self.driver) volume_utils.require_driver_initialized(self.driver)
LOG.debug("Group snapshot %(grp_snap_id)s: creating.", LOG.debug("Group snapshot %(grp_snap_id)s: creating.",
{'grp_snap_id': group_snapshot.id}) {'grp_snap_id': group_snapshot.id})
@ -4173,7 +4132,7 @@ class VolumeManager(manager.CleanableManager,
snapshots_model_update = None snapshots_model_update = None
model_update = None model_update = None
try: try:
utils.require_driver_initialized(self.driver) volume_utils.require_driver_initialized(self.driver)
LOG.debug("group_snapshot %(grp_snap_id)s: deleting", LOG.debug("group_snapshot %(grp_snap_id)s: deleting",
{'grp_snap_id': group_snapshot.id}) {'grp_snap_id': group_snapshot.id})
@ -4613,7 +4572,7 @@ class VolumeManager(manager.CleanableManager,
def get_manageable_snapshots(self, ctxt, marker, limit, offset, def get_manageable_snapshots(self, ctxt, marker, limit, offset,
sort_keys, sort_dirs, want_objects=False): sort_keys, sort_dirs, want_objects=False):
try: try:
utils.require_driver_initialized(self.driver) volume_utils.require_driver_initialized(self.driver)
except exception.DriverNotInitialized: except exception.DriverNotInitialized:
with excutils.save_and_reraise_exception(): with excutils.save_and_reraise_exception():
LOG.exception("Listing manageable snapshots failed, due " LOG.exception("Listing manageable snapshots failed, due "
@ -4754,7 +4713,7 @@ class VolumeManager(manager.CleanableManager,
connector) connector)
try: try:
utils.require_driver_initialized(self.driver) volume_utils.require_driver_initialized(self.driver)
self.driver.attach_volume(context, self.driver.attach_volume(context,
vref, vref,
attachment_ref.instance_uuid, attachment_ref.instance_uuid,
@ -4794,7 +4753,7 @@ class VolumeManager(manager.CleanableManager,
Exits early if the attachment does not have a connector and returns Exits early if the attachment does not have a connector and returns
None to indicate shared connections are irrelevant. None to indicate shared connections are irrelevant.
""" """
utils.require_driver_initialized(self.driver) volume_utils.require_driver_initialized(self.driver)
connector = attachment.connector connector = attachment.connector
if not connector and not force: if not connector and not force:
# It's possible to attach a volume to a shelved offloaded server # It's possible to attach a volume to a shelved offloaded server
@ -4840,7 +4799,7 @@ class VolumeManager(manager.CleanableManager,
param: attachment_id: Attachment id to remove param: attachment_id: Attachment id to remove
param: vref: Volume object associated with the attachment param: vref: Volume object associated with the attachment
""" """
utils.require_driver_initialized(self.driver) volume_utils.require_driver_initialized(self.driver)
attachment = objects.VolumeAttachment.get_by_id(context, attachment_id) attachment = objects.VolumeAttachment.get_by_id(context, attachment_id)
self._notify_about_volume_usage(context, vref, "detach.start") self._notify_about_volume_usage(context, vref, "detach.start")
@ -4898,7 +4857,7 @@ class VolumeManager(manager.CleanableManager,
volumes_model_update = None volumes_model_update = None
model_update = None model_update = None
try: try:
utils.require_driver_initialized(self.driver) volume_utils.require_driver_initialized(self.driver)
model_update, volumes_model_update = ( model_update, volumes_model_update = (
self.driver.enable_replication(ctxt, group, volumes)) self.driver.enable_replication(ctxt, group, volumes))
@ -4982,7 +4941,7 @@ class VolumeManager(manager.CleanableManager,
volumes_model_update = None volumes_model_update = None
model_update = None model_update = None
try: try:
utils.require_driver_initialized(self.driver) volume_utils.require_driver_initialized(self.driver)
model_update, volumes_model_update = ( model_update, volumes_model_update = (
self.driver.disable_replication(ctxt, group, volumes)) self.driver.disable_replication(ctxt, group, volumes))
@ -5073,7 +5032,7 @@ class VolumeManager(manager.CleanableManager,
volumes_model_update = None volumes_model_update = None
model_update = None model_update = None
try: try:
utils.require_driver_initialized(self.driver) volume_utils.require_driver_initialized(self.driver)
model_update, volumes_model_update = ( model_update, volumes_model_update = (
self.driver.failover_replication( self.driver.failover_replication(

View File

@ -1634,3 +1634,33 @@ def setup_tracing(trace_flags):
LOG.warning('Invalid trace flag: %s', invalid_flag) LOG.warning('Invalid trace flag: %s', invalid_flag)
TRACE_METHOD = 'method' in trace_flags TRACE_METHOD = 'method' in trace_flags
TRACE_API = 'api' in trace_flags TRACE_API = 'api' in trace_flags
def require_driver_initialized(driver):
"""Verifies if `driver` is initialized
If the driver is not initialized, an exception will be raised.
:params driver: The driver instance.
:raises: `exception.DriverNotInitialized`
"""
# we can't do anything if the driver didn't init
if not driver.initialized:
driver_name = driver.__class__.__name__
LOG.error("Volume driver %s not initialized", driver_name)
raise exception.DriverNotInitialized()
else:
log_unsupported_driver_warning(driver)
def log_unsupported_driver_warning(driver):
"""Annoy the log about unsupported drivers."""
if not driver.supported:
# Check to see if the driver is flagged as supported.
LOG.warning("Volume driver (%(driver_name)s %(version)s) is "
"currently unsupported and may be removed in the "
"next release of OpenStack. Use at your own risk.",
{'driver_name': driver.__class__.__name__,
'version': driver.get_version()},
resource={'type': 'driver',
'id': driver.__class__.__name__})