This commit is contained in:
Sandy Walsh
2011-05-23 22:32:15 -07:00
10 changed files with 49 additions and 27 deletions

View File

@@ -99,7 +99,7 @@ class APIRouter(wsgi.Router):
mapper.resource("zone", "zones", controller=zones.Controller(),
collection={'detail': 'GET', 'info': 'GET',
'select': 'GET'}),
'select': 'POST'}),
mapper.resource("user", "users", controller=users.Controller(),
collection={'detail': 'GET'})

View File

@@ -189,6 +189,9 @@ class Controller(common.OpenstackController):
inst['instance_type'] = inst_type
inst['image_id'] = requested_image_id
# TODO(sandy): REMOVE THIS
LOG.debug(_("***** INST = %(inst)s") % locals())
builder = self._get_view_builder(req)
server = builder.build(inst, is_detail=True)
server['server']['adminPass'] = password

View File

@@ -18,6 +18,7 @@ import urlparse
from nova import crypto
from nova import db
from nova import exception
from nova import flags
from nova import log as logging
from nova.api.openstack import common
@@ -25,11 +26,6 @@ from nova.scheduler import api
FLAGS = flags.FLAGS
flags.DEFINE_string('build_plan_encryption_key',
None,
'128bit (hex) encryption key for scheduler build plans.')
LOG = logging.getLogger('nova.api.openstack.zones')
@@ -121,15 +117,9 @@ class Controller(common.OpenstackController):
"""Returns a weighted list of costs to create instances
of desired capabilities."""
ctx = req.environ['nova.context']
qs = req.environ['QUERY_STRING']
param_dict = urlparse.parse_qs(qs)
param_dict.pop("fresh", None)
# parse_qs returns a dict where the values are lists,
# since query strings can have multiple values for the
# same key. We need to convert that to single values.
for key in param_dict:
param_dict[key] = param_dict[key][0]
build_plan = api.select(ctx, specs=param_dict)
LOG.debug("INCOMING SELECT '%s'" % req.environ)
specs = json.loads(req.body)
build_plan = api.select(ctx, specs=specs)
cooked = self._scrub_build_plan(build_plan)
return {"weights": cooked}

View File

@@ -257,19 +257,21 @@ class API(base.Base):
# we'll be ripping this whole for-loop out and deferring the
# creation of the Instance record. At that point all this will
# change.
filter_driver = 'nova.scheduler.host_filter.InstanceTypeFilter'
request_spec = {
'instance_properties': base_options,
'instance_type': instance_type,
'filter_driver': filter_driver,
'blob': zone_blob
}
LOG.debug(_("**** REQUEST SPEC: %(request_spec)s") % locals())
rpc.cast(context,
FLAGS.scheduler_topic,
{"method": "run_instance",
"args": {"topic": FLAGS.compute_topic,
"instance_id": instance_id,
"request_spec": {
'instance_properties': instance,
'instance_type': instance_type,
'filter_driver':
'nova.scheduler.host_filter.'
'InstanceTypeFilter',
'blob': zone_blob
},
"request_spec": request_spec,
"availability_zone": availability_zone,
"injected_files": injected_files}})

View File

@@ -379,3 +379,5 @@ DEFINE_string('zone_name', 'nova', 'name of this zone')
DEFINE_list('zone_capabilities',
['hypervisor=xenserver;kvm', 'os=linux;windows'],
'Key/Multi-value list representng capabilities of this zone')
DEFINE_string('build_plan_encryption_key', None,
'128bit (hex) encryption key for scheduler build plans.')

View File

@@ -194,6 +194,7 @@ class AdapterConsumer(Consumer):
node_func = getattr(self.proxy, str(method))
node_args = dict((str(k), v) for k, v in args.iteritems())
# NOTE(vish): magic is fun!
logging.exception('CALLING %s on SCHEDULER with %s' % (node_func, node_args))
try:
rval = node_func(context=ctxt, **node_args)
if msg_id:

View File

@@ -18,6 +18,7 @@ Handles all requests relating to schedulers.
"""
import novaclient
import traceback #nuke
from nova import db
from nova import exception
@@ -84,7 +85,7 @@ def get_zone_capabilities(context):
def select(context, specs=None):
"""Returns a list of hosts."""
return _call_scheduler('select', context=context,
params={"specs": specs})
params={"request_spec": specs})
def update_service_capabilities(context, service_name, host, capabilities):
@@ -124,6 +125,7 @@ def call_zone_method(context, method, errors_to_ignore=None, *args, **kwargs):
nova = novaclient.OpenStack(zone.username, zone.password,
zone.api_url)
nova.authenticate()
LOG.warn(_("*** AUTHENTICATED") % locals())#asdads
except novaclient.exceptions.BadRequest, e:
url = zone.api_url
LOG.warn(_("Failed request to zone; URL=%(url)s: %(e)s")
@@ -135,10 +137,13 @@ def call_zone_method(context, method, errors_to_ignore=None, *args, **kwargs):
def _error_trap(*args, **kwargs):
try:
LOG.warn(_("*** CALLING ZONE") % locals())#asdads
return zone_method(*args, **kwargs)
except Exception as e:
if type(e) in errors_to_ignore:
return None
ex = traceback.format_exc(e)
LOG.warn(_("*** CAUGHT EXCEPTION %(ex)s") % locals())#asdads
# TODO (dabo) - want to be able to re-raise here.
# Returning a string now; raising was causing issues.
# raise e

View File

@@ -70,17 +70,24 @@ class SchedulerManager(manager.Manager):
self.zone_manager.update_service_capabilities(service_name,
host, capabilities)
def select(self, context=None, *args, **kwargs):
"""Select a list of hosts best matching the provided specs."""
return self.driver.select(context, *args, **kwargs)
def _schedule(self, method, context, topic, *args, **kwargs):
"""Tries to call schedule_* method on the driver to retrieve host.
Falls back to schedule(context, topic) if method doesn't exist.
"""
driver_method = 'schedule_%s' % method
LOG.debug(_("CALLING %(driver_method)s handled in Scheduler") % locals()) # nuke
elevated = context.elevated()
try:
host = getattr(self.driver, driver_method)(elevated, *args,
**kwargs)
except AttributeError:
except AttributeError, e:
LOG.exception(_("Driver Method %(driver_method)s missing: %(e)s")
% locals())
host = self.driver.schedule(elevated, topic, *args, **kwargs)
if not host:

View File

@@ -55,12 +55,14 @@ class ZoneAwareScheduler(driver.Scheduler):
# TODO(sandy): We'll have to look for richer specs at some point.
if 'blob' in request_spec:
blob = request_spec['blob']
if blob:
self.provision_resource(context, request_spec, instance_id,
request_spec, kwargs)
return None
# Create build plan and provision ...
LOG.debug(_("****** SCHEDULE RUN INSTANCE") % locals())
build_plan = self.select(context, request_spec)
if not build_plan:
raise driver.NoValidHost(_('No hosts were available'))
@@ -162,7 +164,8 @@ class ZoneAwareScheduler(driver.Scheduler):
"""Select returns a list of weights and zone/host information
corresponding to the best hosts to service the request. Any
child zone information has been encrypted so as not to reveal
anything about the children."""
anything about the children."""
LOG.debug(_("XXXXXXX - SELECT %(request_spec)s") % locals()) # nuke this !!!
return self._schedule(context, "compute", request_spec,
*args, **kwargs)
@@ -173,6 +176,7 @@ class ZoneAwareScheduler(driver.Scheduler):
"""The schedule() contract requires we return the one
best-suited host for this request.
"""
LOG.debug(_("XXXXXXX - DEFAULT SCHEDULE %(request_spec)s") % locals()) # nuke this !!!
raise driver.NoValidHost(_('No hosts were available'))
def _schedule(self, context, topic, request_spec, *args, **kwargs):
@@ -187,16 +191,21 @@ class ZoneAwareScheduler(driver.Scheduler):
#TODO(sandy): how to infer this from OS API params?
num_instances = 1
LOG.debug(_("XXXXXXX - 1 - _SCHEDULE"))
# Filter local hosts based on requirements ...
host_list = self.filter_hosts(num_instances, request_spec)
LOG.debug(_("XXXXXXX - 2 - _SCHEDULE"))
# then weigh the selected hosts.
# weighted = [{weight=weight, name=hostname}, ...]
weighted = self.weigh_hosts(num_instances, request_spec, host_list)
LOG.debug(_("XXXXXXX - 3 - _SCHEDULE"))
# Next, tack on the best weights from the child zones ...
child_results = self._call_zone_method(context, "select",
specs=request_spec)
LOG.debug(_("XXXXXXX - 4 - _SCHEDULE - CHILD RESULTS %(child_results)s") % locals())
for child_zone, result in child_results:
for weighting in result:
# Remember the child_zone so we can get back to
@@ -208,6 +217,7 @@ class ZoneAwareScheduler(driver.Scheduler):
"child_blob": weighting["blob"]}
weighted.append(host_dict)
LOG.debug(_("XXXXXXX - 4 - _SCHEDULE"))
weighted.sort(key=operator.itemgetter('weight'))
return weighted

View File

@@ -132,7 +132,9 @@ class Service(object):
self.service_id = service_ref['id']
def __getattr__(self, key):
logging.warn(_('SERVICE __GETATTR__ %s') % (key, ))
manager = self.__dict__.get('manager', None)
logging.warn(_('SERVICE MANAGER %s') % (manager, ))
return getattr(manager, key)
@classmethod