Merge "Switch to latest oslo-incubator"

This commit is contained in:
Jenkins 2015-03-10 05:44:40 +00:00 committed by Gerrit Code Review
commit 8a2be34e7e
5 changed files with 93 additions and 70 deletions

View File

@ -16,25 +16,30 @@ See http://docs.openstack.org/developer/oslo.i18n/usage.html
""" """
import oslo.i18n 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='glance')
# NOTE(dhellmann): This reference to o-s-l-o will be replaced by the # The primary translation function using the well-known name "_"
# application name when this module is synced into the separate _ = _translators.primary
# 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='glance')
# The primary translation function using the well-known name "_" # Translators for log levels.
_ = _translators.primary #
# The abbreviated names are meant to reflect the usual use of a short
# Translators for log levels. # name like '_'. The "L" is for "log" and the other letter comes from
# # the level.
# The abbreviated names are meant to reflect the usual use of a short _LI = _translators.log_info
# name like '_'. The "L" is for "log" and the other letter comes from _LW = _translators.log_warning
# the level. _LE = _translators.log_error
_LI = _translators.log_info _LC = _translators.log_critical
_LW = _translators.log_warning except ImportError:
_LE = _translators.log_error # NOTE(dims): Support for cases where a project wants to use
_LC = _translators.log_critical # code from oslo-incubator, but is not ready to be internationalized
# (like tempest)
_ = _LI = _LW = _LE = _LC = lambda x: x

View File

@ -28,7 +28,7 @@ import traceback
import eventlet.backdoor import eventlet.backdoor
import greenlet import greenlet
from oslo.config import cfg from oslo_config import cfg
from glance.openstack.common._i18n import _LI from glance.openstack.common._i18n import _LI
@ -50,7 +50,7 @@ LOG = logging.getLogger(__name__)
def list_opts(): def list_opts():
"""Entry point for oslo.config-generator. """Entry point for oslo-config-generator.
""" """
return [(None, copy.deepcopy(eventlet_backdoor_opts))] return [(None, copy.deepcopy(eventlet_backdoor_opts))]

View File

@ -15,25 +15,27 @@
import contextlib import contextlib
import errno import errno
import logging
import os import os
import stat
import tempfile import tempfile
from oslo_utils import excutils from oslo_utils import excutils
from glance.openstack.common import log as logging
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
_FILE_CACHE = {} _FILE_CACHE = {}
DEFAULT_MODE = stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO
def ensure_tree(path): def ensure_tree(path, mode=DEFAULT_MODE):
"""Create a directory (and any ancestor directories required) """Create a directory (and any ancestor directories required)
:param path: Directory to create :param path: Directory to create
:param mode: Directory creation permissions
""" """
try: try:
os.makedirs(path) os.makedirs(path, mode)
except OSError as exc: except OSError as exc:
if exc.errno == errno.EEXIST: if exc.errno == errno.EEXIST:
if not os.path.isdir(path): if not os.path.isdir(path):

View File

@ -1,3 +1,5 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2012 OpenStack Foundation. # Copyright (c) 2012 OpenStack Foundation.
# All Rights Reserved. # All Rights Reserved.
# #
@ -22,22 +24,43 @@ string written in the new policy language.
In the list-of-lists representation, each check inside the innermost In the list-of-lists representation, each check inside the innermost
list is combined as with an "and" conjunction--for that check to pass, list is combined as with an "and" conjunction--for that check to pass,
all the specified checks must pass. These innermost lists are then all the specified checks must pass. These innermost lists are then
combined as with an "or" conjunction. This is the original way of combined as with an "or" conjunction. As an example, take the following
expressing policies, but there now exists a new way: the policy rule, expressed in the list-of-lists representation::
language.
In the policy language, each check is specified the same way as in the
list-of-lists representation: a simple "a:b" pair that is matched to
the correct code to perform that check. However, conjunction
operators are available, allowing for more expressiveness in crafting
policies.
As an example, take the following rule, expressed in the list-of-lists
representation::
[["role:admin"], ["project_id:%(project_id)s", "role:projectadmin"]] [["role:admin"], ["project_id:%(project_id)s", "role:projectadmin"]]
In the policy language, this becomes:: This is the original way of expressing policies, but there now exists a
new way: the policy language.
In the policy language, each check is specified the same way as in the
list-of-lists representation: a simple "a:b" pair that is matched to
the correct class to perform that check::
+===========================================================================+
| TYPE | SYNTAX |
+===========================================================================+
|User's Role | role:admin |
+---------------------------------------------------------------------------+
|Rules already defined on policy | rule:admin_required |
+---------------------------------------------------------------------------+
|Against URL's¹ | http://my-url.org/check |
+---------------------------------------------------------------------------+
|User attributes² | project_id:%(target.project.id)s |
+---------------------------------------------------------------------------+
|Strings | <variable>:'xpto2035abc' |
| | 'myproject':<variable> |
+---------------------------------------------------------------------------+
| | project_id:xpto2035abc |
|Literals | domain_id:20 |
| | True:%(user.enabled)s |
+===========================================================================+
¹URL checking must return 'True' to be valid
²User attributes (obtained through the token): user_id, domain_id or project_id
Conjunction operators are available, allowing for more expressiveness
in crafting policies. So, in the policy language, the previous check in
list-of-lists becomes::
role:admin or (project_id:%(project_id)s and role:projectadmin) role:admin or (project_id:%(project_id)s and role:projectadmin)
@ -46,26 +69,16 @@ policy rule::
project_id:%(project_id)s and not role:dunce project_id:%(project_id)s and not role:dunce
It is possible to perform policy checks on the following user
attributes (obtained through the token): user_id, domain_id or
project_id::
domain_id:<some_value>
Attributes sent along with API calls can be used by the policy engine Attributes sent along with API calls can be used by the policy engine
(on the right side of the expression), by using the following syntax:: (on the right side of the expression), by using the following syntax::
<some_value>:user.id <some_value>:%(user.id)s
Contextual attributes of objects identified by their IDs are loaded Contextual attributes of objects identified by their IDs are loaded
from the database. They are also available to the policy engine and from the database. They are also available to the policy engine and
can be checked through the `target` keyword:: can be checked through the `target` keyword::
<some_value>:target.role.name <some_value>:%(target.role.name)s
All these attributes (related to users, API calls, and context) can be
checked against each other or against constants, be it literals (True,
<a_number>) or strings.
Finally, two special policy checks should be mentioned; the policy Finally, two special policy checks should be mentioned; the policy
check "@" will always accept an access, and the policy check "!" will check "@" will always accept an access, and the policy check "!" will
@ -78,18 +91,18 @@ as it allows particular rules to be explicitly disabled.
import abc import abc
import ast import ast
import copy import copy
import logging
import os import os
import re import re
from oslo_config import cfg from oslo_config import cfg
from oslo.serialization import jsonutils from oslo_serialization import jsonutils
import six import six
import six.moves.urllib.parse as urlparse import six.moves.urllib.parse as urlparse
import six.moves.urllib.request as urlrequest import six.moves.urllib.request as urlrequest
from glance.openstack.common import fileutils from glance.openstack.common import fileutils
from glance.openstack.common._i18n import _, _LE, _LW from glance.openstack.common._i18n import _, _LE
from glance.openstack.common import log as logging
policy_opts = [ policy_opts = [
@ -107,7 +120,8 @@ policy_opts = [
'in the search path defined by the config_dir ' 'in the search path defined by the config_dir '
'option, or absolute paths. The file defined by ' 'option, or absolute paths. The file defined by '
'policy_file must exist for these directories to ' 'policy_file must exist for these directories to '
'be searched.')), 'be searched. Missing or empty directories are '
'ignored.')),
] ]
CONF = cfg.CONF CONF = cfg.CONF
@ -259,7 +273,6 @@ class Enforcer(object):
try: try:
path = self._get_policy_path(path) path = self._get_policy_path(path)
except cfg.ConfigFilesNotFoundError: except cfg.ConfigFilesNotFoundError:
LOG.warn(_LW("Can not find policy directory: %s"), path)
continue continue
self._walk_through_policy_directory(path, self._walk_through_policy_directory(path,
self._load_policy_file, self._load_policy_file,
@ -279,7 +292,8 @@ class Enforcer(object):
if reloaded or not self.rules or not overwrite: if reloaded or not self.rules or not overwrite:
rules = Rules.load_json(data, self.default_rule) rules = Rules.load_json(data, self.default_rule)
self.set_rules(rules, overwrite=overwrite, use_conf=True) self.set_rules(rules, overwrite=overwrite, use_conf=True)
LOG.debug("Rules successfully reloaded") LOG.debug("Reloaded policy file: %(path)s",
{'path': path})
def _get_policy_path(self, path): def _get_policy_path(self, path):
"""Locate the policy json data file/path. """Locate the policy json data file/path.
@ -898,7 +912,17 @@ class HttpCheck(Check):
""" """
url = ('http:' + self.match) % target url = ('http:' + self.match) % target
data = {'target': jsonutils.dumps(target),
# Convert instances of object() in target temporarily to
# empty dict to avoid circular reference detection
# errors in jsonutils.dumps().
temp_target = copy.deepcopy(target)
for key in target.keys():
element = target.get(key)
if type(element) is object:
temp_target[key] = {}
data = {'target': jsonutils.dumps(temp_target),
'credentials': jsonutils.dumps(creds)} 'credentials': jsonutils.dumps(creds)}
post_data = urlparse.urlencode(data) post_data = urlparse.urlencode(data)
f = urlrequest.urlopen(url, post_data) f = urlrequest.urlopen(url, post_data)

View File

@ -35,7 +35,7 @@ except ImportError:
import eventlet import eventlet
from eventlet import event from eventlet import event
from oslo.config import cfg from oslo_config import cfg
from glance.openstack.common import eventlet_backdoor from glance.openstack.common import eventlet_backdoor
from glance.openstack.common._i18n import _LE, _LI, _LW from glance.openstack.common._i18n import _LE, _LI, _LW
@ -199,16 +199,12 @@ class ServiceWrapper(object):
class ProcessLauncher(object): class ProcessLauncher(object):
def __init__(self, wait_interval=0.01): def __init__(self):
"""Constructor. """Constructor."""
:param wait_interval: The interval to sleep for between checks
of child process exit.
"""
self.children = {} self.children = {}
self.sigcaught = None self.sigcaught = None
self.running = True self.running = True
self.wait_interval = wait_interval
rfd, self.writepipe = os.pipe() rfd, self.writepipe = os.pipe()
self.readpipe = eventlet.greenio.GreenPipe(rfd, 'r') self.readpipe = eventlet.greenio.GreenPipe(rfd, 'r')
self.handle_signal() self.handle_signal()
@ -333,8 +329,8 @@ class ProcessLauncher(object):
def _wait_child(self): def _wait_child(self):
try: try:
# Don't block if no child processes have exited # Block while any of child processes have exited
pid, status = os.waitpid(0, os.WNOHANG) pid, status = os.waitpid(0, 0)
if not pid: if not pid:
return None return None
except OSError as exc: except OSError as exc:
@ -363,10 +359,6 @@ class ProcessLauncher(object):
while self.running: while self.running:
wrap = self._wait_child() wrap = self._wait_child()
if not wrap: if not wrap:
# Yield to other threads if no children have exited
# Sleep for a short time to avoid excessive CPU usage
# (see bug #1095346)
eventlet.greenthread.sleep(self.wait_interval)
continue continue
while self.running and len(wrap.children) < wrap.workers: while self.running and len(wrap.children) < wrap.workers:
self._start_child(wrap) self._start_child(wrap)