X-Git-Url: https://code.grnet.gr/git/ganeti-local/blobdiff_plain/0ce212e5618e1815c51adb62037516eba1c7f0c3..62bfbc7d8137bbcda3686388f0a8414d0dc086f9:/lib/cli.py diff --git a/lib/cli.py b/lib/cli.py index bc75823..e3ec55d 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 @@ -50,6 +50,7 @@ from optparse import (OptionParser, TitledHelpFormatter, __all__ = [ # Command line options + "ABSOLUTE_OPT", "ADD_UIDS_OPT", "ALLOCATABLE_OPT", "ALLOC_POLICY_OPT", @@ -132,6 +133,7 @@ __all__ = [ "NONICS_OPT", "NONLIVE_OPT", "NONPLUS1_OPT", + "NORUNTIME_CHGS_OPT", "NOSHUTDOWN_OPT", "NOSTART_OPT", "NOSSH_KEYCHECK_OPT", @@ -158,6 +160,7 @@ __all__ = [ "REMOVE_INSTANCE_OPT", "REMOVE_UIDS_OPT", "RESERVED_LVS_OPT", + "RUNTIME_MEM_OPT", "ROMAN_OPT", "SECONDARY_IP_OPT", "SECONDARY_ONLY_OPT", @@ -171,7 +174,8 @@ __all__ = [ "SPECS_DISK_SIZE_OPT", "SPECS_MEM_SIZE_OPT", "SPECS_NIC_COUNT_OPT", - "SPECS_DISK_TEMPLATES", + "IPOLICY_DISK_TEMPLATES", + "IPOLICY_VCPU_RATIO", "SPICE_CACERT_OPT", "SPICE_CERT_OPT", "SRC_DIR_OPT", @@ -465,7 +469,7 @@ def AddTags(opts, args): if not args: raise errors.OpPrereqError("No tags to be added") op = opcodes.OpTagsSet(kind=kind, name=name, tags=args) - SubmitOpCode(op, opts=opts) + SubmitOrSend(op, opts) def RemoveTags(opts, args): @@ -482,7 +486,7 @@ def RemoveTags(opts, args): if not args: raise errors.OpPrereqError("No tags to be removed") op = opcodes.OpTagsDel(kind=kind, name=name, tags=args) - SubmitOpCode(op, opts=opts) + SubmitOrSend(op, opts) def check_unit(option, opt, value): # pylint: disable=W0613 @@ -549,7 +553,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) @@ -769,6 +775,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") @@ -804,11 +815,16 @@ SPECS_NIC_COUNT_OPT = cli_option("--specs-nic-count", dest="ispecs_nic_count", type="keyval", default={}, help="NIC count specs: min, max, std") -SPECS_DISK_TEMPLATES = cli_option("--specs-disk-templates", - dest="ispecs_disk_templates", - type="list", default=None, - help="Comma-separated list of" - " enabled disk templates") +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" @@ -1361,6 +1377,15 @@ 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="") + +ABSOLUTE_OPT = cli_option("--absolute", dest="absolute", + action="store_true", default=False, + help="Marks the grow as absolute instead of the" + " (default) relative mode") #: Options provided by all commands COMMON_OPTS = [DEBUG_OPT] @@ -1396,7 +1421,8 @@ INSTANCE_POLICY_OPTS = [ SPECS_DISK_SIZE_OPT, SPECS_MEM_SIZE_OPT, SPECS_NIC_COUNT_OPT, - SPECS_DISK_TEMPLATES, + IPOLICY_DISK_TEMPLATES, + IPOLICY_VCPU_RATIO, ] @@ -2130,15 +2156,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 = {} @@ -2157,13 +2187,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) @@ -2778,7 +2805,8 @@ def _WarnUnknownFields(fdefs): def GenericList(resource, fields, names, unit, separator, header, cl=None, - format_override=None, verbose=False, force_filter=False): + format_override=None, verbose=False, force_filter=False, + namefield=None, qfilter=None): """Generic implementation for listing all items of a resource. @param resource: One of L{constants.QR_VIA_LUXI} @@ -2801,12 +2829,22 @@ def GenericList(resource, fields, names, unit, separator, header, cl=None, indexed by field name, contents like L{_DEFAULT_FORMAT_QUERY} @type verbose: boolean @param verbose: whether to use verbose field descriptions or not + @type namefield: string + @param namefield: Name of field to use for simple filters (see + L{qlang.MakeFilter} for details) + @type qfilter: list or None + @param qfilter: Query filter (in addition to names) """ if not names: names = None - qfilter = qlang.MakeFilter(names, force_filter) + namefilter = qlang.MakeFilter(names, force_filter, namefield=namefield) + + if qfilter is None: + qfilter = namefilter + elif namefilter is not None: + qfilter = [qlang.OP_AND, namefilter, qfilter] if cl is None: cl = GetClient() @@ -2965,8 +3003,9 @@ def FormatTimestamp(ts): """ if not isinstance(ts, (tuple, list)) or len(ts) != 2: return "?" - sec, usec = ts - return time.strftime("%F %T", time.localtime(sec)) + ".%06d" % usec + + (sec, usecs) = ts + return utils.FormatTime(sec, usecs=usecs) def ParseTimespec(value):