Add ability to update provider_id during init
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
This commit is contained in:
parent
fdcc2278a0
commit
1a7ce2d32e
|
@ -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')
|
||||
|
|
|
@ -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."""
|
||||
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in New Issue