Switch to Oslo's config generator

This fixes the sample configuration to contain proper
config groups alongway.

Regenerate sample config with oslo's config generator.

DocImpact: Removes the deprecated memcached_server
option from DEFAULT (now in keystone_authtoken group)

Closes-Bug: #1206650
Closes-Bug: #1260322

Change-Id: I170715bfe6ec7dad9f7317e7bb56cbb68034c4ec
This commit is contained in:
Dirk Mueller 2013-12-12 14:22:49 +01:00
parent f52cb1b1c4
commit 783e3243f9
7 changed files with 511 additions and 352 deletions

View File

@ -167,9 +167,6 @@ global_opts = [
'If this is not set then we use the value from the '
'storage_availability_zone option as the default '
'availability_zone for new volumes.'),
cfg.ListOpt('memcached_servers',
default=None,
help='Memcached servers or None for in process cache.'),
cfg.StrOpt('default_volume_type',
default=None,
help='default volume type to use'),

View File

@ -0,0 +1,268 @@
# Copyright 2012 SINA Corporation
# 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.
#
"""Extracts OpenStack config option info from module(s)."""
from __future__ import print_function
import imp
import os
import re
import socket
import sys
import textwrap
from oslo.config import cfg
import six
from cinder.openstack.common import gettextutils
from cinder.openstack.common import importutils
gettextutils.install('cinder')
STROPT = "StrOpt"
BOOLOPT = "BoolOpt"
INTOPT = "IntOpt"
FLOATOPT = "FloatOpt"
LISTOPT = "ListOpt"
MULTISTROPT = "MultiStrOpt"
OPT_TYPES = {
STROPT: 'string value',
BOOLOPT: 'boolean value',
INTOPT: 'integer value',
FLOATOPT: 'floating point value',
LISTOPT: 'list value',
MULTISTROPT: 'multi valued',
}
OPTION_REGEX = re.compile(r"(%s)" % "|".join([STROPT, BOOLOPT, INTOPT,
FLOATOPT, LISTOPT,
MULTISTROPT]))
PY_EXT = ".py"
BASEDIR = os.path.abspath(os.path.join(os.path.dirname(__file__),
"../../../../"))
WORDWRAP_WIDTH = 60
def generate(srcfiles):
mods_by_pkg = dict()
for filepath in srcfiles:
pkg_name = filepath.split(os.sep)[1]
mod_str = '.'.join(['.'.join(filepath.split(os.sep)[:-1]),
os.path.basename(filepath).split('.')[0]])
mods_by_pkg.setdefault(pkg_name, list()).append(mod_str)
# NOTE(lzyeval): place top level modules before packages
pkg_names = filter(lambda x: x.endswith(PY_EXT), mods_by_pkg.keys())
pkg_names.sort()
ext_names = filter(lambda x: x not in pkg_names, mods_by_pkg.keys())
ext_names.sort()
pkg_names.extend(ext_names)
# opts_by_group is a mapping of group name to an options list
# The options list is a list of (module, options) tuples
opts_by_group = {'DEFAULT': []}
extra_modules = os.getenv("OSLO_CONFIG_GENERATOR_EXTRA_MODULES", "")
if extra_modules:
for module_name in extra_modules.split(','):
module_name = module_name.strip()
module = _import_module(module_name)
if module:
for group, opts in _list_opts(module):
opts_by_group.setdefault(group, []).append((module_name,
opts))
for pkg_name in pkg_names:
mods = mods_by_pkg.get(pkg_name)
mods.sort()
for mod_str in mods:
if mod_str.endswith('.__init__'):
mod_str = mod_str[:mod_str.rfind(".")]
mod_obj = _import_module(mod_str)
if not mod_obj:
raise RuntimeError("Unable to import module %s" % mod_str)
for group, opts in _list_opts(mod_obj):
opts_by_group.setdefault(group, []).append((mod_str, opts))
print_group_opts('DEFAULT', opts_by_group.pop('DEFAULT', []))
for group, opts in opts_by_group.items():
print_group_opts(group, opts)
def _import_module(mod_str):
try:
if mod_str.startswith('bin.'):
imp.load_source(mod_str[4:], os.path.join('bin', mod_str[4:]))
return sys.modules[mod_str[4:]]
else:
return importutils.import_module(mod_str)
except Exception as e:
sys.stderr.write("Error importing module %s: %s\n" % (mod_str, str(e)))
return None
def _is_in_group(opt, group):
"Check if opt is in group."
for key, value in group._opts.items():
if value['opt'] == opt:
return True
return False
def _guess_groups(opt, mod_obj):
# is it in the DEFAULT group?
if _is_in_group(opt, cfg.CONF):
return 'DEFAULT'
# what other groups is it in?
for key, value in cfg.CONF.items():
if isinstance(value, cfg.CONF.GroupAttr):
if _is_in_group(opt, value._group):
return value._group.name
raise RuntimeError(
"Unable to find group for option %s, "
"maybe it's defined twice in the same group?"
% opt.name
)
def _list_opts(obj):
def is_opt(o):
return (isinstance(o, cfg.Opt) and
not isinstance(o, cfg.SubCommandOpt))
opts = list()
for attr_str in dir(obj):
attr_obj = getattr(obj, attr_str)
if is_opt(attr_obj):
opts.append(attr_obj)
elif (isinstance(attr_obj, list) and
all(map(lambda x: is_opt(x), attr_obj))):
opts.extend(attr_obj)
ret = {}
for opt in opts:
ret.setdefault(_guess_groups(opt, obj), []).append(opt)
return ret.items()
def print_group_opts(group, opts_by_module):
print("[%s]" % group)
print('')
for mod, opts in opts_by_module:
print('#')
print('# Options defined in %s' % mod)
print('#')
print('')
for opt in opts:
_print_opt(opt)
print('')
def _get_my_ip():
try:
csock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
csock.connect(('8.8.8.8', 80))
(addr, port) = csock.getsockname()
csock.close()
return addr
except socket.error:
return None
def _sanitize_default(name, value):
"""Set up a reasonably sensible default for pybasedir, my_ip and host."""
if value.startswith(sys.prefix):
# NOTE(jd) Don't use os.path.join, because it is likely to think the
# second part is an absolute pathname and therefore drop the first
# part.
value = os.path.normpath("/usr/" + value[len(sys.prefix):])
elif value.startswith(BASEDIR):
return value.replace(BASEDIR, '/usr/lib/python/site-packages')
elif BASEDIR in value:
return value.replace(BASEDIR, '')
elif value == _get_my_ip():
return '10.0.0.1'
elif value == socket.gethostname() and 'host' in name:
return 'cinder'
elif value.strip() != value:
return '"%s"' % value
return value
def _print_opt(opt):
opt_name, opt_default, opt_help = opt.dest, opt.default, opt.help
if not opt_help:
sys.stderr.write('WARNING: "%s" is missing help string.\n' % opt_name)
opt_help = ""
opt_type = None
try:
opt_type = OPTION_REGEX.search(str(type(opt))).group(0)
except (ValueError, AttributeError) as err:
sys.stderr.write("%s\n" % str(err))
sys.exit(1)
opt_help += ' (' + OPT_TYPES[opt_type] + ')'
print('#', "\n# ".join(textwrap.wrap(opt_help, WORDWRAP_WIDTH)))
if opt.deprecated_opts:
for deprecated_opt in opt.deprecated_opts:
if deprecated_opt.name:
deprecated_group = (deprecated_opt.group if
deprecated_opt.group else "DEFAULT")
print('# Deprecated group/name - [%s]/%s' %
(deprecated_group,
deprecated_opt.name))
try:
if opt_default is None:
print('#%s=<None>' % opt_name)
elif opt_type == STROPT:
assert(isinstance(opt_default, six.string_types))
print('#%s=%s' % (opt_name, _sanitize_default(opt_name,
opt_default)))
elif opt_type == BOOLOPT:
assert(isinstance(opt_default, bool))
print('#%s=%s' % (opt_name, str(opt_default).lower()))
elif opt_type == INTOPT:
assert(isinstance(opt_default, int) and
not isinstance(opt_default, bool))
print('#%s=%s' % (opt_name, opt_default))
elif opt_type == FLOATOPT:
assert(isinstance(opt_default, float))
print('#%s=%s' % (opt_name, opt_default))
elif opt_type == LISTOPT:
assert(isinstance(opt_default, list))
print('#%s=%s' % (opt_name, ','.join(opt_default)))
elif opt_type == MULTISTROPT:
assert(isinstance(opt_default, list))
if not opt_default:
opt_default = ['']
for default in opt_default:
print('#%s=%s' % (opt_name, default))
print('')
except Exception:
sys.stderr.write('Error in option "%s"\n' % opt_name)
sys.exit(1)
def main():
generate(sys.argv[1:])
if __name__ == '__main__':
main()

View File

@ -1,7 +1,3 @@
####################
# cinder.conf sample #
####################
[DEFAULT]
#
@ -127,6 +123,7 @@
# Base URL that will be presented to users in links to the
# OpenStack Volume API (string value)
# Deprecated group/name - [DEFAULT]/osapi_compute_link_prefix
#osapi_volume_base_URL=<None>
@ -231,6 +228,7 @@
#
# Driver to use for backups. (string value)
# Deprecated group/name - [DEFAULT]/backup_service
#backup_driver=cinder.backup.drivers.swift
@ -344,9 +342,6 @@
# availability_zone for new volumes. (string value)
#default_availability_zone=<None>
# Memcached servers or None for in process cache. (list value)
#memcached_servers=<None>
# default volume type to use (string value)
#default_volume_type=<None>
@ -492,76 +487,10 @@
#image_conversion_dir=$state_path/conversion
#
# Options defined in cinder.keymgr
#
# The full class name of the key manager API class (string
# value)
#api_class=cinder.keymgr.conf_key_mgr.ConfKeyManager
#
# Options defined in cinder.keymgr.conf_key_mgr
#
# Fixed key returned by key manager, specified in hex (string
# value)
#fixed_key=<None>
#
# Options defined in cinder.openstack.common.db.api
#
# The backend to use for db (string value)
#backend=sqlalchemy
# Enable the experimental use of thread pooling for all DB API
# calls (boolean value)
#use_tpool=false
#
# Options defined in cinder.openstack.common.db.sqlalchemy.session
#
# The SQLAlchemy connection string used to connect to the
# database (string value)
#connection=sqlite:////cinder/openstack/common/db/$sqlite_db
# timeout before idle sql connections are reaped (integer
# value)
#idle_timeout=3600
# Minimum number of SQL connections to keep open in a pool
# (integer value)
#min_pool_size=1
# Maximum number of SQL connections to keep open in a pool
# (integer value)
#max_pool_size=5
# maximum db connection retries during startup. (setting -1
# implies an infinite retry count) (integer value)
#max_retries=10
# interval between retries of opening a sql connection
# (integer value)
#retry_interval=10
# If set, use this value for max_overflow with sqlalchemy
# (integer value)
#max_overflow=<None>
# Verbosity of SQL debugging information. 0=None,
# 100=Everything (integer value)
#connection_debug=0
# Add python stack traces to SQL as comment strings (boolean
# value)
#connection_trace=false
# the filename to use with sqlite (string value)
#sqlite_db=cinder.sqlite
@ -649,6 +578,7 @@
# configuration to any other existing logging options. Please
# see the Python logging module documentation for details on
# logging configuration files. (string value)
# Deprecated group/name - [DEFAULT]/log_config
#log_config_append=<None>
# DEPRECATED. A logging.Formatter log message format string
@ -664,10 +594,12 @@
# (Optional) Name of log file to output to. If no default is
# set, logging will go to stdout. (string value)
# Deprecated group/name - [DEFAULT]/logfile
#log_file=<None>
# (Optional) The base directory used for relative --log-file
# paths (string value)
# Deprecated group/name - [DEFAULT]/logdir
#log_dir=<None>
# Use syslog for logging. (boolean value)
@ -702,14 +634,6 @@
#notification_topics=notifications
#
# Options defined in cinder.openstack.common.notifier.rpc_notifier2
#
# AMQP topic(s) used for OpenStack notifications (list value)
#topics=notifications
#
# Options defined in cinder.openstack.common.periodic_task
#
@ -762,6 +686,7 @@
#amqp_rpc_single_reply_queue=false
# Use durable queues in amqp. (boolean value)
# Deprecated group/name - [DEFAULT]/rabbit_durable_queues
#amqp_durable_queues=false
# Auto-delete queues in amqp. (boolean value)
@ -915,28 +840,6 @@
#matchmaker_heartbeat_ttl=600
#
# Options defined in cinder.openstack.common.rpc.matchmaker_redis
#
# Host to locate redis (string value)
#host=127.0.0.1
# Use this port to connect to redis host. (integer value)
#port=6379
# Password for Redis server. (optional) (string value)
#password=<None>
#
# Options defined in cinder.openstack.common.rpc.matchmaker_ring
#
# Matchmaker ring file (JSON) (string value)
#ringfile=/etc/oslo/matchmaker_ring.json
#
# Options defined in cinder.scheduler.driver
#
@ -1077,6 +980,7 @@
# The maximum number of times to rescan targets to find volume
# (integer value)
# Deprecated group/name - [DEFAULT]/num_iscsi_scan_tries
#num_volume_device_scan_tries=3
# The backend name for a given driver implementation (string
@ -1840,32 +1744,240 @@
#volume_service_inithost_offload=false
[database]
#
# Options defined in cinder.openstack.common.db.api
#
# The backend to use for db (string value)
# Deprecated group/name - [DEFAULT]/db_backend
#backend=sqlalchemy
# Enable the experimental use of thread pooling for all DB API
# calls (boolean value)
# Deprecated group/name - [DEFAULT]/dbapi_use_tpool
#use_tpool=false
#
# Options defined in cinder.openstack.common.db.sqlalchemy.session
#
# The SQLAlchemy connection string used to connect to the
# database (string value)
# Deprecated group/name - [DEFAULT]/sql_connection
#connection=sqlite:///$state_path/$sqlite_db
# timeout before idle sql connections are reaped (integer
# value)
# Deprecated group/name - [DEFAULT]/sql_idle_timeout
#idle_timeout=3600
# Minimum number of SQL connections to keep open in a pool
# (integer value)
# Deprecated group/name - [DEFAULT]/sql_min_pool_size
#min_pool_size=1
# Maximum number of SQL connections to keep open in a pool
# (integer value)
# Deprecated group/name - [DEFAULT]/sql_max_pool_size
#max_pool_size=5
# maximum db connection retries during startup. (setting -1
# implies an infinite retry count) (integer value)
# Deprecated group/name - [DEFAULT]/sql_max_retries
#max_retries=10
# interval between retries of opening a sql connection
# (integer value)
# Deprecated group/name - [DEFAULT]/sql_retry_interval
#retry_interval=10
# If set, use this value for max_overflow with sqlalchemy
# (integer value)
# Deprecated group/name - [DEFAULT]/sql_max_overflow
#max_overflow=<None>
# Verbosity of SQL debugging information. 0=None,
# 100=Everything (integer value)
# Deprecated group/name - [DEFAULT]/sql_connection_debug
#connection_debug=0
# Add python stack traces to SQL as comment strings (boolean
# value)
# Deprecated group/name - [DEFAULT]/sql_connection_trace
#connection_trace=false
[keymgr]
#
# Options defined in cinder.keymgr
#
# The full class name of the key manager API class (string
# value)
#api_class=cinder.keymgr.conf_key_mgr.ConfKeyManager
#
# Options defined in cinder.keymgr.conf_key_mgr
#
# Fixed key returned by key manager, specified in hex (string
# value)
#fixed_key=<None>
[rpc_notifier2]
#
# Options defined in cinder.openstack.common.notifier.rpc_notifier2
#
# AMQP topic(s) used for OpenStack notifications (list value)
#topics=notifications
[matchmaker_redis]
#
# Options defined in cinder.openstack.common.rpc.matchmaker_redis
#
# Host to locate redis (string value)
#host=127.0.0.1
# Use this port to connect to redis host. (integer value)
#port=6379
# Password for Redis server. (optional) (string value)
#password=<None>
[keystone_authtoken]
#
# Options defined in keystoneclient's authtoken middleware
# Options defined in keystoneclient.middleware.auth_token
#
# Host providing the admin Identity API endpoint
auth_host = 127.0.0.1
# Prefix to prepend at the beginning of the path (string
# value)
#auth_admin_prefix=
# Port of the admin Identity API endpoint
auth_port = 35357
# Host providing the admin Identity API endpoint (string
# value)
#auth_host=127.0.0.1
# Protocol of the admin Identity API endpoint
auth_protocol = http
# Port of the admin Identity API endpoint (integer value)
#auth_port=35357
# Protocol of the admin Identity API endpoint(http or https)
# (string value)
#auth_protocol=https
# Complete public Identity API endpoint (string value)
#auth_uri=<None>
# API version of the admin Identity API endpoint (string
# value)
#auth_version=<None>
# Do not handle authorization requests within the middleware,
# but delegate the authorization decision to downstream WSGI
# components (boolean value)
#delay_auth_decision=false
# Request timeout value for communicating with Identity API
# server. (boolean value)
#http_connect_timeout=<None>
# How many times are we trying to reconnect when communicating
# with Identity API Server. (integer value)
#http_request_max_retries=3
# Allows to pass in the name of a fake http_handler callback
# function used instead of httplib.HTTPConnection or
# httplib.HTTPSConnection. Useful for unit testing where
# network is not available. (string value)
#http_handler=<None>
# Single shared secret with the Keystone configuration used
# for bootstrapping a Keystone installation, or otherwise
# bypassing the normal authentication process. (string value)
#admin_token=<None>
# Keystone account username (string value)
#admin_user=<None>
# Keystone account password (string value)
#admin_password=<None>
# Keystone service account tenant name to validate user tokens
admin_tenant_name = %SERVICE_TENANT_NAME%
# (string value)
#admin_tenant_name=admin
# Keystone account username
admin_user = %SERVICE_USER%
# Env key for the swift cache (string value)
#cache=<None>
# Required if Keystone server requires client certificate
# (string value)
#certfile=<None>
# Required if Keystone server requires client certificate
# (string value)
#keyfile=<None>
# A PEM encoded Certificate Authority to use when verifying
# HTTPs connections. Defaults to system CAs. (string value)
#cafile=<None>
# Verify HTTPS connections. (boolean value)
#insecure=false
# Directory used to cache files related to PKI tokens (string
# value)
#signing_dir=<None>
# If defined, the memcache server(s) to use for caching (list
# value)
# Deprecated group/name - [DEFAULT]/memcache_servers
#memcached_servers=<None>
# In order to prevent excessive requests and validations, the
# middleware uses an in-memory cache for the tokens the
# Keystone API returns. This is only valid if memcache_servers
# is defined. Set to -1 to disable caching completely.
# (integer value)
#token_cache_time=300
# Value only used for unit testing (integer value)
#revocation_cache_time=1
# (optional) if defined, indicate whether token data should be
# authenticated or authenticated and encrypted. Acceptable
# values are MAC or ENCRYPT. If MAC, token data is
# authenticated (with HMAC) in the cache. If ENCRYPT, token
# data is encrypted and authenticated in the cache. If the
# value is not one of these options or empty, auth_token will
# raise an exception on initialization. (string value)
#memcache_security_strategy=<None>
# (optional, mandatory if memcache_security_strategy is
# defined) this string is used for key derivation. (string
# value)
#memcache_secret_key=<None>
[matchmaker_ring]
#
# Options defined in cinder.openstack.common.rpc.matchmaker_ring
#
# Matchmaker ring file (JSON) (string value)
# Deprecated group/name - [DEFAULT]/matchmaker_ringfile
#ringfile=/etc/oslo/matchmaker_ring.json
# Keystone account password
admin_password = %SERVICE_PASSWORD%
# Directory used to cache files related to PKI tokens
# signing_dir is configurable, but the default behavior of the authtoken
# middleware should be sufficient. It will create a temporary directory
# in the home directory for the user the cinder process is running as.
#signing_dir = /var/lib/cinder/keystone-signing

View File

@ -2,6 +2,7 @@
# The list of modules to copy from openstack-common
module=context
module=config.generator
module=db
module=db.sqlalchemy
module=excutils

View File

@ -1,193 +0,0 @@
# Copyright 2012 SINA Corporation
# All Rights Reserved.
# Author: Zhongyue Luo <lzyeval@gmail.com>
#
# 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.
"""Extracts OpenStack config option info from module(s)."""
from __future__ import print_function
import __builtin__
setattr(__builtin__, '_', lambda x: x)
import os
import re
import socket
import sys
import textwrap
from oslo.config import cfg
from cinder.openstack.common import importutils
STROPT = "StrOpt"
BOOLOPT = "BoolOpt"
INTOPT = "IntOpt"
FLOATOPT = "FloatOpt"
LISTOPT = "ListOpt"
MULTISTROPT = "MultiStrOpt"
OPTION_REGEX = re.compile(r"(%s)" % "|".join([STROPT, BOOLOPT, INTOPT,
FLOATOPT, LISTOPT,
MULTISTROPT]))
OPTION_HELP_INDENT = "####"
PY_EXT = ".py"
BASEDIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "../../"))
WORDWRAP_WIDTH = 60
def main(srcfiles):
print('\n'.join(['#' * 20, '# cinder.conf sample #', '#' * 20,
'', '[DEFAULT]', '']))
_list_opts(cfg.ConfigOpts,
cfg.__name__ + ':' + cfg.ConfigOpts.__name__)
mods_by_pkg = dict()
for filepath in srcfiles:
pkg_name = filepath.split(os.sep)[1]
mod_str = '.'.join(['.'.join(filepath.split(os.sep)[:-1]),
os.path.basename(filepath).split('.')[0]])
mods_by_pkg.setdefault(pkg_name, list()).append(mod_str)
# NOTE(lzyeval): place top level modules before packages
pkg_names = filter(lambda x: x.endswith(PY_EXT), mods_by_pkg.keys())
pkg_names.sort()
ext_names = filter(lambda x: x not in pkg_names, mods_by_pkg.keys())
ext_names.sort()
pkg_names.extend(ext_names)
for pkg_name in pkg_names:
mods = mods_by_pkg.get(pkg_name)
mods.sort()
for mod_str in mods:
_print_module(mod_str)
def _print_module(mod_str):
mod_obj = None
if mod_str.endswith('.__init__'):
mod_str = mod_str[:mod_str.rfind(".")]
try:
mod_obj = importutils.import_module(mod_str)
except Exception as e:
sys.stderr.write("Failed to collect options from module %s: %s\n" % (
mod_str, str(e)))
return
_list_opts(mod_obj, mod_str)
def _list_opts(obj, name):
opts = list()
for attr_str in dir(obj):
attr_obj = getattr(obj, attr_str)
if isinstance(attr_obj, cfg.Opt):
opts.append(attr_obj)
elif (isinstance(attr_obj, list) and
all(map(lambda x: isinstance(x, cfg.Opt), attr_obj))):
opts.extend(attr_obj)
if not opts:
return
print('#')
print('# Options defined in %s' % name)
print('#')
print()
for opt in opts:
_print_opt(opt)
print()
def _get_my_ip():
try:
csock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
csock.connect(('8.8.8.8', 80))
(addr, port) = csock.getsockname()
csock.close()
return addr
except socket.error:
return None
MY_IP = _get_my_ip()
HOST = socket.gethostname()
def _sanitize_default(s):
"""Set up a reasonably sensible default for pybasedir, my_ip and host."""
if s.startswith(BASEDIR):
return s.replace(BASEDIR, '/usr/lib/python/site-packages')
elif s == MY_IP:
return '10.0.0.1'
elif s == HOST:
return 'cinder'
elif s.strip() != s:
return '"%s"' % s
return s
OPT_TYPES = {
'StrOpt': 'string value',
'BoolOpt': 'boolean value',
'IntOpt': 'integer value',
'FloatOpt': 'floating point value',
'ListOpt': 'list value',
'MultiStrOpt': 'multi valued',
}
def _print_opt(opt):
opt_name, opt_default, opt_help = opt.dest, opt.default, opt.help
if not opt_help:
sys.stderr.write('WARNING: "%s" is missing help string.\n' % opt_name)
opt_type = None
try:
opt_type = OPTION_REGEX.search(str(type(opt))).group(0)
except (ValueError, AttributeError) as err:
sys.stderr.write("%s\n" % str(err))
sys.exit(1)
opt_help += ' (' + OPT_TYPES[opt_type] + ')'
print('#', "\n# ".join(textwrap.wrap(opt_help, WORDWRAP_WIDTH)))
try:
if opt_default is None:
print('#%s=<None>' % opt_name)
elif opt_type == STROPT:
assert(isinstance(opt_default, basestring))
print('#%s=%s' % (opt_name, _sanitize_default(opt_default)))
elif opt_type == BOOLOPT:
assert(isinstance(opt_default, bool))
print('#%s=%s' % (opt_name, str(opt_default).lower()))
elif opt_type == INTOPT:
assert(isinstance(opt_default, int) and
not isinstance(opt_default, bool))
print('#%s=%s' % (opt_name, opt_default))
elif opt_type == FLOATOPT:
assert(isinstance(opt_default, float))
print('#%s=%s' % (opt_name, opt_default))
elif opt_type == LISTOPT:
assert(isinstance(opt_default, list))
print('#%s=%s' % (opt_name, ','.join(opt_default)))
elif opt_type == MULTISTROPT:
assert(isinstance(opt_default, list))
if opt_default:
for default in opt_default:
print('#%s=%s' % (opt_name, default))
else:
print('#%s=' % (opt_name))
print()
except Exception:
sys.stderr.write('Error in option "%s"\n' % opt_name)
sys.exit(1)
if __name__ == '__main__':
if len(sys.argv) < 2:
print("usage: python %s [srcfile]...\n" % sys.argv[0])
sys.exit(0)
main(sys.argv[1:])

View File

@ -43,41 +43,14 @@ OUTPUTFILE=$OUTPUTDIR/cinder.conf.sample
FILES=$(find cinder -type f -name "*.py" ! -path "cinder/tests/*" -exec \
grep -l "Opt(" {} \; | sort -u)
EXTRA_MODULES_FILE="`dirname $0`/oslo.config.generator.rc"
if test -r "$EXTRA_MODULES_FILE"
then
source "$EXTRA_MODULES_FILE"
fi
export EVENTLET_NO_GREENDNS=yes
PYTHONPATH=./:${PYTHONPATH} \
python $(dirname "$0")/extract_opts.py ${FILES} > \
python $(dirname "$0")/../../cinder/openstack/common/config/generator.py ${FILES} > \
$OUTPUTFILE
# When we use openstack.common.config.generate we won't need this any more
sed -i 's/^#connection=sqlite.*/#connection=sqlite:\/\/\/\/cinder\/openstack\/common\/db\/$sqlite_db/' $OUTPUTFILE
cat >> $OUTPUTFILE <<-EOF_CAT
[keystone_authtoken]
#
# Options defined in keystoneclient's authtoken middleware
#
# Host providing the admin Identity API endpoint
auth_host = 127.0.0.1
# Port of the admin Identity API endpoint
auth_port = 35357
# Protocol of the admin Identity API endpoint
auth_protocol = http
# Keystone service account tenant name to validate user tokens
admin_tenant_name = %SERVICE_TENANT_NAME%
# Keystone account username
admin_user = %SERVICE_USER%
# Keystone account password
admin_password = %SERVICE_PASSWORD%
# Directory used to cache files related to PKI tokens
# signing_dir is configurable, but the default behavior of the authtoken
# middleware should be sufficient. It will create a temporary directory
# in the home directory for the user the cinder process is running as.
#signing_dir = /var/lib/cinder/keystone-signing
EOF_CAT

View File

@ -0,0 +1 @@
export OSLO_CONFIG_GENERATOR_EXTRA_MODULES=keystoneclient.middleware.auth_token