Merge "Revise driver api for introspection data backend"
This commit is contained in:
commit
b738f2c305
|
@ -42,10 +42,10 @@ def _filter_data_excluded_keys(data):
|
|||
class BaseStorageBackend(object):
|
||||
|
||||
@abc.abstractmethod
|
||||
def get(self, node_id, processed=True, get_json=False):
|
||||
def get(self, node_uuid, processed=True, get_json=False):
|
||||
"""Get introspected data from storage backend.
|
||||
|
||||
:param node_id: node UUID or name.
|
||||
:param node_uuid: node UUID.
|
||||
:param processed: Specify whether the data to be retrieved is
|
||||
processed or not.
|
||||
:param get_json: Specify whether return the introspection data in json
|
||||
|
@ -55,10 +55,10 @@ class BaseStorageBackend(object):
|
|||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def save(self, node_info, data, processed=True):
|
||||
def save(self, node_uuid, data, processed=True):
|
||||
"""Save introspected data to storage backend.
|
||||
|
||||
:param node_info: a NodeInfo object.
|
||||
:param node_uuid: node UUID.
|
||||
:param data: the introspected data to be saved, in dict format.
|
||||
:param processed: Specify whether the data to be saved is processed or
|
||||
not.
|
||||
|
@ -67,57 +67,62 @@ class BaseStorageBackend(object):
|
|||
|
||||
|
||||
class NoStore(BaseStorageBackend):
|
||||
def get(self, node_id, processed=True, get_json=False):
|
||||
def get(self, node_uuid, processed=True, get_json=False):
|
||||
raise utils.IntrospectionDataStoreDisabled(
|
||||
'Introspection data storage is disabled')
|
||||
|
||||
def save(self, node_info, data, processed=True):
|
||||
def save(self, node_uuid, data, processed=True):
|
||||
LOG.debug('Introspection data storage is disabled, the data will not '
|
||||
'be saved', node_info=node_info)
|
||||
'be saved for node %(node)s', {'node': node_uuid})
|
||||
|
||||
|
||||
class SwiftStore(object):
|
||||
def get(self, node_id, processed=True, get_json=False):
|
||||
def get(self, node_uuid, processed=True, get_json=False):
|
||||
suffix = None if processed else _UNPROCESSED_DATA_STORE_SUFFIX
|
||||
LOG.debug('Fetching introspection data from Swift for %s', node_id)
|
||||
data = swift.get_introspection_data(node_id, suffix=suffix)
|
||||
LOG.debug('Fetching introspection data from Swift for %s', node_uuid)
|
||||
data = swift.get_introspection_data(node_uuid, suffix=suffix)
|
||||
if get_json:
|
||||
return json.loads(data)
|
||||
return data
|
||||
|
||||
def save(self, node_info, data, processed=True):
|
||||
def save(self, node_uuid, data, processed=True):
|
||||
suffix = None if processed else _UNPROCESSED_DATA_STORE_SUFFIX
|
||||
swift_object_name = swift.store_introspection_data(
|
||||
_filter_data_excluded_keys(data),
|
||||
node_info.uuid,
|
||||
node_uuid,
|
||||
suffix=suffix
|
||||
)
|
||||
LOG.info('Introspection data was stored in Swift object %s',
|
||||
swift_object_name, node_info=node_info)
|
||||
LOG.info('Introspection data was stored for node %(node)s in Swift '
|
||||
'object %(obj_name)s', {'node': node_uuid,
|
||||
'obj_name': swift_object_name})
|
||||
if CONF.processing.store_data_location:
|
||||
node_info = node_cache.get_node(node_uuid)
|
||||
# TODO(kaifeng) node_info is not synced back, while we are not
|
||||
# using extra in the processing logic, it looks fine at the moment,
|
||||
# but we should consider refactor in a later time.
|
||||
node_info.patch([{'op': 'add', 'path': '/extra/%s' %
|
||||
CONF.processing.store_data_location,
|
||||
'value': swift_object_name}])
|
||||
|
||||
|
||||
class DatabaseStore(object):
|
||||
def get(self, node_id, processed=True, get_json=False):
|
||||
def get(self, node_uuid, processed=True, get_json=False):
|
||||
LOG.debug('Fetching introspection data from database for %(node)s',
|
||||
{'node': node_id})
|
||||
data = node_cache.get_introspection_data(node_id, processed)
|
||||
{'node': node_uuid})
|
||||
data = node_cache.get_introspection_data(node_uuid, processed)
|
||||
if get_json:
|
||||
return data
|
||||
return json.dumps(data)
|
||||
|
||||
def save(self, node_info, data, processed=True):
|
||||
def save(self, node_uuid, data, processed=True):
|
||||
introspection_data = _filter_data_excluded_keys(data)
|
||||
try:
|
||||
node_cache.store_introspection_data(node_info.uuid,
|
||||
node_cache.store_introspection_data(node_uuid,
|
||||
introspection_data, processed)
|
||||
except Exception as e:
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.exception('Failed to store introspection data in '
|
||||
'database: %(exc)s', {'exc': e})
|
||||
else:
|
||||
LOG.info('Introspection data was stored in database',
|
||||
node_info=node_info)
|
||||
LOG.info('Introspection data was stored in database for node '
|
||||
'%(node)s', {'node': node_uuid})
|
||||
|
|
|
@ -140,21 +140,20 @@ def _filter_data_excluded_keys(data):
|
|||
if k not in _STORAGE_EXCLUDED_KEYS}
|
||||
|
||||
|
||||
def _store_data(node_info, data, processed=True):
|
||||
def _store_data(node_uuid, data, processed=True):
|
||||
introspection_data_manager = plugins_base.introspection_data_manager()
|
||||
store = CONF.processing.store_data
|
||||
ext = introspection_data_manager[store].obj
|
||||
ext.save(node_info, data, processed)
|
||||
ext.save(node_uuid, data, processed)
|
||||
|
||||
|
||||
def _store_unprocessed_data(node_info, data):
|
||||
def _store_unprocessed_data(node_uuid, data):
|
||||
# runs in background
|
||||
try:
|
||||
_store_data(node_info, data, processed=False)
|
||||
_store_data(node_uuid, data, processed=False)
|
||||
except Exception:
|
||||
LOG.exception('Encountered exception saving unprocessed '
|
||||
'introspection data', node_info=node_info,
|
||||
data=data)
|
||||
'introspection data for node %s', node_uuid, data=data)
|
||||
|
||||
|
||||
def get_introspection_data(uuid, processed=True, get_json=False):
|
||||
|
@ -198,7 +197,7 @@ def process(introspection_data):
|
|||
# Note(mkovacik): store data now when we're sure that a background
|
||||
# thread won't race with other process() or introspect.abort()
|
||||
# call
|
||||
utils.executor().submit(_store_unprocessed_data, node_info,
|
||||
utils.executor().submit(_store_unprocessed_data, node_info.uuid,
|
||||
unprocessed_data)
|
||||
|
||||
try:
|
||||
|
@ -243,7 +242,7 @@ def _process_node(node_info, node, introspection_data):
|
|||
# NOTE(dtantsur): repeat the check in case something changed
|
||||
ir_utils.check_provision_state(node)
|
||||
_run_post_hooks(node_info, introspection_data)
|
||||
_store_data(node_info, introspection_data)
|
||||
_store_data(node_info.uuid, introspection_data)
|
||||
|
||||
ironic = ir_utils.get_client()
|
||||
pxe_filter.driver().sync(ironic)
|
||||
|
@ -351,6 +350,6 @@ def _reapply_with_data(node_info, introspection_data):
|
|||
'\n'.join(failures), node_info=node_info)
|
||||
|
||||
_run_post_hooks(node_info, introspection_data)
|
||||
_store_data(node_info, introspection_data)
|
||||
_store_data(node_info.uuid, introspection_data)
|
||||
node_info.invalidate_cache()
|
||||
rules.apply(node_info, introspection_data)
|
||||
|
|
|
@ -72,16 +72,23 @@ class TestSwiftStore(BaseTest):
|
|||
swift_conn.create_object.assert_called_once_with(name,
|
||||
json.dumps(data))
|
||||
|
||||
def _create_node(self):
|
||||
session = db.get_writer_session()
|
||||
with session.begin():
|
||||
db.Node(uuid=self.node_info.uuid,
|
||||
state=istate.States.starting).save(session)
|
||||
|
||||
def test_store_data_location(self, swift_mock):
|
||||
CONF.set_override('store_data_location', 'inspector_data_object',
|
||||
'processing')
|
||||
self._create_node()
|
||||
swift_conn = swift_mock.return_value
|
||||
name = 'inspector_data-%s' % self.uuid
|
||||
patch = [{'path': '/extra/inspector_data_object',
|
||||
'value': name, 'op': 'add'}]
|
||||
expected = self.data
|
||||
|
||||
self.driver.save(self.node_info, self.data)
|
||||
self.driver.save(self.node_info.uuid, self.data)
|
||||
|
||||
data = introspection_data._filter_data_excluded_keys(self.data)
|
||||
swift_conn.create_object.assert_called_once_with(name,
|
||||
|
@ -101,7 +108,7 @@ class TestDatabaseStore(BaseTest):
|
|||
state=istate.States.starting).save(session)
|
||||
|
||||
def test_store_and_get_data(self):
|
||||
self.driver.save(self.node_info, self.data)
|
||||
self.driver.save(self.node_info.uuid, self.data)
|
||||
|
||||
res_data = self.driver.get(self.node_info.uuid)
|
||||
|
||||
|
|
Loading…
Reference in New Issue