Made _issue_novaclient_command() behave better.
Fixed a bunch of tests.
This commit is contained in:
@@ -162,32 +162,53 @@ def child_zone_helper(zone_list, func):
|
|||||||
_wrap_method(_process, func), zone_list)]
|
_wrap_method(_process, func), zone_list)]
|
||||||
|
|
||||||
|
|
||||||
def _issue_novaclient_command(nova, zone, collection, method_name, item_id):
|
def _issue_novaclient_command(nova, zone, collection,
|
||||||
|
method_name, *args, **kwargs):
|
||||||
"""Use novaclient to issue command to a single child zone.
|
"""Use novaclient to issue command to a single child zone.
|
||||||
One of these will be run in parallel for each child zone."""
|
One of these will be run in parallel for each child zone.
|
||||||
|
"""
|
||||||
manager = getattr(nova, collection)
|
manager = getattr(nova, collection)
|
||||||
result = None
|
|
||||||
try:
|
# NOTE(comstud): This is not ideal, but we have to do this based on
|
||||||
|
# how novaclient is implemented right now.
|
||||||
|
# 'find' is special cased as novaclient requires kwargs for it to
|
||||||
|
# filter on a 'get_all'.
|
||||||
|
# Every other method first needs to do a 'get' on the first argument
|
||||||
|
# passed, which should be a UUID. If it's 'get' itself that we want,
|
||||||
|
# we just return the result. Otherwise, we next call the real method
|
||||||
|
# that's wanted... passing other arguments that may or may not exist.
|
||||||
|
if method_name in ['find', 'findall']:
|
||||||
try:
|
try:
|
||||||
result = manager.get(item_id)
|
return getattr(manager, method_name)(**kwargs)
|
||||||
except ValueError, e:
|
except novaclient.NotFound:
|
||||||
result = manager.find(name=item_id)
|
url = zone.api_url
|
||||||
|
LOG.debug(_("%(collection)s.%(method_name)s didn't find "
|
||||||
|
"anything matching '%(kwargs)s' on '%(url)s'" %
|
||||||
|
locals()))
|
||||||
|
return None
|
||||||
|
|
||||||
|
args = list(args)
|
||||||
|
# pop off the UUID to look up
|
||||||
|
item = args.pop(0)
|
||||||
|
try:
|
||||||
|
result = manager.get(item)
|
||||||
except novaclient.NotFound:
|
except novaclient.NotFound:
|
||||||
url = zone.api_url
|
url = zone.api_url
|
||||||
LOG.debug(_("%(collection)s '%(item_id)s' not found on '%(url)s'" %
|
LOG.debug(_("%(collection)s '%(item)s' not found on '%(url)s'" %
|
||||||
locals()))
|
locals()))
|
||||||
return None
|
return None
|
||||||
|
|
||||||
if method_name.lower() not in ['get', 'find']:
|
if method_name.lower() != 'get':
|
||||||
result = getattr(result, method_name)()
|
# if we're doing something other than 'get', call it passing args.
|
||||||
|
result = getattr(result, method_name)(*args, **kwargs)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def wrap_novaclient_function(f, collection, method_name, item_id):
|
def wrap_novaclient_function(f, collection, method_name, *args, **kwargs):
|
||||||
"""Appends collection, method_name and item_id to the incoming
|
"""Appends collection, method_name and arguments to the incoming
|
||||||
(nova, zone) call from child_zone_helper."""
|
(nova, zone) call from child_zone_helper."""
|
||||||
def inner(nova, zone):
|
def inner(nova, zone):
|
||||||
return f(nova, zone, collection, method_name, item_id)
|
return f(nova, zone, collection, method_name, *args, **kwargs)
|
||||||
|
|
||||||
return inner
|
return inner
|
||||||
|
|
||||||
@@ -220,7 +241,7 @@ class reroute_compute(object):
|
|||||||
the wrapped method. (This ensures that zone-local code can
|
the wrapped method. (This ensures that zone-local code can
|
||||||
continue to use integer IDs).
|
continue to use integer IDs).
|
||||||
|
|
||||||
4. If the item was not found, we delgate the call to a child zone
|
4. If the item was not found, we delegate the call to a child zone
|
||||||
using the UUID.
|
using the UUID.
|
||||||
"""
|
"""
|
||||||
def __init__(self, method_name):
|
def __init__(self, method_name):
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ class ZoneAwareScheduler(driver.Scheduler):
|
|||||||
request_spec, kwargs)
|
request_spec, kwargs)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
num_instances = request_spec['num_instances']
|
num_instances = request_spec.get('num_instances', 1)
|
||||||
LOG.debug(_("Attemping to build %d instance%s") %
|
LOG.debug(_("Attemping to build %d instance%s") %
|
||||||
(num_instances, "" if num_instances == 1 else "s"))
|
(num_instances, "" if num_instances == 1 else "s"))
|
||||||
|
|
||||||
@@ -227,7 +227,7 @@ class ZoneAwareScheduler(driver.Scheduler):
|
|||||||
raise NotImplemented(_("Zone Aware Scheduler only understands "
|
raise NotImplemented(_("Zone Aware Scheduler only understands "
|
||||||
"Compute nodes (for now)"))
|
"Compute nodes (for now)"))
|
||||||
|
|
||||||
num_instances = request_spec['num_instances']
|
num_instances = request_spec.get('num_instances', 1)
|
||||||
instance_type = request_spec['instance_type']
|
instance_type = request_spec['instance_type']
|
||||||
|
|
||||||
weighted = []
|
weighted = []
|
||||||
|
|||||||
@@ -122,15 +122,16 @@ class LeastCostSchedulerTestCase(test.TestCase):
|
|||||||
for hostname, caps in hosts]
|
for hostname, caps in hosts]
|
||||||
self.assertWeights(expected, num, request_spec, hosts)
|
self.assertWeights(expected, num, request_spec, hosts)
|
||||||
|
|
||||||
def test_fill_first_cost_fn(self):
|
def test_compute_fill_first_cost_fn(self):
|
||||||
FLAGS.least_cost_scheduler_cost_functions = [
|
FLAGS.least_cost_scheduler_cost_functions = [
|
||||||
'nova.scheduler.least_cost.fill_first_cost_fn',
|
'nova.scheduler.least_cost.compute_fill_first_cost_fn',
|
||||||
]
|
]
|
||||||
FLAGS.fill_first_cost_fn_weight = 1
|
FLAGS.compute_fill_first_cost_fn_weight = 1
|
||||||
|
|
||||||
num = 1
|
num = 1
|
||||||
request_spec = {}
|
instance_type = {'memory_mb': 1024}
|
||||||
hosts = self.sched.filter_hosts(num, request_spec)
|
request_spec = {'instance_type': instance_type}
|
||||||
|
hosts = self.sched.filter_hosts('compute', request_spec, None)
|
||||||
|
|
||||||
expected = []
|
expected = []
|
||||||
for idx, (hostname, caps) in enumerate(hosts):
|
for idx, (hostname, caps) in enumerate(hosts):
|
||||||
|
|||||||
@@ -55,29 +55,21 @@ def fake_zone_manager_service_states(num_hosts):
|
|||||||
|
|
||||||
|
|
||||||
class FakeZoneAwareScheduler(zone_aware_scheduler.ZoneAwareScheduler):
|
class FakeZoneAwareScheduler(zone_aware_scheduler.ZoneAwareScheduler):
|
||||||
def filter_hosts(self, num, specs):
|
# No need to stub anything at the moment
|
||||||
# NOTE(sirp): this is returning [(hostname, services)]
|
pass
|
||||||
return self.zone_manager.service_states.items()
|
|
||||||
|
|
||||||
def weigh_hosts(self, num, specs, hosts):
|
|
||||||
fake_weight = 99
|
|
||||||
weighted = []
|
|
||||||
for hostname, caps in hosts:
|
|
||||||
weighted.append(dict(weight=fake_weight, name=hostname))
|
|
||||||
return weighted
|
|
||||||
|
|
||||||
|
|
||||||
class FakeZoneManager(zone_manager.ZoneManager):
|
class FakeZoneManager(zone_manager.ZoneManager):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.service_states = {
|
self.service_states = {
|
||||||
'host1': {
|
'host1': {
|
||||||
'compute': {'ram': 1000},
|
'compute': {'host_memory_free': 1000*1024*1024},
|
||||||
},
|
},
|
||||||
'host2': {
|
'host2': {
|
||||||
'compute': {'ram': 2000},
|
'compute': {'host_memory_free': 2000*1024*1024},
|
||||||
},
|
},
|
||||||
'host3': {
|
'host3': {
|
||||||
'compute': {'ram': 3000},
|
'compute': {'host_memory_free': 3000*1024*1024},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,13 +156,17 @@ class ZoneAwareSchedulerTestCase(test.TestCase):
|
|||||||
sched.set_zone_manager(zm)
|
sched.set_zone_manager(zm)
|
||||||
|
|
||||||
fake_context = {}
|
fake_context = {}
|
||||||
build_plan = sched.select(fake_context, {})
|
build_plan = sched.select(fake_context,
|
||||||
|
{'instance_type': {'memory_mb': 512},
|
||||||
|
'num_instances': 4 })
|
||||||
|
|
||||||
self.assertEqual(15, len(build_plan))
|
# 4 from local zones, 12 from remotes
|
||||||
|
self.assertEqual(16, len(build_plan))
|
||||||
|
|
||||||
hostnames = [plan_item['name']
|
hostnames = [plan_item['hostname']
|
||||||
for plan_item in build_plan if 'name' in plan_item]
|
for plan_item in build_plan if 'hostname' in plan_item]
|
||||||
self.assertEqual(3, len(hostnames))
|
# 4 local hosts
|
||||||
|
self.assertEqual(4, len(hostnames))
|
||||||
|
|
||||||
def test_empty_zone_aware_scheduler(self):
|
def test_empty_zone_aware_scheduler(self):
|
||||||
"""
|
"""
|
||||||
@@ -185,8 +181,7 @@ class ZoneAwareSchedulerTestCase(test.TestCase):
|
|||||||
fake_context = {}
|
fake_context = {}
|
||||||
self.assertRaises(driver.NoValidHost, sched.schedule_run_instance,
|
self.assertRaises(driver.NoValidHost, sched.schedule_run_instance,
|
||||||
fake_context, 1,
|
fake_context, 1,
|
||||||
dict(host_filter=None,
|
dict(host_filter=None, instance_type={}))
|
||||||
request_spec={'instance_type': {}}))
|
|
||||||
|
|
||||||
def test_schedule_do_not_schedule_with_hint(self):
|
def test_schedule_do_not_schedule_with_hint(self):
|
||||||
"""
|
"""
|
||||||
|
|||||||
Reference in New Issue
Block a user