summaryrefslogtreecommitdiffstats
path: root/nova/cells/messaging.py
diff options
context:
space:
mode:
Diffstat (limited to 'nova/cells/messaging.py')
-rw-r--r--nova/cells/messaging.py84
1 files changed, 83 insertions, 1 deletions
diff --git a/nova/cells/messaging.py b/nova/cells/messaging.py
index 6f4183f5d..cacb4b8e3 100644
--- a/nova/cells/messaging.py
+++ b/nova/cells/messaging.py
@@ -36,6 +36,7 @@ from nova.consoleauth import rpcapi as consoleauth_rpcapi
from nova import context
from nova.db import base
from nova import exception
+from nova.objects import instance as instance_obj
from nova.openstack.common import excutils
from nova.openstack.common import importutils
from nova.openstack.common import jsonutils
@@ -678,6 +679,13 @@ class _TargetedMessageMethods(_BaseMessageMethods):
instance = {'uuid': instance_uuid}
self.msg_runner.instance_destroy_at_top(message.ctxt,
instance)
+ # FIXME(comstud): This is temporary/transitional until I can
+ # work out a better way to pass full objects down.
+ EXPECTS_OBJECTS = ['start', 'stop']
+ if method in EXPECTS_OBJECTS:
+ inst_obj = instance_obj.Instance()
+ inst_obj._from_db_object(inst_obj, instance)
+ instance = inst_obj
args[0] = instance
return fn(message.ctxt, *args, **method_info['method_kwargs'])
@@ -846,7 +854,8 @@ class _BroadcastMessageMethods(_BaseMessageMethods):
except exception.NotFound:
# FIXME(comstud): Strange. Need to handle quotas here,
# if we actually want this code to remain..
- self.db.instance_create(message.ctxt, instance)
+ self.db.instance_create(message.ctxt, instance,
+ legacy=False)
if info_cache:
try:
self.db.instance_info_cache_update(
@@ -957,6 +966,60 @@ class _BroadcastMessageMethods(_BaseMessageMethods):
self.consoleauth_rpcapi.delete_tokens_for_instance(message.ctxt,
instance_uuid)
+ def bdm_update_or_create_at_top(self, message, bdm, create):
+ """Create or update a block device mapping in API cells. If
+ create is True, only try to create. If create is None, try to
+ update but fall back to create. If create is False, only attempt
+ to update. This maps to nova-conductor's behavior.
+ """
+ if not self._at_the_top():
+ return
+ items_to_remove = ['id']
+ for key in items_to_remove:
+ bdm.pop(key, None)
+ if create is None:
+ self.db.block_device_mapping_update_or_create(message.ctxt,
+ bdm,
+ legacy=False)
+ return
+ elif create is True:
+ self.db.block_device_mapping_create(message.ctxt, bdm,
+ legacy=False)
+ return
+ # Unfortunately this update call wants BDM ID... but we don't know
+ # what it is in this cell. Search for it.. try matching either
+ # device_name or volume_id.
+ dev_name = bdm['device_name']
+ vol_id = bdm['volume_id']
+ instance_bdms = self.db.block_device_mapping_get_all_by_instance(
+ message.ctxt, bdm['instance_uuid'])
+ for instance_bdm in instance_bdms:
+ if dev_name and instance_bdm['device_name'] == dev_name:
+ break
+ if vol_id and instance_bdm['volume_id'] == vol_id:
+ break
+ else:
+ LOG.warn(_("No match when trying to update BDM: %(bdm)s"),
+ dict(bdm=bdm))
+ return
+ self.db.block_device_mapping_update(message.ctxt,
+ instance_bdm['id'], bdm,
+ legacy=False)
+
+ def bdm_destroy_at_top(self, message, instance_uuid, device_name,
+ volume_id):
+ """Destroy a block device mapping in API cells by device name
+ or volume_id. device_name or volume_id can be None, but not both.
+ """
+ if not self._at_the_top():
+ return
+ if device_name:
+ self.db.block_device_mapping_destroy_by_instance_and_device(
+ message.ctxt, instance_uuid, device_name)
+ elif volume_id:
+ self.db.block_device_mapping_destroy_by_instance_and_volume(
+ message.ctxt, instance_uuid, volume_id)
+
_CELL_MESSAGE_TYPE_TO_MESSAGE_CLS = {'targeted': _TargetedMessage,
'broadcast': _BroadcastMessage,
@@ -1342,6 +1405,25 @@ class MessageRunner(object):
cell_name, need_response=True)
return message.process()
+ def bdm_update_or_create_at_top(self, ctxt, bdm, create=None):
+ """Update/Create a BDM at top level cell."""
+ message = _BroadcastMessage(self, ctxt,
+ 'bdm_update_or_create_at_top',
+ dict(bdm=bdm, create=create),
+ 'up', run_locally=False)
+ message.process()
+
+ def bdm_destroy_at_top(self, ctxt, instance_uuid, device_name=None,
+ volume_id=None):
+ """Destroy a BDM at top level cell."""
+ method_kwargs = dict(instance_uuid=instance_uuid,
+ device_name=device_name,
+ volume_id=volume_id)
+ message = _BroadcastMessage(self, ctxt, 'bdm_destroy_at_top',
+ method_kwargs,
+ 'up', run_locally=False)
+ message.process()
+
@staticmethod
def get_message_types():
return _CELL_MESSAGE_TYPE_TO_MESSAGE_CLS.keys()