diff options
Diffstat (limited to 'keystone-moon/keystone/common/kvs')
-rw-r--r-- | keystone-moon/keystone/common/kvs/__init__.py | 1 | ||||
-rw-r--r-- | keystone-moon/keystone/common/kvs/backends/inmemdb.py | 5 | ||||
-rw-r--r-- | keystone-moon/keystone/common/kvs/backends/memcached.py | 14 | ||||
-rw-r--r-- | keystone-moon/keystone/common/kvs/core.py | 66 |
4 files changed, 56 insertions, 30 deletions
diff --git a/keystone-moon/keystone/common/kvs/__init__.py b/keystone-moon/keystone/common/kvs/__init__.py index 9a406a85..354bbd8a 100644 --- a/keystone-moon/keystone/common/kvs/__init__.py +++ b/keystone-moon/keystone/common/kvs/__init__.py @@ -15,7 +15,6 @@ from dogpile.cache import region from keystone.common.kvs.core import * # noqa -from keystone.common.kvs.legacy import Base, DictKvs, INMEMDB # noqa # NOTE(morganfainberg): Provided backends are registered here in the __init__ diff --git a/keystone-moon/keystone/common/kvs/backends/inmemdb.py b/keystone-moon/keystone/common/kvs/backends/inmemdb.py index 68072ef4..379b54bf 100644 --- a/keystone-moon/keystone/common/kvs/backends/inmemdb.py +++ b/keystone-moon/keystone/common/kvs/backends/inmemdb.py @@ -12,9 +12,7 @@ # License for the specific language governing permissions and limitations # under the License. -""" -Keystone In-Memory Dogpile.cache backend implementation. -""" +"""Keystone In-Memory Dogpile.cache backend implementation.""" import copy @@ -40,6 +38,7 @@ class MemoryBackend(api.CacheBackend): 'keystone.common.kvs.Memory' ) """ + def __init__(self, arguments): self._db = {} diff --git a/keystone-moon/keystone/common/kvs/backends/memcached.py b/keystone-moon/keystone/common/kvs/backends/memcached.py index f54c1a01..a65cf877 100644 --- a/keystone-moon/keystone/common/kvs/backends/memcached.py +++ b/keystone-moon/keystone/common/kvs/backends/memcached.py @@ -12,26 +12,22 @@ # License for the specific language governing permissions and limitations # under the License. -""" -Keystone Memcached dogpile.cache backend implementation. -""" +"""Keystone Memcached dogpile.cache backend implementation.""" import random as _random import time from dogpile.cache import api from dogpile.cache.backends import memcached +from oslo_cache.backends import memcache_pool from oslo_config import cfg -from oslo_log import log from six.moves import range -from keystone.common.cache.backends import memcache_pool from keystone import exception from keystone.i18n import _ CONF = cfg.CONF -LOG = log.getLogger(__name__) NO_VALUE = api.NO_VALUE random = _random.SystemRandom() @@ -49,6 +45,7 @@ class MemcachedLock(object): http://amix.dk/blog/post/19386 """ + def __init__(self, client_fn, key, lock_timeout, max_lock_attempts): self.client_fn = client_fn self.key = "_lock" + key @@ -63,7 +60,9 @@ class MemcachedLock(object): elif not wait: return False else: - sleep_time = random.random() + sleep_time = random.random() # nosec : random is not used for + # crypto or security, it's just the time to delay between + # retries. time.sleep(sleep_time) raise exception.UnexpectedError( _('Maximum lock attempts on %s occurred.') % self.key) @@ -81,6 +80,7 @@ class MemcachedBackend(object): time `memcached`, `bmemcached`, `pylibmc` and `pooled_memcached` are valid). """ + def __init__(self, arguments): self._key_mangler = None self.raw_no_expiry_keys = set(arguments.pop('no_expiry_keys', set())) diff --git a/keystone-moon/keystone/common/kvs/core.py b/keystone-moon/keystone/common/kvs/core.py index 6ce7b318..064825f8 100644 --- a/keystone-moon/keystone/common/kvs/core.py +++ b/keystone-moon/keystone/common/kvs/core.py @@ -25,6 +25,7 @@ from dogpile.core import nameregistry from oslo_config import cfg from oslo_log import log from oslo_utils import importutils +from oslo_utils import reflection from keystone import exception from keystone.i18n import _ @@ -32,8 +33,8 @@ from keystone.i18n import _LI from keystone.i18n import _LW -__all__ = ['KeyValueStore', 'KeyValueStoreLock', 'LockTimeout', - 'get_key_value_store'] +__all__ = ('KeyValueStore', 'KeyValueStoreLock', 'LockTimeout', + 'get_key_value_store') BACKENDS_REGISTERED = False @@ -66,6 +67,23 @@ def _register_backends(): BACKENDS_REGISTERED = True +def sha1_mangle_key(key): + """Wrapper for dogpile's sha1_mangle_key. + + Taken from oslo_cache.core._sha1_mangle_key + + dogpile's sha1_mangle_key function expects an encoded string, so we + should take steps to properly handle multiple inputs before passing + the key through. + """ + try: + key = key.encode('utf-8', errors='xmlcharrefreplace') + except (UnicodeError, AttributeError): # nosec + # NOTE(stevemar): if encoding fails just continue anyway. + pass + return dogpile_util.sha1_mangle_key(key) + + class LockTimeout(exception.UnexpectedError): debug_message_format = _('Lock Timeout occurred for key, %(target)s') @@ -76,6 +94,7 @@ class KeyValueStore(object): This manager also supports the concept of locking a given key resource to allow for a guaranteed atomic transaction to the backend. """ + def __init__(self, kvs_region): self.locking = True self._lock_timeout = 0 @@ -95,7 +114,6 @@ class KeyValueStore(object): this instantiation :param region_config_args: key-word args passed to the dogpile.cache backend for configuration - :return: """ if self.is_configured: # NOTE(morganfainberg): It is a bad idea to reconfigure a backend, @@ -130,12 +148,16 @@ class KeyValueStore(object): if issubclass(pxy, proxy.ProxyBackend): proxies.append(pxy) else: + pxy_cls_name = reflection.get_class_name( + pxy, fully_qualified=False) LOG.warning(_LW('%s is not a dogpile.proxy.ProxyBackend'), - pxy.__name__) + pxy_cls_name) for proxy_cls in reversed(proxies): + proxy_cls_name = reflection.get_class_name( + proxy_cls, fully_qualified=False) LOG.info(_LI('Adding proxy \'%(proxy)s\' to KVS %(name)s.'), - {'proxy': proxy_cls.__name__, + {'proxy': proxy_cls_name, 'name': self._region.name}) self._region.wrap(proxy_cls) @@ -196,14 +218,14 @@ class KeyValueStore(object): raise exception.ValidationError( _('`key_mangler` option must be a function reference')) else: - LOG.info(_LI('Using default dogpile sha1_mangle_key as KVS ' - 'region %s key_mangler'), self._region.name) - # NOTE(morganfainberg): Sane 'default' keymangler is the - # dogpile sha1_mangle_key function. This ensures that unless - # explicitly changed, we mangle keys. This helps to limit - # unintended cases of exceeding cache-key in backends such - # as memcache. - self._region.key_mangler = dogpile_util.sha1_mangle_key + msg = _LI('Using default keystone.common.kvs.sha1_mangle_key ' + 'as KVS region %s key_mangler') + LOG.info(msg, self._region.name) + # NOTE(morganfainberg): Use 'default' keymangler to ensure + # that unless explicitly changed, we mangle keys. This helps + # to limit unintended cases of exceeding cache-key in backends + # such as memcache. + self._region.key_mangler = sha1_mangle_key self._set_keymangler_on_backend(self._region.key_mangler) else: LOG.info(_LI('KVS region %s key_mangler disabled.'), @@ -251,6 +273,7 @@ class KeyValueStore(object): class _LockWrapper(object): """weakref-capable threading.Lock wrapper.""" + def __init__(self, lock_timeout): self.lock = threading.Lock() self.lock_timeout = lock_timeout @@ -339,8 +362,9 @@ class KeyValueStore(object): @contextlib.contextmanager def _action_with_lock(self, key, lock=None): - """Wrapper context manager to validate and handle the lock and lock - timeout if passed in. + """Wrapper context manager. + + Validates and handles the lock and lock timeout if passed in. """ if not isinstance(lock, KeyValueStoreLock): # NOTE(morganfainberg): Locking only matters if a lock is passed in @@ -362,11 +386,13 @@ class KeyValueStore(object): class KeyValueStoreLock(object): - """Basic KeyValueStoreLock context manager that hooks into the - dogpile.cache backend mutex allowing for distributed locking on resources. + """Basic KeyValueStoreLock context manager. - This is only a write lock, and will not prevent reads from occurring. + Hooks into the dogpile.cache backend mutex allowing for distributed locking + on resources. This is only a write lock, and will not prevent reads from + occurring. """ + def __init__(self, mutex, key, locking_enabled=True, lock_timeout=0): self.mutex = mutex self.key = key @@ -407,7 +433,9 @@ class KeyValueStoreLock(object): def get_key_value_store(name, kvs_region=None): - """Instantiate a new :class:`.KeyValueStore` or return a previous + """Retrieve key value store. + + Instantiate a new :class:`.KeyValueStore` or return a previous instantiation that has the same name. """ global KEY_VALUE_STORE_REGISTRY |