summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xbin/clear_rabbit_queues4
-rwxr-xr-xbin/instance-usage-audit3
-rwxr-xr-xbin/nova-all3
-rwxr-xr-xbin/nova-api3
-rwxr-xr-xbin/nova-api-ec23
-rwxr-xr-xbin/nova-api-metadata3
-rwxr-xr-xbin/nova-api-os-compute3
-rwxr-xr-xbin/nova-api-os-volume3
-rwxr-xr-xbin/nova-cert3
-rwxr-xr-xbin/nova-compute3
-rwxr-xr-xbin/nova-console4
-rwxr-xr-xbin/nova-consoleauth4
-rwxr-xr-xbin/nova-dhcpbridge3
-rwxr-xr-xbin/nova-manage31
-rwxr-xr-xbin/nova-network3
-rwxr-xr-xbin/nova-objectstore3
-rwxr-xr-xbin/nova-scheduler3
-rwxr-xr-xbin/nova-volume3
-rwxr-xr-xbin/nova-xvpvncproxy4
-rw-r--r--nova/flags.py17
-rw-r--r--nova/openstack/common/cfg.py246
-rw-r--r--nova/test.py1
-rw-r--r--nova/tests/test_flags.py66
-rw-r--r--nova/utils.py21
-rwxr-xr-xtools/xenserver/vm_vdi_cleaner.py3
25 files changed, 224 insertions, 219 deletions
diff --git a/bin/clear_rabbit_queues b/bin/clear_rabbit_queues
index 37394add6..1912046b6 100755
--- a/bin/clear_rabbit_queues
+++ b/bin/clear_rabbit_queues
@@ -46,7 +46,6 @@ from nova import flags
from nova import log as logging
from nova.openstack.common import cfg
from nova import rpc
-from nova import utils
delete_exchange_opt = \
@@ -71,8 +70,7 @@ def delete_queues(queues):
x.queue_delete(q)
if __name__ == '__main__':
- utils.default_cfgfile()
- args = flags.FLAGS(sys.argv)
+ args = flags.parse_args(sys.argv)
logging.setup()
rpc.register_opts(flags.FLAGS)
delete_queues(args[1:])
diff --git a/bin/instance-usage-audit b/bin/instance-usage-audit
index 3db812bda..59fff1080 100755
--- a/bin/instance-usage-audit
+++ b/bin/instance-usage-audit
@@ -65,8 +65,7 @@ FLAGS = flags.FLAGS
if __name__ == '__main__':
rpc.register_opts(FLAGS)
admin_context = context.get_admin_context()
- utils.default_cfgfile()
- flags.FLAGS(sys.argv)
+ flags.parse_args(sys.argv)
logging.setup()
begin, end = utils.last_completed_audit_period()
print "Starting instance usage audit"
diff --git a/bin/nova-all b/bin/nova-all
index 529d98ed0..57e84b0dd 100755
--- a/bin/nova-all
+++ b/bin/nova-all
@@ -51,8 +51,7 @@ from nova.vnc import xvp_proxy
LOG = logging.getLogger('nova.all')
if __name__ == '__main__':
- utils.default_cfgfile()
- flags.FLAGS(sys.argv)
+ flags.parse_args(sys.argv)
logging.setup()
utils.monkey_patch()
servers = []
diff --git a/bin/nova-api b/bin/nova-api
index 7a601c3a6..e6779df4f 100755
--- a/bin/nova-api
+++ b/bin/nova-api
@@ -42,8 +42,7 @@ from nova import service
from nova import utils
if __name__ == '__main__':
- utils.default_cfgfile()
- flags.FLAGS(sys.argv)
+ flags.parse_args(sys.argv)
logging.setup()
utils.monkey_patch()
servers = []
diff --git a/bin/nova-api-ec2 b/bin/nova-api-ec2
index e1a1549c7..b53c9158a 100755
--- a/bin/nova-api-ec2
+++ b/bin/nova-api-ec2
@@ -38,8 +38,7 @@ from nova import service
from nova import utils
if __name__ == '__main__':
- utils.default_cfgfile()
- flags.FLAGS(sys.argv)
+ flags.parse_args(sys.argv)
logging.setup()
utils.monkey_patch()
server = service.WSGIService('ec2')
diff --git a/bin/nova-api-metadata b/bin/nova-api-metadata
index c4ca541f4..2f2ef9454 100755
--- a/bin/nova-api-metadata
+++ b/bin/nova-api-metadata
@@ -38,8 +38,7 @@ from nova import service
from nova import utils
if __name__ == '__main__':
- utils.default_cfgfile()
- flags.FLAGS(sys.argv)
+ flags.parse_args(sys.argv)
logging.setup()
utils.monkey_patch()
server = service.WSGIService('metadata')
diff --git a/bin/nova-api-os-compute b/bin/nova-api-os-compute
index 9c49815fe..75c921943 100755
--- a/bin/nova-api-os-compute
+++ b/bin/nova-api-os-compute
@@ -38,8 +38,7 @@ from nova import service
from nova import utils
if __name__ == '__main__':
- utils.default_cfgfile()
- flags.FLAGS(sys.argv)
+ flags.parse_args(sys.argv)
logging.setup()
utils.monkey_patch()
server = service.WSGIService('osapi_compute')
diff --git a/bin/nova-api-os-volume b/bin/nova-api-os-volume
index 21d5dc3de..b93fd51ae 100755
--- a/bin/nova-api-os-volume
+++ b/bin/nova-api-os-volume
@@ -38,8 +38,7 @@ from nova import service
from nova import utils
if __name__ == '__main__':
- utils.default_cfgfile()
- flags.FLAGS(sys.argv)
+ flags.parse_args(sys.argv)
logging.setup()
utils.monkey_patch()
server = service.WSGIService('osapi_volume')
diff --git a/bin/nova-cert b/bin/nova-cert
index f6a5cbbd8..a845c1055 100755
--- a/bin/nova-cert
+++ b/bin/nova-cert
@@ -38,8 +38,7 @@ from nova import service
from nova import utils
if __name__ == '__main__':
- utils.default_cfgfile()
- flags.FLAGS(sys.argv)
+ flags.parse_args(sys.argv)
logging.setup()
utils.monkey_patch()
server = service.Service.create(binary='nova-cert')
diff --git a/bin/nova-compute b/bin/nova-compute
index 8f7e9177d..bef7bce86 100755
--- a/bin/nova-compute
+++ b/bin/nova-compute
@@ -40,8 +40,7 @@ from nova import service
from nova import utils
if __name__ == '__main__':
- utils.default_cfgfile()
- flags.FLAGS(sys.argv)
+ flags.parse_args(sys.argv)
logging.setup()
utils.monkey_patch()
server = service.Service.create(binary='nova-compute')
diff --git a/bin/nova-console b/bin/nova-console
index 06e352f48..f5a760b37 100755
--- a/bin/nova-console
+++ b/bin/nova-console
@@ -36,11 +36,9 @@ if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')):
from nova import flags
from nova import log as logging
from nova import service
-from nova import utils
if __name__ == '__main__':
- utils.default_cfgfile()
- flags.FLAGS(sys.argv)
+ flags.parse_args(sys.argv)
logging.setup()
server = service.Service.create(binary='nova-console')
service.serve(server)
diff --git a/bin/nova-consoleauth b/bin/nova-consoleauth
index 9c566cb7c..71d77b285 100755
--- a/bin/nova-consoleauth
+++ b/bin/nova-consoleauth
@@ -35,12 +35,10 @@ from nova.consoleauth import manager
from nova import flags
from nova import log as logging
from nova import service
-from nova import utils
if __name__ == "__main__":
- utils.default_cfgfile()
- flags.FLAGS(sys.argv)
+ flags.parse_args(sys.argv)
logging.setup()
server = service.Service.create(binary='nova-consoleauth')
diff --git a/bin/nova-dhcpbridge b/bin/nova-dhcpbridge
index fab334bf5..c11947da2 100755
--- a/bin/nova-dhcpbridge
+++ b/bin/nova-dhcpbridge
@@ -96,8 +96,7 @@ def init_leases(network_id):
def main():
"""Parse environment and arguments and call the approproate action."""
flagfile = os.environ.get('FLAGFILE', FLAGS.dhcpbridge_flagfile)
- utils.default_cfgfile(flagfile)
- argv = FLAGS(sys.argv)
+ argv = flags.parse_args(sys.argv)
logging.setup()
rpc.register_opts(FLAGS)
diff --git a/bin/nova-manage b/bin/nova-manage
index f94497087..20326b3c4 100755
--- a/bin/nova-manage
+++ b/bin/nova-manage
@@ -87,6 +87,7 @@ from nova.db import migration
from nova import exception
from nova import flags
from nova import log as logging
+from nova.openstack.common import cfg
from nova.openstack.common import importutils
from nova import quota
from nova import rpc
@@ -1668,26 +1669,24 @@ def methods_of(obj):
def main():
"""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)
try:
- argv = FLAGS(sys.argv)
+ argv = flags.parse_args(sys.argv)
logging.setup()
- except IOError, e:
- if e.errno == errno.EACCES:
- print _('Please re-run nova-manage as root.')
- sys.exit(2)
- raise
+ except cfg.ConfigFilesNotFoundError:
+ cfgfile = FLAGS.config_file[-1] if FLAGS.config_file else None
+ 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')
+
+ print _('Please re-run nova-manage as root.')
+ sys.exit(2)
+
script_name = argv.pop(0)
if len(argv) < 1:
print _("\nOpenStack Nova version: %(version)s (%(vcs)s)\n") % \
diff --git a/bin/nova-network b/bin/nova-network
index d176eb27c..306eddafa 100755
--- a/bin/nova-network
+++ b/bin/nova-network
@@ -40,8 +40,7 @@ from nova import service
from nova import utils
if __name__ == '__main__':
- utils.default_cfgfile()
- flags.FLAGS(sys.argv)
+ flags.parse_args(sys.argv)
logging.setup()
utils.monkey_patch()
server = service.Service.create(binary='nova-network')
diff --git a/bin/nova-objectstore b/bin/nova-objectstore
index e52160c25..e9bd0f42d 100755
--- a/bin/nova-objectstore
+++ b/bin/nova-objectstore
@@ -42,8 +42,7 @@ from nova import utils
if __name__ == '__main__':
- utils.default_cfgfile()
- flags.FLAGS(sys.argv)
+ flags.parse_args(sys.argv)
logging.setup()
utils.monkey_patch()
server = s3server.get_wsgi_server()
diff --git a/bin/nova-scheduler b/bin/nova-scheduler
index 52db4de7e..fb803ab5b 100755
--- a/bin/nova-scheduler
+++ b/bin/nova-scheduler
@@ -42,8 +42,7 @@ from nova import service
from nova import utils
if __name__ == '__main__':
- utils.default_cfgfile()
- flags.FLAGS(sys.argv)
+ flags.parse_args(sys.argv)
logging.setup()
utils.monkey_patch()
server = service.Service.create(binary='nova-scheduler')
diff --git a/bin/nova-volume b/bin/nova-volume
index 1c6ffb58f..d8c13b9a6 100755
--- a/bin/nova-volume
+++ b/bin/nova-volume
@@ -40,8 +40,7 @@ from nova import service
from nova import utils
if __name__ == '__main__':
- utils.default_cfgfile()
- flags.FLAGS(sys.argv)
+ flags.parse_args(sys.argv)
logging.setup()
utils.monkey_patch()
server = service.Service.create(binary='nova-volume')
diff --git a/bin/nova-xvpvncproxy b/bin/nova-xvpvncproxy
index 9db07f148..d338d3a3e 100755
--- a/bin/nova-xvpvncproxy
+++ b/bin/nova-xvpvncproxy
@@ -35,15 +35,13 @@ from nova import flags
from nova import log as logging
from nova import rpc
from nova import service
-from nova import utils
from nova.vnc import xvp_proxy
FLAGS = flags.FLAGS
if __name__ == "__main__":
rpc.register_opts(FLAGS)
- utils.default_cfgfile()
- flags.FLAGS(sys.argv)
+ flags.parse_args(sys.argv)
logging.setup()
wsgi_server = xvp_proxy.get_wsgi_server()
diff --git a/nova/flags.py b/nova/flags.py
index 5dd95add1..34d5fc814 100644
--- a/nova/flags.py
+++ b/nova/flags.py
@@ -33,19 +33,14 @@ import sys
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):
diff --git a/nova/openstack/common/cfg.py b/nova/openstack/common/cfg.py
index 2a2d2bae4..dd367aeb6 100644
--- a/nova/openstack/common/cfg.py
+++ b/nova/openstack/common/cfg.py
@@ -95,7 +95,7 @@ and --config-dir::
class ConfigOpts(object):
- def __init__(self, ...):
+ def __call__(self, ...):
opts = [
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
@@ -768,6 +784,14 @@ class OptGroup(object):
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):
"""Build an optparse.OptionGroup for this group."""
if self._optparse_group is None:
@@ -775,6 +799,10 @@ class OptGroup(object):
self.help)
return self._optparse_group
+ def _clear(self):
+ """Clear this group's option parsing state."""
+ self._optparse_group = None
+
class ParseError(iniparser.ParseError):
def __init__(self, msg, lineno, line, filename):
@@ -849,57 +877,41 @@ class ConfigOpts(collections.Mapping):
the values of options.
"""
- def __init__(self,
- project=None,
- prog=None,
- version=None,
- usage=None,
- default_config_files=None):
- """Construct a ConfigOpts object.
+ def __init__(self):
+ """Construct a ConfigOpts object."""
+ self._opts = {} # dict of dicts of (opt:, override:, default:)
+ self._groups = {}
- Automatically registers the --config-file option with either a supplied
- list of default config files, or a list from find_config_files().
+ self._args = None
+ 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
- :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
- """
+ def _setup(self, project, prog, version, usage, default_config_files):
+ """Initialize a ConfigOpts object for option parsing."""
if prog is None:
prog = os.path.basename(sys.argv[0])
if default_config_files is None:
default_config_files = find_config_files(project, prog)
- self.project = project
- self.prog = prog
- self.version = version
- self.usage = usage
- self.default_config_files = default_config_files
-
- self._opts = {} # dict of dicts of (opt:, override:, default:)
- 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._oparser = optparse.OptionParser(prog=prog,
+ version=version,
+ usage=usage)
+ if self._disable_interspersed_args:
+ self._oparser.disable_interspersed_args()
- self.__cache = {}
-
- opts = [
+ self._config_opts = [
MultiStrOpt('config-file',
- default=self.default_config_files,
+ default=default_config_files,
metavar='PATH',
help='Path to a config file to use. Multiple config '
'files can be specified, with values in later '
'files taking precedence. The default files '
- ' used are: %s' %
- (self.default_config_files, )),
+ ' used are: %s' % (default_config_files, )),
StrOpt('config-dir',
metavar='DIR',
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 '
'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):
@functools.wraps(f)
@@ -921,7 +939,13 @@ class ConfigOpts(collections.Mapping):
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.
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
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
directory are pulled in, after all the file(s) specified by the
--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
:raises: SystemExit, ConfigFilesNotFoundError, ConfigFileParseError,
- RequiredOptError
+ RequiredOptError, DuplicateOptError
"""
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)
-
- 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._parse_config_files()
self._check_required_opts()
- return args
+ return leftovers
def __getattr__(self, name):
"""Look up an option value and perform string substitution.
@@ -996,8 +1019,12 @@ class ConfigOpts(collections.Mapping):
def clear(self):
"""Clear the state of the object to before it was called."""
self._args = None
- self._cli_values = {}
+ self._cli_values.clear()
+ self._oparser = None
self._cparser = None
+ self.unregister_opts(self._config_opts)
+ for group in self._groups.values():
+ group._clear()
@__clear_cache
def register_opt(self, opt, group=None):
@@ -1044,15 +1071,7 @@ class ConfigOpts(collections.Mapping):
if self._args is not None:
raise ArgsAlreadyParsedError("cannot register CLI option")
- if not 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
+ return self.register_opt(opt, group, clear_cache=False)
@__clear_cache
def register_cli_opts(self, opts, group=None):
@@ -1074,6 +1093,28 @@ class ConfigOpts(collections.Mapping):
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
def set_override(self, name, override, group=None):
"""Override an opt value.
@@ -1103,16 +1144,24 @@ class ConfigOpts(collections.Mapping):
opt_info = self._get_opt_info(name, group)
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):
"""Unset any default or override on all options."""
- def unset(opts):
- for info in opts.values():
- info['default'] = None
- info['override'] = None
-
- unset(self._opts)
- for group in self._groups.values():
- unset(group._opts)
+ for info, group in self._all_opt_infos():
+ info['default'] = None
+ info['override'] = None
def disable_interspersed_args(self):
"""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.
"""
- self._oparser.disable_interspersed_args()
+ self._disable_interspersed_args = True
def enable_interspersed_args(self):
"""Set parsing to not stop on the first non-option.
This it the default behaviour."""
- self._oparser.enable_interspersed_args()
+ self._disable_interspersed_args = False
def find_file(self, name):
"""Locate a file located alongside the config files.
@@ -1331,11 +1380,17 @@ class ConfigOpts(collections.Mapping):
return opts[opt_name]
- def _parse_config_files(self, config_files):
- """Parse the supplied configuration files.
+ def _parse_config_files(self):
+ """Parse the config files from --config-file and --config-dir.
: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()
try:
@@ -1347,8 +1402,12 @@ class ConfigOpts(collections.Mapping):
not_read_ok = filter(lambda f: f not in read_ok, config_files)
raise ConfigFilesNotFoundError(not_read_ok)
- def _do_check_required_opts(self, opts, group=None):
- for info in opts.values():
+ def _check_required_opts(self):
+ """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())]
if opt.required:
@@ -1359,15 +1418,25 @@ class ConfigOpts(collections.Mapping):
if self._get(opt.name, group) is None:
raise RequiredOptError(opt.name, group)
- def _check_required_opts(self):
- """Check that all opts marked as required have values specified.
+ def _parse_cli_opts(self, args):
+ """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():
- self._do_check_required_opts(group._opts, group)
+ for opt, group in self._all_opts():
+ opt._add_to_cli(self._oparser, group)
+
+ values, leftovers = self._oparser.parse_args(args)
+
+ return vars(values), leftovers
class GroupAttr(collections.Mapping):
@@ -1483,7 +1552,10 @@ class CommonConfigOpts(ConfigOpts):
help='syslog facility to receive log lines')
]
- def __init__(self, **kwargs):
- super(CommonConfigOpts, self).__init__(**kwargs)
+ def __init__(self):
+ super(CommonConfigOpts, self).__init__()
self.register_cli_opts(self.common_cli_opts)
self.register_cli_opts(self.logging_cli_opts)
+
+
+CONF = CommonConfigOpts()
diff --git a/nova/test.py b/nova/test.py
index 46ba5e49d..478eddded 100644
--- a/nova/test.py
+++ b/nova/test.py
@@ -128,6 +128,7 @@ class TestCase(unittest.TestCase):
super(TestCase, self).setUp()
fake_flags.set_defaults(FLAGS)
+ flags.parse_args([], default_config_files=[])
# NOTE(vish): We need a better method for creating fixtures for tests
# now that we have some required db setup for the system
diff --git a/nova/tests/test_flags.py b/nova/tests/test_flags.py
index af5198dc3..f1baffa0a 100644
--- a/nova/tests/test_flags.py
+++ b/nova/tests/test_flags.py
@@ -34,54 +34,50 @@ class FlagsTestCase(test.TestCase):
def setUp(self):
super(FlagsTestCase, self).setUp()
- self.FLAGS = flags.NovaConfigOpts()
- self.global_FLAGS = flags.FLAGS
- self.flags(config_file=[])
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')
- self.assert_('answer' in self.global_FLAGS)
- self.assertEqual(self.global_FLAGS.answer, 42)
+ self.assert_('answer' in FLAGS)
+ self.assertEqual(FLAGS.answer, 42)
# Make sure we don't overwrite anything
- self.global_FLAGS.set_override('answer', 256)
- self.assertEqual(self.global_FLAGS.answer, 256)
+ FLAGS.set_override('answer', 256)
+ self.assertEqual(FLAGS.answer, 256)
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):
- self.assert_('runtime_answer' not in self.global_FLAGS)
+ self.assert_('runtime_answer' not in FLAGS)
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(argv, args)
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
- self.assert_('runtime_answer' in self.global_FLAGS)
- self.assertEqual(self.global_FLAGS.runtime_answer, 54)
+ self.assert_('runtime_answer' in FLAGS)
+ self.assertEqual(FLAGS.runtime_answer, 54)
def test_long_vs_short_flags(self):
- self.global_FLAGS.clear()
- self.global_FLAGS.register_cli_opt(cfg.StrOpt('duplicate_answer_long',
- default='val',
- help='desc'))
+ FLAGS.clear()
+ FLAGS.register_cli_opt(cfg.StrOpt('duplicate_answer_long',
+ default='val',
+ help='desc'))
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_(self.global_FLAGS.duplicate_answer_long, 60)
+ self.assert_('duplicate_answer' not in FLAGS)
+ self.assert_(FLAGS.duplicate_answer_long, 60)
- self.global_FLAGS.clear()
- self.global_FLAGS.register_cli_opt(cfg.IntOpt('duplicate_answer',
- default=60,
- help='desc'))
- args = self.global_FLAGS(argv)
- self.assertEqual(self.global_FLAGS.duplicate_answer, 60)
- self.assertEqual(self.global_FLAGS.duplicate_answer_long, 'val')
+ FLAGS.clear()
+ FLAGS.register_cli_opt(cfg.IntOpt('duplicate_answer',
+ default=60, help='desc'))
+ args = flags.parse_args(argv, default_config_files=[])
+ self.assertEqual(FLAGS.duplicate_answer, 60)
+ self.assertEqual(FLAGS.duplicate_answer_long, 'val')
def test_flag_leak_left(self):
self.assertEqual(FLAGS.flags_unittest, 'foo')
@@ -99,17 +95,3 @@ class FlagsTestCase(test.TestCase):
self.assertEqual(FLAGS.flags_unittest, 'bar')
FLAGS.reset()
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')
diff --git a/nova/utils.py b/nova/utils.py
index 7bdae8deb..ae99212e9 100644
--- a/nova/utils.py
+++ b/nova/utils.py
@@ -284,27 +284,6 @@ def novadir():
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):
LOG.debug(_('debug in callback: %s'), arg)
return arg
diff --git a/tools/xenserver/vm_vdi_cleaner.py b/tools/xenserver/vm_vdi_cleaner.py
index 0e423462b..bccf50b25 100755
--- a/tools/xenserver/vm_vdi_cleaner.py
+++ b/tools/xenserver/vm_vdi_cleaner.py
@@ -40,8 +40,7 @@ FLAGS = flags.FLAGS
# flagfile. To isolate this awful practice, we're supplying a dummy
# argument list.
dummy = ["fakearg"]
-utils.default_cfgfile(args=dummy)
-FLAGS(dummy)
+flags.parse_args(dummy)
class UnrecognizedNameLabel(Exception):