summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--nova/scheduler/filters/compute_capabilities_filter.py47
-rw-r--r--nova/scheduler/filters/extra_specs_ops.py63
2 files changed, 65 insertions, 45 deletions
diff --git a/nova/scheduler/filters/compute_capabilities_filter.py b/nova/scheduler/filters/compute_capabilities_filter.py
index 2826af170..b4c044370 100644
--- a/nova/scheduler/filters/compute_capabilities_filter.py
+++ b/nova/scheduler/filters/compute_capabilities_filter.py
@@ -12,10 +12,10 @@
# 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 operator
from nova.openstack.common import log as logging
from nova.scheduler import filters
+from nova.scheduler.filters import extra_specs_ops
LOG = logging.getLogger(__name__)
@@ -30,53 +30,10 @@ class ComputeCapabilitiesFilter(filters.BaseHostFilter):
if 'extra_specs' not in instance_type:
return True
- # 1. The following operations are supported:
- # =, s==, s!=, s>=, s>, s<=, s<, <in>, <or>, ==, !=, >=, <=
- # 2. Note that <or> is handled in a different way below.
- # 3. If the first word in the capability is not one of the operators,
- # it is ignored.
- op_methods = {'=': lambda x, y: float(x) >= float(y),
- '<in>': lambda x, y: y in x,
- '==': lambda x, y: float(x) == float(y),
- '!=': lambda x, y: float(x) != float(y),
- '>=': lambda x, y: float(x) >= float(y),
- '<=': lambda x, y: float(x) <= float(y),
- 's==': operator.eq,
- 's!=': operator.ne,
- 's<': operator.lt,
- 's<=': operator.le,
- 's>': operator.gt,
- 's>=': operator.ge}
-
for key, req in instance_type['extra_specs'].iteritems():
cap = capabilities.get(key, None)
- words = req.split()
-
- op = method = None
- if words:
- op = words[0]
- method = op_methods.get(op)
-
- if op != '<or>' and not method:
- if cap != req:
- return False
- continue
-
- if cap is None:
+ if not extra_specs_ops.match(cap, req):
return False
-
- if op == '<or>': # Ex: <or> v1 <or> v2 <or> v3
- for idx in range(1, len(words), 2):
- if words[idx] == cap:
- break
- else:
- return False
- else: # method
- if len(words) == 1:
- return False
- if not method(cap, words[1]):
- return False
-
return True
def host_passes(self, host_state, filter_properties):
diff --git a/nova/scheduler/filters/extra_specs_ops.py b/nova/scheduler/filters/extra_specs_ops.py
new file mode 100644
index 000000000..3720a2c9e
--- /dev/null
+++ b/nova/scheduler/filters/extra_specs_ops.py
@@ -0,0 +1,63 @@
+# Copyright (c) 2011 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 operator
+
+# 1. The following operations are supported:
+# =, s==, s!=, s>=, s>, s<=, s<, <in>, <or>, ==, !=, >=, <=
+# 2. Note that <or> is handled in a different way below.
+# 3. If the first word in the capability is not one of the operators,
+# it is ignored.
+_op_methods = {'=': lambda x, y: float(x) >= float(y),
+ '<in>': lambda x, y: y in x,
+ '==': lambda x, y: float(x) == float(y),
+ '!=': lambda x, y: float(x) != float(y),
+ '>=': lambda x, y: float(x) >= float(y),
+ '<=': lambda x, y: float(x) <= float(y),
+ 's==': operator.eq,
+ 's!=': operator.ne,
+ 's<': operator.lt,
+ 's<=': operator.le,
+ 's>': operator.gt,
+ 's>=': operator.ge}
+
+
+def match(value, req):
+ words = req.split()
+
+ op = method = None
+ if words:
+ op = words.pop(0)
+ method = _op_methods.get(op)
+
+ if op != '<or>' and not method:
+ return value == req
+
+ if value is None:
+ return False
+
+ if op == '<or>': # Ex: <or> v1 <or> v2 <or> v3
+ while True:
+ if words.pop(0) == value:
+ return True
+ if not words:
+ break
+ op = words.pop(0)
+ return False
+
+ if words and method(value, words[0]):
+ return True
+
+ return False