def drv_deployable_make_diff(self, context, device_id, cpid_id, old_driver_dep_list, new_driver_dep_list, host_rp): """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 # name is deleted. for d in deleted: old_driver_dep_obj = old_driver_dep_list[old_name_list.index(d)] rp_uuid = self.get_rp_uuid_from_obj(old_driver_dep_obj) old_driver_dep_obj.destroy(context, device_id) self._delete_provider_and_sub_providers(context, rp_uuid) # 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) self.get_placement_needed_info_and_report(context, new_driver_dep_obj, host_rp) 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) rp_uuid = self.get_rp_uuid_from_obj(new_driver_dep_obj) attrs = new_driver_dep_obj.attribute_list resource_class = [i.value for i in attrs if i.key == 'rc'][0] inv_data = _gen_resource_inventory(resource_class, dep_obj.num_accelerators) self.placement_client.update_inventory(rp_uuid, inv_data) # 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 self.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 self.drv_ah_make_diff(context, dep_obj.id, cpid_id, old_driver_dep_obj.attach_handle_list, new_driver_dep_obj.attach_handle_list)
def _from_db_object(cls, obj, db_obj): """Converts a physical function to a formal object. :param obj: An object of the class. :param db_obj: A DB model of the object :return: The object of the class with the database entity added """ obj = Deployable._from_db_object(obj, db_obj) if cls is PhysicalFunction: obj.virtual_function_list = [] return obj
def get_by_name(cls, context, name): """Form driver-side Deployable object list from DB for one device.""" # get deployable_obj_list for one device_id dep_obj = Deployable.get_by_name(context, name) driver_ah_obj_list = DriverAttachHandle.list(context, dep_obj.id) # get driver_attr_obj_list fro this dep_obj driver_attr_obj_list = DriverAttribute.list(context, dep_obj.id) driver_dep_obj = cls(context=context, name=dep_obj.name, num_accelerators=dep_obj.num_accelerators, attribute_list=driver_attr_obj_list, attach_handle_list=driver_ah_obj_list) return driver_dep_obj
def create(self, context, device_id, cpid_id): """Create a driver-side Deployable object into DB. This object will be stored in seperate db tables: deployable & attach_handle & attribute table.""" # first store in deployable table through Deployable Object. deployable_obj = Deployable(context=context, name=self.name, num_accelerators=self.num_accelerators, device_id=device_id) deployable_obj.create(context) # create attribute_list for this deployable if hasattr(self, 'attribute_list'): for driver_attr in self.attribute_list: driver_attr.create(context, deployable_obj.id) # create attach_handle_list for this deployable if hasattr(self, 'attach_handle_list'): for driver_attach_handle in self.attach_handle_list: driver_attach_handle.create(context, deployable_obj.id, cpid_id)
def drv_attr_make_diff(self, context, dep_id, old_driver_attr_list, new_driver_attr_list): """Diff new driver-side Attribute Object lists with the old one.""" LOG.info("Start differing attributes.") dep_obj = Deployable.get_by_id(context, dep_id) driver_dep = DriverDeployable.get_by_name(context, dep_obj.name) rp_uuid = self.get_rp_uuid_from_obj(driver_dep) 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 deleted. deleted = set(old_key_list) - same for d in deleted: old_driver_attr_obj = old_driver_attr_list[old_key_list.index(d)] self.placement_client.delete_trait_by_name( context, rp_uuid, old_driver_attr_obj.value) old_driver_attr_obj.delete_by_key(context, dep_id, d) # 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) self.placement_client.add_traits_to_rp(rp_uuid, [new_driver_attr_obj.value]) # 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) # Update traits here. if new_driver_attr_obj.key.startswith("trait"): self.placement_client.delete_trait_by_name( context, rp_uuid, old_driver_attr_obj.value) self.placement_client.add_traits_to_rp( rp_uuid, [new_driver_attr_obj.value]) # Update resource classes here. if new_driver_attr_obj.key.startswith("rc"): self.placement_client.ensure_resource_classes( context, [new_driver_attr_obj.value]) inv_data = _gen_resource_inventory( new_driver_attr_obj.value, dep_obj.num_accelerators) self.placement_client.update_inventory(rp_uuid, inv_data) self.placement_client.delete_rc_by_name( context, old_driver_attr_obj.value)
def get_placement_needed_info_and_report(self, context, obj, parent_uuid=None): pr_name = obj.name attrs = obj.attribute_list resource_class = [i.value for i in attrs if i.key == 'rc'][0] traits = [i.value for i in attrs if six.ensure_str(i.key).startswith("trait")] total = obj.num_accelerators rp_uuid = self.provider_report(context, pr_name, resource_class, traits, total, parent_uuid) dep_obj = Deployable.get_by_name(context, pr_name) dep_obj["rp_uuid"] = rp_uuid dep_obj.save(context)
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)
def destroy(self, context, device_id): """delete one driver-side deployable by calling existing Deployable and AttachHandle Object. Use name&host to identify Deployable and attach_info to identify the AttachHandle""" # get deployable_id by name, get only one value. dep_obj = Deployable.get_by_name_deviceid(context, self.name, device_id) # delete attach_handle if hasattr(self, 'attach_handle_list'): for driver_ah_obj in self.attach_handle_list: # get attach_handle_obj, exist and only one. driver_ah_obj.destroy(context, dep_obj.id) # delete attribute_list if hasattr(self, 'attribute_list'): DriverAttribute.destroy(context, dep_obj.id) # delete dep_obj if dep_obj is not None: dep_obj.destroy(context)
def drv_deployable_make_diff(self, context, device_id, cpid_id, old_driver_dep_list, new_driver_dep_list, host_rp): """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 # name is deleted. for d in deleted: old_driver_dep_obj = old_driver_dep_list[old_name_list.index(d)] rp_uuid = self.get_rp_uuid_from_obj(old_driver_dep_obj) old_driver_dep_obj.destroy(context, device_id) self._delete_provider_and_sub_providers(context, rp_uuid) # 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) try: self.get_placement_needed_info_and_report( context, new_driver_dep_obj, host_rp) except Exception as exc: LOG.info( "Failed to add deployable %(deployable)s. " "Reason: %(reason)s", { 'deployable': new_driver_dep_obj, 'reason': exc }) new_driver_dep_obj.destroy(context, device_id) rp_uuid = self.get_rp_uuid_from_obj(new_driver_dep_obj) # TODO(All): If report data to Placement raise exception, we # should revert driver deployable created in Cyborg and # rp created in Placement to reduce the risk of data # inconsistency here between Cyborg and Placement, # we will consider to fix in V release. self._delete_provider_and_sub_providers(context, rp_uuid) 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) rp_uuid = self.get_rp_uuid_from_obj(new_driver_dep_obj) attrs = new_driver_dep_obj.attribute_list resource_class = [i.value for i in attrs if i.key == 'rc'][0] inv_data = _gen_resource_inventory(resource_class, dep_obj.num_accelerators) self.placement_client.update_inventory(rp_uuid, inv_data) # 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 self.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 self.drv_ah_make_diff(context, dep_obj.id, cpid_id, old_driver_dep_obj.attach_handle_list, new_driver_dep_obj.attach_handle_list)