Add driver-side OVO functions.

1. Remove hostname field in DriverDevice, because agent will set
hostname together for drivers.
2. Add in_use field in DriverAttachHandle.
3. Add functions like list,create,destory for driver ovos.
4. Fix bugs of objects.
5. Remove deployable name global unique constrains.

Change-Id: I6a646a38e7c1b7042bc27465e1d912e7ff643651
This commit is contained in:
Coco 2019-03-06 19:51:32 -05:00
parent 5c4e648159
commit 0cbced27fe
14 changed files with 349 additions and 36 deletions

View File

@ -50,7 +50,7 @@ def upgrade():
sa.Column('created_at', sa.DateTime(), nullable=True),
sa.Column('updated_at', sa.DateTime(), nullable=True),
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('uuid', sa.String(length=36), nullable=False),
sa.Column('uuid', sa.String(length=36), nullable=False, unique=True),
sa.Column('parent_id', sa.Integer(),
sa.ForeignKey('deployables.id', ondelete='CASCADE'),
nullable=True),
@ -63,8 +63,6 @@ def upgrade():
sa.ForeignKey('devices.id', ondelete="RESTRICT"),
nullable=False),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('uuid', 'name',
name='uniq_deployables0uuid0name'),
sa.Index('deployables_parent_id_idx', 'parent_id'),
sa.Index('deployables_root_id_idx', 'root_id'),
sa.Index('deployables_device_id_idx', 'device_id'),
@ -93,6 +91,7 @@ def upgrade():
sa.Column('created_at', sa.DateTime(), nullable=True),
sa.Column('updated_at', sa.DateTime(), nullable=True),
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('uuid', sa.String(length=36), nullable=False, unique=True),
sa.Column('device_id', sa.Integer(),
sa.ForeignKey('devices.id', ondelete="RESTRICT"),
nullable=False, index=True),
@ -108,6 +107,7 @@ def upgrade():
sa.Column('created_at', sa.DateTime(), nullable=True),
sa.Column('updated_at', sa.DateTime(), nullable=True),
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('uuid', sa.String(length=36), nullable=False, unique=True),
sa.Column('deployable_id', sa.Integer(),
sa.ForeignKey('deployables.id', ondelete="RESTRICT"),
nullable=False),

View File

@ -15,8 +15,8 @@
"""SQLAlchemy storage backend."""
import copy
import threading
import copy
import uuid
from oslo_db import api as oslo_db_api
@ -27,16 +27,17 @@ from oslo_log import log
from oslo_utils import strutils
from oslo_utils import timeutils
from oslo_utils import uuidutils
from sqlalchemy.orm.exc import NoResultFound
from sqlalchemy.orm import load_only
from sqlalchemy.orm.exc import NoResultFound
from sqlalchemy.sql import func
from cyborg.common import exception
from cyborg.common.i18n import _
from cyborg.db import api
from cyborg.db.sqlalchemy import models
from sqlalchemy import and_
from sqlalchemy import or_
from sqlalchemy import and_
_CONTEXT = threading.local()
LOG = log.getLogger(__name__)
@ -105,8 +106,7 @@ def add_identity_filter(query, value):
raise exception.InvalidIdentity(identity=value)
def _paginate_query(context, model, limit=None, marker=None, sort_key=None,
sort_dir=None, query=None):
def _paginate_query(context, model, limit, marker, sort_key, sort_dir, query):
sort_keys = ['id']
if sort_key and sort_key not in sort_keys:
sort_keys.insert(0, sort_key)
@ -225,7 +225,7 @@ class Connection(api.Connection):
def attach_handle_list(self, context):
query = model_query(context, models.AttachHandle)
return _paginate_query(context, models.AttachHandle, query=query)
return _paginate_query(context, models.AttachHandle)
def attach_handle_update(self, context, uuid, values):
if 'uuid' in values:
@ -290,10 +290,11 @@ class Connection(api.Connection):
if limit == 0:
return []
query_prefix = model_query(context, models.AttachHandle)
query_prefix = model_query(context, models.ControlpathID)
filters = copy.deepcopy(filters)
exact_match_filter_names = ['uuid', 'id', 'device_id']
exact_match_filter_names = ['uuid', 'id', 'device_id', 'cpid_info',
'cpid_type']
# Filter the query
query_prefix = self._exact_filter(models.ControlpathID, query_prefix,
@ -305,7 +306,7 @@ class Connection(api.Connection):
def control_path_list(self, context):
query = model_query(context, models.ControlpathID)
return _paginate_query(context, models.ControlpathID, query=query)
return _paginate_query(context, models.ControlpathID)
def control_path_update(self, context, uuid, values):
if 'uuid' in values:
@ -383,7 +384,7 @@ class Connection(api.Connection):
def device_list(self, context):
query = model_query(context, models.Device)
return _paginate_query(context, models.Device, query=query)
return _paginate_query(context, models.Device)
def device_update(self, context, uuid, values):
if 'uuid' in values:
@ -472,7 +473,7 @@ class Connection(api.Connection):
def device_profile_list(self, context):
query = model_query(context, models.DeviceProfile)
return _paginate_query(context, models.DeviceProfile, query=query)
return _paginate_query(context, models.DeviceProfile)
def device_profile_update(self, context, uuid, values):
if 'uuid' in values:
@ -886,7 +887,7 @@ class Connection(api.Connection):
def quota_reserve(self, context, resources, deltas, expire,
until_refresh, max_age, project_id=None,
is_allocated_reserve=False):
"""Create reservation record in DB according to params"""
""" Create reservation record in DB according to params"""
with _session_for_write() as session:
if project_id is None:
project_id = context.project_id

View File

@ -88,8 +88,6 @@ class Deployable(Base):
__tablename__ = 'deployables'
__table_args__ = (
schema.UniqueConstraint('uuid', 'name',
name='uniq_deployables0uuid0name'),
Index('deployables_parent_id_idx', 'parent_id'),
Index('deployables_root_id_idx', 'root_id'),
Index('deployables_device_id_idx', 'device_id'),
@ -97,7 +95,7 @@ class Deployable(Base):
)
id = Column(Integer, primary_key=True)
uuid = Column(String(36), nullable=False)
uuid = Column(String(36), nullable=False, unique=True)
parent_id = Column(Integer, ForeignKey('deployables.id'), nullable=True)
root_id = Column(Integer, ForeignKey('deployables.id'), nullable=True)
name = Column(String(255), nullable=False)
@ -125,6 +123,7 @@ class ControlpathID(Base):
__tablename__ = 'controlpath_ids'
id = Column(Integer, primary_key=True)
uuid = Column(String(36), nullable=False, unique=True)
device_id = Column(Integer,
ForeignKey('devices.id', ondelete="RESTRICT"),
nullable=False, index=True)
@ -143,6 +142,7 @@ class AttachHandle(Base):
)
id = Column(Integer, primary_key=True)
uuid = Column(String(36), nullable=False, unique=True)
deployable_id = Column(Integer,
ForeignKey('deployables.id', ondelete="RESTRICT"),
nullable=False)

View File

@ -41,12 +41,11 @@ class AttachHandle(base.CyborgObject, object_base.VersionedObjectDictCompat):
nullable=False),
# attach_info should be JSON here.
'attach_info': object_fields.StringField(nullable=False),
'in_use': object_fields.BooleanField(nullable=False)
'in_use': object_fields.BooleanField(nullable=False, default=False)
}
def create(self, context):
"""Create a AttachHandle record in the DB."""
self.in_use = False
values = self.obj_get_changes()
db_ah = self.dbapi.attach_handle_create(context, values)
self._from_db_object(self, db_ah)
@ -70,7 +69,7 @@ class AttachHandle(base.CyborgObject, object_base.VersionedObjectDictCompat):
"""Return a list of AttachHandle objects."""
if filters:
sort_dir = filters.pop('sort_dir', 'desc')
sort_key = filters.pop('sort_key', 'create_at')
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,
@ -93,3 +92,19 @@ class AttachHandle(base.CyborgObject, object_base.VersionedObjectDictCompat):
"""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

View File

@ -87,3 +87,13 @@ class Attribute(base.CyborgObject, object_base.VersionedObjectDictCompat):
def set_key_value_pair(self, set_key, set_value):
self.key = set_key
self.value = set_value
@classmethod
def get_by_dep_key(cls, context, dep_id, key):
"""Get the only one attribute with deployable_id and the key."""
attr_filter = {"deployable_id": dep_id, "key": key}
attr_list = cls.get_by_filter(context, attr_filter)
if len(attr_list) != 0:
return attr_list[0]
else:
return None

View File

@ -59,7 +59,7 @@ class ControlpathID(base.CyborgObject, object_base.VersionedObjectDictCompat):
"""Return a list of ControlpathID objects."""
if filters:
sort_dir = filters.pop('sort_dir', 'desc')
sort_key = filters.pop('sort_key', 'create_at')
sort_key = filters.pop('sort_key', 'created_at')
limit = filters.pop('limit', None)
marker = filters.pop('marker_obj', None)
db_cps = cls.dbapi.control_path_get_by_filters(context, filters,
@ -82,3 +82,24 @@ class ControlpathID(base.CyborgObject, object_base.VersionedObjectDictCompat):
"""Delete a ControlpathID from the DB."""
self.dbapi.control_path_delete(context, self.uuid)
self.obj_reset_changes()
@classmethod
def get_by_device_id(cls, context, device_id):
# control_path is unique for one device.
cpid_filter = {'device_id': device_id}
cpid_obj_list = ControlpathID.list(context, cpid_filter)
if len(cpid_obj_list) != 0:
return cpid_obj_list[0]
else:
return None
@classmethod
def get_by_device_id_cpidinfo(cls, context, device_id, cpid_info):
cpid_filter = {'device_id': device_id,
'cpid_info': cpid_info}
# the list could have one value or is empty.
cpid_obj_list = ControlpathID.list(context, cpid_filter)
if len(cpid_obj_list) != 0:
return cpid_obj_list[0]
else:
return None

View File

@ -55,13 +55,10 @@ class Deployable(base.CyborgObject, object_base.VersionedObjectDictCompat):
def create(self, context):
"""Create a Deployable record in the DB."""
if not hasattr(self, 'parent_id') or self.parent_id is None:
self.root_id = self.id
else:
self.root_id = self._get_parent_root_id(context)
# FIXME: Add parent_uuid and root_uuid constrains when DB change to
# parent_uuid & root_uuid
values = self.obj_get_changes()
db_dep = self.dbapi.deployable_create(context, values)
self._from_db_object(self, db_dep)
self.obj_reset_changes()
@ -72,7 +69,7 @@ class Deployable(base.CyborgObject, object_base.VersionedObjectDictCompat):
"""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
# retrieve all the attributes for this deployable
if with_attribute_list:
query = {"deployable_id": obj_dep.id}
attr_get_list = Attribute.get_by_filter(context,
@ -95,7 +92,7 @@ class Deployable(base.CyborgObject, object_base.VersionedObjectDictCompat):
"""Return a list of Deployable objects."""
if filters:
sort_dir = filters.pop('sort_dir', 'desc')
sort_key = filters.pop('sort_key', 'create_at')
sort_key = filters.pop('sort_key', 'created_at')
limit = filters.pop('limit', None)
marker = filters.pop('marker_obj', None)
db_deps = cls.dbapi.deployable_get_by_filters(context, filters,
@ -199,3 +196,18 @@ class Deployable(base.CyborgObject, object_base.VersionedObjectDictCompat):
obj.attributes_list = []
return obj
@classmethod
def get_list_by_device_id(cls, context, device_id):
dep_filter = {'device_id': device_id}
dep_obj_list = Deployable.list(context, dep_filter)
return dep_obj_list
@classmethod
def get_by_name_deviceid(cls, context, name, device_id):
dep_filter = {'name': name, 'device_id': device_id}
dep_obj_list = Deployable.list(context, dep_filter)
if len(dep_obj_list) != 0:
return dep_obj_list[0]
else:
return None

View File

@ -19,6 +19,7 @@ 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
from cyborg.objects.control_path import ControlpathID
LOG = logging.getLogger(__name__)
@ -63,7 +64,7 @@ class Device(base.CyborgObject, object_base.VersionedObjectDictCompat):
"""Return a list of Device objects."""
if filters:
sort_dir = filters.pop('sort_dir', 'desc')
sort_key = filters.pop('sort_key', 'create_at')
sort_key = filters.pop('sort_key', 'created_at')
limit = filters.pop('limit', None)
marker = filters.pop('marker_obj', None)
db_devices = cls.dbapi.device_list_by_filters(context, filters,
@ -85,3 +86,11 @@ class Device(base.CyborgObject, object_base.VersionedObjectDictCompat):
"""Delete the Device from the DB."""
self.dbapi.device_delete(context, self.uuid)
self.obj_reset_changes()
@classmethod
def get_list_by_hostname(cls, context, hostname):
"""get device object list from the hostname. return [] if not
exist."""
dev_filter = {'hostname': hostname}
device_obj_list = Device.list(context, dev_filter)
return device_obj_list

View File

@ -57,7 +57,7 @@ class DeviceProfile(base.CyborgObject, object_base.VersionedObjectDictCompat):
"""Return a list of Device_profile objects."""
if filters:
sort_dir = filters.pop('sort_dir', 'desc')
sort_key = filters.pop('sort_key', 'create_at')
sort_key = filters.pop('sort_key', 'created_at')
limit = filters.pop('limit', None)
marker = filters.pop('marker_obj', None)
db_device_profiles = cls.dbapi.device_profile_list_by_filters(

View File

@ -16,6 +16,9 @@
from oslo_versionedobjects import base as object_base
from cyborg.objects import fields as object_fields
from cyborg.objects import base
from cyborg.objects.attach_handle import AttachHandle
from oslo_log import log as logging
LOG = logging.getLogger(__name__)
@base.CyborgObjectRegistry.register
@ -31,3 +34,36 @@ class DriverAttachHandle(base.DriverObjectBase,
# 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

View File

@ -16,6 +16,7 @@
from oslo_versionedobjects import base as object_base
from cyborg.objects import base
from cyborg.objects import fields as object_fields
from cyborg.objects.attribute import Attribute
@base.CyborgObjectRegistry.register
@ -28,3 +29,30 @@ class DriverAttribute(base.DriverObjectBase,
'key': object_fields.StringField(nullable=False),
'value': object_fields.StringField(nullable=False)
}
def create(self, context, deployable_id):
"""Convert driver-side Attribute into Attribute Object so as to
store in DB."""
attr_obj = Attribute()
attr_obj.deployable_id = deployable_id
attr_obj.set_key_value_pair(self.key, self.value)
attr_obj.create(context)
@classmethod
def destroy(cls, context, deployable_id):
"""Delete driver-side attribute list from the DB."""
attr_obj_list = Attribute.get_by_deployable_id(context, deployable_id)
for attr_obj in attr_obj_list:
attr_obj.destroy(context)
@classmethod
def list(cls, context, deployable_id):
"""Form driver-side attribute list for one deployable."""
attr_obj_list = Attribute.get_by_deployable_id(context, deployable_id)
driver_attr_obj_list = []
for attr_obj in attr_obj_list:
driver_attr_obj = cls(context=context,
key=attr_obj.key,
value=attr_obj.value)
driver_attr_obj_list.append(driver_attr_obj)
return driver_attr_obj_list

View File

@ -16,6 +16,7 @@
from oslo_versionedobjects import base as object_base
from cyborg.objects import fields as object_fields
from cyborg.objects import base
from cyborg.objects.control_path import ControlpathID
@base.CyborgObjectRegistry.register
@ -27,5 +28,33 @@ class DriverControlPathID(base.DriverObjectBase,
fields = {
'cpid_type': object_fields.StringField(nullable=False),
# PCI BDF, PowerVM device, etc.
'cpid_info': object_fields.StringField(nullable=False),
'cpid_info': object_fields.StringField(nullable=False)
}
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 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)
@classmethod
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

View File

@ -19,6 +19,8 @@ from cyborg.objects import fields as object_fields
from cyborg.objects.driver_objects.driver_attribute import DriverAttribute
from cyborg.objects.driver_objects.driver_attach_handle import \
DriverAttachHandle
from cyborg.objects.deployable import Deployable
from cyborg.objects.attach_handle import AttachHandle
@base.CyborgObjectRegistry.register
@ -37,3 +39,65 @@ class DriverDeployable(base.DriverObjectBase,
'attach_handle_list': object_fields.ListOfObjectsField(
'DriverAttachHandle', default=[], nullable=True)
}
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 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)
@classmethod
def list(cls, context, device_id):
"""Form driver-side Deployable object list from DB for one device."""
# get deployable_obj_list for one device_id
dep_obj_list = Deployable.get_list_by_device_id(context, device_id)
driver_dep_obj_list = []
for dep_obj in dep_obj_list:
# get driver_ah_obj_list for this dep_obj
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)
driver_dep_obj_list.append(driver_dep_obj)
return driver_dep_obj_list

View File

@ -19,6 +19,10 @@ from cyborg.objects import fields as object_fields
from cyborg.objects.driver_objects.driver_deployable import DriverDeployable
from cyborg.objects.driver_objects.driver_controlpath_id import \
DriverControlPathID
from cyborg.objects.device import Device
from cyborg.objects.deployable import Deployable
from cyborg.objects.control_path import ControlpathID
from cyborg.objects.attach_handle import AttachHandle
@base.CyborgObjectRegistry.register
@ -28,15 +32,14 @@ class DriverDevice(base.DriverObjectBase,
VERSION = '1.0'
fields = {
# standard borad info: vendor_id, product_id, remotable?
'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: like acc_topology which is used
# for driver-specific resource provider.
# vendor board info should be a dict for driver-specific resource
# provider.
'vendor_board_info': object_fields.StringField(nullable=True),
'hostname': object_fields.StringField(nullable=False),
# 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',
@ -45,3 +48,88 @@ class DriverDevice(base.DriverObjectBase,
default=[],
nullable=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)
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):
"""
: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