let conductor to update DB and placement
Conductor gets the old_driver_device_list from DB everytime and then compares with the new one reported from agents in different compute nodes, it will save the difference as well. Co-authored-by: coco-Gao <419546439@qq.com> Change-Id: I61ba4b38a1ac3c23873cb89d90e8c256a2dcd475
This commit is contained in:
parent
0cbced27fe
commit
0160a6b3bb
|
@ -17,6 +17,21 @@ import oslo_messaging as messaging
|
|||
|
||||
from cyborg.conf import CONF
|
||||
from cyborg import objects
|
||||
from cyborg.objects.deployable import Deployable
|
||||
from cyborg.objects.device import Device
|
||||
from cyborg.objects.attribute import Attribute
|
||||
from cyborg.objects.attach_handle import AttachHandle
|
||||
from cyborg.objects.control_path import ControlpathID
|
||||
from cyborg.objects.driver_objects.driver_attribute import DriverAttribute
|
||||
from cyborg.objects.driver_objects.driver_controlpath_id import \
|
||||
DriverControlPathID
|
||||
from cyborg.objects.driver_objects.driver_attach_handle import \
|
||||
DriverAttachHandle
|
||||
from cyborg.objects.driver_objects.driver_deployable import DriverDeployable
|
||||
from cyborg.objects.driver_objects.driver_device import DriverDevice
|
||||
|
||||
from oslo_log import log as logging
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ConductorManager(object):
|
||||
|
@ -110,3 +125,181 @@ class ConductorManager(object):
|
|||
:returns: a list of deployable objects.
|
||||
"""
|
||||
return objects.Deployable.list(context)
|
||||
|
||||
def report_data(self, context, hostname, driver_device_list):
|
||||
"""Update the Cyborg DB in one hostname according to the
|
||||
discovered device list.
|
||||
:param context: request context.
|
||||
:param hostname: agent's hostname.
|
||||
:param driver_device_list: a list of driver_device object
|
||||
discovered by agent in the host.
|
||||
"""
|
||||
# TODO: Everytime get from the DB?
|
||||
# First retrieve the old_device_list from the DB.
|
||||
old_driver_device_list = DriverDevice.list(context, hostname)
|
||||
# TODO(wangzhh): Remove invalid driver_devices without controlpath_id.
|
||||
# Then diff two driver device list.
|
||||
self.drv_device_make_diff(context, hostname, old_driver_device_list,
|
||||
driver_device_list)
|
||||
|
||||
@classmethod
|
||||
def drv_device_make_diff(cls, context, host, old_driver_device_list,
|
||||
new_driver_device_list):
|
||||
"""Compare new driver-side device object list with the old one in
|
||||
one host."""
|
||||
LOG.info("Start differing devices.")
|
||||
# TODO:The placement report will be implemented here.
|
||||
# Use cpid.cpid_info to identify whether the device is the same.
|
||||
new_cpid_list = [driver_dev_obj.controlpath_id.cpid_info for
|
||||
driver_dev_obj in new_driver_device_list]
|
||||
old_cpid_list = [driver_dev_obj.controlpath_id.cpid_info for
|
||||
driver_dev_obj in old_driver_device_list]
|
||||
same = set(new_cpid_list) & set(old_cpid_list)
|
||||
added = set(new_cpid_list) - same
|
||||
deleted = set(old_cpid_list) - same
|
||||
for s in same:
|
||||
# get the driver_dev_obj, diff the driver_device layer
|
||||
new_driver_dev_obj = new_driver_device_list[new_cpid_list.index(s)]
|
||||
old_driver_dev_obj = old_driver_device_list[old_cpid_list.index(s)]
|
||||
# First, get dev_obj_list from hostname
|
||||
device_obj_list = Device.get_list_by_hostname(context, host)
|
||||
# Then, use controlpath_id.cpid_info to identiy one Device.
|
||||
cpid_info = new_driver_dev_obj.controlpath_id.cpid_info
|
||||
for dev_obj in device_obj_list:
|
||||
# get cpid_obj, could be empty or only one value.
|
||||
cpid_obj = ControlpathID.get_by_device_id_cpidinfo(
|
||||
context, dev_obj.id, cpid_info)
|
||||
# find the one cpid_obj with cpid_info
|
||||
if cpid_obj is not None:
|
||||
break
|
||||
|
||||
changed_key = ['std_board_info', 'vendor', 'vendor_board_info',
|
||||
'model', 'type']
|
||||
for c_k in changed_key:
|
||||
if getattr(new_driver_dev_obj, c_k) != getattr(
|
||||
old_driver_dev_obj, c_k):
|
||||
setattr(dev_obj, c_k, getattr(new_driver_dev_obj, c_k))
|
||||
dev_obj.save(context)
|
||||
# diff the internal layer: driver_deployable
|
||||
cls.drv_deployable_make_diff(context, dev_obj.id, cpid_obj.id,
|
||||
old_driver_dev_obj.deployable_list,
|
||||
new_driver_dev_obj.deployable_list)
|
||||
# device is deleted.
|
||||
for d in deleted:
|
||||
old_driver_dev_obj = old_driver_device_list[old_cpid_list.index(d)]
|
||||
old_driver_dev_obj.destroy(context, host)
|
||||
# device is added
|
||||
for a in added:
|
||||
new_driver_dev_obj = new_driver_device_list[new_cpid_list.index(a)]
|
||||
new_driver_dev_obj.create(context, host)
|
||||
|
||||
@classmethod
|
||||
def drv_deployable_make_diff(cls, context, device_id, cpid_id,
|
||||
old_driver_dep_list, new_driver_dep_list):
|
||||
"""Compare new driver-side deployable object list with the old one in
|
||||
one host."""
|
||||
# use name to identify whether the deployable is the same.
|
||||
LOG.info("Start differing deploybles.")
|
||||
new_name_list = [driver_dep_obj.name for driver_dep_obj in
|
||||
new_driver_dep_list]
|
||||
old_name_list = [driver_dep_obj.name for driver_dep_obj in
|
||||
old_driver_dep_list]
|
||||
same = set(new_name_list) & set(old_name_list)
|
||||
added = set(new_name_list) - same
|
||||
deleted = set(old_name_list) - same
|
||||
for s in same:
|
||||
# get the driver_dep_obj, diff the driver_dep layer
|
||||
new_driver_dep_obj = new_driver_dep_list[new_name_list.index(s)]
|
||||
old_driver_dep_obj = old_driver_dep_list[old_name_list.index(s)]
|
||||
# get dep_obj, it won't be None because it stored before.
|
||||
dep_obj = Deployable.get_by_name_deviceid(context, s, device_id)
|
||||
# update the driver_dep num_accelerators field
|
||||
if dep_obj.num_accelerators != new_driver_dep_obj.num_accelerators:
|
||||
dep_obj.num_accelerators = new_driver_dep_obj.num_accelerators
|
||||
dep_obj.save(context)
|
||||
# diff the internal layer: driver_attribute_list
|
||||
new_attribute_list = []
|
||||
if hasattr(new_driver_dep_obj, 'attribute_list'):
|
||||
new_attribute_list = new_driver_dep_obj.attribute_list
|
||||
cls.drv_attr_make_diff(context, dep_obj.id,
|
||||
old_driver_dep_obj.attribute_list,
|
||||
new_attribute_list)
|
||||
# diff the internal layer: driver_attach_hanle_list
|
||||
cls.drv_ah_make_diff(context, dep_obj.id, cpid_id,
|
||||
old_driver_dep_obj.attach_handle_list,
|
||||
new_driver_dep_obj.attach_handle_list)
|
||||
# name is deleted.
|
||||
for d in deleted:
|
||||
old_driver_dep_obj = old_driver_dep_list[old_name_list.index(d)]
|
||||
old_driver_dep_obj.destroy(context, device_id)
|
||||
# name is added.
|
||||
for a in added:
|
||||
new_driver_dep_obj = new_driver_dep_list[new_name_list.index(a)]
|
||||
new_driver_dep_obj.create(context, device_id, cpid_id)
|
||||
|
||||
@classmethod
|
||||
def drv_attr_make_diff(cls, context, dep_id, old_driver_attr_list,
|
||||
new_driver_attr_list):
|
||||
"""Diff new dirver-side Attribute Object lists with the old one."""
|
||||
LOG.info("Start differing attributes.")
|
||||
new_key_list = [driver_attr_obj.key for driver_attr_obj in
|
||||
new_driver_attr_list]
|
||||
old_key_list = [driver_attr_obj.key for driver_attr_obj in
|
||||
old_driver_attr_list]
|
||||
same = set(new_key_list) & set(old_key_list)
|
||||
# key is same, diff the value.
|
||||
for s in same:
|
||||
# value is not same, update
|
||||
new_driver_attr_obj = new_driver_attr_list[new_key_list.index(s)]
|
||||
old_driver_attr_obj = old_driver_attr_list[old_key_list.index(s)]
|
||||
if new_driver_attr_obj.value != old_driver_attr_obj.value:
|
||||
attr_obj = Attribute.get_by_dep_key(context, dep_id, s)
|
||||
attr_obj.value = new_driver_attr_obj.value
|
||||
attr_obj.save(context)
|
||||
# key is deleted.
|
||||
deleted = set(old_key_list) - same
|
||||
for d in deleted:
|
||||
old_driver_attr_obj = old_driver_attr_list[
|
||||
old_key_list.index(d)]
|
||||
old_driver_attr_obj.destroy(context, dep_id)
|
||||
# key is added.
|
||||
added = set(new_key_list) - same
|
||||
for a in added:
|
||||
new_driver_attr_obj = new_driver_attr_list[new_key_list.index(a)]
|
||||
new_driver_attr_obj.create(context, dep_id)
|
||||
|
||||
@classmethod
|
||||
def drv_ah_make_diff(cls, context, dep_id, cpid_id, old_driver_ah_list,
|
||||
new_driver_ah_list):
|
||||
"""Diff new dirver-side AttachHandle Object lists with the old one."""
|
||||
LOG.info("Start differing attach_handles.")
|
||||
new_info_list = [driver_ah_obj.attach_info for driver_ah_obj in
|
||||
new_driver_ah_list]
|
||||
old_info_list = [driver_ah_obj.attach_info for driver_ah_obj in
|
||||
old_driver_ah_list]
|
||||
same = set(new_info_list) & set(old_info_list)
|
||||
LOG.info(new_info_list)
|
||||
LOG.info(old_info_list)
|
||||
# attach-info is same
|
||||
for s in same:
|
||||
# get attach_handle obj
|
||||
new_driver_ah_obj = new_driver_ah_list[new_info_list.index(s)]
|
||||
old_driver_ah_obj = old_driver_ah_list[old_info_list.index(s)]
|
||||
changed_key = ['in_use', 'attach_type']
|
||||
ah_obj = AttachHandle.get_ah_by_depid_attachinfo(context,
|
||||
dep_id, s)
|
||||
for c_k in changed_key:
|
||||
if getattr(new_driver_ah_obj, c_k) != getattr(
|
||||
old_driver_ah_obj, c_k):
|
||||
setattr(ah_obj, c_k, getattr(new_driver_ah_obj, c_k))
|
||||
ah_obj.save(context)
|
||||
# attach_info is deleted.
|
||||
deleted = set(old_info_list) - same
|
||||
for d in deleted:
|
||||
old_driver_ah_obj = old_driver_ah_list[old_info_list.index(d)]
|
||||
old_driver_ah_obj.destroy(context, dep_id)
|
||||
# attach_info is added.
|
||||
added = set(new_info_list) - same
|
||||
for a in added:
|
||||
new_driver_ah_obj = new_driver_ah_list[new_info_list.index(a)]
|
||||
new_driver_ah_obj.create(context, dep_id, cpid_id)
|
||||
|
|
|
@ -144,3 +144,11 @@ class ConductorAPI(object):
|
|||
"""
|
||||
cctxt = self.client.prepare(topic=self.topic)
|
||||
return cctxt.call(context, 'deployable_list')
|
||||
|
||||
def report_data(self, context, hostname, driver_device_list):
|
||||
"""Signal to conductor service to update the cyborg DB
|
||||
:parma context: request context.
|
||||
"""
|
||||
cctxt = self.client.prepare(topic=self.topic)
|
||||
cctxt.call(context, 'report_data', hostname=hostname,
|
||||
driver_device_list=driver_device_list)
|
||||
|
|
Loading…
Reference in New Issue