X-Git-Url: https://code.grnet.gr/git/ganeti-local/blobdiff_plain/5a8648eb609f7e3a8d7ad7f82e93cfdd467a8fb5..5a85b99e9085e221208b957a7fc0fe87436843f5:/lib/cli.py diff --git a/lib/cli.py b/lib/cli.py index 0e01980..eeea6ed 100644 --- a/lib/cli.py +++ b/lib/cli.py @@ -29,6 +29,7 @@ import time import logging import errno import itertools +import shlex from cStringIO import StringIO from ganeti import utils @@ -92,6 +93,7 @@ __all__ = [ "DEFAULT_IALLOCATOR_OPT", "IDENTIFY_DEFAULTS_OPT", "IGNORE_CONSIST_OPT", + "IGNORE_ERRORS_OPT", "IGNORE_FAILURES_OPT", "IGNORE_OFFLINE_OPT", "IGNORE_REMOVE_FAILURES_OPT", @@ -1262,6 +1264,11 @@ TO_GROUP_OPT = cli_option("--to", dest="to", metavar="", default=None, action="append", completion_suggest=OPT_COMPL_ONE_NODEGROUP) +IGNORE_ERRORS_OPT = cli_option("-I", "--ignore-errors", default=[], + action="append", dest="ignore_errors", + choices=list(constants.CV_ALL_ECODES_STRINGS), + help="Error code to be ignored") + #: Options provided by all commands COMMON_OPTS = [DEBUG_OPT] @@ -1291,7 +1298,7 @@ COMMON_CREATE_OPTS = [ ] -def _ParseArgs(argv, commands, aliases): +def _ParseArgs(argv, commands, aliases, env_override): """Parser for the command line arguments. This function parses the arguments and returns the function which @@ -1301,8 +1308,11 @@ def _ParseArgs(argv, commands, aliases): @param commands: dictionary with special contents, see the design doc for cmdline handling @param aliases: dictionary with command aliases {'alias': 'target, ...} + @param env_override: list of env variables allowed for default args """ + assert not (env_override - set(commands)) + if len(argv) == 0: binary = "" else: @@ -1356,13 +1366,19 @@ def _ParseArgs(argv, commands, aliases): cmd = aliases[cmd] + if cmd in env_override: + args_env_name = ("%s_%s" % (binary.replace("-", "_"), cmd)).upper() + env_args = os.environ.get(args_env_name) + if env_args: + argv = utils.InsertAtPos(argv, 1, shlex.split(env_args)) + func, args_def, parser_opts, usage, description = commands[cmd] parser = OptionParser(option_list=parser_opts + COMMON_OPTS, description=description, formatter=TitledHelpFormatter(), usage="%%prog %s %s" % (cmd, usage)) parser.disable_interspersed_args() - options, args = parser.parse_args() + options, args = parser.parse_args(args=argv[1:]) if not _CheckArguments(cmd, args_def, args): return None, None, None @@ -1996,16 +2012,18 @@ def FormatError(err): return retcode, obuf.getvalue().rstrip("\n") -def GenericMain(commands, override=None, aliases=None): +def GenericMain(commands, override=None, aliases=None, + env_override=frozenset()): """Generic main function for all the gnt-* commands. - Arguments: - - commands: a dictionary with a special structure, see the design doc - for command line handling. - - override: if not None, we expect a dictionary with keys that will - override command line options; this can be used to pass - options from the scripts to generic functions - - aliases: dictionary with command aliases {'alias': 'target, ...} + @param commands: a dictionary with a special structure, see the design doc + for command line handling. + @param override: if not None, we expect a dictionary with keys that will + override command line options; this can be used to pass + options from the scripts to generic functions + @param aliases: dictionary with command aliases {'alias': 'target, ...} + @param env_override: list of environment names which are allowed to submit + default args for commands """ # save the program name and the entire command line for later logging @@ -2024,7 +2042,7 @@ def GenericMain(commands, override=None, aliases=None): aliases = {} try: - func, options, args = _ParseArgs(sys.argv, commands, aliases) + func, options, args = _ParseArgs(sys.argv, commands, aliases, env_override) except errors.ParameterError, err: result, err_msg = FormatError(err) ToStderr(err_msg) @@ -2682,15 +2700,15 @@ def GenericList(resource, fields, names, unit, separator, header, cl=None, @param verbose: whether to use verbose field descriptions or not """ - if cl is None: - cl = GetClient() - if not names: names = None - filter_ = qlang.MakeFilter(names, force_filter) + qfilter = qlang.MakeFilter(names, force_filter) + + if cl is None: + cl = GetClient() - response = cl.Query(resource, fields, filter_) + response = cl.Query(resource, fields, qfilter) found_unknown = _WarnUnknownFields(response.fields) @@ -2919,24 +2937,24 @@ def GetOnlineNodes(nodes, cl=None, nowarn=False, secondary_ips=False, if cl is None: cl = GetClient() - filter_ = [] + qfilter = [] if nodes: - filter_.append(qlang.MakeSimpleFilter("name", nodes)) + qfilter.append(qlang.MakeSimpleFilter("name", nodes)) if nodegroup is not None: - filter_.append([qlang.OP_OR, [qlang.OP_EQUAL, "group", nodegroup], + qfilter.append([qlang.OP_OR, [qlang.OP_EQUAL, "group", nodegroup], [qlang.OP_EQUAL, "group.uuid", nodegroup]]) if filter_master: - filter_.append([qlang.OP_NOT, [qlang.OP_TRUE, "master"]]) + qfilter.append([qlang.OP_NOT, [qlang.OP_TRUE, "master"]]) - if filter_: - if len(filter_) > 1: - final_filter = [qlang.OP_AND] + filter_ + if qfilter: + if len(qfilter) > 1: + final_filter = [qlang.OP_AND] + qfilter else: - assert len(filter_) == 1 - final_filter = filter_[0] + assert len(qfilter) == 1 + final_filter = qfilter[0] else: final_filter = None