diff options
Diffstat (limited to 'cyborg_enhancement/mitaka_version/cyborg/cyborg/objects')
9 files changed, 832 insertions, 0 deletions
diff --git a/cyborg_enhancement/mitaka_version/cyborg/cyborg/objects/__init__.py b/cyborg_enhancement/mitaka_version/cyborg/cyborg/objects/__init__.py new file mode 100644 index 0000000..a313564 --- /dev/null +++ b/cyborg_enhancement/mitaka_version/cyborg/cyborg/objects/__init__.py @@ -0,0 +1,30 @@ +# Copyright 2017 Huawei Technologies Co.,LTD. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +# NOTE(comstud): You may scratch your head as you see code that imports +# this module and then accesses attributes for objects such as Node, +# etc, yet you do not see these attributes in here. Never fear, there is +# a little bit of magic. When objects are registered, an attribute is set +# on this module automatically, pointing to the newest/latest version of +# the object. + + +def register_all(): + # NOTE(danms): You must make sure your object gets imported in this + # function in order for it to be registered by services that may + # need to receive it via RPC. + __import__('cyborg.objects.accelerator') + __import__('cyborg.objects.port') + __import__('cyborg.objects.deployable') diff --git a/cyborg_enhancement/mitaka_version/cyborg/cyborg/objects/accelerator.py b/cyborg_enhancement/mitaka_version/cyborg/cyborg/objects/accelerator.py new file mode 100644 index 0000000..a19774b --- /dev/null +++ b/cyborg_enhancement/mitaka_version/cyborg/cyborg/objects/accelerator.py @@ -0,0 +1,84 @@ +# Copyright 2017 Huawei Technologies Co.,LTD. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from oslo_log import log as logging +from oslo_versionedobjects import base as object_base + +from cyborg.db import api as dbapi +from cyborg.objects import base +from cyborg.objects import fields as object_fields + + +LOG = logging.getLogger(__name__) + + +@base.CyborgObjectRegistry.register +class Accelerator(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), + 'name': object_fields.StringField(nullable=False), + 'description': object_fields.StringField(nullable=True), + 'project_id': object_fields.UUIDField(nullable=True), + 'user_id': object_fields.UUIDField(nullable=True), + 'device_type': object_fields.StringField(nullable=False), + # The type of the accelerator device, e.g GPU, FPGA, ... + 'acc_type': object_fields.StringField(nullable=False), + # acc_type defines the usage of the accelerator, e.g Crypto + 'acc_capability': object_fields.StringField(nullable=False), + # acc_capability defines the specific capability, e.g AES + 'vendor_id': object_fields.StringField(nullable=False), + # vendor_id refers to ids like NVIDIA, XILINX, INTEL,... + 'product_id': object_fields.StringField(nullable=False), + # product_id refers to ids like P100 + 'remotable': object_fields.IntegerField(nullable=False), + # remotable ids if remote accelerator is supported + } + + def create(self, context): + """Create an Accelerator record in the DB.""" + values = self.obj_get_changes() + db_acc= self.dbapi.accelerator_create(context, values) + self._from_db_object(self, db_acc) + + @classmethod + def get(cls, context, uuid): + """Find a DB Accelerator and return an Ojb Accelerator.""" + db_acc = cls.dbapi.accelerator_get(context, uuid) + obj_acc = cls._from_db_object(cls(context), db_acc) + return obj_acc + + @classmethod + def list(cls, context, limit, marker, sort_key, sort_dir, project_only): + """Return a list of Accelerator objects.""" + db_accs = cls.dbapi.accelerator_list(context, limit, marker, sort_key, + sort_dir, project_only) + return cls._from_db_object_list(context, db_accs) + + def save(self, context): + """Update an Accelerator record in the DB.""" + updates = self.obj_get_changes() + db_acc = self.dbapi.accelerator_update(context, self.uuid, updates) + self._from_db_object(self, db_acc) + + def destory(self, context): + """Delete the Accelerator record from the DB.""" + self.dbapi.accelerator_destory(context, self.uuid) + self.obj_reset_changes() diff --git a/cyborg_enhancement/mitaka_version/cyborg/cyborg/objects/attribute.py b/cyborg_enhancement/mitaka_version/cyborg/cyborg/objects/attribute.py new file mode 100644 index 0000000..460424b --- /dev/null +++ b/cyborg_enhancement/mitaka_version/cyborg/cyborg/objects/attribute.py @@ -0,0 +1,84 @@ +# Copyright 2018 Huawei Technologies Co.,LTD.
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from oslo_log import log as logging
+from oslo_versionedobjects import base as object_base
+
+from cyborg.common import exception
+from cyborg.db import api as dbapi
+from cyborg.objects import base
+from cyborg.objects import fields as object_fields
+
+
+LOG = logging.getLogger(__name__)
+
+
+@base.CyborgObjectRegistry.register
+class Attribute(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),
+ 'key': object_fields.StringField(nullable=False),
+ 'value': object_fields.StringField(nullable=False)
+ }
+
+ def create(self, context):
+ """Create an attribute record in the DB."""
+ if self.deployable_id is None:
+ raise exception.AttributeInvalid()
+
+ values = self.obj_get_changes()
+ db_attr = self.dbapi.attribute_create(context,
+ self.key,
+ self.value)
+ self._from_db_object(self, db_attr)
+
+ @classmethod
+ def get(cls, context, uuid):
+ """Find a DB attribute and return an Obj attribute."""
+ db_attr = cls.dbapi.attribute_get(context, uuid)
+ obj_attr = cls._from_db_object(cls(context), db_attr)
+ return obj_attr
+
+ @classmethod
+ def attribute_get_by_deployable_uuid(cls, context, deployable_uuid):
+ """Get an attribute by deployable uuid."""
+ db_attr = cls.dbapi.attribute_get_by_deployable_uuid(context,
+ deployable_uuid)
+ return cls._from_db_object_list(db_attr, context)
+
+ def save(self, context):
+ """Update an attribute record in the DB."""
+ updates = self.obj_get_changes()
+ db_attr = self.dbapi.attribute_update(context,
+ self.uuid,
+ self.key,
+ self.value)
+ self._from_db_object(self, db_attr)
+
+ def destroy(self, context):
+ """Delete an attribute from the DB."""
+ self.dbapi.attribute_delete(context, self.uuid)
+ self.obj_reset_changes()
+
+ def set_key_value_pair(self, set_key, set_value):
+ self.key = set_key
+ self.value = set_value
diff --git a/cyborg_enhancement/mitaka_version/cyborg/cyborg/objects/base.py b/cyborg_enhancement/mitaka_version/cyborg/cyborg/objects/base.py new file mode 100644 index 0000000..49370f9 --- /dev/null +++ b/cyborg_enhancement/mitaka_version/cyborg/cyborg/objects/base.py @@ -0,0 +1,176 @@ +# Copyright 2017 Huawei Technologies Co.,LTD. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +"""Cyborg common internal object model""" + +from oslo_utils import versionutils +from oslo_versionedobjects import base as object_base + +from cyborg import objects +from cyborg.objects import fields as object_fields +import netaddr + + +class CyborgObjectRegistry(object_base.VersionedObjectRegistry): + def registration_hook(self, cls, index): + # NOTE(jroll): blatantly stolen from nova + # NOTE(danms): This is called when an object is registered, + # and is responsible for maintaining cyborg.objects.$OBJECT + # as the highest-versioned implementation of a given object. + version = versionutils.convert_version_to_tuple(cls.VERSION) + if not hasattr(objects, cls.obj_name()): + setattr(objects, cls.obj_name(), cls) + else: + cur_version = versionutils.convert_version_to_tuple( + getattr(objects, cls.obj_name()).VERSION) + if version >= cur_version: + setattr(objects, cls.obj_name(), cls) + + +class CyborgObject(object_base.VersionedObject): + """Base class and object factory. + + This forms the base of all objects that can be remoted or instantiated + via RPC. Simply defining a class that inherits from this base class + will make it remotely instantiatable. Objects should implement the + necessary "get" classmethod routines as well as "save" object methods + as appropriate. + """ + + OBJ_SERIAL_NAMESPACE = 'cyborg_object' + OBJ_PROJECT_NAMESPACE = 'cyborg' + + fields = { + 'created_at': object_fields.DateTimeField(nullable=True), + 'updated_at': object_fields.DateTimeField(nullable=True), + } + + def as_dict(self): + return dict((k, getattr(self, k)) + for k in self.fields + if hasattr(self, k)) + + @staticmethod + def _from_db_object(obj, db_obj): + """Converts a database entity 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 + """ + + for field in obj.fields: + obj[field] = db_obj[field] + + obj.obj_reset_changes() + return obj + + @classmethod + def _from_db_object_list(cls, context, db_objs): + """Converts a list of database entities to a list of formal objects.""" + objs = [] + for db_obj in db_objs: + objs.append(cls._from_db_object(cls(context), db_obj)) + return objs + +class CyborgObjectSerializer(object_base.VersionedObjectSerializer): + # Base class to use for object hydration + OBJ_BASE_CLASS = CyborgObject + + +CyborgObjectDictCompat = object_base.VersionedObjectDictCompat + + +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), + } + + +class ObjectListBase(object_base.ObjectListBase): + + @classmethod + def _obj_primitive_key(cls, field): + return 'cyborg_object.%s' % field + + @classmethod + def _obj_primitive_field(cls, primitive, field, + default=object_fields.UnspecifiedDefault): + key = cls._obj_primitive_key(field) + if default == object_fields.UnspecifiedDefault: + return primitive[key] + else: + return primitive.get(key, default) + + +def obj_to_primitive(obj): + """Recursively turn an object into a python primitive. + A CyborgObject becomes a dict, and anything that implements ObjectListBase + becomes a list. + """ + if isinstance(obj, ObjectListBase): + return [obj_to_primitive(x) for x in obj] + elif isinstance(obj, CyborgObject): + result = {} + for key in obj.obj_fields: + if obj.obj_attr_is_set(key) or key in obj.obj_extra_fields: + result[key] = obj_to_primitive(getattr(obj, key)) + return result + elif isinstance(obj, netaddr.IPAddress): + return str(obj) + elif isinstance(obj, netaddr.IPNetwork): + return str(obj) + else: + return obj + + + +def obj_equal_prims(obj_1, obj_2, ignore=None): + """Compare two primitives for equivalence ignoring some keys. + This operation tests the primitives of two objects for equivalence. + Object primitives may contain a list identifying fields that have been + changed - this is ignored in the comparison. The ignore parameter lists + any other keys to be ignored. + :param:obj1: The first object in the comparison + :param:obj2: The second object in the comparison + :param:ignore: A list of fields to ignore + :returns: True if the primitives are equal ignoring changes + and specified fields, otherwise False. + """ + + def _strip(prim, keys): + if isinstance(prim, dict): + for k in keys: + prim.pop(k, None) + for v in prim.values(): + _strip(v, keys) + if isinstance(prim, list): + for v in prim: + _strip(v, keys) + return prim + + if ignore is not None: + keys = ['cyborg_object.changes'] + ignore + else: + keys = ['cyborg_object.changes'] + prim_1 = _strip(obj_1.obj_to_primitive(), keys) + prim_2 = _strip(obj_2.obj_to_primitive(), keys) + return prim_1 == prim_2 diff --git a/cyborg_enhancement/mitaka_version/cyborg/cyborg/objects/deployable.py b/cyborg_enhancement/mitaka_version/cyborg/cyborg/objects/deployable.py new file mode 100644 index 0000000..3f152c6 --- /dev/null +++ b/cyborg_enhancement/mitaka_version/cyborg/cyborg/objects/deployable.py @@ -0,0 +1,139 @@ +# Copyright 2018 Huawei Technologies Co.,LTD. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from oslo_log import log as logging +from oslo_versionedobjects import base as object_base + +from cyborg.common import exception +from cyborg.db import api as dbapi +from cyborg.objects import base +from cyborg.objects import fields as object_fields +# from cyborg.objects.attribute import Attribute + + +LOG = logging.getLogger(__name__) + + +@base.CyborgObjectRegistry.register +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 diff --git a/cyborg_enhancement/mitaka_version/cyborg/cyborg/objects/fields.py b/cyborg_enhancement/mitaka_version/cyborg/cyborg/objects/fields.py new file mode 100644 index 0000000..52d3349 --- /dev/null +++ b/cyborg_enhancement/mitaka_version/cyborg/cyborg/objects/fields.py @@ -0,0 +1,30 @@ +# Copyright 2017 Huawei Technologies Co.,LTD. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from oslo_versionedobjects import fields as object_fields + + +IntegerField = object_fields.IntegerField +UUIDField = object_fields.UUIDField +StringField = object_fields.StringField +DateTimeField = object_fields.DateTimeField +# added for port object +BooleanField = object_fields.BooleanField +ObjectField = object_fields.ObjectField +ListOfObjectsField = object_fields.ListOfObjectsField +ListOfStringsField = object_fields.ListOfStringsField +IPAddressField = object_fields.IPAddressField +IPNetworkField = object_fields.IPNetworkField +UnspecifiedDefault = object_fields.UnspecifiedDefault diff --git a/cyborg_enhancement/mitaka_version/cyborg/cyborg/objects/physical_function.py b/cyborg_enhancement/mitaka_version/cyborg/cyborg/objects/physical_function.py new file mode 100644 index 0000000..4445565 --- /dev/null +++ b/cyborg_enhancement/mitaka_version/cyborg/cyborg/objects/physical_function.py @@ -0,0 +1,137 @@ +# Copyright 2018 Huawei Technologies Co.,LTD.
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import copy
+from oslo_log import log as logging
+from oslo_versionedobjects import base as object_base
+
+from cyborg.common import exception
+from cyborg.db import api as dbapi
+from cyborg.objects import base
+from cyborg.objects import fields as object_fields
+from cyborg.objects.deployable import Deployable
+from cyborg.objects.virtual_function import VirtualFunction
+
+LOG = logging.getLogger(__name__)
+
+
+@base.CyborgObjectRegistry.register
+class PhysicalFunction(Deployable):
+ # Version 1.0: Initial version
+ VERSION = '1.0'
+ virtual_function_list = []
+
+ def create(self, context):
+ # To ensure the creating type is PF
+ if self.type != 'pf':
+ raise exception.InvalidDeployType()
+ super(PhysicalFunction, self).create(context)
+
+ def save(self, context):
+ """In addition to save the pf, it should also save the
+ vfs associated with this pf
+ """
+ # To ensure the saving type is PF
+ if self.type != 'pf':
+ raise exception.InvalidDeployType()
+
+ for exist_vf in self.virtual_function_list:
+ exist_vf.save(context)
+ super(PhysicalFunction, self).save(context)
+
+ def add_vf(self, vf):
+ """add a vf object to the virtual_function_list.
+ If the vf already exists, it will ignore,
+ otherwise, the vf will be appended to the list
+ """
+ if not isinstance(vf, VirtualFunction) or vf.type != 'vf':
+ raise exception.InvalidDeployType()
+ for exist_vf in self.virtual_function_list:
+ if base.obj_equal_prims(vf, exist_vf):
+ LOG.warning("The vf already exists")
+ return None
+ vf.parent_uuid = self.uuid
+ vf.root_uuid = self.root_uuid
+ vf_copy = copy.deepcopy(vf)
+ self.virtual_function_list.append(vf_copy)
+
+ def delete_vf(self, context, vf):
+ """remove a vf from the virtual_function_list
+ if the vf does not exist, ignore it
+ """
+ for idx, exist_vf in self.virtual_function_list:
+ if base.obj_equal_prims(vf, exist_vf):
+ removed_vf = self.virtual_function_list.pop(idx)
+ removed_vf.destroy(context)
+ return
+ LOG.warning("The removing vf does not exist!")
+
+ def destroy(self, context):
+ """Delete a the pf from the DB."""
+ del self.virtual_function_list[:]
+ super(PhysicalFunction, self).destroy(context)
+
+ @classmethod
+ def get(cls, context, uuid):
+ """Find a DB Physical Function and return an Obj Physical Function.
+ In addition, it will also finds all the Virtual Functions associated
+ with this Physical Function and place them in virtual_function_list
+ """
+ db_pf = cls.dbapi.deployable_get(context, uuid)
+ obj_pf = cls._from_db_object(cls(context), db_pf)
+ pf_uuid = obj_pf.uuid
+
+ query = {"parent_uuid": pf_uuid, "type": "vf"}
+ db_vf_list = cls.dbapi.deployable_get_by_filters(context, query)
+
+ for db_vf in db_vf_list:
+ obj_vf = VirtualFunction.get(context, db_vf.uuid)
+ obj_pf.virtual_function_list.append(obj_vf)
+ return obj_pf
+
+ @classmethod
+ def get_by_filter(cls, context,
+ filters, sort_key='created_at',
+ sort_dir='desc', limit=None,
+ marker=None, join=None):
+ obj_dpl_list = []
+ filters['type'] = 'pf'
+ 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)
+ query = {"parent_uuid": obj_dpl.uuid}
+ vf_get_list = VirtualFunction.get_by_filter(context,
+ query)
+ obj_dpl.virtual_function_list = vf_get_list
+ obj_dpl_list.append(obj_dpl)
+ return obj_dpl_list
+
+ @classmethod
+ 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
\ No newline at end of file diff --git a/cyborg_enhancement/mitaka_version/cyborg/cyborg/objects/port.py b/cyborg_enhancement/mitaka_version/cyborg/cyborg/objects/port.py new file mode 100644 index 0000000..6379db6 --- /dev/null +++ b/cyborg_enhancement/mitaka_version/cyborg/cyborg/objects/port.py @@ -0,0 +1,91 @@ +# Copyright 2018 Lenovo Research Co.,LTD. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from oslo_log import log as logging +from oslo_versionedobjects import base as object_base + +from cyborg.db import api as dbapi +from cyborg.objects import base +from cyborg.objects import fields as object_fields + +LOG = logging.getLogger(__name__) + +@base.CyborgObjectRegistry.register +class Port(base.CyborgObject, object_base.VersionedObjectDictCompat): + # Version 1.0: Initial version + VERSION = '1.0' + + dbapi = dbapi.get_instance() + + fields = { + 'uuid': object_fields.UUIDField(nullable=False), + 'computer_node': object_fields.UUIDField(nullable=False), + 'phy_port_name': object_fields.StringField(nullable=True), + 'pci_slot': object_fields.StringField(nullable=True), + 'product_id': object_fields.StringField(nullable=True), + 'vendor_id': object_fields.StringField(nullable=False), + 'is_used': object_fields.IntegerField(nullable=False), + 'accelerator_id': object_fields.UUIDField(nullable=True), + 'bind_instance_id': object_fields.UUIDField(nullable=True), + 'bind_port_id': object_fields.UUIDField(nullable=True), + 'device_type': object_fields.StringField(nullable=True), + } + + def __init__(self, *args, **kwargs): + super(Port, self).__init__(*args, **kwargs) + + def create(self, context=None): + """Create an Port record in the DB, this can be used by cyborg-agents + to auto register physical port of network cards.""" + values = self.obj_get_changes() + db_port= self.dbapi.port_create(context, values) + self._from_db_object(self, db_port) + + @classmethod + def get(cls, context, uuid): + """Find a DB Port and return an Ojb Port.""" + db_port = cls.dbapi.port_get(context, uuid) + obj_port = cls._from_db_object(cls(context), db_port) + return obj_port + + @classmethod + def get(cls, context, phy_port_name, pci_slot, computer_node): + """Return a list of Port objects.""" + db_port = cls.dbapi.port_get(context, phy_port_name=phy_port_name, + pci_slot=pci_slot, computer_node=computer_node) + if db_port: + obj_port = cls._from_db_object(cls(context), db_port) + return obj_port + else: + return None + + @classmethod + def list(cls, context, limit, marker, sort_key, sort_dir): + """Return a list of Port objects.""" + db_ports = cls.dbapi.port_list(context, limit, marker, sort_key, + sort_dir) + obj_ports = cls._from_db_object_list(context, db_ports) + return obj_ports + + def save(self, context): + """Update a Port record in the DB.""" + updates = self.obj_get_changes() + db_port = self.dbapi.port_update(context, self.uuid, updates) + self._from_db_object(self, db_port) + + def destory(self, context): + """Delete the Port record in the DB.""" + self.dbapi.port_destory(context, self.uuid) + self.obj_reset_changes() diff --git a/cyborg_enhancement/mitaka_version/cyborg/cyborg/objects/virtual_function.py b/cyborg_enhancement/mitaka_version/cyborg/cyborg/objects/virtual_function.py new file mode 100644 index 0000000..3258c9d --- /dev/null +++ b/cyborg_enhancement/mitaka_version/cyborg/cyborg/objects/virtual_function.py @@ -0,0 +1,61 @@ +# Copyright 2018 Huawei Technologies Co.,LTD.
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from oslo_log import log as logging
+from oslo_versionedobjects import base as object_base
+
+from cyborg.common import exception
+from cyborg.db import api as dbapi
+from cyborg.objects import base
+from cyborg.objects import fields as object_fields
+from cyborg.objects.deployable import Deployable
+
+LOG = logging.getLogger(__name__)
+
+
+@base.CyborgObjectRegistry.register
+class VirtualFunction(Deployable):
+ # Version 1.0: Initial version
+ VERSION = '1.0'
+
+ def create(self, context):
+ # To ensure the creating type is VF
+ if self.type != 'vf':
+ raise exception.InvalidDeployType()
+ super(VirtualFunction, self).create(context)
+
+ def save(self, context):
+ # To ensure the saving type is VF
+ if self.type != 'vf':
+ raise exception.InvalidDeployType()
+ super(VirtualFunction, self).save(context)
+
+ @classmethod
+ def get_by_filter(cls, context,
+ filters, sort_key='created_at',
+ sort_dir='desc', limit=None,
+ marker=None, join=None):
+ obj_dpl_list = []
+ filters['type'] = 'vf'
+ 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
|