From: Bill Owen Date: Wed, 28 Aug 2013 21:09:49 +0000 (-0700) Subject: Add support for LocalConnector type in brick X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=046c4ed223f0a60ade90b0fff92625ab7e6a6ab2;p=openstack-build%2Fcinder-build.git Add support for LocalConnector type in brick GPFS and other file based drivers require a LocalConnector to support volume connection and migration operations. Modify brick/initiator/connector.py to add LocalConnector class. Modify test_brick_connector.py to extend test_factory to include LocalConnector class. Modify test_gpfs.py to include new migrate_volume test. Modify test_utils.py to extend test_brick_get_connector to include LocalConnector class. Closes-Bug: #1218052 Change-Id: I259fae339c2df7ae304a91c80c27d135762041f5 --- diff --git a/cinder/brick/initiator/connector.py b/cinder/brick/initiator/connector.py index ae16f2c53..0fb65ba53 100644 --- a/cinder/brick/initiator/connector.py +++ b/cinder/brick/initiator/connector.py @@ -110,6 +110,11 @@ class InitiatorConnector(executor.Executor): execute=execute, driver=driver, root_helper=root_helper) + + elif protocol == "LOCAL": + return LocalConnector(execute=execute, + driver=driver, + root_helper=root_helper) else: msg = (_("Invalid InitiatorConnector protocol " "specified %(protocol)s") % @@ -808,4 +813,34 @@ class RemoteFsConnector(InitiatorConnector): def disconnect_volume(self, connection_properties, device_info): """No need to do anything to disconnect a volume in a filesystem.""" + + +class LocalConnector(InitiatorConnector): + """"Connector class to attach/detach File System backed volumes.""" + + def __init__(self, root_helper, driver=None, execute=putils.execute, + *args, **kwargs): + super(LocalConnector, self).__init__(root_helper, + driver, + execute, + *args, + **kwargs) + + def connect_volume(self, connection_properties): + """Connect to a volume. + + connection_properties must include: + device_path - path to the volume to be connected + """ + if 'device_path' not in connection_properties: + msg = (_("Invalid connection_properties specified " + "no device_path attribute")) + raise ValueError(msg) + + device_info = {'type': 'local', + 'path': connection_properties['device_path']} + return device_info + + def disconnect_volume(self, connection_properties, device_info): + """Disconnect a volume from the local host.""" pass diff --git a/cinder/tests/brick/test_brick_connector.py b/cinder/tests/brick/test_brick_connector.py index 64dd29823..72470fbd0 100644 --- a/cinder/tests/brick/test_brick_connector.py +++ b/cinder/tests/brick/test_brick_connector.py @@ -71,6 +71,9 @@ class ConnectorTestCase(test.TestCase): obj = connector.InitiatorConnector.factory('glusterfs', None) self.assertEqual(obj.__class__.__name__, "RemoteFsConnector") + obj = connector.InitiatorConnector.factory('local', None) + self.assertEqual(obj.__class__.__name__, "LocalConnector") + self.assertRaises(ValueError, connector.InitiatorConnector.factory, "bogus", None) @@ -588,3 +591,24 @@ class RemoteFsConnectorTestCase(ConnectorTestCase): def test_disconnect_volume(self): """Nothing should happen here -- make sure it doesn't blow up.""" self.connector.disconnect_volume(self.connection_properties, {}) + + +class LocalConnectorTestCase(test.TestCase): + + def setUp(self): + super(LocalConnectorTestCase, self).setUp() + self.connection_properties = {'name': 'foo', + 'device_path': '/tmp/bar'} + + def test_connect_volume(self): + self.connector = connector.LocalConnector(None) + cprops = self.connection_properties + dev_info = self.connector.connect_volume(cprops) + self.assertTrue(dev_info['type'] == 'local') + self.assertTrue(dev_info['path'] == cprops['device_path']) + + def test_connect_volume_with_invalid_connection_data(self): + self.connector = connector.LocalConnector(None) + cprops = {} + self.assertRaises(ValueError, + self.connector.connect_volume, cprops) diff --git a/cinder/tests/test_gpfs.py b/cinder/tests/test_gpfs.py index 6490adf1a..c9941f430 100644 --- a/cinder/tests/test_gpfs.py +++ b/cinder/tests/test_gpfs.py @@ -167,6 +167,16 @@ class GPFSDriverTestCase(test.TestCase): self.volume.delete_volume(self.context, volume_id) self.assertFalse(os.path.exists(path)) + def test_migrate_volume(self): + """Test volume migration done by driver.""" + loc = 'GPFSDriver:cindertest:openstack' + cap = {'location_info': loc} + host = {'host': 'foo', 'capabilities': cap} + volume = test_utils.create_volume(self.context, host=CONF.host) + self.driver.create_volume(volume) + self.driver.migrate_volume(self.context, volume, host) + self.driver.delete_volume(volume) + def _create_snapshot(self, volume_id, size='0'): """Create a snapshot object.""" snap = {} diff --git a/cinder/tests/test_utils.py b/cinder/tests/test_utils.py index 3ccdf817e..e2f1b0b38 100644 --- a/cinder/tests/test_utils.py +++ b/cinder/tests/test_utils.py @@ -805,8 +805,14 @@ class BrickUtils(test.TestCase): driver=None, root_helper=root_helper) + self.mox.StubOutClassWithMocks(connector, 'LocalConnector') + connector.LocalConnector(execute=putils.execute, + driver=None, + root_helper=root_helper) + self.mox.ReplayAll() utils.brick_get_connector('iscsi') utils.brick_get_connector('fibre_channel') utils.brick_get_connector('aoe') + utils.brick_get_connector('local') self.mox.VerifyAll()