]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Pull newly merged Olso update for 'is' operator
authorZhiteng Huang <zhiteng.huang@intel.com>
Fri, 8 Mar 2013 08:54:03 +0000 (16:54 +0800)
committerZhiteng Huang <zhiteng.huang@intel.com>
Fri, 8 Mar 2013 05:07:14 +0000 (13:07 +0800)
A recent update to common/scheduler/filters/extra_specs_ops.py in
Oslo added new 'is' operator to allow Boolean check. The original
commit message was:

"Boolean values for capabilities don't work because extra_specs are
all converted to unicode. The scheduler will then check, for example,
if the boolean 'True' is equal to the unicode string 'True', and will
always return False. This patch allows admins to specify '<is> True'
in extra_specs, which will compare successfully to boolean True."

Notice extra_specs_ops now relies on strutils from Olso, so this
change pull strutils from Oslo as well.

Fix bug: # 1146306

Change-Id: I83adf707c30274a3862aa8034e72c3361fd19952

cinder/openstack/common/scheduler/filters/extra_specs_ops.py
cinder/openstack/common/strutils.py [new file with mode: 0644]
openstack-common.conf

index f4d4ff44bb7fbe13fef6d4b028cebb2c955c4fa5..1565ff292c8367192579d6f231df81654dba10c4 100644 (file)
 
 import operator
 
+from cinder.openstack.common import strutils
+
 # 1. The following operations are supported:
-#   =, s==, s!=, s>=, s>, s<=, s<, <in>, <or>, ==, !=, >=, <=
+#   =, s==, s!=, s>=, s>, s<=, s<, <in>, <is>, <or>, ==, !=, >=, <=
 # 2. Note that <or> is handled in a different way below.
 # 3. If the first word in the extra_specs 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,
+               '<is>': lambda x, y: (strutils.bool_from_string(x) is
+                                     strutils.bool_from_string(y)),
                '==': lambda x, y: float(x) == float(y),
                '!=': lambda x, y: float(x) != float(y),
                '>=': lambda x, y: float(x) >= float(y),
diff --git a/cinder/openstack/common/strutils.py b/cinder/openstack/common/strutils.py
new file mode 100644 (file)
index 0000000..7813b64
--- /dev/null
@@ -0,0 +1,133 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 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.
+
+"""
+System-level utilities and helper functions.
+"""
+
+import logging
+import sys
+
+LOG = logging.getLogger(__name__)
+
+
+def int_from_bool_as_string(subject):
+    """
+    Interpret a string as a boolean and return either 1 or 0.
+
+    Any string value in:
+
+        ('True', 'true', 'On', 'on', '1')
+
+    is interpreted as a boolean True.
+
+    Useful for JSON-decoded stuff and config file parsing
+    """
+    return bool_from_string(subject) and 1 or 0
+
+
+def bool_from_string(subject):
+    """
+    Interpret a string as a boolean.
+
+    Any string value in:
+
+        ('True', 'true', 'On', 'on', 'Yes', 'yes', '1')
+
+    is interpreted as a boolean True.
+
+    Useful for JSON-decoded stuff and config file parsing
+    """
+    if isinstance(subject, bool):
+        return subject
+    if isinstance(subject, basestring):
+        if subject.strip().lower() in ('true', 'on', 'yes', '1'):
+            return True
+    return False
+
+
+def safe_decode(text, incoming=None, errors='strict'):
+    """
+    Decodes incoming str using `incoming` if they're
+    not already unicode.
+
+    :param incoming: Text's current encoding
+    :param errors: Errors handling policy. See here for valid
+        values http://docs.python.org/2/library/codecs.html
+    :returns: text or a unicode `incoming` encoded
+                representation of it.
+    :raises TypeError: If text is not an isntance of basestring
+    """
+    if not isinstance(text, basestring):
+        raise TypeError("%s can't be decoded" % type(text))
+
+    if isinstance(text, unicode):
+        return text
+
+    if not incoming:
+        incoming = (sys.stdin.encoding or
+                    sys.getdefaultencoding())
+
+    try:
+        return text.decode(incoming, errors)
+    except UnicodeDecodeError:
+        # Note(flaper87) If we get here, it means that
+        # sys.stdin.encoding / sys.getdefaultencoding
+        # didn't return a suitable encoding to decode
+        # text. This happens mostly when global LANG
+        # var is not set correctly and there's no
+        # default encoding. In this case, most likely
+        # python will use ASCII or ANSI encoders as
+        # default encodings but they won't be capable
+        # of decoding non-ASCII characters.
+        #
+        # Also, UTF-8 is being used since it's an ASCII
+        # extension.
+        return text.decode('utf-8', errors)
+
+
+def safe_encode(text, incoming=None,
+                encoding='utf-8', errors='strict'):
+    """
+    Encodes incoming str/unicode using `encoding`. If
+    incoming is not specified, text is expected to
+    be encoded with current python's default encoding.
+    (`sys.getdefaultencoding`)
+
+    :param incoming: Text's current encoding
+    :param encoding: Expected encoding for text (Default UTF-8)
+    :param errors: Errors handling policy. See here for valid
+        values http://docs.python.org/2/library/codecs.html
+    :returns: text or a bytestring `encoding` encoded
+                representation of it.
+    :raises TypeError: If text is not an isntance of basestring
+    """
+    if not isinstance(text, basestring):
+        raise TypeError("%s can't be encoded" % type(text))
+
+    if not incoming:
+        incoming = (sys.stdin.encoding or
+                    sys.getdefaultencoding())
+
+    if isinstance(text, unicode):
+        return text.encode(encoding, errors)
+    elif text and encoding != incoming:
+        # Decode text before encoding it with `encoding`
+        text = safe_decode(text, incoming, errors)
+        return text.encode(encoding, errors)
+
+    return text
index a74b810225dd3bc3f28697d9e0a71d852859ca83..c4774529c277aa7f05c14376323ef92a2bac74ef 100644 (file)
@@ -1,7 +1,7 @@
 [DEFAULT]
 
 # The list of modules to copy from openstack-common
-modules=exception,excutils,gettextutils,importutils,jsonutils,local,rootwrap,rpc,timeutils,log,setup,notifier,context,network_utils,policy,uuidutils,lockutils,fileutils,gettextutils,scheduler,scheduler.filters,scheduler.weights,install_venv_common,flakes,version
+modules=exception,excutils,gettextutils,importutils,jsonutils,local,rootwrap,rpc,timeutils,log,setup,notifier,context,network_utils,policy,uuidutils,lockutils,fileutils,gettextutils,scheduler,scheduler.filters,scheduler.weights,install_venv_common,flakes,version,strutils
 
 # The base module to hold the copy of openstack.common
 base=cinder