From cd0c32e32fc3566a68d5b7b2afcaf120a58d5bf7 Mon Sep 17 00:00:00 2001 From: Xavier Queralt Date: Fri, 14 Jun 2013 15:18:23 +0200 Subject: [PATCH] Raise an error if iSCSI is not supported Since the compute nodes may not have iSCSI support, volume drivers requiring it will raise an error if the connector's initiator attribute is not set when initializing the connection. bug #1007084 Related to: I5da472e5013fdc0c733ecb12b919c1068873bdc6 Change-Id: I95d859c11cf81bf57cecf7af8b224cdbb71592d5 --- .../tests/api/contrib/test_admin_actions.py | 25 ++++++++++++++++--- cinder/tests/test_volume.py | 13 ++++++++++ cinder/volume/driver.py | 12 +++++++++ cinder/volume/manager.py | 1 + 4 files changed, 48 insertions(+), 3 deletions(-) diff --git a/cinder/tests/api/contrib/test_admin_actions.py b/cinder/tests/api/contrib/test_admin_actions.py index 5d1f90590..87725f18c 100644 --- a/cinder/tests/api/contrib/test_admin_actions.py +++ b/cinder/tests/api/contrib/test_admin_actions.py @@ -266,10 +266,11 @@ class AdminActionsTest(test.TestCase): # current status is available volume = db.volume_create(ctx, {'status': 'available', 'host': 'test', 'provider_location': ''}) + connector = {'initiator': 'iqn.2012-07.org.fake:01'} # start service to handle rpc messages for attach requests svc = self.start_service('volume', host='test') self.volume_api.reserve_volume(ctx, volume) - self.volume_api.initialize_connection(ctx, volume, {}) + self.volume_api.initialize_connection(ctx, volume, connector) mountpoint = '/dev/vbd' self.volume_api.attach(ctx, volume, stubs.FAKE_UUID, mountpoint) # volume is attached @@ -306,10 +307,11 @@ class AdminActionsTest(test.TestCase): # current status is available volume = db.volume_create(ctx, {'status': 'available', 'host': 'test', 'provider_location': ''}) + connector = {'initiator': 'iqn.2012-07.org.fake:01'} # start service to handle rpc messages for attach requests svc = self.start_service('volume', host='test') self.volume_api.reserve_volume(ctx, volume) - self.volume_api.initialize_connection(ctx, volume, {}) + self.volume_api.initialize_connection(ctx, volume, connector) mountpoint = '/dev/vbd' self.volume_api.attach(ctx, volume, stubs.FAKE_UUID, mountpoint) self.assertRaises(exception.InvalidVolume, @@ -321,6 +323,22 @@ class AdminActionsTest(test.TestCase): # cleanup svc.stop() + def test_invalid_iscsi_connector(self): + """Test connector without the initiator (required by iscsi driver).""" + # admin context + ctx = context.RequestContext('admin', 'fake', True) + # current status is available + volume = db.volume_create(ctx, {'status': 'available', 'host': 'test', + 'provider_location': ''}) + connector = {} + # start service to handle rpc messages for attach requests + svc = self.start_service('volume', host='test') + self.assertRaises(exception.VolumeBackendAPIException, + self.volume_api.initialize_connection, + ctx, volume, connector) + # cleanup + svc.stop() + def test_attach_attaching_volume_with_different_instance(self): """Test that attaching volume reserved for another instance fails.""" # admin context @@ -328,9 +346,10 @@ class AdminActionsTest(test.TestCase): # current status is available volume = db.volume_create(ctx, {'status': 'available', 'host': 'test', 'provider_location': ''}) + connector = {'initiator': 'iqn.2012-07.org.fake:01'} # start service to handle rpc messages for attach requests svc = self.start_service('volume', host='test') - self.volume_api.initialize_connection(ctx, volume, {}) + self.volume_api.initialize_connection(ctx, volume, connector) values = {'status': 'attaching', 'instance_uuid': fakes.get_fake_uuid()} db.volume_update(ctx, volume['id'], values) diff --git a/cinder/tests/test_volume.py b/cinder/tests/test_volume.py index 64761e831..c5180e385 100644 --- a/cinder/tests/test_volume.py +++ b/cinder/tests/test_volume.py @@ -1300,6 +1300,19 @@ class ISCSITestCase(DriverTestCase): self.assertEquals(stats['total_capacity_gb'], float('5.52')) self.assertEquals(stats['free_capacity_gb'], float('0.52')) + def test_validate_connector(self): + iscsi_driver = driver.ISCSIDriver() + # Validate a valid connector + connector = {'ip': '10.0.0.2', + 'host': 'fakehost', + 'initiator': 'iqn.2012-07.org.fake:01'} + iscsi_driver.validate_connector(connector) + + # Validate a connector without the initiator + connector = {'ip': '10.0.0.2', 'host': 'fakehost'} + self.assertRaises(exception.VolumeBackendAPIException, + iscsi_driver.validate_connector, connector) + class FibreChannelTestCase(DriverTestCase): """Test Case for FibreChannelDriver""" diff --git a/cinder/volume/driver.py b/cinder/volume/driver.py index a6b445571..a296af6e6 100644 --- a/cinder/volume/driver.py +++ b/cinder/volume/driver.py @@ -164,6 +164,10 @@ class VolumeDriver(object): """Any initialization the volume driver does while starting""" pass + def validate_connector(self, connector): + """Fail if connector doesn't contain all the data needed by driver""" + pass + def copy_image_to_volume(self, context, volume, image_service, image_id): """Fetch the image from image_service and write it to the volume.""" raise NotImplementedError() @@ -354,6 +358,14 @@ class ISCSIDriver(VolumeDriver): 'data': iscsi_properties } + def validate_connector(self, connector): + # iSCSI drivers require the initiator information + if 'initiator' not in connector: + err_msg = (_('The volume driver requires the iSCSI initiator ' + 'name in the connector.')) + LOG.error(err_msg) + raise exception.VolumeBackendAPIException(data=err_msg) + def terminate_connection(self, volume, connector, **kwargs): pass diff --git a/cinder/volume/manager.py b/cinder/volume/manager.py index e986b7cd0..4555b4a71 100644 --- a/cinder/volume/manager.py +++ b/cinder/volume/manager.py @@ -694,6 +694,7 @@ class VolumeManager(manager.SchedulerDependentManager): data types. """ volume_ref = self.db.volume_get(context, volume_id) + self.driver.validate_connector(connector) return self.driver.initialize_connection(volume_ref, connector) def terminate_connection(self, context, volume_id, connector, force=False): -- 2.45.2