Add fault object
add fault object ,it is a optional object_field of instance. if error occured, we can save related message into fault. Change-Id: I6fb5cde7e5752683facf6ce7375c354a19cfd81a
This commit is contained in:
parent
c105c98151
commit
4875b5676e
|
@ -115,3 +115,11 @@ class Connection(object):
|
|||
|
||||
This creates or updates a nic db entry.
|
||||
"""
|
||||
# Instances Faults
|
||||
@abc.abstractmethod
|
||||
def instance_fault_create(self, context, values):
|
||||
"""Create a new Instance Fault."""
|
||||
|
||||
@abc.abstractmethod
|
||||
def instance_fault_get_by_instance_uuids(self, context, instance_uuids):
|
||||
"""Get all instance faults for the provided instance_uuids."""
|
||||
|
|
|
@ -94,7 +94,6 @@ def upgrade():
|
|||
mysql_ENGINE='InnoDB',
|
||||
mysql_DEFAULT_CHARSET='UTF8'
|
||||
)
|
||||
|
||||
op.create_table(
|
||||
'instance_nics',
|
||||
sa.Column('created_at', sa.DateTime(), nullable=True),
|
||||
|
@ -111,3 +110,17 @@ def upgrade():
|
|||
mysql_ENGINE='InnoDB',
|
||||
mysql_DEFAULT_CHARSET='UTF8'
|
||||
)
|
||||
op.create_table(
|
||||
'instance_faults',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('instance_uuid', sa.String(length=36), nullable=True),
|
||||
sa.Column('code', sa.Integer(), nullable=False),
|
||||
sa.Column('created_at', sa.DateTime(), nullable=True),
|
||||
sa.Column('updated_at', sa.DateTime(), nullable=True),
|
||||
sa.Column('message', sa.String(length=255), nullable=True),
|
||||
sa.Column('detail', sa.Text(), nullable=True),
|
||||
sa.ForeignKeyConstraint(['instance_uuid'], ['instances.uuid']),
|
||||
sa.PrimaryKeyConstraint('id'),
|
||||
mysql_ENGINE='InnoDB',
|
||||
mysql_DEFAULT_CHARSET='UTF8'
|
||||
)
|
||||
|
|
|
@ -24,6 +24,7 @@ from oslo_utils import strutils
|
|||
from oslo_utils import uuidutils
|
||||
from sqlalchemy.orm.exc import NoResultFound
|
||||
from sqlalchemy.orm import joinedload
|
||||
from sqlalchemy.sql.expression import desc
|
||||
|
||||
from mogan.common import exception
|
||||
from mogan.common.i18n import _
|
||||
|
@ -315,6 +316,36 @@ class Connection(api.Connection):
|
|||
return model_query(context, models.InstanceNic).filter_by(
|
||||
instance_uuid=instance_uuid).all()
|
||||
|
||||
def instance_fault_create(context, values):
|
||||
"""Create a new InstanceFault."""
|
||||
|
||||
fault = models.InstanceFault()
|
||||
fault.update(values)
|
||||
|
||||
with _session_for_write() as session:
|
||||
session.add(fault)
|
||||
session.flush()
|
||||
return fault
|
||||
|
||||
def instance_fault_get_by_instance_uuids(context, instance_uuids):
|
||||
"""Get all instance faults for the provided instance_uuids."""
|
||||
if not instance_uuids:
|
||||
return {}
|
||||
|
||||
rows = model_query(context, models.InstanceFault).\
|
||||
filter(models.InstanceFault.instance_uuid.in_(instance_uuids)).\
|
||||
order_by(desc("created_at"), desc("id")).all()
|
||||
|
||||
output = {}
|
||||
for instance_uuid in instance_uuids:
|
||||
output[instance_uuid] = []
|
||||
|
||||
for row in rows:
|
||||
data = dict(row)
|
||||
output[row['instance_uuid']].append(data)
|
||||
|
||||
return output
|
||||
|
||||
|
||||
def _type_get_id_from_type_query(context, type_id):
|
||||
return model_query(context, models.InstanceTypes). \
|
||||
|
|
|
@ -21,9 +21,10 @@ from oslo_db import options as db_options
|
|||
from oslo_db.sqlalchemy import models
|
||||
from oslo_db.sqlalchemy import types as db_types
|
||||
import six.moves.urllib.parse as urlparse
|
||||
from sqlalchemy import Boolean, Column, DateTime, Enum, ForeignKey
|
||||
from sqlalchemy import Boolean, Column, DateTime, Enum, ForeignKey, Text
|
||||
from sqlalchemy import orm
|
||||
from sqlalchemy import schema, String, Integer
|
||||
from sqlalchemy.dialects.mysql import MEDIUMTEXT
|
||||
from sqlalchemy.ext.declarative import declarative_base
|
||||
|
||||
from mogan.common import paths
|
||||
|
@ -35,6 +36,10 @@ _DEFAULT_SQL_CONNECTION = 'sqlite:///' + paths.state_path_def('mogan.sqlite')
|
|||
db_options.set_defaults(CONF, _DEFAULT_SQL_CONNECTION, 'mogan.sqlite')
|
||||
|
||||
|
||||
def MediumText():
|
||||
return Text().with_variant(MEDIUMTEXT(), 'mysql')
|
||||
|
||||
|
||||
def table_args():
|
||||
engine_name = urlparse.urlparse(CONF.database.connection).scheme
|
||||
if engine_name == 'mysql':
|
||||
|
@ -163,3 +168,21 @@ class InstanceTypeExtraSpecs(Base):
|
|||
foreign_keys=instance_type_uuid,
|
||||
primaryjoin='InstanceTypeExtraSpecs.instance_type_uuid '
|
||||
'== InstanceTypes.uuid')
|
||||
|
||||
|
||||
class InstanceFault(Base):
|
||||
"""Represents fault info for instance"""
|
||||
|
||||
__tablename__ = "instance_faults"
|
||||
|
||||
id = Column(Integer, primary_key=True, nullable=False)
|
||||
instance_uuid = Column(String(36),
|
||||
ForeignKey('instances.uuid'))
|
||||
code = Column(Integer(), nullable=False)
|
||||
message = Column(String(255))
|
||||
detail = Column(MediumText())
|
||||
instance = orm.relationship(
|
||||
Instance,
|
||||
backref=orm.backref('instance_faults', uselist=False),
|
||||
foreign_keys=instance_uuid,
|
||||
primaryjoin='Instance.uuid == InstanceFault.instance_uuid')
|
||||
|
|
|
@ -28,3 +28,4 @@ def register_all():
|
|||
__import__('mogan.objects.instance_type')
|
||||
__import__('mogan.objects.instance')
|
||||
__import__('mogan.objects.instance_nics')
|
||||
__import__('mogan.objects.instance_fault')
|
||||
|
|
|
@ -24,7 +24,7 @@ from mogan import objects
|
|||
from mogan.objects import base
|
||||
from mogan.objects import fields as object_fields
|
||||
|
||||
OPTIONAL_ATTRS = ['nics', ]
|
||||
OPTIONAL_ATTRS = ['nics', 'fault', ]
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
@ -80,9 +80,7 @@ class Instance(base.MoganObject, object_base.VersionedObjectDictCompat):
|
|||
:param db_inst: A DB Instance model of the object
|
||||
:return: The object of the class with the database entity added
|
||||
"""
|
||||
for field in instance.fields:
|
||||
if field in OPTIONAL_ATTRS:
|
||||
continue
|
||||
for field in set(instance.fields) - set(OPTIONAL_ATTRS):
|
||||
instance[field] = db_inst[field]
|
||||
|
||||
if expected_attrs is None:
|
||||
|
@ -91,6 +89,8 @@ class Instance(base.MoganObject, object_base.VersionedObjectDictCompat):
|
|||
instance._load_instance_nics(instance._context, instance.uuid)
|
||||
else:
|
||||
instance.nics = None
|
||||
if 'fault' in expected_attrs:
|
||||
instance._load_fault(instance._context, instance.uuid)
|
||||
|
||||
instance.obj_reset_changes()
|
||||
return instance
|
||||
|
@ -102,9 +102,19 @@ class Instance(base.MoganObject, object_base.VersionedObjectDictCompat):
|
|||
@staticmethod
|
||||
def _from_db_object_list(db_objects, cls, context):
|
||||
"""Converts a list of database entities to a list of formal objects."""
|
||||
return [Instance._from_db_object(cls(context), obj,
|
||||
('nics', ))
|
||||
for obj in db_objects]
|
||||
instances = []
|
||||
for obj in db_objects:
|
||||
expected_attrs = ['nics']
|
||||
if obj["status"] == "error":
|
||||
expected_attrs.append("fault")
|
||||
instances.append(Instance._from_db_object(cls(context),
|
||||
obj,
|
||||
expected_attrs))
|
||||
return instances
|
||||
|
||||
def _load_fault(self, context, instance_uuid):
|
||||
self.fault = objects.InstanceFault.get_latest_for_instance(
|
||||
context=context, instance_uuid=instance_uuid)
|
||||
|
||||
def _save_nics(self, context):
|
||||
for nic_obj in self.nics or []:
|
||||
|
@ -126,9 +136,13 @@ class Instance(base.MoganObject, object_base.VersionedObjectDictCompat):
|
|||
@classmethod
|
||||
def get(cls, context, uuid):
|
||||
"""Find a instance and return a Instance object."""
|
||||
expected_attrs = ['nics']
|
||||
db_instance = cls.dbapi.instance_get(context, uuid)
|
||||
instance = Instance._from_db_object(cls(context), db_instance,
|
||||
('nics', ))
|
||||
if db_instance["status"] == "error":
|
||||
expected_attrs.append("fault")
|
||||
instance = Instance._from_db_object(cls(context),
|
||||
db_instance,
|
||||
expected_attrs)
|
||||
return instance
|
||||
|
||||
def create(self, context=None):
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
# Copyright 2017 Intel
|
||||
# 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 itertools
|
||||
|
||||
from oslo_versionedobjects import base as object_base
|
||||
|
||||
from mogan.common import exception
|
||||
from mogan.db import api as dbapi
|
||||
from mogan import objects
|
||||
from mogan.objects import base
|
||||
from mogan.objects import fields as object_fields
|
||||
|
||||
|
||||
@base.MoganObjectRegistry.register
|
||||
class InstanceFault(base.MoganObject, object_base.VersionedObjectDictCompat):
|
||||
# Version 1.0: Initial version
|
||||
VERSION = '1.0'
|
||||
|
||||
dbapi = dbapi.get_instance()
|
||||
|
||||
fields = {
|
||||
'id': object_fields.IntegerField(),
|
||||
'instance_uuid': object_fields.UUIDField(),
|
||||
'code': object_fields.IntegerField(),
|
||||
'message': object_fields.StringField(nullable=True),
|
||||
'detail': object_fields.StringField(nullable=True),
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def _from_db_object(context, fault, db_fault):
|
||||
for key in fault.fields:
|
||||
fault[key] = db_fault[key]
|
||||
fault._context = context
|
||||
fault.obj_reset_changes()
|
||||
return fault
|
||||
|
||||
@classmethod
|
||||
def get_latest_for_instance(cls, context, instance_uuid):
|
||||
db_faults = cls.dbapi.instance_fault_get_by_instance_uuids(
|
||||
[instance_uuid])
|
||||
if instance_uuid in db_faults and db_faults[instance_uuid]:
|
||||
return cls._from_db_object(context, cls(),
|
||||
db_faults[instance_uuid][0])
|
||||
|
||||
def create(self):
|
||||
if self.obj_attr_is_set('id'):
|
||||
raise exception.ObjectActionError(action='create',
|
||||
reason='already created')
|
||||
values = {
|
||||
'instance_uuid': self.instance_uuid,
|
||||
'code': self.code,
|
||||
'message': self.message,
|
||||
'detail': self.detail,
|
||||
'created_at': self.created_at,
|
||||
}
|
||||
db_fault = self.dbapi.instance_fault_create(self._context, values)
|
||||
self._from_db_object(self._context, self, db_fault)
|
||||
self.obj_reset_changes()
|
||||
|
||||
|
||||
@base.MoganObjectRegistry.register
|
||||
class InstanceFaultList(base.MoganObject,
|
||||
object_base.VersionedObjectDictCompat):
|
||||
# Version 1.0: Initial version
|
||||
|
||||
VERSION = '1.0'
|
||||
|
||||
dbapi = dbapi.get_instance()
|
||||
|
||||
fields = {
|
||||
'objects': object_fields.ListOfObjectsField('InstanceFault')
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def get_by_instance_uuids(cls, context, instance_uuids):
|
||||
db_faultdict = cls.dbapi.instance_fault_get_by_instance_uuids(
|
||||
context, instance_uuids)
|
||||
db_faultlist = itertools.chain(*db_faultdict.values())
|
||||
return object_base.obj_make_list(context, cls(context),
|
||||
objects.InstanceFault,
|
||||
db_faultlist)
|
|
@ -383,6 +383,8 @@ class _TestObject(object):
|
|||
# The fingerprint values should only be changed if there is a version bump.
|
||||
expected_object_fingerprints = {
|
||||
'Instance': '1.0-18d0ffc894a0f6b52df73a29919c035b',
|
||||
'InstanceFault': '1.0-6b5b01b2cc7b6b547837acb168ec6eb9',
|
||||
'InstanceFaultList': '1.0-43e8aad0258652921f929934e9e048fd',
|
||||
'InstanceType': '1.0-589b096651fcdb30898ff50f748dd948',
|
||||
'MyObj': '1.1-aad62eedc5a5cc8bcaf2982c285e753f',
|
||||
'FakeNode': '1.0-07813a70fee67557d8a71ad96f31cee7',
|
||||
|
|
Loading…
Reference in New Issue