diff --git a/ironic/api/controllers/v1/node.py b/ironic/api/controllers/v1/node.py index 53f95a883f..b90d119b52 100644 --- a/ironic/api/controllers/v1/node.py +++ b/ironic/api/controllers/v1/node.py @@ -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)): diff --git a/ironic/api/hooks.py b/ironic/api/hooks.py index 547958fe8c..62acf1da7a 100644 --- a/ironic/api/hooks.py +++ b/ironic/api/hooks.py @@ -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 diff --git a/ironic/api/wsgi.py b/ironic/api/wsgi.py index bf98de90fb..039ef3ccd6 100644 --- a/ironic/api/wsgi.py +++ b/ironic/api/wsgi.py @@ -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) diff --git a/ironic/command/api.py b/ironic/command/api.py index b017ee9e1e..c4eb7f265d 100644 --- a/ironic/command/api.py +++ b/ironic/command/api.py @@ -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) diff --git a/ironic/command/novncproxy.py b/ironic/command/novncproxy.py index 41c6cd0cd3..05a2e4a109 100644 --- a/ironic/command/novncproxy.py +++ b/ironic/command/novncproxy.py @@ -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() diff --git a/ironic/command/pxe_filter.py b/ironic/command/pxe_filter.py index ad48a9c0fb..f29c4a01d4 100644 --- a/ironic/command/pxe_filter.py +++ b/ironic/command/pxe_filter.py @@ -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') diff --git a/ironic/command/singleprocess.py b/ironic/command/singleprocess.py index 4f13c1a129..f2d37a5b25 100644 --- a/ironic/command/singleprocess.py +++ b/ironic/command/singleprocess.py @@ -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) diff --git a/ironic/common/hash_ring.py b/ironic/common/hash_ring.py index fab102b0e7..4ba6150c2c 100644 --- a/ironic/common/hash_ring.py +++ b/ironic/common/hash_ring.py @@ -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(): diff --git a/ironic/common/release_mappings.py b/ironic/common/release_mappings.py index 8c424dee41..36a0bdb621 100644 --- a/ironic/common/release_mappings.py +++ b/ironic/common/release_mappings.py @@ -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'], } }, } diff --git a/ironic/conductor/manager.py b/ironic/conductor/manager.py index 9d59391cbe..b4ca59f1da 100644 --- a/ironic/conductor/manager.py +++ b/ironic/conductor/manager.py @@ -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() diff --git a/ironic/conf/default.py b/ironic/conf/default.py index 639273fa44..2b8a54104e 100644 --- a/ironic/conf/default.py +++ b/ironic/conf/default.py @@ -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 = [ diff --git a/ironic/objects/allocation.py b/ironic/objects/allocation.py index 3ae7f9985d..3c41bfdcf4 100644 --- a/ironic/objects/allocation.py +++ b/ironic/objects/allocation.py @@ -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. diff --git a/ironic/objects/base.py b/ironic/objects/base.py index 3eeb29b736..e93b406651 100644 --- a/ironic/objects/base.py +++ b/ironic/objects/base.py @@ -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): diff --git a/ironic/objects/bios.py b/ironic/objects/bios.py index d99e06b1f5..1a1f3d16b7 100644 --- a/ironic/objects/bios.py +++ b/ironic/objects/bios.py @@ -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. diff --git a/ironic/objects/chassis.py b/ironic/objects/chassis.py index 714fb83729..dc3e52dcd4 100644 --- a/ironic/objects/chassis.py +++ b/ironic/objects/chassis.py @@ -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. diff --git a/ironic/objects/conductor.py b/ironic/objects/conductor.py index 75d8db1d9d..3312bbc13b 100644 --- a/ironic/objects/conductor.py +++ b/ironic/objects/conductor.py @@ -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() diff --git a/ironic/objects/deploy_template.py b/ironic/objects/deploy_template.py index a9c8a60fe0..f87bd46dfe 100644 --- a/ironic/objects/deploy_template.py +++ b/ironic/objects/deploy_template.py @@ -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. diff --git a/ironic/objects/deployment.py b/ironic/objects/deployment.py index 7fe7f75444..e9fa9b20a2 100644 --- a/ironic/objects/deployment.py +++ b/ironic/objects/deployment.py @@ -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. diff --git a/ironic/objects/firmware.py b/ironic/objects/firmware.py index d30bc16911..2a1eaa3701 100644 --- a/ironic/objects/firmware.py +++ b/ironic/objects/firmware.py @@ -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. diff --git a/ironic/objects/indirection.py b/ironic/objects/indirection.py index cf92cb40a9..bc0ac1deb3 100644 --- a/ironic/objects/indirection.py +++ b/ironic/objects/indirection.py @@ -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__() diff --git a/ironic/objects/inspection_rule.py b/ironic/objects/inspection_rule.py index 1773f0d5f2..1e533a92f6 100644 --- a/ironic/objects/inspection_rule.py +++ b/ironic/objects/inspection_rule.py @@ -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. diff --git a/ironic/objects/node.py b/ironic/objects/node.py index 19f0105484..7ef1443a7d 100644 --- a/ironic/objects/node.py +++ b/ironic/objects/node.py @@ -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. diff --git a/ironic/objects/node_history.py b/ironic/objects/node_history.py index abccd51843..cc93e40229 100644 --- a/ironic/objects/node_history.py +++ b/ironic/objects/node_history.py @@ -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. diff --git a/ironic/objects/node_inventory.py b/ironic/objects/node_inventory.py index eccc842dd8..8061cbb800 100644 --- a/ironic/objects/node_inventory.py +++ b/ironic/objects/node_inventory.py @@ -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. diff --git a/ironic/objects/port.py b/ironic/objects/port.py index ecda6c5b0b..db5462af96 100644 --- a/ironic/objects/port.py +++ b/ironic/objects/port.py @@ -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. diff --git a/ironic/objects/portgroup.py b/ironic/objects/portgroup.py index 0fac096a39..662e074d60 100644 --- a/ironic/objects/portgroup.py +++ b/ironic/objects/portgroup.py @@ -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. diff --git a/ironic/objects/runbook.py b/ironic/objects/runbook.py index 66a0656d9a..3168c32946 100644 --- a/ironic/objects/runbook.py +++ b/ironic/objects/runbook.py @@ -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. diff --git a/ironic/objects/trait.py b/ironic/objects/trait.py index d7e6c4b376..0575628f73 100644 --- a/ironic/objects/trait.py +++ b/ironic/objects/trait.py @@ -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] diff --git a/ironic/objects/volume_connector.py b/ironic/objects/volume_connector.py index 57070ab069..37dbff3856 100644 --- a/ironic/objects/volume_connector.py +++ b/ironic/objects/volume_connector.py @@ -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. diff --git a/ironic/objects/volume_target.py b/ironic/objects/volume_target.py index 051d9ed9e7..f833c7844a 100644 --- a/ironic/objects/volume_target.py +++ b/ironic/objects/volume_target.py @@ -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. diff --git a/ironic/tests/unit/conductor/test_base_manager.py b/ironic/tests/unit/conductor/test_base_manager.py index 05fee8ef71..a01edcf912 100644 --- a/ironic/tests/unit/conductor/test_base_manager.py +++ b/ironic/tests/unit/conductor/test_base_manager.py @@ -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') diff --git a/ironic/tests/unit/db/test_bios_settings.py b/ironic/tests/unit/db/test_bios_settings.py index 9cb077e07c..9c80d0f70c 100644 --- a/ironic/tests/unit/db/test_bios_settings.py +++ b/ironic/tests/unit/db/test_bios_settings.py @@ -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): diff --git a/ironic/tests/unit/db/test_firmware_component.py b/ironic/tests/unit/db/test_firmware_component.py index 70431ca002..54e78a7362 100644 --- a/ironic/tests/unit/db/test_firmware_component.py +++ b/ironic/tests/unit/db/test_firmware_component.py @@ -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): diff --git a/ironic/tests/unit/db/test_nodes.py b/ironic/tests/unit/db/test_nodes.py index 82d6e45167..1b341d5fa3 100644 --- a/ironic/tests/unit/db/test_nodes.py +++ b/ironic/tests/unit/db/test_nodes.py @@ -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): diff --git a/ironic/tests/unit/objects/test_bios.py b/ironic/tests/unit/objects/test_bios.py index 9f7f4e7465..e76897044a 100644 --- a/ironic/tests/unit/objects/test_bios.py +++ b/ironic/tests/unit/objects/test_bios.py @@ -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'], diff --git a/ironic/tests/unit/objects/test_objects.py b/ironic/tests/unit/objects/test_objects.py index 54ca8caf9c..3deb6ec329 100644 --- a/ironic/tests/unit/objects/test_objects.py +++ b/ironic/tests/unit/objects/test_objects.py @@ -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', } diff --git a/ironic/tests/unit/objects/test_trait.py b/ironic/tests/unit/objects/test_trait.py index ba18f6ace4..8f1c27f449 100644 --- a/ironic/tests/unit/objects/test_trait.py +++ b/ironic/tests/unit/objects/test_trait.py @@ -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) diff --git a/releasenotes/notes/remotable-api-92d7b9bc7e843cd4.yaml b/releasenotes/notes/remotable-api-92d7b9bc7e843cd4.yaml new file mode 100644 index 0000000000..1b08643e59 --- /dev/null +++ b/releasenotes/notes/remotable-api-92d7b9bc7e843cd4.yaml @@ -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.