X-Git-Url: https://code.grnet.gr/git/ganeti-local/blobdiff_plain/863d7f46442636bfbc8ae6e60d43dfd44a2ee41f..91e0748c38b1b629961564362c90a29b218193b9:/lib/cli.py diff --git a/lib/cli.py b/lib/cli.py index 8065f3d..c81bf54 100644 --- a/lib/cli.py +++ b/lib/cli.py @@ -38,31 +38,87 @@ from ganeti import luxi from ganeti import ssconf from ganeti import rpc -from optparse import (OptionParser, make_option, TitledHelpFormatter, +from optparse import (OptionParser, TitledHelpFormatter, Option, OptionValueError) -__all__ = ["DEBUG_OPT", "NOHDR_OPT", "SEP_OPT", "GenericMain", - "SubmitOpCode", "GetClient", - "cli_option", - "GenerateTable", "AskUser", - "ARGS_NONE", "ARGS_FIXED", "ARGS_ATLEAST", "ARGS_ANY", "ARGS_ONE", - "USEUNITS_OPT", "FIELDS_OPT", "FORCE_OPT", "SUBMIT_OPT", - "ListTags", "AddTags", "RemoveTags", "TAG_SRC_OPT", - "FormatError", "SplitNodeOption", "SubmitOrSend", - "JobSubmittedException", "FormatTimestamp", "ParseTimespec", - "ToStderr", "ToStdout", "UsesRPC", - "GetOnlineNodes", "JobExecutor", "SYNC_OPT", "CONFIRM_OPT", - "ArgJobId", "ArgSuggest", "ArgUnknown", "ArgFile", "ArgCommand", - "ArgInstance", "ArgNode", "ArgChoice", - ] +__all__ = [ + # Command line options + "BACKEND_OPT", + "CONFIRM_OPT", + "DEBUG_OPT", + "DEBUG_SIMERR_OPT", + "DISK_TEMPLATE_OPT", + "FIELDS_OPT", + "FILESTORE_DIR_OPT", + "FILESTORE_DRIVER_OPT", + "HVLIST_OPT", + "HVOPTS_OPT", + "HYPERVISOR_OPT", + "IALLOCATOR_OPT", + "FORCE_OPT", + "NOHDR_OPT", + "NOIPCHECK_OPT", + "NONICS_OPT", + "NWSYNC_OPT", + "OS_OPT", + "SEP_OPT", + "SUBMIT_OPT", + "SYNC_OPT", + "TAG_SRC_OPT", + "USEUNITS_OPT", + "VERBOSE_OPT", + # Generic functions for CLI programs + "GenericMain", + "GetClient", + "GetOnlineNodes", + "JobExecutor", + "JobSubmittedException", + "ParseTimespec", + "SubmitOpCode", + "SubmitOrSend", + "UsesRPC", + # Formatting functions + "ToStderr", "ToStdout", + "FormatError", + "GenerateTable", + "AskUser", + "FormatTimestamp", + # Tags functions + "ListTags", + "AddTags", + "RemoveTags", + # command line options support infrastructure + "ARGS_MANY_INSTANCES", + "ARGS_MANY_NODES", + "ARGS_NONE", + "ARGS_ONE_INSTANCE", + "ARGS_ONE_NODE", + "ArgChoice", + "ArgCommand", + "ArgFile", + "ArgHost", + "ArgInstance", + "ArgJobId", + "ArgNode", + "ArgSuggest", + "ArgUnknown", + "OPT_COMPL_INST_ADD_NODES", + "OPT_COMPL_MANY_NODES", + "OPT_COMPL_ONE_IALLOCATOR", + "OPT_COMPL_ONE_INSTANCE", + "OPT_COMPL_ONE_NODE", + "OPT_COMPL_ONE_OS", + "cli_option", + "SplitNodeOption", + ] NO_PREFIX = "no_" UN_PREFIX = "-" class _Argument: - def __init__(self, min=0, max=None, suggest=None): + def __init__(self, min=0, max=None): self.min = min self.max = max @@ -130,6 +186,20 @@ class ArgCommand(_Argument): """ +class ArgHost(_Argument): + """Host argument. + + """ + + +ARGS_NONE = [] +ARGS_MANY_INSTANCES = [ArgInstance()] +ARGS_MANY_NODES = [ArgNode()] +ARGS_ONE_INSTANCE = [ArgInstance(min=1, max=1)] +ARGS_ONE_NODE = [ArgNode(min=1, max=1)] + + + def _ExtractTagsObject(opts, args): """Extract the tag type object. @@ -232,68 +302,6 @@ def RemoveTags(opts, args): SubmitOpCode(op) -DEBUG_OPT = make_option("-d", "--debug", default=False, - action="store_true", - help="Turn debugging on") - -NOHDR_OPT = make_option("--no-headers", default=False, - action="store_true", dest="no_headers", - help="Don't display column headers") - -SEP_OPT = make_option("--separator", default=None, - action="store", dest="separator", - help="Separator between output fields" - " (defaults to one space)") - -USEUNITS_OPT = make_option("--units", default=None, - dest="units", choices=('h', 'm', 'g', 't'), - help="Specify units for output (one of hmgt)") - -FIELDS_OPT = make_option("-o", "--output", dest="output", action="store", - type="string", help="Comma separated list of" - " output fields", - metavar="FIELDS") - -FORCE_OPT = make_option("-f", "--force", dest="force", action="store_true", - default=False, help="Force the operation") - -CONFIRM_OPT = make_option("--yes", dest="confirm", action="store_true", - default=False, help="Do not require confirmation") - -TAG_SRC_OPT = make_option("--from", dest="tags_source", - default=None, help="File with tag names") - -SUBMIT_OPT = make_option("--submit", dest="submit_only", - default=False, action="store_true", - help="Submit the job and return the job ID, but" - " don't wait for the job to finish") - -SYNC_OPT = make_option("--sync", dest="do_locking", - default=False, action="store_true", - help="Grab locks while doing the queries" - " in order to ensure more consistent results") - -_DRY_RUN_OPT = make_option("--dry-run", default=False, - action="store_true", - help="Do not execute the operation, just run the" - " check steps and verify it it could be executed") - - -def ARGS_FIXED(val): - """Macro-like function denoting a fixed number of arguments""" - return -val - - -def ARGS_ATLEAST(val): - """Macro-like function denoting a minimum number of arguments""" - return val - - -ARGS_NONE = None -ARGS_ONE = ARGS_FIXED(1) -ARGS_ANY = ARGS_ATLEAST(0) - - def check_unit(option, opt, value): """OptParsers custom converter for units. @@ -378,6 +386,25 @@ def check_key_val(option, opt, value): return _SplitKeyVal(opt, value) +# completion_suggestion is normally a list. Using numeric values not evaluating +# to False for dynamic completion. +(OPT_COMPL_MANY_NODES, + OPT_COMPL_ONE_NODE, + OPT_COMPL_ONE_INSTANCE, + OPT_COMPL_ONE_OS, + OPT_COMPL_ONE_IALLOCATOR, + OPT_COMPL_INST_ADD_NODES) = range(100, 106) + +OPT_COMPL_ALL = frozenset([ + OPT_COMPL_MANY_NODES, + OPT_COMPL_ONE_NODE, + OPT_COMPL_ONE_INSTANCE, + OPT_COMPL_ONE_OS, + OPT_COMPL_ONE_IALLOCATOR, + OPT_COMPL_INST_ADD_NODES, + ]) + + class CliOption(Option): """Custom option class for optparse. @@ -400,6 +427,120 @@ class CliOption(Option): cli_option = CliOption +DEBUG_OPT = cli_option("-d", "--debug", default=False, + action="store_true", + help="Turn debugging on") + +NOHDR_OPT = cli_option("--no-headers", default=False, + action="store_true", dest="no_headers", + help="Don't display column headers") + +SEP_OPT = cli_option("--separator", default=None, + action="store", dest="separator", + help=("Separator between output fields" + " (defaults to one space)")) + +USEUNITS_OPT = cli_option("--units", default=None, + dest="units", choices=('h', 'm', 'g', 't'), + help="Specify units for output (one of hmgt)") + +FIELDS_OPT = cli_option("-o", "--output", dest="output", action="store", + type="string", metavar="FIELDS", + help="Comma separated list of output fields") + +FORCE_OPT = cli_option("-f", "--force", dest="force", action="store_true", + default=False, help="Force the operation") + +CONFIRM_OPT = cli_option("--yes", dest="confirm", action="store_true", + default=False, help="Do not require confirmation") + +TAG_SRC_OPT = cli_option("--from", dest="tags_source", + default=None, help="File with tag names") + +SUBMIT_OPT = cli_option("--submit", dest="submit_only", + default=False, action="store_true", + help=("Submit the job and return the job ID, but" + " don't wait for the job to finish")) + +SYNC_OPT = cli_option("--sync", dest="do_locking", + default=False, action="store_true", + help=("Grab locks while doing the queries" + " in order to ensure more consistent results")) + +_DRY_RUN_OPT = cli_option("--dry-run", default=False, + action="store_true", + help=("Do not execute the operation, just run the" + " check steps and verify it it could be" + " executed")) + +VERBOSE_OPT = cli_option("-v", "--verbose", default=False, + action="store_true", + help="Increase the verbosity of the operation") + +DEBUG_SIMERR_OPT = cli_option("--debug-simulate-errors", default=False, + action="store_true", dest="simulate_errors", + help="Debugging option that makes the operation" + " treat most runtime checks as failed") + +NWSYNC_OPT = cli_option("--no-wait-for-sync", dest="wait_for_sync", + default=True, action="store_false", + help="Don't wait for sync (DANGEROUS!)") + +DISK_TEMPLATE_OPT = cli_option("-t", "--disk-template", dest="disk_template", + help="Custom disk setup (diskless, file," + " plain or drbd)", + default=None, metavar="TEMPL", + choices=list(constants.DISK_TEMPLATES)) + +NONICS_OPT = cli_option("--no-nics", default=False, action="store_true", + help="Do not create any network cards for" + " the instance") + +FILESTORE_DIR_OPT = cli_option("--file-storage-dir", dest="file_storage_dir", + help="Relative path under default cluster-wide" + " file storage dir to store file-based disks", + default=None, metavar="