summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--nova/api/zone_redirect.py5
-rw-r--r--nova/compute/api.py10
-rw-r--r--nova/compute/manager.py5
-rw-r--r--nova/db/api.py35
-rw-r--r--nova/exception.py4
-rw-r--r--nova/scheduler/api.py23
6 files changed, 50 insertions, 32 deletions
diff --git a/nova/api/zone_redirect.py b/nova/api/zone_redirect.py
index 0adf94046..4fe255c99 100644
--- a/nova/api/zone_redirect.py
+++ b/nova/api/zone_redirect.py
@@ -43,7 +43,7 @@ LOG = logging.getLogger('server')
class RequestForwarder(api.ChildZoneHelper):
-
+ """Worker for sending an OpenStack Request to each child zone."""
def __init__(self, resource, method, body):
self.resource = resource
self.method = method
@@ -98,10 +98,13 @@ class ZoneRedirectMiddleware(wsgi.Middleware):
scheme, netloc, path, query, frag = \
urlparse.urlsplit(req.path_qs)
query = urlparse.parse_qsl(query)
+ # Remove any cache busters from old novaclient calls ...
query = [(key, value) for key, value in query if key != 'fresh']
query = urllib.urlencode(query)
url = urlparse.urlunsplit((scheme, netloc, path, query, frag))
+ # Strip off the API version, since this is given when the
+ # child zone was added.
m = re.search('/v\d+\.\d+/(.+)', url)
resource = m.group(1)
diff --git a/nova/compute/api.py b/nova/compute/api.py
index 215257217..f4bfe720c 100644
--- a/nova/compute/api.py
+++ b/nova/compute/api.py
@@ -34,7 +34,6 @@ from nova import rpc
from nova import utils
from nova import volume
from nova.compute import instance_types
-from nova.scheduler import api as scheduler
from nova.db import base
FLAGS = flags.FLAGS
@@ -51,7 +50,7 @@ class API(base.Base):
def __init__(self, image_service=None, network_api=None,
volume_api=None, hostname_factory=generate_default_hostname,
- scheduler_api=None, **kwargs):
+ **kwargs):
if not image_service:
image_service = utils.import_object(FLAGS.image_service)
self.image_service = image_service
@@ -61,9 +60,6 @@ class API(base.Base):
if not volume_api:
volume_api = volume.API()
self.volume_api = volume_api
- if not scheduler_api:
- scheduler_api = scheduler.API()
- self.scheduler_api = scheduler_api
self.hostname_factory = hostname_factory
super(API, self).__init__(**kwargs)
@@ -347,8 +343,7 @@ class API(base.Base):
def get(self, context, instance_id):
"""Get a single instance with the given ID."""
- rv = self.scheduler_api.get_instance_or_reroute(context, instance_id)
- #rv = self.db.instance_get(context, instance_id)
+ rv = self.db.instance_get(context, instance_id)
return dict(rv.iteritems())
def get_all(self, context, project_id=None, reservation_id=None,
@@ -513,7 +508,6 @@ class API(base.Base):
def get_ajax_console(self, context, instance_id):
"""Get a url to an AJAX Console"""
- instance = self.get(context, instance_id)
output = self._call_compute_message('get_ajax_console',
context,
instance_id)
diff --git a/nova/compute/manager.py b/nova/compute/manager.py
index 499b212e2..ce60c6b43 100644
--- a/nova/compute/manager.py
+++ b/nova/compute/manager.py
@@ -48,7 +48,6 @@ from nova import scheduler_manager
from nova import rpc
from nova import utils
from nova.compute import power_state
-from nova.scheduler import api as scheduler_api
FLAGS = flags.FLAGS
flags.DEFINE_string('instances_path', '$state_path/instances',
@@ -523,9 +522,7 @@ class ComputeManager(scheduler_manager.SchedulerDependentManager):
"""Pause an instance on this server."""
context = context.elevated()
LOG.debug(_('*** instance %s: starting pause'), instance_id)
- instance_ref = scheduler_api.get_instance_or_reroute(context,
- instance_id)
- #instance_ref = self.db.instance_get(context, instance_id)
+ instance_ref = self.db.instance_get(context, instance_id)
LOG.audit(_('instance %s: pausing'), instance_id, context=context)
self.db.instance_set_state(context,
instance_id,
diff --git a/nova/db/api.py b/nova/db/api.py
index 2ecfc0211..6298e16ad 100644
--- a/nova/db/api.py
+++ b/nova/db/api.py
@@ -34,6 +34,7 @@ The underlying driver is loaded as a :class:`LazyPluggable`.
from nova import exception
from nova import flags
+from nova import log as logging
from nova import utils
@@ -52,6 +53,9 @@ IMPL = utils.LazyPluggable(FLAGS['db_backend'],
sqlalchemy='nova.db.sqlalchemy.api')
+LOG = logging.getLogger('server')
+
+
class NoMoreAddresses(exception.Error):
"""No more available addresses."""
pass
@@ -71,6 +75,34 @@ class NoMoreTargets(exception.Error):
"""No more available blades"""
pass
+
+###################
+
+
+def reroute_if_not_found(key_args_index=None):
+ """Decorator used to indicate that the method should throw
+ a RouteRedirectException if the query can't find anything.
+ """
+ def wrap(f):
+ def wrapped_f(*args, **kwargs):
+ try:
+ return f(*args, **kwargs)
+ except exception.InstanceNotFound, e:
+ context = args[0]
+ key = None
+ if key_args_index:
+ key = args[key_args_index]
+ LOG.debug(_("Instance %(key)s not found locally: '%(e)s'" %
+ locals()))
+
+ # Throw a reroute Exception for the middleware to pick up.
+ LOG.debug("Firing ZoneRouteException")
+ zones = zone_get_all(context)
+ raise exception.ZoneRouteException(zones, e)
+ return wrapped_f
+ return wrap
+
+
###################
@@ -367,7 +399,8 @@ def instance_destroy(context, instance_id):
return IMPL.instance_destroy(context, instance_id)
-def instance_get(context, instance_id):
+@reroute_if_not_found(key_args_index=1)
+def instance_get(context, instance_id, reroute=True):
"""Get an instance or raise if it does not exist."""
return IMPL.instance_get(context, instance_id)
diff --git a/nova/exception.py b/nova/exception.py
index d0baa2e29..cfed32a72 100644
--- a/nova/exception.py
+++ b/nova/exception.py
@@ -93,8 +93,10 @@ class TimeoutException(Error):
class ZoneRouteException(Error):
- def __init__(self, zones, *args, **kwargs):
+ """Thrown in API to reroute request to child zones."""
+ def __init__(self, zones, original_exception, *args, **kwargs):
self.zones = zones
+ self.original_exception = original_exception
super(ZoneRouteException, self).__init__(*args, **kwargs)
diff --git a/nova/scheduler/api.py b/nova/scheduler/api.py
index 073784f31..2da2dabfe 100644
--- a/nova/scheduler/api.py
+++ b/nova/scheduler/api.py
@@ -78,30 +78,16 @@ class API(object):
capabilities=capabilities))
return rpc.fanout_cast(context, 'scheduler', kwargs)
- @classmethod
- def get_instance_or_reroute(cls, context, instance_id):
- """Return an instance from the db or throw a ZoneRouteException
- if not found."""
- try:
- instance = db.instance_get(context, instance_id)
- return instance
- except exception.InstanceNotFound, e:
- LOG.debug(_("Instance %(instance_id)s not found locally: '%(e)s'" %
- locals()))
-
- # Throw a reroute Exception for the middleware to pick up.
- LOG.debug("Firing ZoneRouteException")
- zones = db.zone_get_all(context)
- raise exception.ZoneRouteException(zones)
-
def _wrap_method(function, self):
+ """Wrap method to supply 'self'."""
def _wrap(*args, **kwargs):
return function(self, *args, **kwargs)
return _wrap
def _process(self, zone):
+ """Worker stub for green thread pool"""
nova = client.OpenStackClient(zone.username, zone.password,
zone.api_url)
nova.authenticate()
@@ -114,10 +100,13 @@ class ChildZoneHelper(object):
plug-ins to query the children."""
def start(self, zone_list):
+ """Spawn a green thread for each child zone, calling the
+ derived classes process() method as the worker. Returns
+ a list of HTTP Responses. 1 per child."""
self.green_pool = greenpool.GreenPool()
return [ result for result in self.green_pool.imap(
_wrap_method(_process, self), zone_list)]
def process(self, client, zone):
- """Derived class must override."""
+ """Worker Method. Derived class must override."""
pass