Merge "Port nova.flags to cfg"

This commit is contained in:
Jenkins
2011-12-09 19:13:45 +00:00
committed by Gerrit Code Review

View File

@@ -19,22 +19,21 @@
"""Command-line flag library. """Command-line flag library.
Emulates gflags by wrapping optparse. Emulates gflags by wrapping cfg.ConfigOpts.
The idea is to move to optparse eventually, and this wrapper is a The idea is to move fully to cfg eventually, and this wrapper is a
stepping stone. stepping stone.
""" """
import copy
import optparse
import os import os
import socket import socket
import string
import sys import sys
import gflags import gflags
from nova.common import cfg
class FlagValues(object): class FlagValues(object):
class Flag: class Flag:
@@ -69,76 +68,50 @@ class FlagValues(object):
return filter(lambda i: i == a or i.startswith(a + "="), args)[0] return filter(lambda i: i == a or i.startswith(a + "="), args)[0]
def __init__(self): def __init__(self):
self._parser = optparse.OptionParser() self._conf = cfg.ConfigOpts()
self._parser.disable_interspersed_args() self._conf._oparser.disable_interspersed_args()
self._multistring_defaults = {} self._opts = {}
self.Reset() self.Reset()
def _apply_multistring_defaults(self, values):
#
# This horrendous hack is to stop optparse appending
# values to the default value. See:
# http://bugs.python.org/issue5088
#
for flag, default in self._multistring_defaults.items():
if not getattr(values, flag):
setattr(values, flag, default)
return values
def _parse(self): def _parse(self):
if not self._values is None: if self._extra is not None:
return return
args = gflags.FlagValues().ReadFlagsFromFiles(self._args) args = gflags.FlagValues().ReadFlagsFromFiles(self._args)
values = extra = None extra = None
#
# This horrendous hack is needed because optparse only
# shallow copies its defaults dict before parsing
#
defaults = copy.deepcopy(self._parser.defaults)
# #
# This horrendous hack allows us to stop optparse # This horrendous hack allows us to stop optparse
# exiting when it encounters an unknown option # exiting when it encounters an unknown option
# #
error_catcher = self.ErrorCatcher(self._parser.error) error_catcher = self.ErrorCatcher(self._conf._oparser.error)
self._parser.error = error_catcher.catch self._conf._oparser.error = error_catcher.catch
try: try:
while True: while True:
error_catcher.reset() error_catcher.reset()
(values, extra) = self._parser.parse_args(args) extra = self._conf(args)
unknown = error_catcher.get_unknown_arg(args) unknown = error_catcher.get_unknown_arg(args)
if not unknown: if not unknown:
break break
args.remove(unknown) args.remove(unknown)
self._parser.defaults = defaults
defaults = copy.deepcopy(defaults)
finally: finally:
self._parser.error = error_catcher.orig_error self._conf._oparser.error = error_catcher.orig_error
self._parser.defaults = defaults
values = self._apply_multistring_defaults(values) self._extra = extra
(self._values, self._extra) = (values, extra)
def __call__(self, argv): def __call__(self, argv):
self.Reset()
self._args = argv[1:] self._args = argv[1:]
self._values = None
self._parse() self._parse()
return [argv[0]] + self._extra return [argv[0]] + self._extra
def __getattr__(self, name): def __getattr__(self, name):
self._parse() self._parse()
val = getattr(self._values, name) return getattr(self._conf, name)
if type(val) is str:
tmpl = string.Template(val)
return tmpl.substitute(vars(self._values))
return val
def get(self, name, default): def get(self, name, default):
value = getattr(self, name) value = getattr(self, name)
@@ -149,11 +122,10 @@ class FlagValues(object):
def __contains__(self, name): def __contains__(self, name):
self._parse() self._parse()
return hasattr(self._values, name) return hasattr(self._conf, name)
def _update_default(self, name, default): def _update_default(self, name, default):
self._parser.set_default(name, default) self._conf.set_default(name, default)
self._values = None
def __iter__(self): def __iter__(self):
return self.FlagValuesDict().iterkeys() return self.FlagValuesDict().iterkeys()
@@ -165,55 +137,51 @@ class FlagValues(object):
return self.Flag(name, getattr(self, name), self._update_default) return self.Flag(name, getattr(self, name), self._update_default)
def Reset(self): def Reset(self):
self._conf.reset()
self._args = [] self._args = []
self._values = None
self._extra = None self._extra = None
def ParseNewFlags(self): def ParseNewFlags(self):
pass pass
def FlagValuesDict(self): def FlagValuesDict(self):
self._parse()
ret = {} ret = {}
for opt in self._parser.option_list: for opt in self._opts.values():
if opt.dest:
ret[opt.dest] = getattr(self, opt.dest) ret[opt.dest] = getattr(self, opt.dest)
return ret return ret
def _add_option(self, name, default, help, prefix='--', **kwargs): def _add_option(self, opt):
prefixed_name = prefix + name if opt.dest in self._opts:
for opt in self._parser.option_list:
if prefixed_name == opt.get_opt_string():
return return
self._parser.add_option(prefixed_name, dest=name,
default=default, help=help, **kwargs) self._opts[opt.dest] = opt
self._values = None
try:
self._conf.register_cli_opts(self._opts.values())
except cfg.ArgsAlreadyParsedError:
self._conf.reset()
self._conf.register_cli_opts(self._opts.values())
self._extra = None
def define_string(self, name, default, help): def define_string(self, name, default, help):
self._add_option(name, default, help) self._add_option(cfg.StrOpt(name, default=default, help=help))
def define_integer(self, name, default, help): def define_integer(self, name, default, help):
self._add_option(name, default, help, type='int') self._add_option(cfg.IntOpt(name, default=default, help=help))
def define_float(self, name, default, help): def define_float(self, name, default, help):
self._add_option(name, default, help, type='float') self._add_option(cfg.FloatOpt(name, default=default, help=help))
def define_bool(self, name, default, help): def define_bool(self, name, default, help):
# self._add_option(cfg.BoolOpt(name, default=default, help=help))
# FIXME(markmc): this doesn't support --boolflag=true/false/t/f/1/0
#
self._add_option(name, default, help, action='store_true')
self._add_option(name, default, help,
prefix="--no", action='store_false')
def define_list(self, name, default, help): def define_list(self, name, default, help):
def parse_list(option, opt, value, parser): self._add_option(cfg.ListOpt(name, default=default, help=help))
setattr(self._parser.values, name, value.split(','))
self._add_option(name, default, help, type='string',
action='callback', callback=parse_list)
def define_multistring(self, name, default, help): def define_multistring(self, name, default, help):
self._add_option(name, [], help, action='append') self._add_option(cfg.MultiStrOpt(name, default=default, help=help))
self._multistring_defaults[name] = default
FLAGS = FlagValues() FLAGS = FlagValues()