]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Add ability to update provider_id during init
authorJohn Griffith <john.griffith8@gmail.com>
Thu, 20 Aug 2015 16:45:03 +0000 (10:45 -0600)
committerJohn Griffith <john.griffith8@gmail.com>
Fri, 21 Aug 2015 16:38:04 +0000 (10:38 -0600)
During the Liberty release we added the ability to store
a provider_id for a volume in the Cinder database.  This
simplifies a number of things for back ends when accessing
volumes.

One missing piece here however is that we have no way to
populate this data for existing deployments if/when they
upgrade.

This patch provides a simple solution that issues an update
call to the drivers on host init.  It works by fetching a
list of volumes for the specific host, and passes those in
to the driver.  The driver can do nothing, or it can go
through and sync up the Cinder ID's with it's internal
ID's and return the provider update info.

Change-Id: Ib3b078a6f492afada24e534f380f5f014033d603

cinder/tests/unit/test_utils.py
cinder/utils.py
cinder/volume/driver.py
cinder/volume/manager.py

index 5f389c8cf2bf2d459ec9cf75dc1d593832de4211..d7988c7afc00977eefe7f5dbbc3cf05c49014ba6 100644 (file)
@@ -510,6 +510,15 @@ class GenericUtilsTestCase(test.TestCase):
         self.assertEqual('sudo cinder-rootwrap /path/to/conf',
                          utils.get_root_helper())
 
+    def test_list_of_dicts_to_dict(self):
+        a = {'id': '1', 'color': 'orange'}
+        b = {'id': '2', 'color': 'blue'}
+        c = {'id': '3', 'color': 'green'}
+        lst = [a, b, c]
+
+        resp = utils.list_of_dicts_to_dict(lst, 'id')
+        self.assertEqual(c['id'], resp['3']['id'])
+
 
 class TemporaryChownTestCase(test.TestCase):
     @mock.patch('os.stat')
index a2c853b066b6f359214cb28f3e937a46974ef8fe..bde22e8357d9416d809d730b45f52e8956b89ff2 100644 (file)
@@ -288,6 +288,24 @@ def last_completed_audit_period(unit=None):
     return (begin, end)
 
 
+def list_of_dicts_to_dict(seq, key):
+    """Convert list of dicts to a indexted dict.
+
+    Takes a list of dicts, and converts it a nested dict
+    indexed by <key>
+
+    :param seq: list of dicts
+    :parm key: key in dicts to index by
+
+    example:
+      lst = [{'id': 1, ...}, {'id': 2, ...}...]
+      key = 'id'
+      returns {1:{'id': 1, ...}, 2:{'id':2, ...}
+
+    """
+    return {d[key]: dict(d, index=d[key]) for (i, d) in enumerate(seq)}
+
+
 class ProtectedExpatParser(expatreader.ExpatParser):
     """An expat parser which disables DTD's and entities by default."""
 
index 85feacf893ce97cf5e31b2552de7e5dfd31353ed..764ead528c769fb827cbb9ffbc6967b0e04279e6 100644 (file)
@@ -1179,6 +1179,14 @@ class BaseVD(object):
         """
         return None
 
+    def update_provider_info(self, volid_list):
+        """Get provider info updates from driver.
+
+        :param volid_list: List of Cinder vol id's to check for updates
+        :return: dict of update {'id': uuid, provider_id: <provider-id>}
+        """
+        return None
+
 
 @six.add_metaclass(abc.ABCMeta)
 class LocalVD(object):
index c212b8a1907681463674e743c0a91bdc233f9b6f..944213e8fe7a24bfa60d082ed83322aa4b251981 100644 (file)
@@ -295,6 +295,25 @@ class VolumeManager(manager.SchedulerDependentManager):
             LOG.info(_LI("Determined volume DB was not empty at startup."))
             return False
 
+    def _sync_provider_info(self, ctxt, volumes):
+        # NOTE(jdg): For now this just updates provider_id, we can add more
+        # add more items to the update if theyr'e releveant but we need
+        # to be safe in what we allow and add a list of allowed keys
+        # things that make sense are provider_*, replication_status etc
+
+        updates = self.driver.update_provider_info([v['id'] for v in volumes])
+        host_vols = utils.list_of_dicts_to_dict(volumes, 'id')
+
+        for u in updates or []:
+            update = {}
+            # NOTE(JDG): Make sure returned item is in this hosts volumes
+            if host_vols.get(u['id'], None):
+                update['provider_id'] = u['provider_id']
+            if update:
+                self.db.volume_update(ctxt,
+                                      u['id'],
+                                      update)
+
     def init_host(self):
         """Perform any required initialization."""
 
@@ -315,6 +334,7 @@ class VolumeManager(manager.SchedulerDependentManager):
             return
 
         volumes = self.db.volume_get_all_by_host(ctxt, self.host)
+        self._sync_provider_info(ctxt, volumes)
         # FIXME volume count for exporting is wrong
 
         try: