]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Add support for LocalConnector type in brick
authorBill Owen <billowen@us.ibm.com>
Wed, 28 Aug 2013 21:09:49 +0000 (14:09 -0700)
committerAvishay Traeger <avishay@il.ibm.com>
Sun, 8 Sep 2013 09:35:35 +0000 (12:35 +0300)
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

cinder/brick/initiator/connector.py
cinder/tests/brick/test_brick_connector.py
cinder/tests/test_gpfs.py
cinder/tests/test_utils.py

index ae16f2c535c05eb732764c855cfa9da5e720d0d1..0fb65ba53b13fe3cda6c216d0c48ec94493a2e32 100644 (file)
@@ -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
index 64dd298237ccddab68127a893802bbc86ce21446..72470fbd0cab924f35b56d6333fdad317e63c680 100644 (file)
@@ -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)
index 6490adf1ae8942d4edcac90129615f9d9756188c..c9941f430781ac885ee16f168a5cdc0cfc136341 100644 (file)
@@ -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 = {}
index 3ccdf817e630952e197e3af275703ac914571813..e2f1b0b389fb5e1159a68cd3542ae9fd92f85670 100644 (file)
@@ -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()