Optional indirection API use

Adds the capability to utilize the indirection API model.

The vast majority of this change is the removal of legacy
comments and the swap of decorators on object methods to
allow the Versioned Objects Indirection API to route the
calls upon objects through the RPC layer to the conductor.

In order to make these calls occur, we need to also send along
a context, which is required to call the RPC layer, which is
fine. Original tests still work in that API surface calls still
ultimately trigger DB API calls in the backend, thus test changes
are actually minimal, similar to very slight changes in trait
retrieval as well. In that we really can't nest objects across
the indirection layer.

Change-Id: Ia161fef67b8a116fdf7cad9b2e559ba75263e196
Signed-off-by: Julia Kreger <juliaashleykreger@gmail.com>
This commit is contained in:
Julia Kreger
2025-08-04 10:22:34 -07:00
parent 8fd1cc8c97
commit 67da8d8c31
38 changed files with 338 additions and 636 deletions

View File

@@ -1008,7 +1008,9 @@ class NodeStatesController(rest.RestController):
policy_name='baremetal:runbook:use',
runbook_ident=runbook)
node_traits = rpc_node.traits.get_trait_names() or []
traits = objects.TraitList.get_by_node_id(api.request.context,
rpc_node.id)
node_traits = traits.get_trait_names() or []
if rpc_runbook.name not in node_traits:
msg = (_('This runbook has not been approved for '
'use on this node %s. Please ask an administrator '
@@ -1649,7 +1651,9 @@ def node_convert_with_links(rpc_node, fields=None, sanitize=True):
fields=_get_fields_for_node_query(fields))
if node.get('traits') is not None:
node['traits'] = rpc_node.traits.get_trait_names()
traits = objects.TraitList.get_by_node_id(api.request.context,
rpc_node.id)
node['traits'] = traits.get_trait_names()
if (api_utils.allow_expose_conductors()
and (fields is None or 'conductor' in fields)):

View File

@@ -38,6 +38,8 @@ ID_FORMAT = (r'^req-[a-f0-9]{8}-[a-f0-9]{4}-'
# a ton of extra overhead.
DBAPI = dbapi.get_instance()
CONF = cfg.CONF
def policy_deprecation_check():
global CHECKED_DEPRECATED_POLICY_ARGS
@@ -80,8 +82,16 @@ class ConfigHook(hooks.PecanHook):
class DBHook(hooks.PecanHook):
"""Attach the dbapi object to the request so controllers can get to it."""
# NOTE(TheJulia): This hook is deprecated, and should be expected to be
# removed after the 2026.2 Ironic release.
def before(self, state):
state.request.dbapi = DBAPI
if CONF.rpc_transport == 'none' or CONF.use_rpc_for_database:
# If the transport is disabled, the request is not to use
# the database, and as such it doesn't need to be attached
# to the request.
state.request.dbapi = None
else:
state.request.dbapi = DBAPI
def after(self, state):
# Explicitly set to None since we don't need the DB connection

View File

@@ -19,6 +19,8 @@ from oslo_log import log
from ironic.api import app
from ironic.common import i18n
from ironic.common import service
from ironic.objects import base as objects_base
from ironic.objects import indirection
CONF = cfg.CONF
@@ -32,6 +34,10 @@ def initialize_wsgi_app(argv=sys.argv):
service.prepare_command(argv)
service.ensure_rpc_transport()
if CONF.rpc_transport in ['local', 'none'] or CONF.use_rpc_for_database:
objects_base.IronicObject.indirection_api = \
indirection.IronicObjectIndirectionAPI()
LOG.debug("Configuration:")
CONF.log_opt_values(LOG, log.DEBUG)

View File

@@ -24,6 +24,8 @@ from oslo_log import log
from ironic.common import service as ironic_service
from ironic.common import wsgi_service
from ironic.objects import base as objects_base
from ironic.objects import indirection
CONF = cfg.CONF
@@ -46,6 +48,12 @@ def main():
ironic_service.prepare_service('ironic_api', sys.argv)
ironic_service.ensure_rpc_transport()
# Sets the indirection API to direct API calls for objects across the
# RPC layer.
if CONF.rpc_transport in ['local', 'none'] or CONF.use_rpc_for_database:
objects_base.IronicObject.indirection_api = \
indirection.IronicObjectIndirectionAPI()
# Build and start the WSGI app
launcher = ironic_service.process_launcher()
server = wsgi_service.WSGIService('ironic_api', CONF.api.enable_ssl_api)

View File

@@ -26,6 +26,8 @@ import oslo_middleware.cors as cors_middleware
from ironic.common import exception
from ironic.common import service as ironic_service
from ironic.console import novncproxy_service
from ironic.objects import base as objects_base
from ironic.objects import indirection
CONF = cfg.CONF
@@ -45,6 +47,12 @@ def main():
raise exception.ConfigInvalid("To allow this service to start, set "
"[vnc]enabled = True")
# Sets the indirection API to direct API calls for objects across the
# RPC layer.
if CONF.rpc_transport in ['local', 'none'] or CONF.use_rpc_for_database:
objects_base.IronicObject.indirection_api = \
indirection.IronicObjectIndirectionAPI()
# Build and start the websocket proxy
launcher = ironic_service.process_launcher(no_fork=True)
server = novncproxy_service.NoVNCProxyService()

View File

@@ -18,6 +18,8 @@ from oslo_service import service
from ironic.common import rpc_service
from ironic.common import service as ironic_service
from ironic.objects import base as objects_base
from ironic.objects import indirection
CONF = cfg.CONF
LOG = log.getLogger(__name__)
@@ -56,6 +58,12 @@ def main():
"rpc_transport = json-rpc. Please use another "
"RPC transport.")
# Sets the indirection API to direct API calls for objects across the
# RPC layer.
if CONF.rpc_transport in ['local', 'none'] or CONF.use_rpc_for_database:
objects_base.IronicObject.indirection_api = \
indirection.IronicObjectIndirectionAPI()
mgr = RPCService(
CONF.host, 'ironic.pxe_filter.service', 'PXEFilterManager')

View File

@@ -23,6 +23,8 @@ from ironic.common import wsgi_service
from ironic.conductor import local_rpc
from ironic.conductor import rpc_service
from ironic.console import novncproxy_service
from ironic.objects import base as objects_base
from ironic.objects import indirection
CONF = cfg.CONF
@@ -55,6 +57,12 @@ def main():
conductor_cmd.issue_startup_warnings(CONF)
launcher.launch_service(mgr)
# Sets the indirection API to direct API calls for objects across the
# RPC layer.
if CONF.rpc_transport in ['local', 'none'] or CONF.use_rpc_for_database:
objects_base.IronicObject.indirection_api = \
indirection.IronicObjectIndirectionAPI()
wsgi = wsgi_service.WSGIService('ironic_api', CONF.api.enable_ssl_api)
launcher.launch_service(wsgi)

View File

@@ -19,12 +19,12 @@ import time
from oslo_log import log
from tooz import hashring
from ironic.common import context
from ironic.common import exception
from ironic.common.i18n import _
from ironic.common import utils
from ironic.conf import CONF
from ironic.db import api as dbapi
from ironic import objects
LOG = log.getLogger(__name__)
@@ -34,7 +34,6 @@ class HashRingManager(object):
_lock = threading.Lock()
def __init__(self, use_groups=True, cache=True):
self.dbapi = dbapi.get_instance()
self.use_groups = use_groups
self.cache = cache
@@ -68,7 +67,11 @@ class HashRingManager(object):
def _load_hash_rings(self):
rings = {}
d2c = self.dbapi.get_active_hardware_type_dict(
# NOTE(TheJulia): Do not use the dbapi interface directly
# as hash_ring code is common code with the API, and want
# the overall flow respected.
d2c = objects.Conductor.get_active_hardware_type_dict(
context.get_admin_context(),
use_groups=self.use_groups)
for driver_name, hosts in d2c.items():

View File

@@ -899,24 +899,24 @@ RELEASE_MAPPING = {
'api': '1.100',
'rpc': '1.61',
'objects': {
'Allocation': ['1.2', '1.1'],
'BIOSSetting': ['1.1'],
'Node': ['1.41'],
'NodeHistory': ['1.0'],
'NodeInventory': ['1.0'],
'Conductor': ['1.5', '1.4'],
'Chassis': ['1.3'],
'Deployment': ['1.0'],
'DeployTemplate': ['1.1'],
'Port': ['1.13'],
'Portgroup': ['1.5'],
'Trait': ['1.0'],
'TraitList': ['1.0'],
'VolumeConnector': ['1.0'],
'VolumeTarget': ['1.0'],
'FirmwareComponent': ['1.0'],
'Runbook': ['1.0'],
'InspectionRule': ['1.0'],
'Allocation': ['1.3', '1.2', '1.1'],
'BIOSSetting': ['1.2', '1.1'],
'Node': ['1.42', '1.41'],
'NodeHistory': ['1.1', '1.0'],
'NodeInventory': ['1.1', '1.0'],
'Conductor': ['1.6', '1.5', '1.4'],
'Chassis': ['1.4', '1.3'],
'Deployment': ['1.1', '1.0'],
'DeployTemplate': ['1.2', '1.1'],
'Port': ['1.14', '1.13', '1.12'],
'Portgroup': ['1.6', '1.5'],
'Trait': ['1.1', '1.0'],
'TraitList': ['1.1', '1.0'],
'VolumeConnector': ['1.1', '1.0'],
'VolumeTarget': ['1.1', '1.0'],
'FirmwareComponent': ['1.1', '1.0'],
'Runbook': ['1.1', '1.0'],
'InspectionRule': ['1.1', '1.0'],
}
},
}

View File

@@ -3473,6 +3473,11 @@ class ConductorManager(base_manager.BaseConductorManager):
try:
# NOTE(danms): Keep the getattr inside the try block since
# a missing method is really a client problem
# NOTE(TheJulia): Explicitly set the indirection_api to None
# because we don't want to recurse into calling ourselves as
# a side-effect in single process mode -- i.e. if we have a
# request on this end, we've already routed through the layers.
target.indirection_api = None
return getattr(target, method)(context, *args, **kwargs)
except Exception:
# NOTE(danms): This is oslo.messaging fu. ExpectedException()

View File

@@ -99,6 +99,14 @@ api_opts = [
default="",
help=_('The conductor_group to use for new nodes when no '
'conductor_group was defined in the creation request.')),
cfg.BoolOpt('use_rpc_for_database',
default=False,
mutable=False,
help=_('If the Ironic API should utilize the RPC layer for '
'database interactions as opposed to directly '
'connecting to the database API endpoint. Defaults '
'to False, however is implied when the '
'[default]rpc_transport option is set to \'none\'.')),
]
driver_opts = [

View File

@@ -28,7 +28,8 @@ class Allocation(base.IronicObject, object_base.VersionedObjectDictCompat):
# Version 1.0: Initial version
# Version 1.1: Add owner field
# Version 1.2: Add remotable method check_node_list
VERSION = '1.2'
# Version 1.3: Relevant methods changed to be remotable methods.
VERSION = '1.3'
dbapi = dbapi.get_instance()
@@ -80,11 +81,7 @@ class Allocation(base.IronicObject, object_base.VersionedObjectDictCompat):
# DB: set unavailable fields to their default.
self.owner = None
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def get(cls, context, allocation_ident):
"""Find an allocation by its ID, UUID or name.
@@ -103,11 +100,7 @@ class Allocation(base.IronicObject, object_base.VersionedObjectDictCompat):
else:
raise exception.InvalidIdentity(identity=allocation_ident)
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def get_by_id(cls, context, allocation_id):
"""Find an allocation by its integer ID.
@@ -122,11 +115,7 @@ class Allocation(base.IronicObject, object_base.VersionedObjectDictCompat):
allocation = cls._from_db_object(context, cls(), db_allocation)
return allocation
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def get_by_uuid(cls, context, uuid):
"""Find an allocation by its UUID.
@@ -141,11 +130,7 @@ class Allocation(base.IronicObject, object_base.VersionedObjectDictCompat):
allocation = cls._from_db_object(context, cls(), db_allocation)
return allocation
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def get_by_name(cls, context, name):
"""Find an allocation based by its name.
@@ -160,11 +145,7 @@ class Allocation(base.IronicObject, object_base.VersionedObjectDictCompat):
allocation = cls._from_db_object(context, cls(), db_allocation)
return allocation
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def list(cls, context, filters=None, limit=None, marker=None,
sort_key=None, sort_dir=None):
"""Return a list of Allocation objects.
@@ -187,10 +168,7 @@ class Allocation(base.IronicObject, object_base.VersionedObjectDictCompat):
sort_dir=sort_dir)
return cls._from_db_object_list(context, db_allocations)
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable
@object_base.remotable
def create(self, context=None):
"""Create a Allocation record in the DB.
@@ -207,10 +185,7 @@ class Allocation(base.IronicObject, object_base.VersionedObjectDictCompat):
db_allocation = self.dbapi.create_allocation(values)
self._from_db_object(self._context, self, db_allocation)
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable
@object_base.remotable
def destroy(self, context=None):
"""Delete the Allocation from the DB.
@@ -226,10 +201,7 @@ class Allocation(base.IronicObject, object_base.VersionedObjectDictCompat):
self.dbapi.destroy_allocation(self.uuid)
self.obj_reset_changes()
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable
@object_base.remotable
def save(self, context=None):
"""Save updates to this Allocation.
@@ -249,10 +221,7 @@ class Allocation(base.IronicObject, object_base.VersionedObjectDictCompat):
updated_allocation = self.dbapi.update_allocation(self.uuid, updates)
self._from_db_object(self._context, self, updated_allocation)
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable
@object_base.remotable
def refresh(self, context=None):
"""Loads updates for this Allocation.

View File

@@ -27,6 +27,7 @@ from ironic.objects import fields as object_fields
LOG = log.getLogger(__name__)
remotable_classmethod = object_base.remotable_classmethod
remotable = object_base.remotable
def max_version(versions):

View File

@@ -25,7 +25,8 @@ from ironic.objects import fields as object_fields
class BIOSSetting(base.IronicObject):
# Version 1.0: Initial version
# Version 1.1: Added registry
VERSION = '1.1'
# Version 1.2: Relevant methods changed to be remotable methods.
VERSION = '1.2'
dbapi = dbapi.get_instance()
@@ -49,10 +50,7 @@ class BIOSSetting(base.IronicObject):
'upper_bound': object_fields.IntegerField(nullable=True)
}
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable
@object_base.remotable
def create(self, context=None):
"""Create a BIOS Setting record in DB.
@@ -74,10 +72,7 @@ class BIOSSetting(base.IronicObject):
values['node_id'], [settings], values['version'])
self._from_db_object(self._context, self, db_bios_setting[0])
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable
@object_base.remotable
def save(self, context=None):
"""Save BIOS Setting update in DB.
@@ -100,11 +95,7 @@ class BIOSSetting(base.IronicObject):
values['node_id'], [settings], values['version'])
self._from_db_object(self._context, self, updated_bios_setting[0])
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def get(cls, context, node_id, name):
"""Get a BIOS Setting based on its node_id and name.
@@ -118,11 +109,7 @@ class BIOSSetting(base.IronicObject):
db_bios_setting = cls.dbapi.get_bios_setting(node_id, name)
return cls._from_db_object(context, cls(), db_bios_setting)
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def delete(cls, context, node_id, name):
"""Delete a BIOS Setting based on its node_id and name.
@@ -172,7 +159,8 @@ class BIOSSetting(base.IronicObject):
@base.IronicObjectRegistry.register
class BIOSSettingList(base.IronicObjectListBase, base.IronicObject):
# Version 1.0: Initial version
VERSION = '1.0'
# Version 1.1: Relevant methods changed to be remotable methods.
VERSION = '1.1'
dbapi = dbapi.get_instance()
@@ -180,11 +168,7 @@ class BIOSSettingList(base.IronicObjectListBase, base.IronicObject):
'objects': object_fields.ListOfObjectsField('BIOSSetting'),
}
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def create(cls, context, node_id, settings):
"""Create a list of BIOS Setting records in DB.
@@ -207,11 +191,7 @@ class BIOSSettingList(base.IronicObjectListBase, base.IronicObject):
return object_base.obj_make_list(
context, cls(), BIOSSetting, db_setting_list)
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def save(cls, context, node_id, settings):
"""Save a list of BIOS Setting updates in DB.
@@ -234,11 +214,7 @@ class BIOSSettingList(base.IronicObjectListBase, base.IronicObject):
return object_base.obj_make_list(
context, cls(), BIOSSetting, updated_setting_list)
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def delete(cls, context, node_id, names):
"""Delete BIOS Settings based on node_id and names.
@@ -250,11 +226,7 @@ class BIOSSettingList(base.IronicObjectListBase, base.IronicObject):
"""
cls.dbapi.delete_bios_setting_list(node_id, names)
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def get_by_node_id(cls, context, node_id):
"""Get BIOS Setting based on node_id.
@@ -267,11 +239,7 @@ class BIOSSettingList(base.IronicObjectListBase, base.IronicObject):
return object_base.obj_make_list(
context, cls(), BIOSSetting, node_bios_setting)
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def sync_node_setting(cls, context, node_id, settings):
"""Returns lists of create/update/delete/unchanged settings.

View File

@@ -31,7 +31,8 @@ class Chassis(base.IronicObject, object_base.VersionedObjectDictCompat):
# only work with a uuid
# Version 1.2: Add create() and destroy()
# Version 1.3: Add list()
VERSION = '1.3'
# Version 1.4: Relevant methods changed to be remotable methods.
VERSION = '1.4'
dbapi = dbapi.get_instance()
@@ -42,11 +43,7 @@ class Chassis(base.IronicObject, object_base.VersionedObjectDictCompat):
'description': object_fields.StringField(nullable=True),
}
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable_classmethod
@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.
@@ -61,11 +58,7 @@ class Chassis(base.IronicObject, object_base.VersionedObjectDictCompat):
else:
raise exception.InvalidIdentity(identity=chassis_id)
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable_classmethod
@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.
@@ -78,11 +71,7 @@ class Chassis(base.IronicObject, object_base.VersionedObjectDictCompat):
chassis = cls._from_db_object(context, cls(), db_chassis)
return chassis
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def get_by_uuid(cls, context, uuid):
"""Find a chassis based on UUID and return a :class:`Chassis` object.
@@ -95,11 +84,7 @@ class Chassis(base.IronicObject, object_base.VersionedObjectDictCompat):
chassis = cls._from_db_object(context, cls(), db_chassis)
return chassis
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable_classmethod
@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.
@@ -119,10 +104,7 @@ class Chassis(base.IronicObject, object_base.VersionedObjectDictCompat):
sort_dir=sort_dir)
return cls._from_db_object_list(context, db_chassis)
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable
@object_base.remotable
def create(self, context=None):
"""Create a Chassis record in the DB.
@@ -143,10 +125,7 @@ class Chassis(base.IronicObject, object_base.VersionedObjectDictCompat):
db_chassis = self.dbapi.create_chassis(values)
self._from_db_object(self._context, self, db_chassis)
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable
@object_base.remotable
def destroy(self, context=None):
"""Delete the Chassis from the DB.
@@ -160,10 +139,7 @@ class Chassis(base.IronicObject, object_base.VersionedObjectDictCompat):
self.dbapi.destroy_chassis(self.uuid)
self.obj_reset_changes()
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable
@object_base.remotable
def save(self, context=None):
"""Save updates to this Chassis.
@@ -181,10 +157,7 @@ class Chassis(base.IronicObject, object_base.VersionedObjectDictCompat):
updated_chassis = self.dbapi.update_chassis(self.uuid, updates)
self._from_db_object(self._context, self, updated_chassis)
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable
@object_base.remotable
def refresh(self, context=None):
"""Loads and applies updates for this Chassis.

View File

@@ -37,7 +37,9 @@ class Conductor(base.IronicObject, object_base.VersionedObjectDictCompat):
# Version 1.5: Add new remotable methods
# get_shard_list, list_hardware_type_interfaces,
# and get_active_hardware_type_dict
VERSION = '1.5'
# Version 1.6: Updates methods numerous conductor methods to
# to be remotable calls.
VERSION = '1.6'
dbapi = db_api.get_instance()
@@ -49,7 +51,7 @@ class Conductor(base.IronicObject, object_base.VersionedObjectDictCompat):
'online': object_fields.BooleanField(),
}
@classmethod
@object_base.remotable_classmethod
def list(cls, context, limit=None, marker=None, sort_key=None,
sort_dir=None):
"""Return a list of Conductor objects.
@@ -68,11 +70,7 @@ class Conductor(base.IronicObject, object_base.VersionedObjectDictCompat):
sort_dir=sort_dir)
return cls._from_db_object_list(context, db_conductors)
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def get_by_hostname(cls, context, hostname, online=True):
"""Get a Conductor record by its hostname.
@@ -88,15 +86,13 @@ class Conductor(base.IronicObject, object_base.VersionedObjectDictCompat):
conductor = cls._from_db_object(context, cls(), db_obj)
return conductor
@object_base.remotable
def save(self, context):
"""Save is not supported by Conductor objects."""
raise NotImplementedError(
_('Cannot update a conductor record directly.'))
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable
@object_base.remotable
def refresh(self, context=None):
"""Loads and applies updates for this Conductor.
@@ -114,18 +110,10 @@ class Conductor(base.IronicObject, object_base.VersionedObjectDictCompat):
current = self.get_by_hostname(self._context, hostname=self.hostname)
self.obj_refresh(current)
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable
def touch(self, context=None, online=True):
"""Touch this conductor's DB record, marking it as up-to-date."""
self.dbapi.touch_conductor(self.hostname, online=online)
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable
@classmethod
def register(cls, context, hostname, drivers, conductor_group,
update_existing=False):
@@ -154,10 +142,6 @@ class Conductor(base.IronicObject, object_base.VersionedObjectDictCompat):
update_existing=update_existing)
return cls._from_db_object(context, cls(), db_cond)
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable
def unregister(self, context=None):
"""Remove this conductor from the service registry."""
self.unregister_all_hardware_interfaces()
@@ -187,7 +171,10 @@ class Conductor(base.IronicObject, object_base.VersionedObjectDictCompat):
and does so as a direct call for compatibility with lightweight
API method.
"""
return cls.dbapi.get_active_hardware_type_dict(use_groups=use_groups)
# NOTE(TheJulia): Return a dict object instead of a collection object
# because the indirection layer cannot handle a collection class.
return dict(
cls.dbapi.get_active_hardware_type_dict(use_groups=use_groups))
@base.remotable_classmethod
def list_hardware_type_interfaces_dict(cls, context, names):
@@ -227,4 +214,6 @@ class Conductor(base.IronicObject, object_base.VersionedObjectDictCompat):
indirection_api call usage instead of trying to directly invoke the
database.
"""
# FIXME(TheJulia): Ideally this should be a formal object, but the
# calling method expects json, so it works.
return cls.dbapi.get_shard_list()

View File

@@ -22,7 +22,8 @@ from ironic.objects import notification
class DeployTemplate(base.IronicObject, object_base.VersionedObjectDictCompat):
# Version 1.0: Initial version
# Version 1.1: Added 'extra' field
VERSION = '1.1'
# Version 1.2: Relevant methods changed to be remotable methods.
VERSION = '1.2'
dbapi = db_api.get_instance()
@@ -34,11 +35,7 @@ class DeployTemplate(base.IronicObject, object_base.VersionedObjectDictCompat):
'extra': object_fields.FlexibleDictField(nullable=True),
}
# NOTE(mgoddard): We don't want to enable RPC on this call just yet.
# Remotable methods can be used in the future to replace current explicit
# RPC calls. Implications of calling new remote procedures should be
# thought through.
# @object_base.remotable
@object_base.remotable
def create(self, context=None):
"""Create a DeployTemplate record in the DB.
@@ -57,11 +54,7 @@ class DeployTemplate(base.IronicObject, object_base.VersionedObjectDictCompat):
db_template = self.dbapi.create_deploy_template(values)
self._from_db_object(self._context, self, db_template)
# NOTE(mgoddard): We don't want to enable RPC on this call just yet.
# Remotable methods can be used in the future to replace current explicit
# RPC calls. Implications of calling new remote procedures should be
# thought through.
# @object_base.remotable
@object_base.remotable
def save(self, context=None):
"""Save updates to this DeployTemplate.
@@ -82,11 +75,7 @@ class DeployTemplate(base.IronicObject, object_base.VersionedObjectDictCompat):
db_template = self.dbapi.update_deploy_template(self.uuid, updates)
self._from_db_object(self._context, self, db_template)
# NOTE(mgoddard): We don't want to enable RPC on this call just yet.
# Remotable methods can be used in the future to replace current explicit
# RPC calls. Implications of calling new remote procedures should be
# thought through.
# @object_base.remotable_classmethod
@object_base.remotable
def destroy(self):
"""Delete the DeployTemplate from the DB.
@@ -102,12 +91,7 @@ class DeployTemplate(base.IronicObject, object_base.VersionedObjectDictCompat):
self.dbapi.destroy_deploy_template(self.id)
self.obj_reset_changes()
# NOTE(mgoddard): We don't want to enable RPC on this call just yet.
# Remotable methods can be used in the future to replace current explicit
# RPC calls. Implications of calling new remote procedures should be
# thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def get_by_id(cls, context, template_id):
"""Find a deploy template based on its integer ID.
@@ -126,12 +110,7 @@ class DeployTemplate(base.IronicObject, object_base.VersionedObjectDictCompat):
template = cls._from_db_object(context, cls(), db_template)
return template
# NOTE(mgoddard): We don't want to enable RPC on this call just yet.
# Remotable methods can be used in the future to replace current explicit
# RPC calls. Implications of calling new remote procedures should be
# thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def get_by_uuid(cls, context, uuid):
"""Find a deploy template based on its UUID.
@@ -150,12 +129,7 @@ class DeployTemplate(base.IronicObject, object_base.VersionedObjectDictCompat):
template = cls._from_db_object(context, cls(), db_template)
return template
# NOTE(mgoddard): We don't want to enable RPC on this call just yet.
# Remotable methods can be used in the future to replace current explicit
# RPC calls. Implications of calling new remote procedures should be
# thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def get_by_name(cls, context, name):
"""Find a deploy template based on its name.
@@ -174,12 +148,7 @@ class DeployTemplate(base.IronicObject, object_base.VersionedObjectDictCompat):
template = cls._from_db_object(context, cls(), db_template)
return template
# NOTE(mgoddard): We don't want to enable RPC on this call just yet.
# Remotable methods can be used in the future to replace current explicit
# RPC calls. Implications of calling new remote procedures should be
# thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def list(cls, context, limit=None, marker=None, sort_key=None,
sort_dir=None):
"""Return a list of DeployTemplate objects.
@@ -200,12 +169,7 @@ class DeployTemplate(base.IronicObject, object_base.VersionedObjectDictCompat):
limit=limit, marker=marker, sort_key=sort_key, sort_dir=sort_dir)
return cls._from_db_object_list(context, db_templates)
# NOTE(mgoddard): We don't want to enable RPC on this call just yet.
# Remotable methods can be used in the future to replace current explicit
# RPC calls. Implications of calling new remote procedures should be
# thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def list_by_names(cls, context, names):
"""Return a list of DeployTemplate objects matching a set of names.
@@ -221,6 +185,7 @@ class DeployTemplate(base.IronicObject, object_base.VersionedObjectDictCompat):
db_templates = cls.dbapi.get_deploy_template_list_by_names(names)
return cls._from_db_object_list(context, db_templates)
@object_base.remotable
def refresh(self, context=None):
"""Loads updates for this deploy template.

View File

@@ -23,7 +23,8 @@ from ironic.objects import node as node_obj
@base.IronicObjectRegistry.register
class Deployment(base.IronicObject, object_base.VersionedObjectDictCompat):
# Version 1.0: Initial version
VERSION = '1.0'
# Version 1.1: Relevant methods changed to be remotable methods.
VERSION = '1.1'
dbapi = dbapi.get_instance()
@@ -118,11 +119,7 @@ class Deployment(base.IronicObject, object_base.VersionedObjectDictCompat):
node.instance_info = instance_info
return node
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def get_by_uuid(cls, context, uuid):
"""Find a deployment by its UUID.
@@ -136,11 +133,7 @@ class Deployment(base.IronicObject, object_base.VersionedObjectDictCompat):
node = node_obj.Node.get_by_instance_uuid(context, uuid)
return cls._from_node_object(context, node)
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def get_by_node_uuid(cls, context, node_uuid):
"""Find a deployment based by its node's UUID.
@@ -154,11 +147,7 @@ class Deployment(base.IronicObject, object_base.VersionedObjectDictCompat):
node = node_obj.Node.get_by_uuid(context, node_uuid)
return cls._from_node_object(context, node)
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def list(cls, context, filters=None, limit=None, marker=None,
sort_key=None, sort_dir=None):
"""Return a list of Deployment objects.
@@ -179,10 +168,7 @@ class Deployment(base.IronicObject, object_base.VersionedObjectDictCompat):
sort_dir=sort_dir)
return [cls._from_node_object(context, node) for node in nodes]
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable
@object_base.remotable
def create(self, context=None, node=None):
"""Create a Deployment.
@@ -213,10 +199,7 @@ class Deployment(base.IronicObject, object_base.VersionedObjectDictCompat):
self._update_from_node_object(node)
self.obj_reset_changes()
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable
@object_base.remotable
def destroy(self, context=None, node=None):
"""Delete the Deployment.
@@ -240,10 +223,7 @@ class Deployment(base.IronicObject, object_base.VersionedObjectDictCompat):
self._update_from_node_object(node)
self.obj_reset_changes()
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable
@object_base.remotable
def refresh(self, context=None):
"""Refresh the object by re-fetching from the DB.

View File

@@ -23,7 +23,8 @@ from ironic.objects import fields as object_fields
@base.IronicObjectRegistry.register
class FirmwareComponent(base.IronicObject):
# Version 1.0: Initial version
VERSION = '1.0'
# Version 1.1: Relevant methods changed to be remotable methods.
VERSION = '1.1'
dbapi = dbapi.get_instance()
@@ -36,6 +37,7 @@ class FirmwareComponent(base.IronicObject):
'last_version_flashed': object_fields.StringField(nullable=True),
}
@object_base.remotable
def create(self, context=None):
"""Create a Firmware record in the DB.
@@ -50,6 +52,7 @@ class FirmwareComponent(base.IronicObject):
db_fwcmp = self.dbapi.create_firmware_component(values)
self._from_db_object(self._context, self, db_fwcmp)
@object_base.remotable
def save(self, context=None):
"""Save updates to this Firmware Component.
@@ -74,7 +77,7 @@ class FirmwareComponent(base.IronicObject):
self.node_id, self.component, updates)
self._from_db_object(self._context, self, up_fwcmp)
@classmethod
@object_base.remotable_classmethod
def get(cls, context, node_id, name):
"""Get a FirmwareComponent based on its node_id and name.
@@ -94,7 +97,8 @@ class FirmwareComponent(base.IronicObject):
@base.IronicObjectRegistry.register
class FirmwareComponentList(base.IronicObjectListBase, base.IronicObject):
# Version 1.0: Initial version
VERSION = '1.0'
# Version 1.1: Relevant methods changed to be remotable methods.
VERSION = '1.1'
dbapi = dbapi.get_instance()
@@ -102,7 +106,7 @@ class FirmwareComponentList(base.IronicObjectListBase, base.IronicObject):
'objects': object_fields.ListOfObjectsField('FirmwareComponent'),
}
@classmethod
@object_base.remotable_classmethod
def get_by_node_id(cls, context, node_id):
"""Get FirmwareComponent based on node_id.

View File

@@ -15,6 +15,9 @@ from oslo_versionedobjects import base as object_base
from ironic.conductor import rpcapi as conductor_api
# NOTE(TheJulia): The whole purpose of the indirection API is to disjoint
# the interactions to the conductor through a class based upon the
# VersionedObjectIndirectionAPI class provided by oslo.versionedobjects.
class IronicObjectIndirectionAPI(object_base.VersionedObjectIndirectionAPI):
def __init__(self):
super(IronicObjectIndirectionAPI, self).__init__()

View File

@@ -20,7 +20,8 @@ from ironic.objects import notification
@base.IronicObjectRegistry.register
class InspectionRule(base.IronicObject, object_base.VersionedObjectDictCompat):
# Version 1.0: Initial version
VERSION = '1.0'
# Version 1.1: Relevant methods changed to be remotable methods.
VERSION = '1.1'
dbapi = db_api.get_instance()
@@ -36,11 +37,7 @@ class InspectionRule(base.IronicObject, object_base.VersionedObjectDictCompat):
'conditions': object_fields.ListOfFlexibleDictsField(nullable=True),
}
# NOTE(mgoddard): We don't want to enable RPC on this call just yet.
# Remotable methods can be used in the future to replace current explicit
# RPC calls. Implications of calling new remote procedures should be
# thought through.
# @object_base.remotable
@object_base.remotable
def create(self, context=None):
"""Create a InspectionRule record in the DB.
@@ -59,6 +56,7 @@ class InspectionRule(base.IronicObject, object_base.VersionedObjectDictCompat):
db_rule = self.dbapi.create_inspection_rule(values)
self._from_db_object(self._context, self, db_rule)
@object_base.remotable
def save(self, context=None):
"""Save updates to this InspectionRule.
@@ -77,6 +75,7 @@ class InspectionRule(base.IronicObject, object_base.VersionedObjectDictCompat):
db_rule = self.dbapi.update_inspection_rule(self.uuid, updates)
self._from_db_object(self._context, self, db_rule)
@object_base.remotable
def destroy(self):
"""Delete the InspectionRule from the DB.
@@ -92,12 +91,7 @@ class InspectionRule(base.IronicObject, object_base.VersionedObjectDictCompat):
self.dbapi.destroy_inspection_rule(self.id)
self.obj_reset_changes()
# NOTE(mgoddard): We don't want to enable RPC on this call just yet.
# Remotable methods can be used in the future to replace current explicit
# RPC calls. Implications of calling new remote procedures should be
# thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def get_by_uuid(cls, context, uuid):
"""Find a inspection rule based on its UUID.
@@ -116,12 +110,7 @@ class InspectionRule(base.IronicObject, object_base.VersionedObjectDictCompat):
rule = cls._from_db_object(context, cls(), db_rule)
return rule
# NOTE(mgoddard): We don't want to enable RPC on this call just yet.
# Remotable methods can be used in the future to replace current explicit
# RPC calls. Implications of calling new remote procedures should be
# thought through.
# @object_base.remotable_classmethod
@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 InspectionRule objects.
@@ -143,6 +132,7 @@ class InspectionRule(base.IronicObject, object_base.VersionedObjectDictCompat):
filters=filters)
return cls._from_db_object_list(context, db_rules)
@object_base.remotable
def refresh(self, context=None):
"""Loads updates for this inspection rule.

View File

@@ -83,7 +83,8 @@ class Node(base.IronicObject, object_base.VersionedObjectDictCompat):
# Version 1.39: Add firmware_interface field
# Version 1.40: Add service_step field
# Version 1.41: Add disable_power_off field
VERSION = '1.41'
# Version 1.42: Moves multiple methods to be remotable methods.
VERSION = '1.42'
dbapi = db_api.get_instance()
@@ -240,11 +241,7 @@ class Node(base.IronicObject, object_base.VersionedObjectDictCompat):
fields=['trait', 'version'])
self.traits.obj_reset_changes()
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable_classmethod
@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.
@@ -259,11 +256,7 @@ class Node(base.IronicObject, object_base.VersionedObjectDictCompat):
else:
raise exception.InvalidIdentity(identity=node_id)
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable_classmethod
@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.
@@ -276,11 +269,7 @@ class Node(base.IronicObject, object_base.VersionedObjectDictCompat):
node = cls._from_db_object(context, cls(), db_node)
return node
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def get_by_uuid(cls, context, uuid):
"""Find a node based on UUID and return a Node object.
@@ -293,11 +282,7 @@ class Node(base.IronicObject, object_base.VersionedObjectDictCompat):
node = cls._from_db_object(context, cls(), db_node)
return node
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def get_by_name(cls, context, name):
"""Find a node based on name and return a Node object.
@@ -310,11 +295,7 @@ class Node(base.IronicObject, object_base.VersionedObjectDictCompat):
node = cls._from_db_object(context, cls(), db_node)
return node
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable_classmethod
@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.
@@ -327,11 +308,7 @@ class Node(base.IronicObject, object_base.VersionedObjectDictCompat):
node = cls._from_db_object(context, cls(), db_node)
return node
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def list(cls, context, limit=None, marker=None, sort_key=None,
sort_dir=None, filters=None, fields=None):
"""Return a list of Node objects.
@@ -367,10 +344,9 @@ class Node(base.IronicObject, object_base.VersionedObjectDictCompat):
fields=target_fields)
return cls._from_db_object_list(context, db_nodes, target_fields)
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable_classmethod
# NOTE(TheJulia): The choice to not make this a remotable method is
# explicit in that locks are intended only for a conductor. If we choose
# to change this, we need reconsider the locking model.
@classmethod
def reserve(cls, context, tag, node_id):
"""Get and reserve a node.
@@ -390,10 +366,9 @@ class Node(base.IronicObject, object_base.VersionedObjectDictCompat):
node = cls._from_db_object(context, cls(), db_node)
return node
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable_classmethod
# NOTE(TheJulia): The choice to not make this a remotable method is
# explicit in that locks are intended only for a conductor. If we choose
# to change this, we need reconsider the locking model.
@classmethod
def release(cls, context, tag, node_id):
"""Release the reservation on a node.
@@ -406,10 +381,7 @@ class Node(base.IronicObject, object_base.VersionedObjectDictCompat):
"""
cls.dbapi.release_node(tag, node_id)
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable
@object_base.remotable
def create(self, context=None):
"""Create a Node record in the DB.
@@ -433,10 +405,7 @@ class Node(base.IronicObject, object_base.VersionedObjectDictCompat):
db_node = self.dbapi.create_node(values)
self._from_db_object(self._context, self, db_node)
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable
@object_base.remotable
def destroy(self, context=None):
"""Delete the Node from the DB.
@@ -450,10 +419,7 @@ class Node(base.IronicObject, object_base.VersionedObjectDictCompat):
self.dbapi.destroy_node(self.uuid)
self.obj_reset_changes()
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable
@object_base.remotable
def save(self, context=None):
"""Save updates to this Node.
@@ -519,10 +485,7 @@ class Node(base.IronicObject, object_base.VersionedObjectDictCompat):
utils.validate_conductor_group(fields['conductor_group'])
fields['conductor_group'] = fields['conductor_group'].lower()
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable
@object_base.remotable
def refresh(self, context=None):
"""Refresh the object by re-fetching from the DB.
@@ -537,15 +500,11 @@ class Node(base.IronicObject, object_base.VersionedObjectDictCompat):
self.obj_refresh(current)
self.obj_reset_changes()
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @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)
@classmethod
@object_base.remotable_classmethod
def get_by_port_addresses(cls, context, addresses):
"""Get a node by associated port addresses.

View File

@@ -23,7 +23,8 @@ from ironic.objects import fields as object_fields
@base.IronicObjectRegistry.register
class NodeHistory(base.IronicObject, object_base.VersionedObjectDictCompat):
# Version 1.0: Initial version
VERSION = '1.0'
# Version 1.1: Relevant methods changed to be remotable methods.
VERSION = '1.1'
dbapi = dbapi.get_instance()
@@ -38,11 +39,7 @@ class NodeHistory(base.IronicObject, object_base.VersionedObjectDictCompat):
'severity': object_fields.StringField(nullable=True),
}
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def get(cls, context, history_ident):
"""Get a history based on its id or uuid.
@@ -59,11 +56,7 @@ class NodeHistory(base.IronicObject, object_base.VersionedObjectDictCompat):
else:
raise exception.InvalidIdentity(identity=history_ident)
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def get_by_id(cls, context, history_id):
"""Get a NodeHistory object by its integer ID.
@@ -78,11 +71,7 @@ class NodeHistory(base.IronicObject, object_base.VersionedObjectDictCompat):
history = cls._from_db_object(context, cls(), db_history)
return history
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def get_by_uuid(cls, context, uuid):
"""Get a NodeHistory object by its UUID.
@@ -97,11 +86,7 @@ class NodeHistory(base.IronicObject, object_base.VersionedObjectDictCompat):
history = cls._from_db_object(context, cls(), db_history)
return history
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def list(cls, context, limit=None, marker=None, sort_key=None,
sort_dir=None):
"""Return a list of NodeHistory objects.
@@ -122,11 +107,7 @@ class NodeHistory(base.IronicObject, object_base.VersionedObjectDictCompat):
sort_dir=sort_dir)
return cls._from_db_object_list(context, db_histories)
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable_classmethod
@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 NodeHistory objects belongs to a given node ID.
@@ -147,10 +128,6 @@ class NodeHistory(base.IronicObject, object_base.VersionedObjectDictCompat):
sort_dir=sort_dir)
return cls._from_db_object_list(context, db_histories)
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable
def create(self, context=None):
"""Create a NodeHistory record in the DB.
@@ -165,10 +142,6 @@ class NodeHistory(base.IronicObject, object_base.VersionedObjectDictCompat):
db_history = self.dbapi.create_node_history(values)
self._from_db_object(self._context, self, db_history)
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable
def destroy(self, context=None):
"""Delete the NodeHistory from the DB.

View File

@@ -20,7 +20,8 @@ from ironic.objects import fields as object_fields
@base.IronicObjectRegistry.register
class NodeInventory(base.IronicObject, object_base.VersionedObjectDictCompat):
# Version 1.0: Initial version
VERSION = '1.0'
# Version 1.1: Relevant methods changed to be remotable methods.
VERSION = '1.1'
dbapi = dbapi.get_instance()
@@ -45,7 +46,7 @@ class NodeInventory(base.IronicObject, object_base.VersionedObjectDictCompat):
for src, dest in self.instance_info_mapping.items():
setattr(self, dest, node.instance_info.get(src))
@classmethod
@object_base.remotable_classmethod
def get_by_node_id(cls, context, node_id):
"""Get a NodeInventory object by its node ID.
@@ -60,6 +61,7 @@ class NodeInventory(base.IronicObject, object_base.VersionedObjectDictCompat):
inventory = cls._from_db_object(context, cls(), db_inventory)
return inventory
@object_base.remotable
def create(self, context=None):
"""Create a NodeInventory record in the DB.
@@ -74,6 +76,7 @@ class NodeInventory(base.IronicObject, object_base.VersionedObjectDictCompat):
db_inventory = self.dbapi.create_node_inventory(values)
self._from_db_object(self._context, self, db_inventory)
@object_base.remotable
def destroy(self, context=None):
"""Delete the NodeInventory from the DB.

View File

@@ -47,7 +47,8 @@ class Port(base.IronicObject, object_base.VersionedObjectDictCompat):
# Version 1.11: Add node_uuid field
# Version 1.12: Add description field
# Version 1.13: Add vendor field
VERSION = '1.13'
# Version 1.14: Mark multiple methods as remotable methods.
VERSION = '1.14'
dbapi = dbapi.get_instance()
@@ -163,11 +164,7 @@ class Port(base.IronicObject, object_base.VersionedObjectDictCompat):
self._convert_field_by_version('vendor', (1, 13), target_version,
remove_unavailable_fields)
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def get(cls, context, port_id):
"""Find a port.
@@ -191,11 +188,7 @@ class Port(base.IronicObject, object_base.VersionedObjectDictCompat):
else:
raise exception.InvalidIdentity(identity=port_id)
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable_classmethod
@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.
@@ -210,11 +203,7 @@ class Port(base.IronicObject, object_base.VersionedObjectDictCompat):
port = cls._from_db_object(context, cls(), db_port)
return port
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def get_by_uuid(cls, context, uuid):
"""Find a port based on UUID and return a :class:`Port` object.
@@ -229,11 +218,7 @@ class Port(base.IronicObject, object_base.VersionedObjectDictCompat):
port = cls._from_db_object(context, cls(), db_port)
return port
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def get_by_address(cls, context, address, owner=None, project=None):
"""Find a port based on address and return a :class:`Port` object.
@@ -252,11 +237,7 @@ class Port(base.IronicObject, object_base.VersionedObjectDictCompat):
port = cls._from_db_object(context, cls(), db_port)
return port
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def get_by_name(cls, context, name):
"""Find a port based on name and return a :class:`Port` object.
@@ -271,11 +252,7 @@ class Port(base.IronicObject, object_base.VersionedObjectDictCompat):
port = cls._from_db_object(context, cls(), db_port)
return port
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def list(cls, context, limit=None, marker=None, sort_key=None,
sort_dir=None, owner=None, project=None, conductor_groups=None,
filters=None):
@@ -330,11 +307,7 @@ class Port(base.IronicObject, object_base.VersionedObjectDictCompat):
filters=filters)
return cls._from_db_object_list(context, db_ports)
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def list_by_node_id(cls, context, node_id, limit=None, marker=None,
sort_key=None, sort_dir=None, owner=None,
project=None, filters=None):
@@ -362,11 +335,7 @@ class Port(base.IronicObject, object_base.VersionedObjectDictCompat):
filters=filters)
return cls._from_db_object_list(context, db_ports)
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def list_by_portgroup_id(cls, context, portgroup_id, limit=None,
marker=None, sort_key=None, sort_dir=None,
owner=None, project=None, filters=None):
@@ -395,10 +364,7 @@ class Port(base.IronicObject, object_base.VersionedObjectDictCompat):
filters=filters)
return cls._from_db_object_list(context, db_ports)
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable
@object_base.remotable
def create(self, context=None):
"""Create a Port record in the DB.
@@ -420,10 +386,7 @@ class Port(base.IronicObject, object_base.VersionedObjectDictCompat):
db_port = self.dbapi.get_port_by_id(db_port['id'])
self._from_db_object(self._context, self, db_port)
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable
@object_base.remotable
def destroy(self, context=None):
"""Delete the Port from the DB.
@@ -439,10 +402,7 @@ class Port(base.IronicObject, object_base.VersionedObjectDictCompat):
self.dbapi.destroy_port(self.uuid)
self.obj_reset_changes()
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable
@object_base.remotable
def save(self, context=None):
"""Save updates to this Port.
@@ -463,10 +423,7 @@ class Port(base.IronicObject, object_base.VersionedObjectDictCompat):
updated_port = self.dbapi.update_port(self.uuid, updates)
self._from_db_object(self._context, self, updated_port)
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable
@object_base.remotable
def refresh(self, context=None):
"""Loads updates for this Port.

View File

@@ -37,7 +37,8 @@ class Portgroup(base.IronicObject, object_base.VersionedObjectDictCompat):
# internal_info['tenant_vif_port_id'] (not an explicit db
# change)
# Version 1.5: Add node_uuid field
VERSION = '1.5'
# Version 1.6: Relevant methods changed to be remotable methods.
VERSION = '1.6'
dbapi = dbapi.get_instance()
@@ -86,11 +87,7 @@ class Portgroup(base.IronicObject, object_base.VersionedObjectDictCompat):
internal_info['tenant_vif_port_id'] = vif
self.internal_info = internal_info
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def get(cls, context, portgroup_ident):
"""Find a portgroup based on its id, uuid, name or address.
@@ -111,11 +108,7 @@ class Portgroup(base.IronicObject, object_base.VersionedObjectDictCompat):
else:
raise exception.InvalidIdentity(identity=portgroup_ident)
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def get_by_id(cls, context, portgroup_id):
"""Find a portgroup by its integer ID and return a Portgroup object.
@@ -130,11 +123,7 @@ class Portgroup(base.IronicObject, object_base.VersionedObjectDictCompat):
portgroup = cls._from_db_object(context, cls(), db_portgroup)
return portgroup
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def get_by_uuid(cls, context, uuid):
"""Find a portgroup by UUID and return a :class:`Portgroup` object.
@@ -149,11 +138,7 @@ class Portgroup(base.IronicObject, object_base.VersionedObjectDictCompat):
portgroup = cls._from_db_object(context, cls(), db_portgroup)
return portgroup
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def get_by_address(cls, context, address, project=None):
"""Find portgroup by address and return a :class:`Portgroup` object.
@@ -170,11 +155,7 @@ class Portgroup(base.IronicObject, object_base.VersionedObjectDictCompat):
portgroup = cls._from_db_object(context, cls(), db_portgroup)
return portgroup
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def get_by_name(cls, context, name):
"""Find portgroup based on name and return a :class:`Portgroup` object.
@@ -189,11 +170,7 @@ class Portgroup(base.IronicObject, object_base.VersionedObjectDictCompat):
portgroup = cls._from_db_object(context, cls(), db_portgroup)
return portgroup
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def list(cls, context, limit=None, marker=None,
sort_key=None, sort_dir=None, project=None,
conductor_groups=None, filters=None):
@@ -223,11 +200,7 @@ class Portgroup(base.IronicObject, object_base.VersionedObjectDictCompat):
conductor_groups=conductor_groups)
return cls._from_db_object_list(context, db_portgroups)
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def list_by_node_id(cls, context, node_id, limit=None, marker=None,
sort_key=None, sort_dir=None, project=None):
"""Return a list of Portgroup objects associated with a given node ID.
@@ -252,10 +225,7 @@ class Portgroup(base.IronicObject, object_base.VersionedObjectDictCompat):
project=project)
return cls._from_db_object_list(context, db_portgroups)
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable
@object_base.remotable
def create(self, context=None):
"""Create a Portgroup record in the DB.
@@ -276,10 +246,7 @@ class Portgroup(base.IronicObject, object_base.VersionedObjectDictCompat):
db_portgroup = self.dbapi.get_portgroup_by_id(db_portgroup['id'])
self._from_db_object(self._context, self, db_portgroup)
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable
@object_base.remotable
def destroy(self, context=None):
"""Delete the Portgroup from the DB.
@@ -295,10 +262,7 @@ class Portgroup(base.IronicObject, object_base.VersionedObjectDictCompat):
self.dbapi.destroy_portgroup(self.id)
self.obj_reset_changes()
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable
@object_base.remotable
def save(self, context=None):
"""Save updates to this Portgroup.
@@ -318,10 +282,7 @@ class Portgroup(base.IronicObject, object_base.VersionedObjectDictCompat):
updated_portgroup = self.dbapi.update_portgroup(self.uuid, updates)
self._from_db_object(self._context, self, updated_portgroup)
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable
@object_base.remotable
def refresh(self, context=None):
"""Loads updates for this Portgroup.

View File

@@ -21,7 +21,8 @@ from ironic.objects import notification
@base.IronicObjectRegistry.register
class Runbook(base.IronicObject, object_base.VersionedObjectDictCompat):
# Version 1.0: Initial version
VERSION = '1.0'
# Version 1.1: Relevant methods changed to be remotable methods.
VERSION = '1.1'
dbapi = db_api.get_instance()
@@ -36,6 +37,7 @@ class Runbook(base.IronicObject, object_base.VersionedObjectDictCompat):
'owner': object_fields.StringField(nullable=True),
}
@object_base.remotable
def create(self, context=None):
"""Create a Runbook record in the DB.
@@ -54,6 +56,7 @@ class Runbook(base.IronicObject, object_base.VersionedObjectDictCompat):
db_template = self.dbapi.create_runbook(values)
self._from_db_object(self._context, self, db_template)
@object_base.remotable
def save(self, context=None):
"""Save updates to this Runbook.
@@ -74,6 +77,7 @@ class Runbook(base.IronicObject, object_base.VersionedObjectDictCompat):
db_template = self.dbapi.update_runbook(self.uuid, updates)
self._from_db_object(self._context, self, db_template)
@object_base.remotable
def destroy(self):
"""Delete the Runbook from the DB.
@@ -89,7 +93,7 @@ class Runbook(base.IronicObject, object_base.VersionedObjectDictCompat):
self.dbapi.destroy_runbook(self.id)
self.obj_reset_changes()
@classmethod
@object_base.remotable_classmethod
def get_by_id(cls, context, runbook_id):
"""Find a runbook based on its integer ID.
@@ -108,7 +112,7 @@ class Runbook(base.IronicObject, object_base.VersionedObjectDictCompat):
template = cls._from_db_object(context, cls(), db_template)
return template
@classmethod
@object_base.remotable_classmethod
def get_by_uuid(cls, context, uuid):
"""Find a runbook based on its UUID.
@@ -127,7 +131,7 @@ class Runbook(base.IronicObject, object_base.VersionedObjectDictCompat):
template = cls._from_db_object(context, cls(), db_template)
return template
@classmethod
@object_base.remotable_classmethod
def get_by_name(cls, context, name):
"""Find a runbook based on its name.
@@ -146,7 +150,7 @@ class Runbook(base.IronicObject, object_base.VersionedObjectDictCompat):
template = cls._from_db_object(context, cls(), db_template)
return template
@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 Runbook objects.
@@ -170,7 +174,7 @@ class Runbook(base.IronicObject, object_base.VersionedObjectDictCompat):
filters=filters)
return cls._from_db_object_list(context, db_templates)
@classmethod
@object_base.remotable_classmethod
def list_by_names(cls, context, names):
"""Return a list of Runbook objects matching a set of names.
@@ -186,6 +190,7 @@ class Runbook(base.IronicObject, object_base.VersionedObjectDictCompat):
db_templates = cls.dbapi.get_runbook_list_by_names(names)
return cls._from_db_object_list(context, db_templates)
@object_base.remotable
def refresh(self, context=None):
"""Loads updates for this runbook.

View File

@@ -20,7 +20,8 @@ from ironic.objects import fields as object_fields
@base.IronicObjectRegistry.register
class Trait(base.IronicObject):
# Version 1.0: Initial version
VERSION = '1.0'
# Version 1.1: Relevant methods changed to be remotable methods.
VERSION = '1.1'
dbapi = db_api.get_instance()
@@ -29,11 +30,7 @@ class Trait(base.IronicObject):
'trait': object_fields.StringField(),
}
# NOTE(mgoddard): We don't want to enable RPC on this call just yet.
# Remotable methods can be used in the future to replace current explicit
# RPC calls. Implications of calling new remote procedures should be
# thought through.
# @object_base.remotable
@object_base.remotable
def create(self, context=None):
"""Create a Trait record in the DB.
@@ -52,12 +49,7 @@ class Trait(base.IronicObject):
values['node_id'], values['trait'], values['version'])
self._from_db_object(self._context, self, db_trait)
# NOTE(mgoddard): We don't want to enable RPC on this call just yet.
# Remotable methods can be used in the future to replace current explicit
# RPC calls. Implications of calling new remote procedures should be
# thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def destroy(cls, context, node_id, trait):
"""Delete the Trait from the DB.
@@ -74,12 +66,7 @@ class Trait(base.IronicObject):
"""
cls.dbapi.delete_node_trait(node_id, trait)
# NOTE(mgoddard): We don't want to enable RPC on this call just yet.
# Remotable methods can be used in the future to replace current explicit
# RPC calls. Implications of calling new remote procedures should be
# thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def exists(cls, context, node_id, trait):
"""Check whether a Trait exists in the DB.
@@ -100,7 +87,8 @@ class Trait(base.IronicObject):
@base.IronicObjectRegistry.register
class TraitList(base.IronicObjectListBase, base.IronicObject):
# Version 1.0: Initial version
VERSION = '1.0'
# Version 1.1: Relevant methods changed to be remotable methods.
VERSION = '1.1'
dbapi = db_api.get_instance()
@@ -108,12 +96,7 @@ class TraitList(base.IronicObjectListBase, base.IronicObject):
'objects': object_fields.ListOfObjectsField('Trait'),
}
# NOTE(mgoddard): We don't want to enable RPC on this call just yet.
# Remotable methods can be used in the future to replace current explicit
# RPC calls. Implications of calling new remote procedures should be
# thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def get_by_node_id(cls, context, node_id):
"""Return all traits for the specified node.
@@ -129,12 +112,7 @@ class TraitList(base.IronicObjectListBase, base.IronicObject):
db_traits = cls.dbapi.get_node_traits_by_node_id(node_id)
return object_base.obj_make_list(context, cls(), Trait, db_traits)
# NOTE(mgoddard): We don't want to enable RPC on this call just yet.
# Remotable methods can be used in the future to replace current explicit
# RPC calls. Implications of calling new remote procedures should be
# thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def create(cls, context, node_id, traits):
"""Replace all existing traits with the specified list.
@@ -154,12 +132,7 @@ class TraitList(base.IronicObjectListBase, base.IronicObject):
db_traits = cls.dbapi.set_node_traits(node_id, traits, version)
return object_base.obj_make_list(context, cls(), Trait, db_traits)
# NOTE(mgoddard): We don't want to enable RPC on this call just yet.
# Remotable methods can be used in the future to replace current explicit
# RPC calls. Implications of calling new remote procedures should be
# thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def destroy(cls, context, node_id):
"""Delete all traits for the specified node.
@@ -174,6 +147,7 @@ class TraitList(base.IronicObjectListBase, base.IronicObject):
"""
cls.dbapi.unset_node_traits(node_id)
def get_trait_names(self):
@object_base.remotable
def get_trait_names(self, context=None):
"""Return a list of names of the traits in this list."""
return [t.trait for t in self.objects]

View File

@@ -27,7 +27,8 @@ from ironic.objects import notification
class VolumeConnector(base.IronicObject,
object_base.VersionedObjectDictCompat):
# Version 1.0: Initial version
VERSION = '1.0'
# Version 1.1: Relevant methods changed to be remotable methods.
VERSION = '1.1'
dbapi = db_api.get_instance()
@@ -40,11 +41,7 @@ class VolumeConnector(base.IronicObject,
'extra': object_fields.FlexibleDictField(nullable=True),
}
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def get(cls, context, ident):
"""Find a volume connector based on its ID or UUID.
@@ -63,11 +60,7 @@ class VolumeConnector(base.IronicObject,
else:
raise exception.InvalidIdentity(identity=ident)
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def get_by_id(cls, context, db_id):
"""Find a volume connector based on its integer ID.
@@ -83,11 +76,7 @@ class VolumeConnector(base.IronicObject,
connector = cls._from_db_object(context, cls(), db_connector)
return connector
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def get_by_uuid(cls, context, uuid):
"""Find a volume connector based on its UUID.
@@ -102,11 +91,7 @@ class VolumeConnector(base.IronicObject,
connector = cls._from_db_object(context, cls(), db_connector)
return connector
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def list(cls, context, limit=None, marker=None,
sort_key=None, sort_dir=None, project=None):
"""Return a list of VolumeConnector objects.
@@ -127,11 +112,7 @@ class VolumeConnector(base.IronicObject,
project=project)
return cls._from_db_object_list(context, db_connectors)
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def list_by_node_id(cls, context, node_id, limit=None, marker=None,
sort_key=None, sort_dir=None, project=None):
"""Return a list of VolumeConnector objects related to a given node ID.
@@ -156,10 +137,7 @@ class VolumeConnector(base.IronicObject,
project=project)
return cls._from_db_object_list(context, db_connectors)
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable
@object_base.remotable
def create(self, context=None):
"""Create a VolumeConnector record in the DB.
@@ -178,10 +156,7 @@ class VolumeConnector(base.IronicObject,
db_connector = self.dbapi.create_volume_connector(values)
self._from_db_object(self._context, self, db_connector)
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable
@object_base.remotable
def destroy(self, context=None):
"""Delete the VolumeConnector from the DB.
@@ -197,10 +172,7 @@ class VolumeConnector(base.IronicObject,
self.dbapi.destroy_volume_connector(self.uuid)
self.obj_reset_changes()
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable
@object_base.remotable
def save(self, context=None):
"""Save updates to this VolumeConnector.
@@ -225,10 +197,7 @@ class VolumeConnector(base.IronicObject,
updates)
self._from_db_object(self._context, self, updated_connector)
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable
@object_base.remotable
def refresh(self, context=None):
"""Load updates for this VolumeConnector.

View File

@@ -27,7 +27,8 @@ from ironic.objects import notification
class VolumeTarget(base.IronicObject,
object_base.VersionedObjectDictCompat):
# Version 1.0: Initial version
VERSION = '1.0'
# Version 1.1: Relevant methods changed to be remotable methods.
VERSION = '1.1'
dbapi = db_api.get_instance()
@@ -42,11 +43,7 @@ class VolumeTarget(base.IronicObject,
'extra': object_fields.FlexibleDictField(nullable=True),
}
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def get(cls, context, ident):
"""Find a volume target based on its ID or UUID.
@@ -65,11 +62,7 @@ class VolumeTarget(base.IronicObject,
else:
raise exception.InvalidIdentity(identity=ident)
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def get_by_id(cls, context, db_id):
"""Find a volume target based on its database ID.
@@ -83,11 +76,7 @@ class VolumeTarget(base.IronicObject,
target = cls._from_db_object(context, cls(), db_target)
return target
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def get_by_uuid(cls, context, uuid):
"""Find a volume target based on its UUID.
@@ -101,11 +90,7 @@ class VolumeTarget(base.IronicObject,
target = cls._from_db_object(context, cls(), db_target)
return target
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def list(cls, context, limit=None, marker=None,
sort_key=None, sort_dir=None, project=None):
"""Return a list of VolumeTarget objects.
@@ -127,11 +112,7 @@ class VolumeTarget(base.IronicObject,
project=project)
return cls._from_db_object_list(context, db_targets)
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def list_by_node_id(cls, context, node_id, limit=None, marker=None,
sort_key=None, sort_dir=None, project=None):
"""Return a list of VolumeTarget objects related to a given node ID.
@@ -156,11 +137,7 @@ class VolumeTarget(base.IronicObject,
project=project)
return cls._from_db_object_list(context, db_targets)
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable_classmethod
@classmethod
@object_base.remotable_classmethod
def list_by_volume_id(cls, context, volume_id, limit=None, marker=None,
sort_key=None, sort_dir=None, project=None):
"""Return a list of VolumeTarget objects related to a given volume ID.
@@ -184,10 +161,7 @@ class VolumeTarget(base.IronicObject,
project=project)
return cls._from_db_object_list(context, db_targets)
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable
@object_base.remotable
def create(self, context=None):
"""Create a VolumeTarget record in the DB.
@@ -206,10 +180,7 @@ class VolumeTarget(base.IronicObject,
db_target = self.dbapi.create_volume_target(values)
self._from_db_object(self._context, self, db_target)
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable
@object_base.remotable
def destroy(self, context=None):
"""Delete the VolumeTarget from the DB.
@@ -224,10 +195,7 @@ class VolumeTarget(base.IronicObject,
self.dbapi.destroy_volume_target(self.uuid)
self.obj_reset_changes()
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable
@object_base.remotable
def save(self, context=None):
"""Save updates to this VolumeTarget.
@@ -249,10 +217,7 @@ class VolumeTarget(base.IronicObject,
updated_target = self.dbapi.update_volume_target(self.uuid, updates)
self._from_db_object(self._context, self, updated_target)
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
# methods can be used in the future to replace current explicit RPC calls.
# Implications of calling new remote procedures should be thought through.
# @object_base.remotable
@object_base.remotable
def refresh(self, context=None):
"""Loads updates for this VolumeTarget.

View File

@@ -309,7 +309,10 @@ class StartStopTestCase(mgr_utils.ServiceSetUpMixin, db_base.DbTestCase):
@mock.patch.object(dbapi, 'get_instance', autospec=True)
def test_start_dbapi_single_call(self, mock_dbapi):
self._start_service()
self.assertEqual(1, mock_dbapi.call_count)
# NOTE(TheJulia): This counts the dbapi instance count
# from starting the hash_ring, but since the hashring is
# common code, it shouldn't invoke a db call directly.
self.assertEqual(0, mock_dbapi.call_count)
def test_start_with_json_rpc(self):
CONF.set_override('rpc_transport', 'json-rpc')

View File

@@ -29,7 +29,7 @@ class DbBIOSSettingTestCase(base.DbTestCase):
self.assertEqual(result['node_id'], self.node.id)
self.assertEqual(result['name'], 'virtualization')
self.assertEqual(result['value'], 'on')
self.assertEqual(result['version'], '1.1')
self.assertEqual(result['version'], '1.2')
def test_get_bios_setting_node_not_exist(self):
self.assertRaises(exception.NodeNotFound,
@@ -50,7 +50,7 @@ class DbBIOSSettingTestCase(base.DbTestCase):
self.assertEqual(result[0]['node_id'], self.node.id)
self.assertEqual(result[0]['name'], 'virtualization')
self.assertEqual(result[0]['value'], 'on')
self.assertEqual(result[0]['version'], '1.1')
self.assertEqual(result[0]['version'], '1.2')
self.assertEqual(len(result), 1)
def test_get_bios_setting_list_node_not_exist(self):

View File

@@ -63,7 +63,7 @@ class DbFirmwareComponentTestCase(base.DbTestCase):
self.assertEqual(result[0]['node_id'], self.node.id)
self.assertEqual(result[0]['component'], 'bmc')
self.assertEqual(result[0]['initial_version'], 'v1.0.0')
self.assertEqual(result[0]['version'], '1.0')
self.assertEqual(result[0]['version'], '1.1')
self.assertEqual(len(result), 1)
def test_get_firmware_component_list_node_not_exist(self):

View File

@@ -798,7 +798,7 @@ class DbNodeTestCase(base.DbTestCase):
created_at=second_timestamp,
plugin_data={"pdata":
{"plugin": "data"}},
version='1.0')
version='1.1')
self.assertJsonEqual(expected_inventory, node_inventory)
def test_inventory_get_destroyed_after_destroying_a_node_by_uuid(self):

View File

@@ -151,7 +151,7 @@ class TestBIOSSettingObject(db_base.DbTestCase, obj_utils.SchemasTestMixIn):
self.context, self.node_id, settings)
mock_create_list.assert_called_once_with(mock.ANY, self.node_id,
settings, '1.1')
settings, '1.2')
self.assertEqual(self.context, bios_obj_list._context)
self.assertEqual(2, len(bios_obj_list))
self.assertEqual(self.bios_setting['node_id'],
@@ -171,7 +171,7 @@ class TestBIOSSettingObject(db_base.DbTestCase, obj_utils.SchemasTestMixIn):
self.context, self.node_id, settings)
mock_update_list.assert_called_once_with(mock.ANY, self.node_id,
settings, '1.1')
settings, '1.2')
self.assertEqual(self.context, bios_obj_list._context)
self.assertEqual(2, len(bios_obj_list))
self.assertEqual(self.bios_setting['node_id'],

View File

@@ -675,12 +675,12 @@ class TestObject(_LocalTest, _TestObject):
# version bump. It is an MD5 hash of the object fields and remotable methods.
# The fingerprint values should only be changed if there is a version bump.
expected_object_fingerprints = {
'Node': '1.41-baff7b2b06243d97448b720030b2e612',
'Node': '1.42-a1d3e6011e3cdb27aafa9353b7c0b6d4',
'MyObj': '1.5-9459d30d6954bffc7a9afd347a807ca6',
'Chassis': '1.3-d656e039fd8ae9f34efc232ab3980905',
'Port': '1.13-f79db5cc15189d3e8b257db582b2329e',
'Portgroup': '1.5-df4dc15967f67114d51176a98a901a83',
'Conductor': '1.5-c241d0c83c05c263b12c9b0289995462',
'Chassis': '1.4-fe427272d8bad232a8d46e996a5ca42a',
'Port': '1.14-684faad7173c1d9e8a2d630381c51903',
'Portgroup': '1.6-ada5300518c2262766121a4333d92df3',
'Conductor': '1.6-ed00540fae97aa1c9982f9017c6e8b68',
'EventType': '1.1-aa2ba1afd38553e3880c267404e8d370',
'NotificationPublisher': '1.0-51a09397d6c0687771fb5be9a999605d',
'NodePayload': '1.17-4022bb737b058d426a7ff878b1875e5c',
@@ -692,8 +692,8 @@ expected_object_fingerprints = {
'NodeSetProvisionStateNotification':
'1.0-59acc533c11d306f149846f922739c15',
'NodeSetProvisionStatePayload': '1.18-ac98c88d6dc8c6c924a415868f0a36e7',
'VolumeConnector': '1.0-3e0252c0ab6e6b9d158d09238a577d97',
'VolumeTarget': '1.0-0b10d663d8dae675900b2c7548f76f5e',
'VolumeConnector': '1.1-658527dd56485af9a7375d517b57d5c7',
'VolumeTarget': '1.1-ea229476f06db156e87ed547f1c539f4',
'ChassisCRUDNotification': '1.0-59acc533c11d306f149846f922739c15',
'ChassisCRUDPayload': '1.0-dce63895d8186279a7dd577cffccb202',
'NodeCRUDNotification': '1.0-59acc533c11d306f149846f922739c15',
@@ -708,25 +708,25 @@ expected_object_fingerprints = {
'VolumeConnectorCRUDPayload': '1.0-5e8dbb41e05b6149d8f7bfd4daff9339',
'VolumeTargetCRUDNotification': '1.0-59acc533c11d306f149846f922739c15',
'VolumeTargetCRUDPayload': '1.0-30dcc4735512c104a3a36a2ae1e2aeb2',
'Trait': '1.0-3f26cb70c8a10a3807d64c219453e347',
'TraitList': '1.0-33a2e1bb91ad4082f9f63429b77c1244',
'BIOSSetting': '1.1-1137db88675a4e2d7f7bcc3a0d52345a',
'BIOSSettingList': '1.0-33a2e1bb91ad4082f9f63429b77c1244',
'Allocation': '1.2-9aae5cc874a292af10ba08918ba21b13',
'Trait': '1.1-ae534208fc5ade27700db7202b5b6b82',
'TraitList': '1.1-1e938b9a94cba59f5ac35a5db0a6dc0f',
'BIOSSetting': '1.2-a0c2924d8ffef7ed872e48435a569a83',
'BIOSSettingList': '1.1-6e606655643a9a5fa116ce771cbebe59',
'Allocation': '1.3-91102bce67725a4ee924c6b2f213bcde',
'AllocationCRUDNotification': '1.0-59acc533c11d306f149846f922739c15',
'AllocationCRUDPayload': '1.1-3c8849932b80380bb96587ff62e8f087',
'DeployTemplate': '1.1-4e30c8e9098595e359bb907f095bf1a9',
'DeployTemplate': '1.2-8b218ab0b3d30208adc601322abc2c50',
'DeployTemplateCRUDNotification': '1.0-59acc533c11d306f149846f922739c15',
'DeployTemplateCRUDPayload': '1.0-200857e7e715f58a5b6d6b700ab73a3b',
'Deployment': '1.0-ff10ae028c5968f1596131d85d7f5f9d',
'NodeHistory': '1.0-9b576c6481071e7f7eac97317fa29418',
'NodeInventory': '1.0-97692fec24e20ab02022b9db54e8f539',
'FirmwareComponent': '1.0-0e0720dab959e20247bbcfd5f28958c5',
'FirmwareComponentList': '1.0-33a2e1bb91ad4082f9f63429b77c1244',
'Runbook': '1.0-7a9c65b49b5f7b45686b6a674e703629',
'Deployment': '1.1-1f326911955bbb1c24cb6ec0a453f6cc',
'NodeHistory': '1.1-0879ccda2fce5e24cc0ada4116ada6b6',
'NodeInventory': '1.1-acc176aeb9358c3866ceecdd13832b44',
'FirmwareComponent': '1.1-3fc6cfd07d01b681b69d0b654b42745a',
'FirmwareComponentList': '1.1-b1b32f4ead70f94f71913e39ea628eda',
'Runbook': '1.1-019383ff9ef3b62a0d0726cb1ae8cbbf',
'RunbookCRUDNotification': '1.0-59acc533c11d306f149846f922739c15',
'RunbookCRUDPayload': '1.0-f0c97f4ff29eb3401e53b34550a95e30',
'InspectionRule': '1.0-517185d327442696e408781343c2b83f',
'InspectionRule': '1.1-6ee14959b85a90a13f3c7b48c53522c7',
'InspectionRuleCRUDNotification': '1.0-59acc533c11d306f149846f922739c15',
'InspectionRuleCRUDPayload': '1.0-85d1cf2105308534a630299a897bf562',
}

View File

@@ -49,7 +49,7 @@ class TestTraitObject(db_base.DbTestCase, obj_utils.SchemasTestMixIn):
result = objects.TraitList.create(self.context, self.node_id, traits)
mock_set_traits.assert_called_once_with(self.node_id, traits, '1.0')
mock_set_traits.assert_called_once_with(self.node_id, traits, '1.1')
self.assertEqual(self.context, result._context)
self.assertEqual(2, len(result))
self.assertEqual(self.fake_trait['node_id'], result[0].node_id)
@@ -72,7 +72,7 @@ class TestTraitObject(db_base.DbTestCase, obj_utils.SchemasTestMixIn):
trait.create()
mock_add_trait.assert_called_once_with(self.node_id, 'fake', '1.0')
mock_add_trait.assert_called_once_with(self.node_id, 'fake', '1.1')
self.assertEqual(self.fake_trait['trait'], trait.trait)
self.assertEqual(self.fake_trait['node_id'], trait.node_id)

View File

@@ -0,0 +1,23 @@
---
features:
- |
Adds the capability for the Ironic API services to operate without
a direct connection to the Ironic database backend. Instead the
RPC Object model through the concept of remotable objects.
The ``[default]use_rpc_for_database`` setting can be utilized to
leverage this mode of operation, however it is also implied when
the ``[default]rpc_transport`` option is set to ``none`` or ``local``.
upgrade:
- |
The introduction of the capability to utilize remotable objects with
the API has resulted in object versions internally being incremented
without actual schema changes. This may result in an upgrade taking
a little longer, depending on the size of the database,
as object versions are updated during the upgrade sequence.
deprecations:
- |
Use of the API DBHook feature, i.e. the resulting ``api.request.dbapi``
pattern in API service code is deprecated and the DBHook will be removed
in a future release of Ironic. Any downstream maintainers which utilize
this pattern are encouraged to utilize an object to serve as an
intermediary stepping stone between the API and the database.