Merge "Use oslo.versionedobjects remotable decorators"

This commit is contained in:
Jenkins 2015-09-17 12:04:01 +00:00 committed by Gerrit Code Review
commit 548d73502f
7 changed files with 48 additions and 107 deletions

View File

@ -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).')

View File

@ -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

View File

@ -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.

View File

@ -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)

View File

@ -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)

View File

@ -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.

View File

@ -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()