X-Git-Url: https://code.grnet.gr/git/ganeti-local/blobdiff_plain/b6aaf437623832b6ddded9a84f1b1b8c152631c2..415feb2ee0a760e48a21a50488f6072f8afa9cff:/lib/cli.py diff --git a/lib/cli.py b/lib/cli.py index 00cb0da..87f0493 100644 --- a/lib/cli.py +++ b/lib/cli.py @@ -1,7 +1,7 @@ # # -# Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Google Inc. +# Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Google Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -132,6 +132,7 @@ __all__ = [ "NONICS_OPT", "NONLIVE_OPT", "NONPLUS1_OPT", + "NORUNTIME_CHGS_OPT", "NOSHUTDOWN_OPT", "NOSTART_OPT", "NOSSH_KEYCHECK_OPT", @@ -158,6 +159,7 @@ __all__ = [ "REMOVE_INSTANCE_OPT", "REMOVE_UIDS_OPT", "RESERVED_LVS_OPT", + "RUNTIME_MEM_OPT", "ROMAN_OPT", "SECONDARY_IP_OPT", "SECONDARY_ONLY_OPT", @@ -171,6 +173,8 @@ __all__ = [ "SPECS_DISK_SIZE_OPT", "SPECS_MEM_SIZE_OPT", "SPECS_NIC_COUNT_OPT", + "IPOLICY_DISK_TEMPLATES", + "IPOLICY_VCPU_RATIO", "SPICE_CACERT_OPT", "SPICE_CERT_OPT", "SRC_DIR_OPT", @@ -193,6 +197,7 @@ __all__ = [ "DISK_STATE_OPT", "HV_STATE_OPT", "IGNORE_IPOLICY_OPT", + "INSTANCE_POLICY_OPTS", # Generic functions for CLI programs "ConfirmOperation", "GenericMain", @@ -547,7 +552,9 @@ def check_ident_key_val(option, opt, value): # pylint: disable=W0613 msg = "Cannot pass options when removing parameter groups: %s" % value raise errors.ParameterError(msg) retval = (ident[len(NO_PREFIX):], False) - elif ident.startswith(UN_PREFIX): + elif (ident.startswith(UN_PREFIX) and + (len(ident) <= len(UN_PREFIX) or + not ident[len(UN_PREFIX)][0].isdigit())): if rest: msg = "Cannot pass options when removing parameter groups: %s" % value raise errors.ParameterError(msg) @@ -582,6 +589,18 @@ def check_bool(option, opt, value): # pylint: disable=W0613 raise errors.ParameterError("Invalid boolean value '%s'" % value) +def check_list(option, opt, value): # pylint: disable=W0613 + """Custom parser for comma-separated lists. + + """ + # we have to make this explicit check since "".split(",") is [""], + # not an empty list :( + if not value: + return [] + else: + return utils.UnescapeAndSplit(value) + + # completion_suggestion is normally a list. Using numeric values not evaluating # to False for dynamic completion. (OPT_COMPL_MANY_NODES, @@ -615,12 +634,14 @@ class CliOption(Option): "keyval", "unit", "bool", + "list", ) TYPE_CHECKER = Option.TYPE_CHECKER.copy() TYPE_CHECKER["identkeyval"] = check_ident_key_val TYPE_CHECKER["keyval"] = check_key_val TYPE_CHECKER["unit"] = check_unit TYPE_CHECKER["bool"] = check_bool + TYPE_CHECKER["list"] = check_list # optparse.py sets make_option, so we do it for our own option class, too @@ -753,6 +774,11 @@ NO_INSTALL_OPT = cli_option("--no-install", dest="no_install", help="Do not install the OS (will" " enable no-start)") +NORUNTIME_CHGS_OPT = cli_option("--no-runtime-changes", + dest="allow_runtime_chgs", + default=True, action="store_false", + help="Don't allow runtime changes") + BACKEND_OPT = cli_option("-B", "--backend-parameters", dest="beparams", type="keyval", default={}, help="Backend parameters") @@ -788,6 +814,17 @@ SPECS_NIC_COUNT_OPT = cli_option("--specs-nic-count", dest="ispecs_nic_count", type="keyval", default={}, help="NIC count specs: min, max, std") +IPOLICY_DISK_TEMPLATES = cli_option("--ipolicy-disk-templates", + dest="ipolicy_disk_templates", + type="list", default=None, + help="Comma-separated list of" + " enabled disk templates") + +IPOLICY_VCPU_RATIO = cli_option("--ipolicy-vcpu-ratio", + dest="ipolicy_vcpu_ratio", + type="float", default=None, + help="The maximum allowed vcpu-to-cpu ratio") + HYPERVISOR_OPT = cli_option("-H", "--hypervisor-parameters", dest="hypervisor", help="Hypervisor and hypervisor options, in the" " format hypervisor:option=value,option=value,...", @@ -1339,6 +1376,10 @@ IGNORE_IPOLICY_OPT = cli_option("--ignore-ipolicy", dest="ignore_ipolicy", action="store_true", default=False, help="Ignore instance policy violations") +RUNTIME_MEM_OPT = cli_option("-m", "--runtime-memory", dest="runtime_mem", + help="Sets the instance's runtime memory," + " ballooning it up or down to the new value", + default=None, type="unit", metavar="") #: Options provided by all commands COMMON_OPTS = [DEBUG_OPT] @@ -1367,6 +1408,17 @@ COMMON_CREATE_OPTS = [ PRIORITY_OPT, ] +# common instance policy options +INSTANCE_POLICY_OPTS = [ + SPECS_CPU_COUNT_OPT, + SPECS_DISK_COUNT_OPT, + SPECS_DISK_SIZE_OPT, + SPECS_MEM_SIZE_OPT, + SPECS_NIC_COUNT_OPT, + IPOLICY_DISK_TEMPLATES, + IPOLICY_VCPU_RATIO, + ] + def _ParseArgs(argv, commands, aliases, env_override): """Parser for the command line arguments. @@ -2098,15 +2150,19 @@ def GenericMain(commands, override=None, aliases=None, """ # save the program name and the entire command line for later logging if sys.argv: - binary = os.path.basename(sys.argv[0]) or sys.argv[0] + binary = os.path.basename(sys.argv[0]) + if not binary: + binary = sys.argv[0] + if len(sys.argv) >= 2: - binary += " " + sys.argv[1] - old_cmdline = " ".join(sys.argv[2:]) + logname = utils.ShellQuoteArgs([binary, sys.argv[1]]) else: - old_cmdline = "" + logname = binary + + cmdline = utils.ShellQuoteArgs([binary] + sys.argv[1:]) else: binary = "" - old_cmdline = "" + cmdline = "" if aliases is None: aliases = {} @@ -2125,13 +2181,10 @@ def GenericMain(commands, override=None, aliases=None, for key, val in override.iteritems(): setattr(options, key, val) - utils.SetupLogging(constants.LOG_COMMANDS, binary, debug=options.debug, + utils.SetupLogging(constants.LOG_COMMANDS, logname, debug=options.debug, stderr_logging=True) - if old_cmdline: - logging.info("run with arguments '%s'", old_cmdline) - else: - logging.info("run with no arguments") + logging.info("Command line: %s", cmdline) try: result = func(options, args) @@ -2309,7 +2362,8 @@ def GenericInstanceCreate(mode, opts, args): src_path=src_path, tags=tags, no_install=no_install, - identify_defaults=identify_defaults) + identify_defaults=identify_defaults, + ignore_ipolicy=opts.ignore_ipolicy) SubmitOrSend(op, opts) return 0