First attempt to rewrite reroute_compute

This commit is contained in:
Rick Harris
2011-06-15 21:50:36 +00:00
parent 266b876efa
commit 0267e05f1f

View File

@@ -24,6 +24,7 @@ from nova import exception
from nova import flags from nova import flags
from nova import log as logging from nova import log as logging
from nova import rpc from nova import rpc
from nova import utils
from eventlet import greenpool from eventlet import greenpool
@@ -224,32 +225,57 @@ class reroute_compute(object):
def __init__(self, method_name): def __init__(self, method_name):
self.method_name = method_name self.method_name = method_name
def __call__(self, f):
def wrapped_f(*args, **kwargs):
collection, context, item_id = \
self.get_collection_context_and_id(args, kwargs)
try:
# Call the original function ...
return f(*args, **kwargs)
except exception.InstanceNotFound, e:
LOG.debug(_("Instance %(item_id)s not found "
"locally: '%(e)s'" % locals()))
def _route_local():
pass
def _route_to_child_zones(context, collection, item_uuid):
if not FLAGS.enable_zone_routing: if not FLAGS.enable_zone_routing:
raise raise InstanceNotFound(instance_id=item_uuid)
zones = db.zone_get_all(context) zones = db.zone_get_all(context)
if not zones: if not zones:
raise raise InstanceNotFound(instance_id=item_uuid)
# Ask the children to provide an answer ... # Ask the children to provide an answer ...
LOG.debug(_("Asking child zones ...")) LOG.debug(_("Asking child zones ..."))
result = self._call_child_zones(zones, result = self._call_child_zones(zones,
wrap_novaclient_function(_issue_novaclient_command, wrap_novaclient_function(_issue_novaclient_command,
collection, self.method_name, item_id)) collection, self.method_name, item_uuid))
# Scrub the results and raise another exception # Scrub the results and raise another exception
# so the API layers can bail out gracefully ... # so the API layers can bail out gracefully ...
raise RedirectResult(self.unmarshall_result(result)) raise RedirectResult(self.unmarshall_result(result))
def __call__(self, f):
def wrapped_f(*args, **kwargs):
collection, context, item_id_or_uuid = \
self.get_collection_context_and_id(args, kwargs)
attempt_reroute = False
if utils.is_uuid_like(item_id_or_uuid):
item_uuid = item_id_or_uuid
try:
instance = self.db.instance_get_by_uuid(
context, item_uuid)
except exception.InstanceNotFound, e:
# NOTE(sirp): since a UUID was passed in, we can attempt
# to reroute to a child zone
attempt_reroute = True
LOG.debug(_("Instance %(item_uuid)s not found "
"locally: '%(e)s'" % locals()))
else:
# NOTE(sirp): since we're not re-routing in this case, and we
# we were passed a UUID, we need to replace that UUID with an
# integer ID in the argument list so that the zone-local code
# can continue to use integer IDs.
item_id = instance['id']
self.replace_uuid_with_id(args, kwargs, replacement_id)
if attempt_reroute:
self._route_to_child_zones(context, collection, item_uuid)
else:
return f(*args, **kwargs)
return wrapped_f return wrapped_f
def _call_child_zones(self, zones, function): def _call_child_zones(self, zones, function):
@@ -268,6 +294,18 @@ class reroute_compute(object):
instance_id = args[2] instance_id = args[2]
return ("servers", context, instance_id) return ("servers", context, instance_id)
@staticmethod
def replace_uuid_with_id(args, kwargs, replacement_id):
"""
Extracts the UUID parameter from the arg or kwarg list and replaces
it with an integer ID.
"""
if 'instance_id' in kwargs:
kwargs['instance_id'] = replacement_id
elif len(args) > 1:
args.pop(2)
args.insert(2, replacement_id)
def unmarshall_result(self, zone_responses): def unmarshall_result(self, zone_responses):
"""Result is a list of responses from each child zone. """Result is a list of responses from each child zone.
Each decorator derivation is responsible to turning this Each decorator derivation is responsible to turning this