def create(self, context, device_id): """Create a driver-side ControlPathID for drivers. Call ControlpathID object to store in DB.""" cpid_obj = ControlpathID(context=context, device_id=device_id, cpid_type=self.cpid_type, cpid_info=self.cpid_info) cpid_obj.create(context) return cpid_obj
def get_device_obj_by_device_id(self, context, device_id): """Get device object by device id. :param context: requested context. :param host: hostname of the node. :return: a device object of current driver device object. It will return on value because it has controlpath_id. """ # get dev_obj_list from hostname device_obj = Device.get_by_device_id(context, device_id) # use controlpath_id.cpid_info to identiy one Device. # get cpid_obj, could be empty or only one value. ControlpathID.get_by_device_id_cpidinfo(context, device_obj.id, self.controlpath_id.cpid_info) # find the one cpid_obj with cpid_info return device_obj
def get(cls, context, device_id): # return None when can't found any. cpid_obj = ControlpathID.get_by_device_id(context, device_id) driver_cpid_obj = None if cpid_obj is not None: driver_cpid_obj = cls(context=context, cpid_type=cpid_obj.cpid_type, cpid_info=cpid_obj.cpid_info) return driver_cpid_obj
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)
def destroy(self, context, host): """Delete a driver-side Device Object from db. This should delete the internal layer objects.""" # get dev_obj_list from hostname device_obj = self.get_device_obj(context, host) if hasattr(self.controlpath_id, 'cpid_info'): cpid_obj = ControlpathID.get_by_device_id_cpidinfo( context, device_obj.id, self.controlpath_id.cpid_info) # delete controlpath_id cpid_obj.destroy(context) # delete deployable_list first. for driver_deployable in self.deployable_list: driver_deployable.destroy(context, device_obj.id) # delete the device device_obj.destroy(context)
def get_device_obj(self, context, host): """Get a driver-side Device Object from db. :param context: requested context. :param host: hostname of the node. :return: a device object of current driver device object. It will return on value because it has controlpath_id. """ # get dev_obj_list from hostname device_obj_list = Device.get_list_by_hostname(context, host) # use controlpath_id.cpid_info to identiy one Device. for device_obj in device_obj_list: # get cpid_obj, could be empty or only one value. cpid_obj = ControlpathID.get_by_device_id_cpidinfo( context, device_obj.id, self.controlpath_id.cpid_info) # find the one cpid_obj with cpid_info if cpid_obj is not None: return device_obj
def destroy(self, context, device_id): cpid_obj = ControlpathID.get_by_device_id_cpidinfo( context, device_id, self.cpid_info) if cpid_obj is not None: cpid_obj.destroy(context)
def drv_device_make_diff(self, 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. stub_cpid_list = [ driver_dev_obj.controlpath_id.cpid_info for driver_dev_obj in new_driver_device_list if driver_dev_obj.stub ] 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) - set(stub_cpid_list) added = set(new_cpid_list) - same - set(stub_cpid_list) deleted = set(old_cpid_list) - same - set(stub_cpid_list) host_rp = self._get_root_provider(context, host) # device is deleted. for d in deleted: old_driver_dev_obj = old_driver_device_list[old_cpid_list.index(d)] for driver_dep_obj in old_driver_dev_obj.deployable_list: rp_uuid = self.get_rp_uuid_from_obj(driver_dep_obj) self._delete_provider_and_sub_providers(context, rp_uuid) 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)] try: new_driver_dev_obj.create(context, host) except Exception as exc: LOG.exception( "Failed to add device %(device)s. " "Reason: %(reason)s", { 'device': new_driver_dev_obj, 'reason': exc }) new_driver_dev_obj.destroy(context, host) # TODO(All): If report data to Placement raise exception, we # should revert driver device 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. cleanup_inconsistency_resources = False for driver_dep_obj in new_driver_dev_obj.deployable_list: try: self.get_placement_needed_info_and_report( context, driver_dep_obj, host_rp) except Exception as exc: LOG.info( "Failed to add device %(device)s. " "Reason: %(reason)s", { 'device': new_driver_dev_obj, 'reason': exc }) cleanup_inconsistency_resources = True break if cleanup_inconsistency_resources: new_driver_dev_obj.destroy(context, host) for driver_dep_obj in new_driver_dev_obj.deployable_list: rp_uuid = self.get_rp_uuid_from_obj(driver_dep_obj) self._delete_provider_and_sub_providers(context, rp_uuid) 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 self.drv_deployable_make_diff(context, dev_obj.id, cpid_obj.id, old_driver_dev_obj.deployable_list, new_driver_dev_obj.deployable_list, host_rp)