Merge "Use oslo.versionedobjects remotable decorators"
This commit is contained in:
commit
548d73502f
@ -345,10 +345,6 @@ class SSHCommandFailed(IronicException):
|
||||
message = _("Failed to execute command via SSH: %(cmd)s.")
|
||||
|
||||
|
||||
class OrphanedObjectError(IronicException):
|
||||
message = _('Cannot call %(method)s on orphaned %(objtype)s object')
|
||||
|
||||
|
||||
class UnsupportedDriverExtension(Invalid):
|
||||
message = _('Driver %(driver)s does not support %(extension)s '
|
||||
'(disabled or not implemented).')
|
||||
|
@ -14,7 +14,6 @@
|
||||
|
||||
"""Ironic common internal object model"""
|
||||
|
||||
from oslo_context import context
|
||||
from oslo_log import log as logging
|
||||
from oslo_versionedobjects import base as object_base
|
||||
|
||||
@ -30,59 +29,6 @@ class IronicObjectRegistry(object_base.VersionedObjectRegistry):
|
||||
pass
|
||||
|
||||
|
||||
# These are decorators that mark an object's method as remotable.
|
||||
# If the metaclass is configured to forward object methods to an
|
||||
# indirection service, these will result in making an RPC call
|
||||
# instead of directly calling the implementation in the object. Instead,
|
||||
# the object implementation on the remote end will perform the
|
||||
# requested action and the result will be returned here.
|
||||
def remotable_classmethod(fn):
|
||||
"""Decorator for remotable classmethods."""
|
||||
def wrapper(cls, context, *args, **kwargs):
|
||||
if IronicObject.indirection_api:
|
||||
result = IronicObject.indirection_api.object_class_action(
|
||||
context, cls.obj_name(), fn.__name__, cls.VERSION,
|
||||
args, kwargs)
|
||||
else:
|
||||
result = fn(cls, context, *args, **kwargs)
|
||||
if isinstance(result, IronicObject):
|
||||
result._context = context
|
||||
return result
|
||||
return classmethod(wrapper)
|
||||
|
||||
|
||||
# See comment above for remotable_classmethod()
|
||||
#
|
||||
# Note that this will use either the provided context, or the one
|
||||
# stashed in the object. If neither are present, the object is
|
||||
# "orphaned" and remotable methods cannot be called.
|
||||
def remotable(fn):
|
||||
"""Decorator for remotable object methods."""
|
||||
def wrapper(self, *args, **kwargs):
|
||||
ctxt = self._context
|
||||
try:
|
||||
if isinstance(args[0], (context.RequestContext)):
|
||||
ctxt = args[0]
|
||||
args = args[1:]
|
||||
except IndexError:
|
||||
pass
|
||||
if ctxt is None:
|
||||
raise exception.OrphanedObjectError(method=fn.__name__,
|
||||
objtype=self.obj_name())
|
||||
if IronicObject.indirection_api:
|
||||
updates, result = IronicObject.indirection_api.object_action(
|
||||
ctxt, self, fn.__name__, args, kwargs)
|
||||
for key, value in updates.items():
|
||||
if key in self.fields:
|
||||
field = self.fields[key]
|
||||
self[key] = field.from_primitive(self, key, value)
|
||||
self._changed_fields = set(updates.get('obj_what_changed', []))
|
||||
return result
|
||||
else:
|
||||
return fn(self, ctxt, *args, **kwargs)
|
||||
return wrapper
|
||||
|
||||
|
||||
# Object versioning rules
|
||||
#
|
||||
# Each service has its set of objects, each with a version attached. When
|
||||
|
@ -55,7 +55,7 @@ class Chassis(base.IronicObject, object_base.VersionedObjectDictCompat):
|
||||
chassis.obj_reset_changes()
|
||||
return chassis
|
||||
|
||||
@base.remotable_classmethod
|
||||
@object_base.remotable_classmethod
|
||||
def get(cls, context, chassis_id):
|
||||
"""Find a chassis based on its id or uuid and return a Chassis object.
|
||||
|
||||
@ -69,7 +69,7 @@ class Chassis(base.IronicObject, object_base.VersionedObjectDictCompat):
|
||||
else:
|
||||
raise exception.InvalidIdentity(identity=chassis_id)
|
||||
|
||||
@base.remotable_classmethod
|
||||
@object_base.remotable_classmethod
|
||||
def get_by_id(cls, context, chassis_id):
|
||||
"""Find a chassis based on its integer id and return a Chassis object.
|
||||
|
||||
@ -80,7 +80,7 @@ class Chassis(base.IronicObject, object_base.VersionedObjectDictCompat):
|
||||
chassis = Chassis._from_db_object(cls(context), db_chassis)
|
||||
return chassis
|
||||
|
||||
@base.remotable_classmethod
|
||||
@object_base.remotable_classmethod
|
||||
def get_by_uuid(cls, context, uuid):
|
||||
"""Find a chassis based on uuid and return a :class:`Chassis` object.
|
||||
|
||||
@ -92,7 +92,7 @@ class Chassis(base.IronicObject, object_base.VersionedObjectDictCompat):
|
||||
chassis = Chassis._from_db_object(cls(context), db_chassis)
|
||||
return chassis
|
||||
|
||||
@base.remotable_classmethod
|
||||
@object_base.remotable_classmethod
|
||||
def list(cls, context, limit=None, marker=None,
|
||||
sort_key=None, sort_dir=None):
|
||||
"""Return a list of Chassis objects.
|
||||
@ -112,7 +112,7 @@ class Chassis(base.IronicObject, object_base.VersionedObjectDictCompat):
|
||||
return [Chassis._from_db_object(cls(context), obj)
|
||||
for obj in db_chassis]
|
||||
|
||||
@base.remotable
|
||||
@object_base.remotable
|
||||
def create(self, context=None):
|
||||
"""Create a Chassis record in the DB.
|
||||
|
||||
@ -133,7 +133,7 @@ class Chassis(base.IronicObject, object_base.VersionedObjectDictCompat):
|
||||
db_chassis = self.dbapi.create_chassis(values)
|
||||
self._from_db_object(self, db_chassis)
|
||||
|
||||
@base.remotable
|
||||
@object_base.remotable
|
||||
def destroy(self, context=None):
|
||||
"""Delete the Chassis from the DB.
|
||||
|
||||
@ -147,7 +147,7 @@ class Chassis(base.IronicObject, object_base.VersionedObjectDictCompat):
|
||||
self.dbapi.destroy_chassis(self.uuid)
|
||||
self.obj_reset_changes()
|
||||
|
||||
@base.remotable
|
||||
@object_base.remotable
|
||||
def save(self, context=None):
|
||||
"""Save updates to this Chassis.
|
||||
|
||||
@ -165,7 +165,7 @@ class Chassis(base.IronicObject, object_base.VersionedObjectDictCompat):
|
||||
updated_chassis = self.dbapi.update_chassis(self.uuid, updates)
|
||||
self._from_db_object(self, updated_chassis)
|
||||
|
||||
@base.remotable
|
||||
@object_base.remotable
|
||||
def refresh(self, context=None):
|
||||
"""Loads and applies updates for this Chassis.
|
||||
|
||||
|
@ -42,7 +42,7 @@ class Conductor(base.IronicObject, object_base.VersionedObjectDictCompat):
|
||||
conductor.obj_reset_changes()
|
||||
return conductor
|
||||
|
||||
@base.remotable_classmethod
|
||||
@object_base.remotable_classmethod
|
||||
def get_by_hostname(cls, context, hostname):
|
||||
"""Get a Conductor record by its hostname.
|
||||
|
||||
@ -58,7 +58,7 @@ class Conductor(base.IronicObject, object_base.VersionedObjectDictCompat):
|
||||
raise NotImplementedError(
|
||||
_('Cannot update a conductor record directly.'))
|
||||
|
||||
@base.remotable
|
||||
@object_base.remotable
|
||||
def refresh(self, context=None):
|
||||
"""Loads and applies updates for this Conductor.
|
||||
|
||||
@ -77,7 +77,7 @@ class Conductor(base.IronicObject, object_base.VersionedObjectDictCompat):
|
||||
hostname=self.hostname)
|
||||
self.obj_refresh(current)
|
||||
|
||||
@base.remotable
|
||||
@object_base.remotable
|
||||
def touch(self, context):
|
||||
"""Touch this conductor's DB record, marking it as up-to-date."""
|
||||
self.dbapi.touch_conductor(self.hostname)
|
||||
|
@ -106,7 +106,7 @@ class Node(base.IronicObject, object_base.VersionedObjectDictCompat):
|
||||
node.obj_reset_changes()
|
||||
return node
|
||||
|
||||
@base.remotable_classmethod
|
||||
@object_base.remotable_classmethod
|
||||
def get(cls, context, node_id):
|
||||
"""Find a node based on its id or uuid and return a Node object.
|
||||
|
||||
@ -120,7 +120,7 @@ class Node(base.IronicObject, object_base.VersionedObjectDictCompat):
|
||||
else:
|
||||
raise exception.InvalidIdentity(identity=node_id)
|
||||
|
||||
@base.remotable_classmethod
|
||||
@object_base.remotable_classmethod
|
||||
def get_by_id(cls, context, node_id):
|
||||
"""Find a node based on its integer id and return a Node object.
|
||||
|
||||
@ -131,7 +131,7 @@ class Node(base.IronicObject, object_base.VersionedObjectDictCompat):
|
||||
node = Node._from_db_object(cls(context), db_node)
|
||||
return node
|
||||
|
||||
@base.remotable_classmethod
|
||||
@object_base.remotable_classmethod
|
||||
def get_by_uuid(cls, context, uuid):
|
||||
"""Find a node based on uuid and return a Node object.
|
||||
|
||||
@ -142,7 +142,7 @@ class Node(base.IronicObject, object_base.VersionedObjectDictCompat):
|
||||
node = Node._from_db_object(cls(context), db_node)
|
||||
return node
|
||||
|
||||
@base.remotable_classmethod
|
||||
@object_base.remotable_classmethod
|
||||
def get_by_name(cls, context, name):
|
||||
"""Find a node based on name and return a Node object.
|
||||
|
||||
@ -153,7 +153,7 @@ class Node(base.IronicObject, object_base.VersionedObjectDictCompat):
|
||||
node = Node._from_db_object(cls(context), db_node)
|
||||
return node
|
||||
|
||||
@base.remotable_classmethod
|
||||
@object_base.remotable_classmethod
|
||||
def get_by_instance_uuid(cls, context, instance_uuid):
|
||||
"""Find a node based on the instance uuid and return a Node object.
|
||||
|
||||
@ -164,7 +164,7 @@ class Node(base.IronicObject, object_base.VersionedObjectDictCompat):
|
||||
node = Node._from_db_object(cls(context), db_node)
|
||||
return node
|
||||
|
||||
@base.remotable_classmethod
|
||||
@object_base.remotable_classmethod
|
||||
def list(cls, context, limit=None, marker=None, sort_key=None,
|
||||
sort_dir=None, filters=None):
|
||||
"""Return a list of Node objects.
|
||||
@ -183,7 +183,7 @@ class Node(base.IronicObject, object_base.VersionedObjectDictCompat):
|
||||
sort_dir=sort_dir)
|
||||
return [Node._from_db_object(cls(context), obj) for obj in db_nodes]
|
||||
|
||||
@base.remotable_classmethod
|
||||
@object_base.remotable_classmethod
|
||||
def reserve(cls, context, tag, node_id):
|
||||
"""Get and reserve a node.
|
||||
|
||||
@ -201,7 +201,7 @@ class Node(base.IronicObject, object_base.VersionedObjectDictCompat):
|
||||
node = Node._from_db_object(cls(context), db_node)
|
||||
return node
|
||||
|
||||
@base.remotable_classmethod
|
||||
@object_base.remotable_classmethod
|
||||
def release(cls, context, tag, node_id):
|
||||
"""Release the reservation on a node.
|
||||
|
||||
@ -213,7 +213,7 @@ class Node(base.IronicObject, object_base.VersionedObjectDictCompat):
|
||||
"""
|
||||
cls.dbapi.release_node(tag, node_id)
|
||||
|
||||
@base.remotable
|
||||
@object_base.remotable
|
||||
def create(self, context=None):
|
||||
"""Create a Node record in the DB.
|
||||
|
||||
@ -234,7 +234,7 @@ class Node(base.IronicObject, object_base.VersionedObjectDictCompat):
|
||||
db_node = self.dbapi.create_node(values)
|
||||
self._from_db_object(self, db_node)
|
||||
|
||||
@base.remotable
|
||||
@object_base.remotable
|
||||
def destroy(self, context=None):
|
||||
"""Delete the Node from the DB.
|
||||
|
||||
@ -248,7 +248,7 @@ class Node(base.IronicObject, object_base.VersionedObjectDictCompat):
|
||||
self.dbapi.destroy_node(self.uuid)
|
||||
self.obj_reset_changes()
|
||||
|
||||
@base.remotable
|
||||
@object_base.remotable
|
||||
def save(self, context=None):
|
||||
"""Save updates to this Node.
|
||||
|
||||
@ -272,7 +272,7 @@ class Node(base.IronicObject, object_base.VersionedObjectDictCompat):
|
||||
self.dbapi.update_node(self.uuid, updates)
|
||||
self.obj_reset_changes()
|
||||
|
||||
@base.remotable
|
||||
@object_base.remotable
|
||||
def refresh(self, context=None):
|
||||
"""Refresh the object by re-fetching from the DB.
|
||||
|
||||
@ -286,7 +286,7 @@ class Node(base.IronicObject, object_base.VersionedObjectDictCompat):
|
||||
current = self.__class__.get_by_uuid(self._context, self.uuid)
|
||||
self.obj_refresh(current)
|
||||
|
||||
@base.remotable
|
||||
@object_base.remotable
|
||||
def touch_provisioning(self, context=None):
|
||||
"""Touch the database record to mark the provisioning as alive."""
|
||||
self.dbapi.touch_node_provisioning(self.id)
|
||||
|
@ -58,7 +58,7 @@ class Port(base.IronicObject, object_base.VersionedObjectDictCompat):
|
||||
"""Converts a list of database entities to a list of formal objects."""
|
||||
return [Port._from_db_object(cls(context), obj) for obj in db_objects]
|
||||
|
||||
@base.remotable_classmethod
|
||||
@object_base.remotable_classmethod
|
||||
def get(cls, context, port_id):
|
||||
"""Find a port based on its id or uuid and return a Port object.
|
||||
|
||||
@ -76,7 +76,7 @@ class Port(base.IronicObject, object_base.VersionedObjectDictCompat):
|
||||
else:
|
||||
raise exception.InvalidIdentity(identity=port_id)
|
||||
|
||||
@base.remotable_classmethod
|
||||
@object_base.remotable_classmethod
|
||||
def get_by_id(cls, context, port_id):
|
||||
"""Find a port based on its integer id and return a Port object.
|
||||
|
||||
@ -89,7 +89,7 @@ class Port(base.IronicObject, object_base.VersionedObjectDictCompat):
|
||||
port = Port._from_db_object(cls(context), db_port)
|
||||
return port
|
||||
|
||||
@base.remotable_classmethod
|
||||
@object_base.remotable_classmethod
|
||||
def get_by_uuid(cls, context, uuid):
|
||||
"""Find a port based on uuid and return a :class:`Port` object.
|
||||
|
||||
@ -103,7 +103,7 @@ class Port(base.IronicObject, object_base.VersionedObjectDictCompat):
|
||||
port = Port._from_db_object(cls(context), db_port)
|
||||
return port
|
||||
|
||||
@base.remotable_classmethod
|
||||
@object_base.remotable_classmethod
|
||||
def get_by_address(cls, context, address):
|
||||
"""Find a port based on address and return a :class:`Port` object.
|
||||
|
||||
@ -117,7 +117,7 @@ class Port(base.IronicObject, object_base.VersionedObjectDictCompat):
|
||||
port = Port._from_db_object(cls(context), db_port)
|
||||
return port
|
||||
|
||||
@base.remotable_classmethod
|
||||
@object_base.remotable_classmethod
|
||||
def list(cls, context, limit=None, marker=None,
|
||||
sort_key=None, sort_dir=None):
|
||||
"""Return a list of Port objects.
|
||||
@ -137,7 +137,7 @@ class Port(base.IronicObject, object_base.VersionedObjectDictCompat):
|
||||
sort_dir=sort_dir)
|
||||
return Port._from_db_object_list(db_ports, cls, context)
|
||||
|
||||
@base.remotable_classmethod
|
||||
@object_base.remotable_classmethod
|
||||
def list_by_node_id(cls, context, node_id, limit=None, marker=None,
|
||||
sort_key=None, sort_dir=None):
|
||||
"""Return a list of Port objects associated with a given node ID.
|
||||
@ -157,7 +157,7 @@ class Port(base.IronicObject, object_base.VersionedObjectDictCompat):
|
||||
sort_dir=sort_dir)
|
||||
return Port._from_db_object_list(db_ports, cls, context)
|
||||
|
||||
@base.remotable
|
||||
@object_base.remotable
|
||||
def create(self, context=None):
|
||||
"""Create a Port record in the DB.
|
||||
|
||||
@ -175,7 +175,7 @@ class Port(base.IronicObject, object_base.VersionedObjectDictCompat):
|
||||
db_port = self.dbapi.create_port(values)
|
||||
self._from_db_object(self, db_port)
|
||||
|
||||
@base.remotable
|
||||
@object_base.remotable
|
||||
def destroy(self, context=None):
|
||||
"""Delete the Port from the DB.
|
||||
|
||||
@ -191,7 +191,7 @@ class Port(base.IronicObject, object_base.VersionedObjectDictCompat):
|
||||
self.dbapi.destroy_port(self.uuid)
|
||||
self.obj_reset_changes()
|
||||
|
||||
@base.remotable
|
||||
@object_base.remotable
|
||||
def save(self, context=None):
|
||||
"""Save updates to this Port.
|
||||
|
||||
@ -212,7 +212,7 @@ class Port(base.IronicObject, object_base.VersionedObjectDictCompat):
|
||||
updated_port = self.dbapi.update_port(self.uuid, updates)
|
||||
self._from_db_object(self, updated_port)
|
||||
|
||||
@base.remotable
|
||||
@object_base.remotable
|
||||
def refresh(self, context=None):
|
||||
"""Loads updates for this Port.
|
||||
|
||||
|
@ -23,7 +23,6 @@ from oslo_versionedobjects import base as object_base
|
||||
from oslo_versionedobjects import exception as object_exception
|
||||
import six
|
||||
|
||||
from ironic.common import exception
|
||||
from ironic.objects import base
|
||||
from ironic.objects import fields
|
||||
from ironic.objects import utils
|
||||
@ -44,7 +43,7 @@ class MyObj(base.IronicObject, object_base.VersionedObjectDictCompat):
|
||||
def obj_load_attr(self, attrname):
|
||||
setattr(self, attrname, 'loaded!')
|
||||
|
||||
@base.remotable_classmethod
|
||||
@object_base.remotable_classmethod
|
||||
def query(cls, context):
|
||||
obj = cls(context)
|
||||
obj.foo = 1
|
||||
@ -52,29 +51,29 @@ class MyObj(base.IronicObject, object_base.VersionedObjectDictCompat):
|
||||
obj.obj_reset_changes()
|
||||
return obj
|
||||
|
||||
@base.remotable
|
||||
def marco(self, context):
|
||||
@object_base.remotable
|
||||
def marco(self, context=None):
|
||||
return 'polo'
|
||||
|
||||
@base.remotable
|
||||
def update_test(self, context):
|
||||
if context.tenant == 'alternate':
|
||||
@object_base.remotable
|
||||
def update_test(self, context=None):
|
||||
if context and context.tenant == 'alternate':
|
||||
self.bar = 'alternate-context'
|
||||
else:
|
||||
self.bar = 'updated'
|
||||
|
||||
@base.remotable
|
||||
def save(self, context):
|
||||
@object_base.remotable
|
||||
def save(self, context=None):
|
||||
self.obj_reset_changes()
|
||||
|
||||
@base.remotable
|
||||
def refresh(self, context):
|
||||
@object_base.remotable
|
||||
def refresh(self, context=None):
|
||||
self.foo = 321
|
||||
self.bar = 'refreshed'
|
||||
self.obj_reset_changes()
|
||||
|
||||
@base.remotable
|
||||
def modify_save_modify(self, context):
|
||||
@object_base.remotable
|
||||
def modify_save_modify(self, context=None):
|
||||
self.bar = 'meow'
|
||||
self.save()
|
||||
self.foo = 42
|
||||
@ -85,7 +84,7 @@ class MyObj2(object):
|
||||
def obj_name(cls):
|
||||
return 'MyObj'
|
||||
|
||||
@base.remotable_classmethod
|
||||
@object_base.remotable_classmethod
|
||||
def get(cls, *args, **kwargs):
|
||||
pass
|
||||
|
||||
@ -257,7 +256,7 @@ class _TestObject(object):
|
||||
def test_orphaned_object(self):
|
||||
obj = MyObj.query(self.context)
|
||||
obj._context = None
|
||||
self.assertRaises(exception.OrphanedObjectError,
|
||||
self.assertRaises(object_exception.OrphanedObjectError,
|
||||
obj.update_test)
|
||||
self.assertRemotes()
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user