예제 #1
0
파일: base.py 프로젝트: opnfv/cran
class CyborgPersistentObject(object):
    """Mixin class for Persistent objects.
    This adds the fields that we use in common for most persistent objects.
    """
    fields = {
        'created_at': object_fields.DateTimeField(nullable=True),
        'updated_at': object_fields.DateTimeField(nullable=True),
        'deleted_at': object_fields.DateTimeField(nullable=True),
        'deleted': object_fields.BooleanField(default=False),
        }
예제 #2
0
class DriverAttachHandle(base.DriverObjectBase,
                         object_base.VersionedObjectDictCompat):
    # Version 1.0: Initial version
    VERSION = '1.0'

    fields = {
        'attach_type': object_fields.StringField(nullable=False),
        # PCI BDF or mediated device ID...
        'attach_info': object_fields.StringField(nullable=False),
        # The status of attach_handle, is in use or not.
        'in_use': object_fields.BooleanField(nullable=False, default=False)
    }

    def create(self, context, deployable_id, cpid_id):
        """Create a driver-side AttachHandle object, call AttachHandle
        Object to store in DB.
        """
        attach_handle_obj = AttachHandle(context=context,
                                         deployable_id=deployable_id,
                                         cpid_id=cpid_id,
                                         attach_type=self.attach_type,
                                         attach_info=self.attach_info,
                                         in_use=self.in_use)
        attach_handle_obj.create(context)

    def destroy(self, context, deployable_id):
        ah_obj = AttachHandle.get_ah_by_depid_attachinfo(
            context, deployable_id, self.attach_info)
        if ah_obj is not None:
            ah_obj.destroy(context)

    @classmethod
    def list(cls, context, deployable_id):
        """Form a driver-side attach_handle list for one deployable."""
        ah_obj_list = AttachHandle.get_ah_list_by_deployable_id(
            context, deployable_id)
        driver_ah_obj_list = []
        for ah_obj in ah_obj_list:
            driver_ah_obj = cls(context=context,
                                attach_type=ah_obj.attach_type,
                                attach_info=ah_obj.attach_info,
                                in_use=ah_obj.in_use)
            driver_ah_obj_list.append(driver_ah_obj)
        return driver_ah_obj_list
예제 #3
0
class AttachHandle(base.CyborgObject, object_base.VersionedObjectDictCompat):
    # Version 1.0: Initial version
    VERSION = '1.0'

    dbapi = dbapi.get_instance()

    fields = {
        'id': object_fields.IntegerField(nullable=False),
        'uuid': object_fields.UUIDField(nullable=False),
        'deployable_id': object_fields.IntegerField(nullable=False),
        'cpid_id': object_fields.IntegerField(nullable=False),
        'attach_type': object_fields.EnumField(valid_values=ATTACH_TYPE,
                                               nullable=False),
        # attach_info should be JSON here.
        'attach_info': object_fields.StringField(nullable=False),
        'in_use': object_fields.BooleanField(nullable=False, default=False)
    }

    def create(self, context):
        """Create a AttachHandle record in the DB."""
        values = self.obj_get_changes()
        db_ah = self.dbapi.attach_handle_create(context, values)
        self._from_db_object(self, db_ah)

    @classmethod
    def get(cls, context, uuid):
        """Find a DB AttachHandle and return an Obj AttachHandle."""
        db_ah = cls.dbapi.attach_handle_get_by_uuid(context, uuid)
        obj_ah = cls._from_db_object(cls(context), db_ah)
        return obj_ah

    @classmethod
    def get_by_id(cls, context, id):
        """Find a DB AttachHandle by ID and return an Obj AttachHandle."""
        db_ah = cls.dbapi.attach_handle_get_by_id(context, id)
        obj_ah = cls._from_db_object(cls(context), db_ah)
        return obj_ah

    @classmethod
    def list(cls, context, filters={}):
        """Return a list of AttachHandle objects."""
        if filters:
            sort_dir = filters.pop('sort_dir', 'desc')
            sort_key = filters.pop('sort_key', 'created_at')
            limit = filters.pop('limit', None)
            marker = filters.pop('marker_obj', None)
            db_ahs = cls.dbapi.attach_handle_get_by_filters(context, filters,
                                                            sort_dir=sort_dir,
                                                            sort_key=sort_key,
                                                            limit=limit,
                                                            marker=marker)
        else:
            db_ahs = cls.dbapi.attach_handle_list(context)
        obj_ah_list = cls._from_db_object_list(db_ahs, context)
        return obj_ah_list

    def save(self, context):
        """Update an AttachHandle record in the DB"""
        updates = self.obj_get_changes()
        db_ahs = self.dbapi.attach_handle_update(context, self.uuid, updates)
        self._from_db_object(self, db_ahs)

    def destroy(self, context):
        """Delete a AttachHandle from the DB."""
        self.dbapi.attach_handle_delete(context, self.uuid)
        self.obj_reset_changes()

    @classmethod
    def get_ah_list_by_deployable_id(cls, context, deployable_id):
        ah_filter = {'deployable_id': deployable_id}
        ah_obj_list = AttachHandle.list(context, ah_filter)
        return ah_obj_list

    @classmethod
    def get_ah_by_depid_attachinfo(cls, context, deployable_id, attach_info):
        ah_filter = {'deployable_id': deployable_id,
                     'attach_info': attach_info}
        ah_obj_list = AttachHandle.list(context, ah_filter)
        if len(ah_obj_list) != 0:
            return ah_obj_list[0]
        else:
            return None
예제 #4
0
class Deployable(base.CyborgObject, object_base.VersionedObjectDictCompat):
    # Version 1.0: Initial version
    VERSION = '1.0'

    dbapi = dbapi.get_instance()
    attributes_list = []

    fields = {
        'id': object_fields.IntegerField(nullable=False),
        'uuid': object_fields.UUIDField(nullable=False),
        'name': object_fields.StringField(nullable=False),
        'parent_uuid': object_fields.UUIDField(nullable=True),
        # parent_uuid refers to the id of the VF's parent node
        'root_uuid': object_fields.UUIDField(nullable=True),
        # root_uuid refers to the id of the VF's root which has to be a PF
        'address': object_fields.StringField(nullable=False),
        # if interface_type is pci(/mdev), address is the pci_address(/path)
        'host': object_fields.StringField(nullable=False),
        'board': object_fields.StringField(nullable=False),
        # board refers to a specific acc board type, e.g P100 GPU card
        'vendor': object_fields.StringField(nullable=False),
        'version': object_fields.StringField(nullable=False),
        'type': object_fields.StringField(nullable=False),
        # type of deployable, e.g, pf/vf/*f
        'interface_type': object_fields.StringField(nullable=False),
        # interface to hypervisor(libvirt), e.g, pci/mdev...
        'assignable': object_fields.BooleanField(nullable=False),
        # identify if an accelerator is in use
        'instance_uuid': object_fields.UUIDField(nullable=True),
        # The id of the virtualized accelerator instance
        'availability': object_fields.StringField(nullable=False),
        # identify the state of acc, e.g released/claimed/...
        'accelerator_id': object_fields.IntegerField(nullable=False)
        # Foreign key constrain to reference accelerator table
    }

    def _get_parent_root_uuid(self):
        obj_dep = Deployable.get(None, self.parent_uuid)
        return obj_dep.root_uuid

    def create(self, context):
        """Create a Deployable record in the DB."""
        if 'uuid' not in self:
            raise exception.ObjectActionError(action='create',
                                              reason='uuid is required')

        if not hasattr(self, 'parent_uuid') or self.parent_uuid is None:
            self.root_uuid = self.uuid
        else:
            self.root_uuid = self._get_parent_root_uuid()

        values = self.obj_get_changes()

        db_dep = self.dbapi.deployable_create(context, values)
        self._from_db_object(self, db_dep)
        del self.attributes_list[:]

    @classmethod
    def get(cls, context, uuid):
        """Find a DB Deployable and return an Obj Deployable."""
        db_dep = cls.dbapi.deployable_get(context, uuid)
        obj_dep = cls._from_db_object(cls(context), db_dep)
        # retrieve all the attrobutes for this deployable
        query = {"deployable_id": obj_dep.id}
        attr_get_list = Attribute.get_by_filter(context, query)
        obj_dep.attributes_list = attr_get_list
        return obj_dep

    @classmethod
    def get_by_host(cls, context, host):
        """Get a Deployable by host."""
        db_deps = cls.dbapi.deployable_get_by_host(context, host)
        obj_dpl_list = cls._from_db_object_list(db_deps, context)
        for obj_dpl in obj_dpl_list:
            query = {"deployable_id": obj_dpl.id}
            attr_get_list = Attribute.get_by_filter(context, query)
            obj_dpl.attributes_list = attr_get_list
        return obj_dpl_list

    @classmethod
    def list(cls, context, filters={}):
        """Return a list of Deployable objects."""
        if filters:
            sort_dir = filters.pop('sort_dir', 'desc')
            sort_key = filters.pop('sort_key', 'create_at')
            limit = filters.pop('limit', None)
            marker = filters.pop('marker_obj', None)
            db_deps = cls.dbapi.deployable_get_by_filters(context,
                                                          filters,
                                                          sort_dir=sort_dir,
                                                          sort_key=sort_key,
                                                          limit=limit,
                                                          marker=marker)
        else:
            db_deps = cls.dbapi.deployable_list(context)
        obj_dpl_list = cls._from_db_object_list(db_deps, context)
        for obj_dpl in obj_dpl_list:
            query = {"deployable_id": obj_dpl.id}
            attr_get_list = Attribute.get_by_filter(context, query)
            obj_dpl.attributes_list = attr_get_list
        return obj_dpl_list

    def save(self, context):
        """Update a Deployable record in the DB."""
        updates = self.obj_get_changes()
        db_dep = self.dbapi.deployable_update(context, self.uuid, updates)
        self._from_db_object(self, db_dep)
        query = {"deployable_id": self.id}
        attr_get_list = Attribute.get_by_filter(context, query)
        self.attributes_list = attr_get_list

    def destroy(self, context):
        """Delete a Deployable from the DB."""
        del self.attributes_list[:]
        self.dbapi.deployable_delete(context, self.uuid)
        self.obj_reset_changes()

    def add_attribute(self, context, key, value):
        """add a attribute object to the attribute_list.
        If the attribute already exists, it will update the value,
        otherwise, the vf will be appended to the list
        """

        for exist_attr in self.attributes_list:
            if key == exist_attr.key:
                LOG.warning("The attribute already exists")
                if value != exist_attr.value:
                    exist_attr.value = value
                    exist_attr.save(context)
                return None
        # The attribute does not exist yet. Create it.
        attr_vals = {'deployable_id': self.id, 'key': key, 'value': value}
        attr = Attribute(context, **attr_vals)
        attr.create(context)
        self.attributes_list.append(attr)

    def delete_attribute(self, context, attribute):
        """remove an attribute from the attributes_list
        if the attribute does not exist, ignore it
        """

        idx = 0
        for exist_attribute in self.attributes_list:
            if base.obj_equal_prims(attribute, exist_attribute):
                removed_attribute = self.attributes_list.pop(idx)
                removed_attribute.destroy(context)
                return
            idx = idx + 1
        LOG.warning("The removing attribute does not exist!")

    @classmethod
    def get_by_filter(cls, context, filters):
        obj_dpl_list = []
        db_dpl_list = cls.dbapi.deployable_get_by_filters_with_attributes(
            context, filters)

        if db_dpl_list:
            for db_dpl in db_dpl_list:
                obj_dpl = cls._from_db_object(cls(context), db_dpl)
                query = {"deployable_id": obj_dpl.id}
                attr_get_list = Attribute.get_by_filter(context, query)
                obj_dpl.attributes_list = attr_get_list
                obj_dpl_list.append(obj_dpl)

        return obj_dpl_list

    @classmethod
    def _from_db_object(cls, obj, db_obj):
        """Converts a deployable 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 = base.CyborgObject._from_db_object(obj, db_obj)
        obj.attributes_list = []

        return obj
예제 #5
0
class Deployable(base.CyborgObject, object_base.VersionedObjectDictCompat):
    # Version 1.0: Initial version
    VERSION = '1.0'

    dbapi = dbapi.get_instance()

    fields = {
        'uuid': object_fields.UUIDField(nullable=False),
        'name': object_fields.StringField(nullable=False),
        'parent_uuid': object_fields.UUIDField(nullable=True),
        # parent_uuid refers to the id of the VF's parent node
        'root_uuid': object_fields.UUIDField(nullable=True),
        # root_uuid refers to the id of the VF's root which has to be a PF
        'pcie_address': object_fields.StringField(nullable=False),
        'host': object_fields.StringField(nullable=False),
        'board': object_fields.StringField(nullable=False),
        # board refers to a specific acc board type, e.g P100 GPU card
        'vendor': object_fields.StringField(nullable=False),
        'version': object_fields.StringField(nullable=False),
        'type': object_fields.StringField(nullable=False),
        # similar to the acc_type in accelerator.py
        'assignable': object_fields.BooleanField(nullable=False),
        # identify if an accelerator is in use
        'instance_uuid': object_fields.UUIDField(nullable=True),
        # The id of the virtualized accelerator instance
        'availability': object_fields.StringField(nullable=False),
        # identify the state of acc, e.g released/claimed/...
    }

    def _get_parent_root_uuid(self):
        obj_dep = Deployable.get(None, self.parent_uuid)
        return obj_dep.root_uuid

    def create(self, context):
        """Create a Deployable record in the DB."""
        if 'uuid' not in self:
            raise exception.ObjectActionError(action='create',
                                              reason='uuid is required')

        if self.parent_uuid is None:
            self.root_uuid = self.uuid
        else:
            self.root_uuid = self._get_parent_root_uuid()

        values = self.obj_get_changes()
        db_dep = self.dbapi.deployable_create(context, values)
        self._from_db_object(self, db_dep)

    @classmethod
    def get(cls, context, uuid):
        """Find a DB Deployable and return an Obj Deployable."""
        db_dep = cls.dbapi.deployable_get(context, uuid)
        obj_dep = cls._from_db_object(cls(context), db_dep)
        return obj_dep

    @classmethod
    def get_by_host(cls, context, host):
        """Get a Deployable by host."""
        db_deps = cls.dbapi.deployable_get_by_host(context, host)
        return cls._from_db_object_list(db_deps, context)

    @classmethod
    def list(cls, context):
        """Return a list of Deployable objects."""
        db_deps = cls.dbapi.deployable_list(context)
        return cls._from_db_object_list(db_deps, context)

    def save(self, context):
        """Update a Deployable record in the DB."""
        updates = self.obj_get_changes()
        db_dep = self.dbapi.deployable_update(context, self.uuid, updates)
        self._from_db_object(self, db_dep)

    def destroy(self, context):
        """Delete a Deployable from the DB."""
        self.dbapi.deployable_delete(context, self.uuid)
        self.obj_reset_changes()
예제 #6
0
파일: deployable.py 프로젝트: opnfv/cran
class Deployable(base.CyborgObject, object_base.VersionedObjectDictCompat):
    # Version 1.0: Initial version
    VERSION = '1.0'

    dbapi = dbapi.get_instance()
    attributes_list = []

    fields = {
        'id': object_fields.IntegerField(nullable=False),
        'uuid': object_fields.UUIDField(nullable=False),
        'name': object_fields.StringField(nullable=False),
        'parent_uuid': object_fields.UUIDField(nullable=True),
        # parent_uuid refers to the id of the VF's parent node
        'root_uuid': object_fields.UUIDField(nullable=True),
        # root_uuid refers to the id of the VF's root which has to be a PF
        'pcie_address': object_fields.StringField(nullable=False),
        'host': object_fields.StringField(nullable=False),
        'board': object_fields.StringField(nullable=False),
        # board refers to a specific acc board type, e.g P100 GPU card
        'vendor': object_fields.StringField(nullable=False),
        'version': object_fields.StringField(nullable=False),
        'type': object_fields.StringField(nullable=False),
        # similar to the acc_type in accelerator.py
        'assignable': object_fields.BooleanField(nullable=False),
        # identify if a instance is in use
        'instance_uuid': object_fields.UUIDField(nullable=True),
        # The id of the virtualized accelerator instance
        'availability': object_fields.StringField(nullable=False),
        # identify the state of acc, e.g released/claimed/...
        # 'accelerator_id': object_fields.IntegerField(nullable=False)
        # Foreign key constrain to reference accelerator table.
    }

    def _get_parent_root_uuid(self):
        obj_dep = Deployable.get(None, self.parent_uuid)
        return obj_dep.root_uuid

    def create(self, context):
        """Create a Deployable record in the DB."""
        if 'uuid' not in self:
            raise exception.ObjectActionError(action='create',
                                              reason='uuid is required')

        if self.parent_uuid is None:
            self.root_uuid = self.uuid
        else:
            self.root_uuid = self._get_parent_root_uuid()

        values = self.obj_get_changes()
        db_dep = self.dbapi.deployable_create(context, values)
        self._from_db_object(self, db_dep)

    @classmethod
    def get(cls, context, uuid):
        """Find a DB Deployable and return an Obj Deployable."""
        db_dep = cls.dbapi.deployable_get(context, uuid)
        obj_dep = cls._from_db_object(cls(context), db_dep)
        return obj_dep

    @classmethod
    def get_by_host(cls, context, host):
        """Get a Deployable by host."""
        db_deps = cls.dbapi.deployable_get_by_host(context, host)
        return cls._from_db_object_list(context, db_deps)

    @classmethod
    def list(cls, context):
        """Return a list of Deployable objects."""
        db_deps = cls.dbapi.deployable_list(context)
        return cls._from_db_object_list(context, db_deps)

    def save(self, context):
        """Update a Deployable record in the DB."""
        updates = self.obj_get_changes()
        db_dep = self.dbapi.deployable_update(context, self.uuid, updates)
        self._from_db_object(self, db_dep)

    def destroy(self, context):
        """Delete a Deployable from the DB."""
        self.dbapi.deployable_delete(context, self.uuid)
        self.obj_reset_changes()

    def add_attribute(self, attribute):
        """add a attribute object to the attribute_list.
        If the attribute already exists, it will update the value,
        otherwise, the vf will be appended to the list.
        """
        if not isinstance(attribute, Attribute):
            raise exception.InvalidDeployType()
        for exist_attr in self.attributes_list:
            if base.obj_equal_prims(vf, exist_attr):
                LOG.warning("The attribute already exists.")
                return None

    @classmethod
    def get_by_filter(cls,
                      context,
                      filters,
                      sort_key='created_at',
                      sort_dir='desc',
                      limit=None,
                      marker=None,
                      join=None):
        obj_dpl_list = []
        db_dpl_list = cls.dbapi.deployable_get_by_filters(context,
                                                          filters,
                                                          sort_key=sort_key,
                                                          sort_dir=sort_dir,
                                                          limit=limit,
                                                          marker=marker,
                                                          join_columns=join)
        for db_dpl in db_dpl_list:
            obj_dpl = cls._from_db_object(cls(context), db_dpl)
            obj_dpl_list.append(obj_dpl)
        return obj_dpl_list
예제 #7
0
class DriverDevice(base.DriverObjectBase,
                   object_base.VersionedObjectDictCompat):
    # Version 1.0: Initial version
    VERSION = '1.0'

    fields = {
        'vendor':
        object_fields.StringField(nullable=False),
        'model':
        object_fields.StringField(nullable=False),
        'type':
        object_fields.DeviceTypeField(nullable=False),
        'std_board_info':
        object_fields.StringField(nullable=True),
        # vendor board info should be a dict for driver-specific resource
        # provider.
        'vendor_board_info':
        object_fields.StringField(nullable=True),
        # hostname will be set by the agent, so driver don't need to report.
        # Each controlpath_id corresponds to a different PF. For now
        # we are sticking with a single cpid.
        'controlpath_id':
        object_fields.ObjectField('DriverControlPathID', nullable=False),
        'deployable_list':
        object_fields.ListOfObjectsField('DriverDeployable',
                                         default=[],
                                         nullable=False),
        'stub':
        object_fields.BooleanField(nullable=False, default=False)
    }

    def create(self, context, host):
        """Create a driver-side Device Object into DB. This object will be
        stored in many db tables: device, deployable, attach_handle,
        controlpath_id etc. by calling related Object.
        """
        # first store in device table through Device Object.

        device_obj = Device(context=context,
                            type=self.type,
                            vendor=self.vendor,
                            model=self.model,
                            hostname=host)
        if hasattr(self, 'std_board_info'):
            device_obj.std_board_info = self.std_board_info
        if hasattr(self, 'vendor_board_info'):
            device_obj.vendor_board_info = self.vendor_board_info
        device_obj.create(context)

        # for the controlpath_id, call driver_controlpath_id to create.
        cpid_obj = self.controlpath_id.create(context, device_obj.id)
        # for deployable_list, call internal layer object: driver_deployable
        # to create.
        for driver_deployable in self.deployable_list:
            driver_deployable.create(context, device_obj.id, cpid_obj.id)

    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)
        # delete deployable_list first.
        for driver_deployable in self.deployable_list:
            driver_deployable.destroy(context, device_obj.id)
        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 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

    @classmethod
    def list(cls, context, host):
        """Form driver-side device object list from DB for one host.
        A list may contains driver_device_object without controlpath_id.(In
        the case some of controlpath_id can't store successfully but its
        devices stores successfully.)
        """
        # get dev_obj_list from hostname
        dev_obj_list = Device.get_list_by_hostname(context, host)
        driver_dev_obj_list = []
        for dev_obj in dev_obj_list:
            cpid = DriverControlPathID.get(context, dev_obj.id)
            # NOTE: will not return device without controlpath_id.
            if cpid is not None:
                driver_dev_obj = \
                    cls(context=context, vendor=dev_obj.vendor,
                        model=dev_obj.model, type=dev_obj.type,
                        std_board_info=dev_obj.std_board_info,
                        vendor_board_info=dev_obj.vendor_board_info,
                        controlpath_id=cpid,
                        deployable_list=DriverDeployable.list(context,
                                                              dev_obj.id)
                        )
                driver_dev_obj_list.append(driver_dev_obj)
        return driver_dev_obj_list

    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