remove obsolete oslo incubator code
as part of the openstack wide community goals, oslo incubator code should be removed from all projects [1] [1] https://governance.openstack.org/goals/ocata/remove-incubated-oslo-code.html Change-Id: Ifa3564df125ed002dc1710d7a7c0e9346c34c9f1
This commit is contained in:
parent
868e4cf640
commit
fccb2fef4b
@ -1,7 +1,7 @@
|
|||||||
[run]
|
[run]
|
||||||
branch = True
|
branch = True
|
||||||
source = castellan
|
source = castellan
|
||||||
omit = castellan/tests/*,castellan/openstack/*
|
omit = castellan/tests/*
|
||||||
|
|
||||||
[report]
|
[report]
|
||||||
ignore_errors = True
|
ignore_errors = True
|
||||||
|
@ -19,7 +19,7 @@ Castellan exception subclasses
|
|||||||
|
|
||||||
import six.moves.urllib.parse as urlparse
|
import six.moves.urllib.parse as urlparse
|
||||||
|
|
||||||
from castellan.openstack.common import _i18n as u
|
from castellan.i18n import _
|
||||||
|
|
||||||
_FATAL_EXCEPTION_FORMAT_ERRORS = False
|
_FATAL_EXCEPTION_FORMAT_ERRORS = False
|
||||||
|
|
||||||
@ -36,7 +36,7 @@ class CastellanException(Exception):
|
|||||||
a 'message' property. That message will get printf'd
|
a 'message' property. That message will get printf'd
|
||||||
with the keyword arguments provided to the constructor.
|
with the keyword arguments provided to the constructor.
|
||||||
"""
|
"""
|
||||||
message = u._("An unknown exception occurred")
|
message = _("An unknown exception occurred")
|
||||||
|
|
||||||
def __init__(self, message_arg=None, *args, **kwargs):
|
def __init__(self, message_arg=None, *args, **kwargs):
|
||||||
if not message_arg:
|
if not message_arg:
|
||||||
@ -53,22 +53,22 @@ class CastellanException(Exception):
|
|||||||
|
|
||||||
|
|
||||||
class Forbidden(CastellanException):
|
class Forbidden(CastellanException):
|
||||||
message = u._("You are not authorized to complete this action.")
|
message = _("You are not authorized to complete this action.")
|
||||||
|
|
||||||
|
|
||||||
class KeyManagerError(CastellanException):
|
class KeyManagerError(CastellanException):
|
||||||
message = u._("Key manager error: %(reason)s")
|
message = _("Key manager error: %(reason)s")
|
||||||
|
|
||||||
|
|
||||||
class ManagedObjectNotFoundError(CastellanException):
|
class ManagedObjectNotFoundError(CastellanException):
|
||||||
message = u._("Key not found, uuid: %(uuid)s")
|
message = _("Key not found, uuid: %(uuid)s")
|
||||||
|
|
||||||
|
|
||||||
class AuthTypeInvalidError(CastellanException):
|
class AuthTypeInvalidError(CastellanException):
|
||||||
message = u._("Invalid auth_type was specified, auth_type: %(type)s")
|
message = _("Invalid auth_type was specified, auth_type: %(type)s")
|
||||||
|
|
||||||
|
|
||||||
class InsufficientCredentialDataError(CastellanException):
|
class InsufficientCredentialDataError(CastellanException):
|
||||||
message = u._("Insufficient credential data was provided, either "
|
message = _("Insufficient credential data was provided, either "
|
||||||
"\"token\" must be set in the passed conf, or a context "
|
"\"token\" must be set in the passed conf, or a context "
|
||||||
"with an \"auth_token\" property must be passed.")
|
"with an \"auth_token\" property must be passed.")
|
||||||
|
@ -21,7 +21,7 @@ from castellan.common.credentials import keystone_token
|
|||||||
from castellan.common.credentials import password
|
from castellan.common.credentials import password
|
||||||
from castellan.common.credentials import token
|
from castellan.common.credentials import token
|
||||||
from castellan.common import exception
|
from castellan.common import exception
|
||||||
from castellan.openstack.common import _i18n as u
|
from castellan.i18n import _LE
|
||||||
|
|
||||||
from oslo_config import cfg
|
from oslo_config import cfg
|
||||||
from oslo_log import log as logging
|
from oslo_log import log as logging
|
||||||
@ -164,7 +164,7 @@ def credential_factory(conf=None, context=None):
|
|||||||
reauthenticate=conf.key_manager.reauthenticate)
|
reauthenticate=conf.key_manager.reauthenticate)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
LOG.error(u._LE("Invalid auth_type specified."))
|
LOG.error(_LE("Invalid auth_type specified."))
|
||||||
raise exception.AuthTypeInvalidError(
|
raise exception.AuthTypeInvalidError(
|
||||||
type=conf.key_manager.auth_type)
|
type=conf.key_manager.auth_type)
|
||||||
|
|
||||||
|
37
castellan/i18n.py
Normal file
37
castellan/i18n.py
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
# Copyright 2014 IBM Corp.
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
"""oslo.i18n integration module.
|
||||||
|
|
||||||
|
See http://docs.openstack.org/developer/oslo.i18n/usage.html .
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
import oslo_i18n
|
||||||
|
|
||||||
|
|
||||||
|
_translators = oslo_i18n.TranslatorFactory(domain='castellan')
|
||||||
|
|
||||||
|
# The primary translation function using the well-known name "_"
|
||||||
|
_ = _translators.primary
|
||||||
|
|
||||||
|
# Translators for log levels.
|
||||||
|
#
|
||||||
|
# The abbreviated names are meant to reflect the usual use of a short
|
||||||
|
# name like '_'. The "L" is for "log" and the other letter comes from
|
||||||
|
# the level.
|
||||||
|
_LI = _translators.log_info
|
||||||
|
_LW = _translators.log_warning
|
||||||
|
_LE = _translators.log_error
|
||||||
|
_LC = _translators.log_critical
|
@ -38,7 +38,7 @@ from castellan.common.objects import public_key as pub_key
|
|||||||
from castellan.common.objects import symmetric_key as sym_key
|
from castellan.common.objects import symmetric_key as sym_key
|
||||||
from castellan.common.objects import x_509
|
from castellan.common.objects import x_509
|
||||||
from castellan.key_manager import key_manager
|
from castellan.key_manager import key_manager
|
||||||
from castellan.openstack.common import _i18n as u
|
from castellan.i18n import _, _LE, _LI
|
||||||
|
|
||||||
from barbicanclient import client as barbican_client
|
from barbicanclient import client as barbican_client
|
||||||
from barbicanclient import exceptions as barbican_exceptions
|
from barbicanclient import exceptions as barbican_exceptions
|
||||||
@ -100,7 +100,7 @@ class BarbicanKeyManager(key_manager.KeyManager):
|
|||||||
|
|
||||||
# Confirm context is provided, if not raise forbidden
|
# Confirm context is provided, if not raise forbidden
|
||||||
if not context:
|
if not context:
|
||||||
msg = u._("User is not authorized to use key manager.")
|
msg = _LE("User is not authorized to use key manager.")
|
||||||
LOG.error(msg)
|
LOG.error(msg)
|
||||||
raise exception.Forbidden(msg)
|
raise exception.Forbidden(msg)
|
||||||
|
|
||||||
@ -118,7 +118,7 @@ class BarbicanKeyManager(key_manager.KeyManager):
|
|||||||
self._current_context = context
|
self._current_context = context
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
LOG.error(u._LE("Error creating Barbican client: %s"), e)
|
LOG.error(_LE("Error creating Barbican client: %s"), e)
|
||||||
raise exception.KeyManagerError(reason=e)
|
raise exception.KeyManagerError(reason=e)
|
||||||
|
|
||||||
self._base_url = self._create_base_url(auth,
|
self._base_url = self._create_base_url(auth,
|
||||||
@ -166,7 +166,7 @@ class BarbicanKeyManager(key_manager.KeyManager):
|
|||||||
token=context.auth_token,
|
token=context.auth_token,
|
||||||
project_id=context.tenant)
|
project_id=context.tenant)
|
||||||
else:
|
else:
|
||||||
msg = u._("context must be of type KeystonePassword, "
|
msg = _LE("context must be of type KeystonePassword, "
|
||||||
"KeystoneToken, or RequestContext.")
|
"KeystoneToken, or RequestContext.")
|
||||||
LOG.error(msg)
|
LOG.error(msg)
|
||||||
raise exception.Forbidden(reason=msg)
|
raise exception.Forbidden(reason=msg)
|
||||||
@ -187,7 +187,7 @@ class BarbicanKeyManager(key_manager.KeyManager):
|
|||||||
discovery = auth.get_discovery(sess, url=endpoint)
|
discovery = auth.get_discovery(sess, url=endpoint)
|
||||||
raw_data = discovery.raw_version_data()
|
raw_data = discovery.raw_version_data()
|
||||||
if len(raw_data) == 0:
|
if len(raw_data) == 0:
|
||||||
msg = u._LE(
|
msg = _LE(
|
||||||
"Could not find discovery information for %s") % endpoint
|
"Could not find discovery information for %s") % endpoint
|
||||||
LOG.error(msg)
|
LOG.error(msg)
|
||||||
raise exception.KeyManagerError(reason=msg)
|
raise exception.KeyManagerError(reason=msg)
|
||||||
@ -225,7 +225,7 @@ class BarbicanKeyManager(key_manager.KeyManager):
|
|||||||
except (barbican_exceptions.HTTPAuthError,
|
except (barbican_exceptions.HTTPAuthError,
|
||||||
barbican_exceptions.HTTPClientError,
|
barbican_exceptions.HTTPClientError,
|
||||||
barbican_exceptions.HTTPServerError) as e:
|
barbican_exceptions.HTTPServerError) as e:
|
||||||
LOG.error(u._LE("Error creating key: %s"), e)
|
LOG.error(_LE("Error creating key: %s"), e)
|
||||||
raise exception.KeyManagerError(reason=e)
|
raise exception.KeyManagerError(reason=e)
|
||||||
|
|
||||||
def create_key_pair(self, context, algorithm, length,
|
def create_key_pair(self, context, algorithm, length,
|
||||||
@ -263,7 +263,7 @@ class BarbicanKeyManager(key_manager.KeyManager):
|
|||||||
except (barbican_exceptions.HTTPAuthError,
|
except (barbican_exceptions.HTTPAuthError,
|
||||||
barbican_exceptions.HTTPClientError,
|
barbican_exceptions.HTTPClientError,
|
||||||
barbican_exceptions.HTTPServerError) as e:
|
barbican_exceptions.HTTPServerError) as e:
|
||||||
LOG.error(u._LE("Error creating key pair: %s"), e)
|
LOG.error(_LE("Error creating key pair: %s"), e)
|
||||||
raise exception.KeyManagerError(reason=e)
|
raise exception.KeyManagerError(reason=e)
|
||||||
|
|
||||||
def _get_barbican_object(self, barbican_client, managed_object):
|
def _get_barbican_object(self, barbican_client, managed_object):
|
||||||
@ -342,7 +342,7 @@ class BarbicanKeyManager(key_manager.KeyManager):
|
|||||||
except (barbican_exceptions.HTTPAuthError,
|
except (barbican_exceptions.HTTPAuthError,
|
||||||
barbican_exceptions.HTTPClientError,
|
barbican_exceptions.HTTPClientError,
|
||||||
barbican_exceptions.HTTPServerError) as e:
|
barbican_exceptions.HTTPServerError) as e:
|
||||||
LOG.error(u._LE("Error storing object: %s"), e)
|
LOG.error(_LE("Error storing object: %s"), e)
|
||||||
raise exception.KeyManagerError(reason=e)
|
raise exception.KeyManagerError(reason=e)
|
||||||
|
|
||||||
def _create_secret_ref(self, object_id):
|
def _create_secret_ref(self, object_id):
|
||||||
@ -352,7 +352,7 @@ class BarbicanKeyManager(key_manager.KeyManager):
|
|||||||
:return: the URL of the requested secret
|
:return: the URL of the requested secret
|
||||||
"""
|
"""
|
||||||
if not object_id:
|
if not object_id:
|
||||||
msg = u._("Key ID is None")
|
msg = _("Key ID is None")
|
||||||
raise exception.KeyManagerError(reason=msg)
|
raise exception.KeyManagerError(reason=msg)
|
||||||
base_url = self._base_url
|
base_url = self._base_url
|
||||||
if base_url[-1] != '/':
|
if base_url[-1] != '/':
|
||||||
@ -376,8 +376,8 @@ class BarbicanKeyManager(key_manager.KeyManager):
|
|||||||
kwargs = {"status": error_status,
|
kwargs = {"status": error_status,
|
||||||
"code": order.error_status_code,
|
"code": order.error_status_code,
|
||||||
"reason": order.error_reason}
|
"reason": order.error_reason}
|
||||||
msg = u._LE("Order is in %(status)s status - status code: "
|
msg = _LE("Order is in %(status)s status - status code: "
|
||||||
"%(code)s, status reason: %(reason)s") % kwargs
|
"%(code)s, status reason: %(reason)s") % kwargs
|
||||||
LOG.error(msg)
|
LOG.error(msg)
|
||||||
raise exception.KeyManagerError(reason=msg)
|
raise exception.KeyManagerError(reason=msg)
|
||||||
if order.status != active_status:
|
if order.status != active_status:
|
||||||
@ -386,17 +386,17 @@ class BarbicanKeyManager(key_manager.KeyManager):
|
|||||||
'status': order.status,
|
'status': order.status,
|
||||||
'active': active_status,
|
'active': active_status,
|
||||||
'delay': retry_delay}
|
'delay': retry_delay}
|
||||||
msg = u._LI("Retry attempt #%(attempt)i out of %(total)i: "
|
msg = _LI("Retry attempt #%(attempt)i out of %(total)i: "
|
||||||
"Order status is '%(status)s'. Waiting for "
|
"Order status is '%(status)s'. Waiting for "
|
||||||
"'%(active)s', will retry in %(delay)s "
|
"'%(active)s', will retry in %(delay)s "
|
||||||
"seconds")
|
"seconds")
|
||||||
LOG.info(msg, kwargs)
|
LOG.info(msg, kwargs)
|
||||||
time.sleep(retry_delay)
|
time.sleep(retry_delay)
|
||||||
order = barbican_client.orders.get(order_ref)
|
order = barbican_client.orders.get(order_ref)
|
||||||
else:
|
else:
|
||||||
return order
|
return order
|
||||||
msg = u._LE("Exceeded retries: Failed to find '%(active)s' status "
|
msg = _LE("Exceeded retries: Failed to find '%(active)s' status "
|
||||||
"within %(num_retries)i retries") % {
|
"within %(num_retries)i retries") % {
|
||||||
'active': active_status,
|
'active': active_status,
|
||||||
'num_retries': number_of_retries}
|
'num_retries': number_of_retries}
|
||||||
LOG.error(msg)
|
LOG.error(msg)
|
||||||
@ -500,7 +500,7 @@ class BarbicanKeyManager(key_manager.KeyManager):
|
|||||||
barbican_exceptions.HTTPClientError,
|
barbican_exceptions.HTTPClientError,
|
||||||
barbican_exceptions.HTTPServerError) as e:
|
barbican_exceptions.HTTPServerError) as e:
|
||||||
with excutils.save_and_reraise_exception():
|
with excutils.save_and_reraise_exception():
|
||||||
LOG.error(u._LE("Error getting secret metadata: %s"), e)
|
LOG.error(_LE("Error getting secret metadata: %s"), e)
|
||||||
|
|
||||||
def _is_secret_not_found_error(self, error):
|
def _is_secret_not_found_error(self, error):
|
||||||
if (isinstance(error, barbican_exceptions.HTTPClientError) and
|
if (isinstance(error, barbican_exceptions.HTTPClientError) and
|
||||||
@ -527,7 +527,7 @@ class BarbicanKeyManager(key_manager.KeyManager):
|
|||||||
except (barbican_exceptions.HTTPAuthError,
|
except (barbican_exceptions.HTTPAuthError,
|
||||||
barbican_exceptions.HTTPClientError,
|
barbican_exceptions.HTTPClientError,
|
||||||
barbican_exceptions.HTTPServerError) as e:
|
barbican_exceptions.HTTPServerError) as e:
|
||||||
LOG.error(u._LE("Error retrieving object: %s"), e)
|
LOG.error(_LE("Error retrieving object: %s"), e)
|
||||||
if self._is_secret_not_found_error(e):
|
if self._is_secret_not_found_error(e):
|
||||||
raise exception.ManagedObjectNotFoundError(
|
raise exception.ManagedObjectNotFoundError(
|
||||||
uuid=managed_object_id)
|
uuid=managed_object_id)
|
||||||
@ -551,7 +551,7 @@ class BarbicanKeyManager(key_manager.KeyManager):
|
|||||||
except (barbican_exceptions.HTTPAuthError,
|
except (barbican_exceptions.HTTPAuthError,
|
||||||
barbican_exceptions.HTTPClientError,
|
barbican_exceptions.HTTPClientError,
|
||||||
barbican_exceptions.HTTPServerError) as e:
|
barbican_exceptions.HTTPServerError) as e:
|
||||||
LOG.error(u._LE("Error deleting object: %s"), e)
|
LOG.error(_LE("Error deleting object: %s"), e)
|
||||||
if self._is_secret_not_found_error(e):
|
if self._is_secret_not_found_error(e):
|
||||||
raise exception.ManagedObjectNotFoundError(
|
raise exception.ManagedObjectNotFoundError(
|
||||||
uuid=managed_object_id)
|
uuid=managed_object_id)
|
||||||
|
@ -1,45 +0,0 @@
|
|||||||
# 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.
|
|
||||||
|
|
||||||
"""oslo.i18n integration module.
|
|
||||||
|
|
||||||
See http://docs.openstack.org/developer/oslo.i18n/usage.html
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
try:
|
|
||||||
import oslo_i18n
|
|
||||||
|
|
||||||
# NOTE(dhellmann): This reference to o-s-l-o will be replaced by the
|
|
||||||
# application name when this module is synced into the separate
|
|
||||||
# repository. It is OK to have more than one translation function
|
|
||||||
# using the same domain, since there will still only be one message
|
|
||||||
# catalog.
|
|
||||||
_translators = oslo_i18n.TranslatorFactory(domain='castellan')
|
|
||||||
|
|
||||||
# The primary translation function using the well-known name "_"
|
|
||||||
_ = _translators.primary
|
|
||||||
|
|
||||||
# Translators for log levels.
|
|
||||||
#
|
|
||||||
# The abbreviated names are meant to reflect the usual use of a short
|
|
||||||
# name like '_'. The "L" is for "log" and the other letter comes from
|
|
||||||
# the level.
|
|
||||||
_LI = _translators.log_info
|
|
||||||
_LW = _translators.log_warning
|
|
||||||
_LE = _translators.log_error
|
|
||||||
_LC = _translators.log_critical
|
|
||||||
except ImportError:
|
|
||||||
# NOTE(dims): Support for cases where a project wants to use
|
|
||||||
# code from oslo-incubator, but is not ready to be internationalized
|
|
||||||
# (like tempest)
|
|
||||||
_ = _LI = _LW = _LE = _LC = lambda x: x
|
|
@ -1,149 +0,0 @@
|
|||||||
# Copyright 2011 OpenStack Foundation.
|
|
||||||
# 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 contextlib
|
|
||||||
import errno
|
|
||||||
import logging
|
|
||||||
import os
|
|
||||||
import stat
|
|
||||||
import tempfile
|
|
||||||
|
|
||||||
from oslo_utils import excutils
|
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
_FILE_CACHE = {}
|
|
||||||
DEFAULT_MODE = stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO
|
|
||||||
|
|
||||||
|
|
||||||
def ensure_tree(path, mode=DEFAULT_MODE):
|
|
||||||
"""Create a directory (and any ancestor directories required)
|
|
||||||
|
|
||||||
:param path: Directory to create
|
|
||||||
:param mode: Directory creation permissions
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
os.makedirs(path, mode)
|
|
||||||
except OSError as exc:
|
|
||||||
if exc.errno == errno.EEXIST:
|
|
||||||
if not os.path.isdir(path):
|
|
||||||
raise
|
|
||||||
else:
|
|
||||||
raise
|
|
||||||
|
|
||||||
|
|
||||||
def read_cached_file(filename, force_reload=False):
|
|
||||||
"""Read from a file if it has been modified.
|
|
||||||
|
|
||||||
:param force_reload: Whether to reload the file.
|
|
||||||
:returns: A tuple with a boolean specifying if the data is fresh
|
|
||||||
or not.
|
|
||||||
"""
|
|
||||||
global _FILE_CACHE
|
|
||||||
|
|
||||||
if force_reload:
|
|
||||||
delete_cached_file(filename)
|
|
||||||
|
|
||||||
reloaded = False
|
|
||||||
mtime = os.path.getmtime(filename)
|
|
||||||
cache_info = _FILE_CACHE.setdefault(filename, {})
|
|
||||||
|
|
||||||
if not cache_info or mtime > cache_info.get('mtime', 0):
|
|
||||||
LOG.debug("Reloading cached file %s" % filename)
|
|
||||||
with open(filename) as fap:
|
|
||||||
cache_info['data'] = fap.read()
|
|
||||||
cache_info['mtime'] = mtime
|
|
||||||
reloaded = True
|
|
||||||
return (reloaded, cache_info['data'])
|
|
||||||
|
|
||||||
|
|
||||||
def delete_cached_file(filename):
|
|
||||||
"""Delete cached file if present.
|
|
||||||
|
|
||||||
:param filename: filename to delete
|
|
||||||
"""
|
|
||||||
global _FILE_CACHE
|
|
||||||
|
|
||||||
if filename in _FILE_CACHE:
|
|
||||||
del _FILE_CACHE[filename]
|
|
||||||
|
|
||||||
|
|
||||||
def delete_if_exists(path, remove=os.unlink):
|
|
||||||
"""Delete a file, but ignore file not found error.
|
|
||||||
|
|
||||||
:param path: File to delete
|
|
||||||
:param remove: Optional function to remove passed path
|
|
||||||
"""
|
|
||||||
|
|
||||||
try:
|
|
||||||
remove(path)
|
|
||||||
except OSError as e:
|
|
||||||
if e.errno != errno.ENOENT:
|
|
||||||
raise
|
|
||||||
|
|
||||||
|
|
||||||
@contextlib.contextmanager
|
|
||||||
def remove_path_on_error(path, remove=delete_if_exists):
|
|
||||||
"""Protect code that wants to operate on PATH atomically.
|
|
||||||
Any exception will cause PATH to be removed.
|
|
||||||
|
|
||||||
:param path: File to work with
|
|
||||||
:param remove: Optional function to remove passed path
|
|
||||||
"""
|
|
||||||
|
|
||||||
try:
|
|
||||||
yield
|
|
||||||
except Exception:
|
|
||||||
with excutils.save_and_reraise_exception():
|
|
||||||
remove(path)
|
|
||||||
|
|
||||||
|
|
||||||
def file_open(*args, **kwargs):
|
|
||||||
"""Open file
|
|
||||||
|
|
||||||
see built-in open() documentation for more details
|
|
||||||
|
|
||||||
Note: The reason this is kept in a separate module is to easily
|
|
||||||
be able to provide a stub module that doesn't alter system
|
|
||||||
state at all (for unit tests)
|
|
||||||
"""
|
|
||||||
return open(*args, **kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
def write_to_tempfile(content, path=None, suffix='', prefix='tmp'):
|
|
||||||
"""Create temporary file or use existing file.
|
|
||||||
|
|
||||||
This util is needed for creating temporary file with
|
|
||||||
specified content, suffix and prefix. If path is not None,
|
|
||||||
it will be used for writing content. If the path doesn't
|
|
||||||
exist it'll be created.
|
|
||||||
|
|
||||||
:param content: content for temporary file.
|
|
||||||
:param path: same as parameter 'dir' for mkstemp
|
|
||||||
:param suffix: same as parameter 'suffix' for mkstemp
|
|
||||||
:param prefix: same as parameter 'prefix' for mkstemp
|
|
||||||
|
|
||||||
For example: it can be used in database tests for creating
|
|
||||||
configuration files.
|
|
||||||
"""
|
|
||||||
if path:
|
|
||||||
ensure_tree(path)
|
|
||||||
|
|
||||||
(fd, path) = tempfile.mkstemp(suffix=suffix, dir=path, prefix=prefix)
|
|
||||||
try:
|
|
||||||
os.write(fd, content)
|
|
||||||
finally:
|
|
||||||
os.close(fd)
|
|
||||||
return path
|
|
@ -1,45 +0,0 @@
|
|||||||
# Copyright 2011 OpenStack Foundation.
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
"""Local storage of variables using weak references"""
|
|
||||||
|
|
||||||
import threading
|
|
||||||
import weakref
|
|
||||||
|
|
||||||
|
|
||||||
class WeakLocal(threading.local):
|
|
||||||
def __getattribute__(self, attr):
|
|
||||||
rval = super(WeakLocal, self).__getattribute__(attr)
|
|
||||||
if rval:
|
|
||||||
# NOTE(mikal): this bit is confusing. What is stored is a weak
|
|
||||||
# reference, not the value itself. We therefore need to lookup
|
|
||||||
# the weak reference and return the inner value here.
|
|
||||||
rval = rval()
|
|
||||||
return rval
|
|
||||||
|
|
||||||
def __setattr__(self, attr, value):
|
|
||||||
value = weakref.ref(value)
|
|
||||||
return super(WeakLocal, self).__setattr__(attr, value)
|
|
||||||
|
|
||||||
|
|
||||||
# NOTE(mikal): the name "store" should be deprecated in the future
|
|
||||||
store = WeakLocal()
|
|
||||||
|
|
||||||
# A "weak" store uses weak references and allows an object to fall out of scope
|
|
||||||
# when it falls out of scope in the code that uses the thread local storage. A
|
|
||||||
# "strong" store will hold a reference to the object so that it never falls out
|
|
||||||
# of scope.
|
|
||||||
weak_store = WeakLocal()
|
|
||||||
strong_store = threading.local()
|
|
@ -1,8 +0,0 @@
|
|||||||
[DEFAULT]
|
|
||||||
|
|
||||||
# The list of modules to copy from oslo-incubator.git
|
|
||||||
module=log
|
|
||||||
module=policy
|
|
||||||
|
|
||||||
# The base module to hold the copy of openstack.common
|
|
||||||
base=castellan
|
|
@ -8,5 +8,6 @@ cryptography!=1.3.0,>=1.0 # BSD/Apache-2.0
|
|||||||
python-barbicanclient>=4.0.0 # Apache-2.0
|
python-barbicanclient>=4.0.0 # Apache-2.0
|
||||||
oslo.config>=3.14.0 # Apache-2.0
|
oslo.config>=3.14.0 # Apache-2.0
|
||||||
oslo.context>=2.9.0 # Apache-2.0
|
oslo.context>=2.9.0 # Apache-2.0
|
||||||
|
oslo.i18n>=2.1.0 # Apache-2.0
|
||||||
oslo.log>=3.11.0 # Apache-2.0
|
oslo.log>=3.11.0 # Apache-2.0
|
||||||
oslo.utils>=3.17.0 # Apache-2.0
|
oslo.utils>=3.17.0 # Apache-2.0
|
||||||
|
5
tox.ini
5
tox.ini
@ -61,4 +61,7 @@ commands =
|
|||||||
# H803 skipped on purpose per list discussion.
|
# H803 skipped on purpose per list discussion.
|
||||||
|
|
||||||
show-source = True
|
show-source = True
|
||||||
exclude=.venv,.git,.tox,dist,doc,*openstack/common*,*lib/python*,*egg,build
|
exclude=.venv,.git,.tox,dist,doc,*lib/python*,*egg,build
|
||||||
|
|
||||||
|
[hacking]
|
||||||
|
import_exceptions = castellan.i18n
|
||||||
|
Loading…
Reference in New Issue
Block a user