summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVishvananda Ishaya <vishvananda@gmail.com>2012-01-20 15:28:39 -0800
committerVishvananda Ishaya <vishvananda@gmail.com>2012-01-20 17:34:09 -0800
commit16ea348a1623f055809d0d9b7fe9f046515b5dd1 (patch)
tree76111cfafd680c467aae2a4cd074fdcd66d61254
parent1bf066c59bbfe40a30e498f2b24fdddd82fb2508 (diff)
Add option to force hosts to scheduler
Change-Id: I7364115e247ebeb441fa838ac66db5ef5f608b55
-rw-r--r--nova/compute/api.py22
-rw-r--r--nova/flags.py2
-rw-r--r--nova/scheduler/host_manager.py3
-rw-r--r--nova/scheduler/simple.py2
-rw-r--r--nova/tests/scheduler/test_host_manager.py20
5 files changed, 41 insertions, 8 deletions
diff --git a/nova/compute/api.py b/nova/compute/api.py
index 9cc9744b8..138d70b66 100644
--- a/nova/compute/api.py
+++ b/nova/compute/api.py
@@ -284,6 +284,20 @@ class API(base.Base):
root_device_name = block_device.properties_root_device_name(
image['properties'])
+ # NOTE(vish): We have a legacy hack to allow admins to specify hosts
+ # via az using az:host. It might be nice to expose an
+ # api to specify specific hosts to force onto, but for
+ # now it just supports this legacy hack.
+ host = None
+ if availability_zone:
+ availability_zone, _x, host = availability_zone.partition(':')
+ if not availability_zone:
+ availability_zone = FLAGS.default_schedule_zone
+ if context.is_admin and host:
+ filter_properties = {'force_hosts': [host]}
+ else:
+ filter_properties = {}
+
base_options = {
'reservation_id': reservation_id,
'image_ref': image_href,
@@ -343,7 +357,8 @@ class API(base.Base):
availability_zone, injected_files,
admin_password, image,
num_instances, requested_networks,
- block_device_mapping, security_group)
+ block_device_mapping, security_group,
+ filter_properties)
if create_instance_here:
return ([instance], reservation_id)
@@ -516,7 +531,8 @@ class API(base.Base):
num_instances,
requested_networks,
block_device_mapping,
- security_group):
+ security_group,
+ filter_properties):
"""Send a run_instance request to the schedulers for processing."""
pid = context.project_id
@@ -525,8 +541,6 @@ class API(base.Base):
LOG.debug(_("Sending create to scheduler for %(pid)s/%(uid)s's") %
locals())
- filter_properties = {}
-
request_spec = {
'image': image,
'instance_properties': base_options,
diff --git a/nova/flags.py b/nova/flags.py
index f89e53796..b9aad32b5 100644
--- a/nova/flags.py
+++ b/nova/flags.py
@@ -467,3 +467,5 @@ DEFINE_boolean('allow_ec2_admin_api', False, 'Enable/Disable EC2 Admin API')
DEFINE_integer('service_down_time', 60,
'maximum time since last check-in for up service')
+DEFINE_string('default_schedule_zone', None,
+ 'zone to use when user doesnt specify one')
diff --git a/nova/scheduler/host_manager.py b/nova/scheduler/host_manager.py
index 6996155ff..1e838259b 100644
--- a/nova/scheduler/host_manager.py
+++ b/nova/scheduler/host_manager.py
@@ -117,6 +117,9 @@ class HostState(object):
if self.host in filter_properties.get('ignore_hosts', []):
return False
+ force_hosts = filter_properties.get('force_hosts', [])
+ if force_hosts:
+ return self.host in force_hosts
for filter_fn in filter_fns:
if not filter_fn(self, filter_properties):
return False
diff --git a/nova/scheduler/simple.py b/nova/scheduler/simple.py
index 52f6be3b1..64ebfb757 100644
--- a/nova/scheduler/simple.py
+++ b/nova/scheduler/simple.py
@@ -35,8 +35,6 @@ flags.DEFINE_integer("max_gigabytes", 10000,
"maximum number of volume gigabytes to allow per host")
flags.DEFINE_integer("max_networks", 1000,
"maximum number of networks to allow per host")
-flags.DEFINE_string('default_schedule_zone', None,
- 'zone to use when user doesnt specify one')
flags.DEFINE_list('isolated_images', [], 'Images to run on isolated host')
flags.DEFINE_list('isolated_hosts', [], 'Host reserved for specific images')
flags.DEFINE_boolean('skip_isolated_core_check', True,
diff --git a/nova/tests/scheduler/test_host_manager.py b/nova/tests/scheduler/test_host_manager.py
index 5b23d0986..9ea00397f 100644
--- a/nova/tests/scheduler/test_host_manager.py
+++ b/nova/tests/scheduler/test_host_manager.py
@@ -18,8 +18,6 @@ Tests For HostManager
import datetime
-import mox
-
from nova import db
from nova import exception
from nova import log as logging
@@ -364,3 +362,21 @@ class HostStateTestCase(test.TestCase):
result = fake_host.passes_filters(filter_fns, filter_properties)
self.mox.VerifyAll()
self.assertFalse(result)
+
+ def test_host_state_passes_filters_skipped_from_force(self):
+ fake_host = host_manager.HostState('host1', 'compute')
+ filter_properties = {'force_hosts': ['host1']}
+
+ cls1 = ComputeFilterClass1()
+ cls2 = ComputeFilterClass2()
+ self.mox.StubOutWithMock(cls1, 'host_passes')
+ self.mox.StubOutWithMock(cls2, 'host_passes')
+ filter_fns = [cls1.host_passes, cls2.host_passes]
+
+ # cls[12].host_passes() not called because of short circuit
+ # with matching host to force
+
+ self.mox.ReplayAll()
+ result = fake_host.passes_filters(filter_fns, filter_properties)
+ self.mox.VerifyAll()
+ self.assertTrue(result)