Use cfg's new global CONF object

Implements blueprint cfg-global-object

Replace nova.flags.FLAGS with openstack.common.cfg.CONF.

In future, we can do a s/FLAGS/CONF/ across the codebase.

Change-Id: Ib293873089a5399febd7a3b0410f66e9bef115f1
This commit is contained in:
Mark McLoughlin
2012-05-29 08:57:58 +01:00
parent 5769472415
commit f91f7d2c46
24 changed files with 223 additions and 217 deletions

View File

@@ -46,7 +46,6 @@ from nova import flags
from nova import log as logging from nova import log as logging
from nova.openstack.common import cfg from nova.openstack.common import cfg
from nova import rpc from nova import rpc
from nova import utils
delete_exchange_opt = \ delete_exchange_opt = \
@@ -71,8 +70,7 @@ def delete_queues(queues):
x.queue_delete(q) x.queue_delete(q)
if __name__ == '__main__': if __name__ == '__main__':
utils.default_cfgfile() args = flags.parse_args(sys.argv)
args = flags.FLAGS(sys.argv)
logging.setup() logging.setup()
rpc.register_opts(flags.FLAGS) rpc.register_opts(flags.FLAGS)
delete_queues(args[1:]) delete_queues(args[1:])

View File

@@ -65,8 +65,7 @@ FLAGS = flags.FLAGS
if __name__ == '__main__': if __name__ == '__main__':
rpc.register_opts(FLAGS) rpc.register_opts(FLAGS)
admin_context = context.get_admin_context() admin_context = context.get_admin_context()
utils.default_cfgfile() flags.parse_args(sys.argv)
flags.FLAGS(sys.argv)
logging.setup() logging.setup()
begin, end = utils.last_completed_audit_period() begin, end = utils.last_completed_audit_period()
print "Starting instance usage audit" print "Starting instance usage audit"

View File

@@ -51,8 +51,7 @@ from nova.vnc import xvp_proxy
LOG = logging.getLogger('nova.all') LOG = logging.getLogger('nova.all')
if __name__ == '__main__': if __name__ == '__main__':
utils.default_cfgfile() flags.parse_args(sys.argv)
flags.FLAGS(sys.argv)
logging.setup() logging.setup()
utils.monkey_patch() utils.monkey_patch()
servers = [] servers = []

View File

@@ -42,8 +42,7 @@ from nova import service
from nova import utils from nova import utils
if __name__ == '__main__': if __name__ == '__main__':
utils.default_cfgfile() flags.parse_args(sys.argv)
flags.FLAGS(sys.argv)
logging.setup() logging.setup()
utils.monkey_patch() utils.monkey_patch()
servers = [] servers = []

View File

@@ -38,8 +38,7 @@ from nova import service
from nova import utils from nova import utils
if __name__ == '__main__': if __name__ == '__main__':
utils.default_cfgfile() flags.parse_args(sys.argv)
flags.FLAGS(sys.argv)
logging.setup() logging.setup()
utils.monkey_patch() utils.monkey_patch()
server = service.WSGIService('ec2') server = service.WSGIService('ec2')

View File

@@ -38,8 +38,7 @@ from nova import service
from nova import utils from nova import utils
if __name__ == '__main__': if __name__ == '__main__':
utils.default_cfgfile() flags.parse_args(sys.argv)
flags.FLAGS(sys.argv)
logging.setup() logging.setup()
utils.monkey_patch() utils.monkey_patch()
server = service.WSGIService('metadata') server = service.WSGIService('metadata')

View File

@@ -38,8 +38,7 @@ from nova import service
from nova import utils from nova import utils
if __name__ == '__main__': if __name__ == '__main__':
utils.default_cfgfile() flags.parse_args(sys.argv)
flags.FLAGS(sys.argv)
logging.setup() logging.setup()
utils.monkey_patch() utils.monkey_patch()
server = service.WSGIService('osapi_compute') server = service.WSGIService('osapi_compute')

View File

@@ -38,8 +38,7 @@ from nova import service
from nova import utils from nova import utils
if __name__ == '__main__': if __name__ == '__main__':
utils.default_cfgfile() flags.parse_args(sys.argv)
flags.FLAGS(sys.argv)
logging.setup() logging.setup()
utils.monkey_patch() utils.monkey_patch()
server = service.WSGIService('osapi_volume') server = service.WSGIService('osapi_volume')

View File

@@ -38,8 +38,7 @@ from nova import service
from nova import utils from nova import utils
if __name__ == '__main__': if __name__ == '__main__':
utils.default_cfgfile() flags.parse_args(sys.argv)
flags.FLAGS(sys.argv)
logging.setup() logging.setup()
utils.monkey_patch() utils.monkey_patch()
server = service.Service.create(binary='nova-cert') server = service.Service.create(binary='nova-cert')

View File

@@ -40,8 +40,7 @@ from nova import service
from nova import utils from nova import utils
if __name__ == '__main__': if __name__ == '__main__':
utils.default_cfgfile() flags.parse_args(sys.argv)
flags.FLAGS(sys.argv)
logging.setup() logging.setup()
utils.monkey_patch() utils.monkey_patch()
server = service.Service.create(binary='nova-compute') server = service.Service.create(binary='nova-compute')

View File

@@ -36,11 +36,9 @@ if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')):
from nova import flags from nova import flags
from nova import log as logging from nova import log as logging
from nova import service from nova import service
from nova import utils
if __name__ == '__main__': if __name__ == '__main__':
utils.default_cfgfile() flags.parse_args(sys.argv)
flags.FLAGS(sys.argv)
logging.setup() logging.setup()
server = service.Service.create(binary='nova-console') server = service.Service.create(binary='nova-console')
service.serve(server) service.serve(server)

View File

@@ -35,12 +35,10 @@ from nova.consoleauth import manager
from nova import flags from nova import flags
from nova import log as logging from nova import log as logging
from nova import service from nova import service
from nova import utils
if __name__ == "__main__": if __name__ == "__main__":
utils.default_cfgfile() flags.parse_args(sys.argv)
flags.FLAGS(sys.argv)
logging.setup() logging.setup()
server = service.Service.create(binary='nova-consoleauth') server = service.Service.create(binary='nova-consoleauth')

View File

@@ -96,8 +96,7 @@ def init_leases(network_id):
def main(): def main():
"""Parse environment and arguments and call the approproate action.""" """Parse environment and arguments and call the approproate action."""
flagfile = os.environ.get('FLAGFILE', FLAGS.dhcpbridge_flagfile) flagfile = os.environ.get('FLAGFILE', FLAGS.dhcpbridge_flagfile)
utils.default_cfgfile(flagfile) argv = flags.parse_args(sys.argv)
argv = FLAGS(sys.argv)
logging.setup() logging.setup()
rpc.register_opts(FLAGS) rpc.register_opts(FLAGS)

View File

@@ -87,6 +87,7 @@ from nova.db import migration
from nova import exception from nova import exception
from nova import flags from nova import flags
from nova import log as logging from nova import log as logging
from nova.openstack.common import cfg
from nova.openstack.common import importutils from nova.openstack.common import importutils
from nova import quota from nova import quota
from nova import rpc from nova import rpc
@@ -1668,26 +1669,24 @@ def methods_of(obj):
def main(): def main():
"""Parse options and call the appropriate class/method.""" """Parse options and call the appropriate class/method."""
cfgfile = utils.default_cfgfile()
if cfgfile and not os.access(cfgfile, os.R_OK):
st = os.stat(cfgfile)
print "Could not read %s. Re-running with sudo" % cfgfile
try:
os.execvp('sudo', ['sudo', '-u', '#%s' % st.st_uid] + sys.argv)
except Exception:
print 'sudo failed, continuing as if nothing happened'
rpc.register_opts(FLAGS) rpc.register_opts(FLAGS)
try: try:
argv = FLAGS(sys.argv) argv = flags.parse_args(sys.argv)
logging.setup() logging.setup()
except IOError, e: except cfg.ConfigFilesNotFoundError:
if e.errno == errno.EACCES: cfgfile = FLAGS.config_file[-1] if FLAGS.config_file else None
print _('Please re-run nova-manage as root.') if cfgfile and not os.access(cfgfile, os.R_OK):
sys.exit(2) st = os.stat(cfgfile)
raise print _("Could not read %s. Re-running with sudo") % cfgfile
try:
os.execvp('sudo', ['sudo', '-u', '#%s' % st.st_uid] + sys.argv)
except Exception:
print _('sudo failed, continuing as if nothing happened')
print _('Please re-run nova-manage as root.')
sys.exit(2)
script_name = argv.pop(0) script_name = argv.pop(0)
if len(argv) < 1: if len(argv) < 1:
print _("\nOpenStack Nova version: %(version)s (%(vcs)s)\n") % \ print _("\nOpenStack Nova version: %(version)s (%(vcs)s)\n") % \

View File

@@ -40,8 +40,7 @@ from nova import service
from nova import utils from nova import utils
if __name__ == '__main__': if __name__ == '__main__':
utils.default_cfgfile() flags.parse_args(sys.argv)
flags.FLAGS(sys.argv)
logging.setup() logging.setup()
utils.monkey_patch() utils.monkey_patch()
server = service.Service.create(binary='nova-network') server = service.Service.create(binary='nova-network')

View File

@@ -42,8 +42,7 @@ from nova import utils
if __name__ == '__main__': if __name__ == '__main__':
utils.default_cfgfile() flags.parse_args(sys.argv)
flags.FLAGS(sys.argv)
logging.setup() logging.setup()
utils.monkey_patch() utils.monkey_patch()
server = s3server.get_wsgi_server() server = s3server.get_wsgi_server()

View File

@@ -42,8 +42,7 @@ from nova import service
from nova import utils from nova import utils
if __name__ == '__main__': if __name__ == '__main__':
utils.default_cfgfile() flags.parse_args(sys.argv)
flags.FLAGS(sys.argv)
logging.setup() logging.setup()
utils.monkey_patch() utils.monkey_patch()
server = service.Service.create(binary='nova-scheduler') server = service.Service.create(binary='nova-scheduler')

View File

@@ -40,8 +40,7 @@ from nova import service
from nova import utils from nova import utils
if __name__ == '__main__': if __name__ == '__main__':
utils.default_cfgfile() flags.parse_args(sys.argv)
flags.FLAGS(sys.argv)
logging.setup() logging.setup()
utils.monkey_patch() utils.monkey_patch()
server = service.Service.create(binary='nova-volume') server = service.Service.create(binary='nova-volume')

View File

@@ -35,15 +35,13 @@ from nova import flags
from nova import log as logging from nova import log as logging
from nova import rpc from nova import rpc
from nova import service from nova import service
from nova import utils
from nova.vnc import xvp_proxy from nova.vnc import xvp_proxy
FLAGS = flags.FLAGS FLAGS = flags.FLAGS
if __name__ == "__main__": if __name__ == "__main__":
rpc.register_opts(FLAGS) rpc.register_opts(FLAGS)
utils.default_cfgfile() flags.parse_args(sys.argv)
flags.FLAGS(sys.argv)
logging.setup() logging.setup()
wsgi_server = xvp_proxy.get_wsgi_server() wsgi_server = xvp_proxy.get_wsgi_server()

View File

@@ -33,19 +33,14 @@ import sys
from nova.openstack.common import cfg from nova.openstack.common import cfg
class NovaConfigOpts(cfg.CommonConfigOpts): FLAGS = cfg.CONF
def __init__(self, *args, **kwargs):
if 'project' not in kwargs:
kwargs['project'] = 'nova'
super(NovaConfigOpts, self).__init__(*args, **kwargs)
self.disable_interspersed_args()
def __call__(self, argv):
return argv[:1] + super(NovaConfigOpts, self).__call__(argv[1:])
FLAGS = NovaConfigOpts() def parse_args(argv, default_config_files=None):
FLAGS.disable_interspersed_args()
return argv[:1] + FLAGS(argv[1:],
project='nova',
default_config_files=default_config_files)
class UnrecognizedFlag(Exception): class UnrecognizedFlag(Exception):

View File

@@ -95,7 +95,7 @@ and --config-dir::
class ConfigOpts(object): class ConfigOpts(object):
def __init__(self, ...): def __call__(self, ...):
opts = [ opts = [
MultiStrOpt('config-file', MultiStrOpt('config-file',
@@ -233,6 +233,22 @@ log files:
... ...
] ]
This module also contains a global instance of the CommonConfigOpts class
in order to support a common usage pattern in OpenStack:
from openstack.common import cfg
opts = [
cfg.StrOpt('bind_host' default='0.0.0.0'),
cfg.IntOpt('bind_port', default=9292),
]
CONF = cfg.CONF
CONF.register_opts(opts)
def start(server, app):
server.start(app, CONF.bind_port, CONF.bind_host)
""" """
import collections import collections
@@ -768,6 +784,14 @@ class OptGroup(object):
return True return True
def _unregister_opt(self, opt):
"""Remove an opt from this group.
:param opt: an Opt object
"""
if opt.dest in self._opts:
del self._opts[opt.dest]
def _get_optparse_group(self, parser): def _get_optparse_group(self, parser):
"""Build an optparse.OptionGroup for this group.""" """Build an optparse.OptionGroup for this group."""
if self._optparse_group is None: if self._optparse_group is None:
@@ -775,6 +799,10 @@ class OptGroup(object):
self.help) self.help)
return self._optparse_group return self._optparse_group
def _clear(self):
"""Clear this group's option parsing state."""
self._optparse_group = None
class ParseError(iniparser.ParseError): class ParseError(iniparser.ParseError):
def __init__(self, msg, lineno, line, filename): def __init__(self, msg, lineno, line, filename):
@@ -849,57 +877,41 @@ class ConfigOpts(collections.Mapping):
the values of options. the values of options.
""" """
def __init__(self, def __init__(self):
project=None, """Construct a ConfigOpts object."""
prog=None, self._opts = {} # dict of dicts of (opt:, override:, default:)
version=None, self._groups = {}
usage=None,
default_config_files=None):
"""Construct a ConfigOpts object.
Automatically registers the --config-file option with either a supplied self._args = None
list of default config files, or a list from find_config_files(). self._oparser = None
self._cparser = None
self._cli_values = {}
self.__cache = {}
self._config_opts = []
self._disable_interspersed_args = False
:param project: the toplevel project name, used to locate config files def _setup(self, project, prog, version, usage, default_config_files):
:param prog: the name of the program (defaults to sys.argv[0] basename) """Initialize a ConfigOpts object for option parsing."""
:param version: the program version (for --version)
:param usage: a usage string (%prog will be expanded)
:param default_config_files: config files to use by default
"""
if prog is None: if prog is None:
prog = os.path.basename(sys.argv[0]) prog = os.path.basename(sys.argv[0])
if default_config_files is None: if default_config_files is None:
default_config_files = find_config_files(project, prog) default_config_files = find_config_files(project, prog)
self.project = project self._oparser = optparse.OptionParser(prog=prog,
self.prog = prog version=version,
self.version = version usage=usage)
self.usage = usage if self._disable_interspersed_args:
self.default_config_files = default_config_files self._oparser.disable_interspersed_args()
self._opts = {} # dict of dicts of (opt:, override:, default:) self._config_opts = [
self._groups = {}
self._args = None
self._cli_values = {}
self._oparser = optparse.OptionParser(prog=self.prog,
version=self.version,
usage=self.usage)
self._cparser = None
self.__cache = {}
opts = [
MultiStrOpt('config-file', MultiStrOpt('config-file',
default=self.default_config_files, default=default_config_files,
metavar='PATH', metavar='PATH',
help='Path to a config file to use. Multiple config ' help='Path to a config file to use. Multiple config '
'files can be specified, with values in later ' 'files can be specified, with values in later '
'files taking precedence. The default files ' 'files taking precedence. The default files '
' used are: %s' % ' used are: %s' % (default_config_files, )),
(self.default_config_files, )),
StrOpt('config-dir', StrOpt('config-dir',
metavar='DIR', metavar='DIR',
help='Path to a config directory to pull *.conf ' help='Path to a config directory to pull *.conf '
@@ -910,7 +922,13 @@ class ConfigOpts(collections.Mapping):
'hence over-ridden options in the directory take ' 'hence over-ridden options in the directory take '
'precedence.'), 'precedence.'),
] ]
self.register_cli_opts(opts) self.register_cli_opts(self._config_opts)
self.project = project
self.prog = prog
self.version = version
self.usage = usage
self.default_config_files = default_config_files
def __clear_cache(f): def __clear_cache(f):
@functools.wraps(f) @functools.wraps(f)
@@ -921,7 +939,13 @@ class ConfigOpts(collections.Mapping):
return __inner return __inner
def __call__(self, args=None): def __call__(self,
args=None,
project=None,
prog=None,
version=None,
usage=None,
default_config_files=None):
"""Parse command line arguments and config files. """Parse command line arguments and config files.
Calling a ConfigOpts object causes the supplied command line arguments Calling a ConfigOpts object causes the supplied command line arguments
@@ -931,35 +955,34 @@ class ConfigOpts(collections.Mapping):
The object may be called multiple times, each time causing the previous The object may be called multiple times, each time causing the previous
set of values to be overwritten. set of values to be overwritten.
Automatically registers the --config-file option with either a supplied
list of default config files, or a list from find_config_files().
If the --config-dir option is set, any *.conf files from this If the --config-dir option is set, any *.conf files from this
directory are pulled in, after all the file(s) specified by the directory are pulled in, after all the file(s) specified by the
--config-file option. --config-file option.
:params args: command line arguments (defaults to sys.argv[1:]) :param args: command line arguments (defaults to sys.argv[1:])
:param project: the toplevel project name, used to locate config files
:param prog: the name of the program (defaults to sys.argv[0] basename)
:param version: the program version (for --version)
:param usage: a usage string (%prog will be expanded)
:param default_config_files: config files to use by default
:returns: the list of arguments left over after parsing options :returns: the list of arguments left over after parsing options
:raises: SystemExit, ConfigFilesNotFoundError, ConfigFileParseError, :raises: SystemExit, ConfigFilesNotFoundError, ConfigFileParseError,
RequiredOptError RequiredOptError, DuplicateOptError
""" """
self.clear() self.clear()
self._args = args self._setup(project, prog, version, usage, default_config_files)
(values, args) = self._oparser.parse_args(self._args) self._cli_values, leftovers = self._parse_cli_opts(args)
self._cli_values = vars(values) self._parse_config_files()
def _list_config_dir():
return sorted(glob.glob(os.path.join(self.config_dir, '*.conf')))
from_file = list(self.config_file)
from_dir = _list_config_dir() if self.config_dir else []
self._parse_config_files(from_file + from_dir)
self._check_required_opts() self._check_required_opts()
return args return leftovers
def __getattr__(self, name): def __getattr__(self, name):
"""Look up an option value and perform string substitution. """Look up an option value and perform string substitution.
@@ -996,8 +1019,12 @@ class ConfigOpts(collections.Mapping):
def clear(self): def clear(self):
"""Clear the state of the object to before it was called.""" """Clear the state of the object to before it was called."""
self._args = None self._args = None
self._cli_values = {} self._cli_values.clear()
self._oparser = None
self._cparser = None self._cparser = None
self.unregister_opts(self._config_opts)
for group in self._groups.values():
group._clear()
@__clear_cache @__clear_cache
def register_opt(self, opt, group=None): def register_opt(self, opt, group=None):
@@ -1044,15 +1071,7 @@ class ConfigOpts(collections.Mapping):
if self._args is not None: if self._args is not None:
raise ArgsAlreadyParsedError("cannot register CLI option") raise ArgsAlreadyParsedError("cannot register CLI option")
if not self.register_opt(opt, group, clear_cache=False): return self.register_opt(opt, group, clear_cache=False)
return False
if group is not None:
group = self._get_group(group, autocreate=True)
opt._add_to_cli(self._oparser, group)
return True
@__clear_cache @__clear_cache
def register_cli_opts(self, opts, group=None): def register_cli_opts(self, opts, group=None):
@@ -1073,6 +1092,28 @@ class ConfigOpts(collections.Mapping):
self._groups[group.name] = copy.copy(group) self._groups[group.name] = copy.copy(group)
@__clear_cache
def unregister_opt(self, opt, group=None):
"""Unregister an option.
:param opt: an Opt object
:param group: an optional OptGroup object or group name
:raises: ArgsAlreadyParsedError, NoSuchGroupError
"""
if self._args is not None:
raise ArgsAlreadyParsedError("reset before unregistering options")
if group is not None:
self._get_group(group)._unregister_opt(opt)
elif opt.dest in self._opts:
del self._opts[opt.dest]
@__clear_cache
def unregister_opts(self, opts, group=None):
"""Unregister multiple CLI option schemas at once."""
for opt in opts:
self.unregister_opt(opt, group, clear_cache=False)
@__clear_cache @__clear_cache
def set_override(self, name, override, group=None): def set_override(self, name, override, group=None):
"""Override an opt value. """Override an opt value.
@@ -1103,16 +1144,24 @@ class ConfigOpts(collections.Mapping):
opt_info = self._get_opt_info(name, group) opt_info = self._get_opt_info(name, group)
opt_info['default'] = default opt_info['default'] = default
def _all_opt_infos(self):
"""A generator function for iteration opt infos."""
for info in self._opts.values():
yield info, None
for group in self._groups.values():
for info in group._opts.values():
yield info, group
def _all_opts(self):
"""A generator function for iteration opts."""
for info, group in self._all_opt_infos():
yield info['opt'], group
def _unset_defaults_and_overrides(self): def _unset_defaults_and_overrides(self):
"""Unset any default or override on all options.""" """Unset any default or override on all options."""
def unset(opts): for info, group in self._all_opt_infos():
for info in opts.values(): info['default'] = None
info['default'] = None info['override'] = None
info['override'] = None
unset(self._opts)
for group in self._groups.values():
unset(group._opts)
def disable_interspersed_args(self): def disable_interspersed_args(self):
"""Set parsing to stop on the first non-option. """Set parsing to stop on the first non-option.
@@ -1131,13 +1180,13 @@ class ConfigOpts(collections.Mapping):
i.e. argument parsing is stopped at the first non-option argument. i.e. argument parsing is stopped at the first non-option argument.
""" """
self._oparser.disable_interspersed_args() self._disable_interspersed_args = True
def enable_interspersed_args(self): def enable_interspersed_args(self):
"""Set parsing to not stop on the first non-option. """Set parsing to not stop on the first non-option.
This it the default behaviour.""" This it the default behaviour."""
self._oparser.enable_interspersed_args() self._disable_interspersed_args = False
def find_file(self, name): def find_file(self, name):
"""Locate a file located alongside the config files. """Locate a file located alongside the config files.
@@ -1331,11 +1380,17 @@ class ConfigOpts(collections.Mapping):
return opts[opt_name] return opts[opt_name]
def _parse_config_files(self, config_files): def _parse_config_files(self):
"""Parse the supplied configuration files. """Parse the config files from --config-file and --config-dir.
:raises: ConfigFilesNotFoundError, ConfigFileParseError :raises: ConfigFilesNotFoundError, ConfigFileParseError
""" """
config_files = list(self.config_file)
if self.config_dir:
config_dir_glob = os.path.join(self.config_dir, '*.conf')
config_files += sorted(glob.glob(config_dir_glob))
self._cparser = MultiConfigParser() self._cparser = MultiConfigParser()
try: try:
@@ -1347,8 +1402,12 @@ class ConfigOpts(collections.Mapping):
not_read_ok = filter(lambda f: f not in read_ok, config_files) not_read_ok = filter(lambda f: f not in read_ok, config_files)
raise ConfigFilesNotFoundError(not_read_ok) raise ConfigFilesNotFoundError(not_read_ok)
def _do_check_required_opts(self, opts, group=None): def _check_required_opts(self):
for info in opts.values(): """Check that all opts marked as required have values specified.
:raises: RequiredOptError
"""
for info, group in self._all_opt_infos():
default, opt, override = [info[k] for k in sorted(info.keys())] default, opt, override = [info[k] for k in sorted(info.keys())]
if opt.required: if opt.required:
@@ -1359,15 +1418,25 @@ class ConfigOpts(collections.Mapping):
if self._get(opt.name, group) is None: if self._get(opt.name, group) is None:
raise RequiredOptError(opt.name, group) raise RequiredOptError(opt.name, group)
def _check_required_opts(self): def _parse_cli_opts(self, args):
"""Check that all opts marked as required have values specified. """Parse command line options.
Initializes the command line option parser and parses the supplied
command line arguments.
:param args: the command line arguments
:returns: a dict of parsed option values
:raises: SystemExit, DuplicateOptError
:raises: RequiredOptError
""" """
self._do_check_required_opts(self._opts) self._args = args
for group in self._groups.values(): for opt, group in self._all_opts():
self._do_check_required_opts(group._opts, group) opt._add_to_cli(self._oparser, group)
values, leftovers = self._oparser.parse_args(args)
return vars(values), leftovers
class GroupAttr(collections.Mapping): class GroupAttr(collections.Mapping):
@@ -1483,7 +1552,10 @@ class CommonConfigOpts(ConfigOpts):
help='syslog facility to receive log lines') help='syslog facility to receive log lines')
] ]
def __init__(self, **kwargs): def __init__(self):
super(CommonConfigOpts, self).__init__(**kwargs) super(CommonConfigOpts, self).__init__()
self.register_cli_opts(self.common_cli_opts) self.register_cli_opts(self.common_cli_opts)
self.register_cli_opts(self.logging_cli_opts) self.register_cli_opts(self.logging_cli_opts)
CONF = CommonConfigOpts()

View File

@@ -128,6 +128,7 @@ class TestCase(unittest.TestCase):
super(TestCase, self).setUp() super(TestCase, self).setUp()
fake_flags.set_defaults(FLAGS) fake_flags.set_defaults(FLAGS)
flags.parse_args([], default_config_files=[])
# NOTE(vish): We need a better method for creating fixtures for tests # NOTE(vish): We need a better method for creating fixtures for tests
# now that we have some required db setup for the system # now that we have some required db setup for the system

View File

@@ -34,54 +34,50 @@ class FlagsTestCase(test.TestCase):
def setUp(self): def setUp(self):
super(FlagsTestCase, self).setUp() super(FlagsTestCase, self).setUp()
self.FLAGS = flags.NovaConfigOpts()
self.global_FLAGS = flags.FLAGS
self.flags(config_file=[])
def test_declare(self): def test_declare(self):
self.assert_('answer' not in self.global_FLAGS) self.assert_('answer' not in FLAGS)
flags.DECLARE('answer', 'nova.tests.declare_flags') flags.DECLARE('answer', 'nova.tests.declare_flags')
self.assert_('answer' in self.global_FLAGS) self.assert_('answer' in FLAGS)
self.assertEqual(self.global_FLAGS.answer, 42) self.assertEqual(FLAGS.answer, 42)
# Make sure we don't overwrite anything # Make sure we don't overwrite anything
self.global_FLAGS.set_override('answer', 256) FLAGS.set_override('answer', 256)
self.assertEqual(self.global_FLAGS.answer, 256) self.assertEqual(FLAGS.answer, 256)
flags.DECLARE('answer', 'nova.tests.declare_flags') flags.DECLARE('answer', 'nova.tests.declare_flags')
self.assertEqual(self.global_FLAGS.answer, 256) self.assertEqual(FLAGS.answer, 256)
def test_getopt_non_interspersed_args(self): def test_getopt_non_interspersed_args(self):
self.assert_('runtime_answer' not in self.global_FLAGS) self.assert_('runtime_answer' not in FLAGS)
argv = ['flags_test', 'extra_arg', '--runtime_answer=60'] argv = ['flags_test', 'extra_arg', '--runtime_answer=60']
args = self.global_FLAGS(argv) args = flags.parse_args(argv, default_config_files=[])
self.assertEqual(len(args), 3) self.assertEqual(len(args), 3)
self.assertEqual(argv, args) self.assertEqual(argv, args)
def test_runtime_and_unknown_flags(self): def test_runtime_and_unknown_flags(self):
self.assert_('runtime_answer' not in self.global_FLAGS) self.assert_('runtime_answer' not in FLAGS)
import nova.tests.runtime_flags import nova.tests.runtime_flags
self.assert_('runtime_answer' in self.global_FLAGS) self.assert_('runtime_answer' in FLAGS)
self.assertEqual(self.global_FLAGS.runtime_answer, 54) self.assertEqual(FLAGS.runtime_answer, 54)
def test_long_vs_short_flags(self): def test_long_vs_short_flags(self):
self.global_FLAGS.clear() FLAGS.clear()
self.global_FLAGS.register_cli_opt(cfg.StrOpt('duplicate_answer_long', FLAGS.register_cli_opt(cfg.StrOpt('duplicate_answer_long',
default='val', default='val',
help='desc')) help='desc'))
argv = ['flags_test', '--duplicate_answer=60', 'extra_arg'] argv = ['flags_test', '--duplicate_answer=60', 'extra_arg']
args = self.global_FLAGS(argv) args = flags.parse_args(argv, default_config_files=[])
self.assert_('duplicate_answer' not in self.global_FLAGS) self.assert_('duplicate_answer' not in FLAGS)
self.assert_(self.global_FLAGS.duplicate_answer_long, 60) self.assert_(FLAGS.duplicate_answer_long, 60)
self.global_FLAGS.clear() FLAGS.clear()
self.global_FLAGS.register_cli_opt(cfg.IntOpt('duplicate_answer', FLAGS.register_cli_opt(cfg.IntOpt('duplicate_answer',
default=60, default=60, help='desc'))
help='desc')) args = flags.parse_args(argv, default_config_files=[])
args = self.global_FLAGS(argv) self.assertEqual(FLAGS.duplicate_answer, 60)
self.assertEqual(self.global_FLAGS.duplicate_answer, 60) self.assertEqual(FLAGS.duplicate_answer_long, 'val')
self.assertEqual(self.global_FLAGS.duplicate_answer_long, 'val')
def test_flag_leak_left(self): def test_flag_leak_left(self):
self.assertEqual(FLAGS.flags_unittest, 'foo') self.assertEqual(FLAGS.flags_unittest, 'foo')
@@ -99,17 +95,3 @@ class FlagsTestCase(test.TestCase):
self.assertEqual(FLAGS.flags_unittest, 'bar') self.assertEqual(FLAGS.flags_unittest, 'bar')
FLAGS.reset() FLAGS.reset()
self.assertEqual(FLAGS.flags_unittest, 'foo') self.assertEqual(FLAGS.flags_unittest, 'foo')
def test_defaults(self):
self.FLAGS.register_opt(cfg.StrOpt('foo', default='bar', help='desc'))
self.assertEqual(self.FLAGS.foo, 'bar')
self.FLAGS.set_default('foo', 'blaa')
self.assertEqual(self.FLAGS.foo, 'blaa')
def test_templated_values(self):
self.FLAGS.register_opt(cfg.StrOpt('foo', default='foo', help='desc'))
self.FLAGS.register_opt(cfg.StrOpt('bar', default='bar', help='desc'))
self.FLAGS.register_opt(cfg.StrOpt('blaa',
default='$foo$bar', help='desc'))
self.assertEqual(self.FLAGS.blaa, 'foobar')

View File

@@ -284,27 +284,6 @@ def novadir():
return os.path.abspath(nova.__file__).split('nova/__init__.py')[0] return os.path.abspath(nova.__file__).split('nova/__init__.py')[0]
def default_cfgfile(filename='nova.conf', args=None):
if args is None:
args = sys.argv
for arg in args:
if arg.find('config-file') != -1:
return arg[arg.index('config-file') + len('config-file') + 1:]
else:
if not os.path.isabs(filename):
# turn relative filename into an absolute path
script_dir = os.path.dirname(inspect.stack()[-1][1])
filename = os.path.abspath(os.path.join(script_dir, filename))
if not os.path.exists(filename):
filename = "./nova.conf"
if not os.path.exists(filename):
filename = '/etc/nova/nova.conf'
if os.path.exists(filename):
cfgfile = '--config-file=%s' % filename
args.insert(1, cfgfile)
return filename
def debug(arg): def debug(arg):
LOG.debug(_('debug in callback: %s'), arg) LOG.debug(_('debug in callback: %s'), arg)
return arg return arg