summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVishvananda Ishaya <vishvananda@gmail.com>2012-01-20 23:15:33 -0800
committerVishvananda Ishaya <vishvananda@gmail.com>2012-01-21 00:20:45 -0800
commit972fc7d80fae386cf4c72b7891f6601d6f7fb00b (patch)
treedc8442483e575e66358cf57bae0f4a88bab20d4b
parentdad0953ff5675831d84f9c28c7d5a93e42204233 (diff)
Adds isolated hosts filter
* Also removes a couple of duplicate tests Part of a series of commits that are moving all of the filtering done in simple scheduler into hosts filters so we can default to the distributed scheduler. Change-Id: I63b05d0c6476ff0ab9cc17e3e6c39f81bec37d77
-rw-r--r--nova/flags.py2
-rw-r--r--nova/scheduler/filters/__init__.py1
-rw-r--r--nova/scheduler/filters/isolated_hosts_filter.py33
-rw-r--r--nova/scheduler/simple.py2
-rw-r--r--nova/tests/scheduler/test_host_filters.py68
5 files changed, 80 insertions, 26 deletions
diff --git a/nova/flags.py b/nova/flags.py
index b9aad32b5..4345b4777 100644
--- a/nova/flags.py
+++ b/nova/flags.py
@@ -469,3 +469,5 @@ 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')
+DEFINE_list('isolated_images', [], 'Images to run on isolated host')
+DEFINE_list('isolated_hosts', [], 'Host reserved for specific images')
diff --git a/nova/scheduler/filters/__init__.py b/nova/scheduler/filters/__init__.py
index f9bf6641b..8dcf9e4ef 100644
--- a/nova/scheduler/filters/__init__.py
+++ b/nova/scheduler/filters/__init__.py
@@ -32,5 +32,6 @@ InstanceType filter.
from abstract_filter import AbstractHostFilter
from all_hosts_filter import AllHostsFilter
+from isolated_hosts_filter import IsolatedHostsFilter
from compute_filter import ComputeFilter
from json_filter import JsonFilter
diff --git a/nova/scheduler/filters/isolated_hosts_filter.py b/nova/scheduler/filters/isolated_hosts_filter.py
new file mode 100644
index 000000000..82478ab7a
--- /dev/null
+++ b/nova/scheduler/filters/isolated_hosts_filter.py
@@ -0,0 +1,33 @@
+# Copyright (c) 2011-2012 Openstack, LLC.
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+
+import abstract_filter
+from nova import flags
+
+
+FLAGS = flags.FLAGS
+
+
+class IsolatedHostsFilter(abstract_filter.AbstractHostFilter):
+ """Returns host."""
+
+ def host_passes(self, host_state, filter_properties):
+ spec = filter_properties.get('request_spec', {})
+ props = spec.get('instance_properties', {})
+ image_ref = props.get('image_ref')
+ image_isolated = image_ref in FLAGS.isolated_images
+ host_isolated = host_state.host in FLAGS.isolated_hosts
+ return image_isolated == host_isolated
diff --git a/nova/scheduler/simple.py b/nova/scheduler/simple.py
index 64ebfb757..11270a13d 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_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,
'Allow overcommitting vcpus on isolated hosts')
diff --git a/nova/tests/scheduler/test_host_filters.py b/nova/tests/scheduler/test_host_filters.py
index 8462422ad..d60f90689 100644
--- a/nova/tests/scheduler/test_host_filters.py
+++ b/nova/tests/scheduler/test_host_filters.py
@@ -135,6 +135,50 @@ class HostFiltersTestCase(test.TestCase):
self.assertFalse(filt_cls.host_passes(host, filter_properties))
+ def test_isolated_hosts_fails_isolated_on_non_isolated(self):
+ self.flags(isolated_images=['isolated'], isolated_hosts=['isolated'])
+ filt_cls = filters.IsolatedHostsFilter()
+ filter_properties = {
+ 'request_spec': {
+ 'instance_properties': {'image_ref': 'isolated'}
+ }
+ }
+ host = fakes.FakeHostState('non-isolated', 'compute', {})
+ self.assertFalse(filt_cls.host_passes(host, filter_properties))
+
+ def test_isolated_hosts_fails_non_isolated_on_isolated(self):
+ self.flags(isolated_images=['isolated'], isolated_hosts=['isolated'])
+ filt_cls = filters.IsolatedHostsFilter()
+ filter_properties = {
+ 'request_spec': {
+ 'instance_properties': {'image_ref': 'non-isolated'}
+ }
+ }
+ host = fakes.FakeHostState('isolated', 'compute', {})
+ self.assertFalse(filt_cls.host_passes(host, filter_properties))
+
+ def test_isolated_hosts_passes_isolated_on_isolated(self):
+ self.flags(isolated_images=['isolated'], isolated_hosts=['isolated'])
+ filt_cls = filters.IsolatedHostsFilter()
+ filter_properties = {
+ 'request_spec': {
+ 'instance_properties': {'image_ref': 'isolated'}
+ }
+ }
+ host = fakes.FakeHostState('isolated', 'compute', {})
+ self.assertTrue(filt_cls.host_passes(host, filter_properties))
+
+ def test_isolated_hosts_passes_non_isolated_on_non_isolated(self):
+ self.flags(isolated_images=['isolated'], isolated_hosts=['isolated'])
+ filt_cls = filters.IsolatedHostsFilter()
+ filter_properties = {
+ 'request_spec': {
+ 'instance_properties': {'image_ref': 'non-isolated'}
+ }
+ }
+ host = fakes.FakeHostState('non-isolated', 'compute', {})
+ self.assertTrue(filt_cls.host_passes(host, filter_properties))
+
def test_json_filter_passes(self):
filt_cls = filters.JsonFilter()
filter_properties = {'instance_type': {'memory_mb': 1024,
@@ -182,18 +226,6 @@ class HostFiltersTestCase(test.TestCase):
'capabilities': capabilities})
self.assertFalse(filt_cls.host_passes(host, filter_properties))
- def test_json_filter_fails_on_disk(self):
- filt_cls = filters.JsonFilter()
- filter_properties = {'instance_type': {'memory_mb': 1024,
- 'local_gb': 200},
- 'query': self.json_query}
- capabilities = {'enabled': True}
- host = fakes.FakeHostState('host1', 'compute',
- {'free_ram_mb': 1024,
- 'free_disk_mb': (200 * 1024) - 1,
- 'capabilities': capabilities})
- self.assertFalse(filt_cls.host_passes(host, filter_properties))
-
def test_json_filter_fails_on_caps_disabled(self):
filt_cls = filters.JsonFilter()
json_query = json.dumps(
@@ -227,18 +259,6 @@ class HostFiltersTestCase(test.TestCase):
'capabilities': capabilities})
self.assertFalse(filt_cls.host_passes(host, filter_properties))
- def test_json_filter_passes(self):
- filt_cls = filters.JsonFilter()
- filter_properties = {'instance_type': {'memory_mb': 1024,
- 'local_gb': 200},
- 'query': self.json_query}
- capabilities = {'enabled': True}
- host = fakes.FakeHostState('host1', 'compute',
- {'free_ram_mb': 1024,
- 'free_disk_mb': 200 * 1024,
- 'capabilities': capabilities})
- self.assertTrue(filt_cls.host_passes(host, filter_properties))
-
def test_json_filter_happy_day(self):
"""Test json filter more thoroughly"""
filt_cls = filters.JsonFilter()