diff options
-rw-r--r-- | nova/scheduler/filters/compute_capabilities_filter.py | 47 | ||||
-rw-r--r-- | nova/scheduler/filters/extra_specs_ops.py | 63 |
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 |