Merge branch 'stable-2.12' into stable-2.13
authorKlaus Aehlig <aehlig@google.com>
Thu, 22 Oct 2015 08:51:36 +0000 (10:51 +0200)
committerKlaus Aehlig <aehlig@google.com>
Thu, 22 Oct 2015 09:37:24 +0000 (11:37 +0200)
* stable-2.12
  Fix inconsistency in python and haskell objects
  Add notSerializeDefault default field option
  Move design-disks.rst to drafts

* stable-2.11
  Fix default for --default-iallocator-params

Conflicts:
doc/design-draft.rst
doc/index.rst
lib/cli.py

Resolution:
for lib/cli.py follow the code move
for the rest, take all additions.

Signed-off-by: Klaus Aehlig <aehlig@google.com>
Reviewed-by: Oleg Ponomarev <oponomarev@google.com>

1  2 
doc/design-draft.rst
lib/cli_opts.py
lib/client/gnt_cluster.py
src/Ganeti/Objects.hs
src/Ganeti/THH.hs
test/hs/Test/Ganeti/Objects.hs

@@@ -18,12 -19,8 +18,13 @@@ Design document draft
     design-os.rst
     design-move-instance-improvements.rst
     design-node-security.rst
 +   design-ifdown.rst
 +   design-location.rst
 +   design-reservations.rst
 +   design-sync-rate-throttling.rst
 +   design-network2.rst
 +   design-configlock.rst
+    design-disks.rst
  
  .. vim: set textwidth=72 :
  .. Local Variables:
diff --cc lib/cli_opts.py
index ec974cb,0000000..79de008
mode 100644,000000..100644
--- /dev/null
@@@ -1,1629 -1,0 +1,1629 @@@
 +#
 +#
 +
 +# Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Google Inc.
 +# All rights reserved.
 +#
 +# Redistribution and use in source and binary forms, with or without
 +# modification, are permitted provided that the following conditions are
 +# met:
 +#
 +# 1. Redistributions of source code must retain the above copyright notice,
 +# this list of conditions and the following disclaimer.
 +#
 +# 2. Redistributions in binary form must reproduce the above copyright
 +# notice, this list of conditions and the following disclaimer in the
 +# documentation and/or other materials provided with the distribution.
 +#
 +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 +# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
 +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 +# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 +
 +
 +"""Module containing Ganeti's command line parsing options"""
 +
 +import re
 +import simplejson
 +
 +from ganeti import utils
 +from ganeti import errors
 +from ganeti import constants
 +from ganeti import compat
 +from ganeti import pathutils
 +from ganeti import serializer
 +
 +from optparse import (Option, OptionValueError)
 +
 +
 +__all__ = [
 +  "ABSOLUTE_OPT",
 +  "ADD_RESERVED_IPS_OPT",
 +  "ADD_UIDS_OPT",
 +  "ALL_OPT",
 +  "ALLOC_POLICY_OPT",
 +  "ALLOCATABLE_OPT",
 +  "ALLOW_FAILOVER_OPT",
 +  "AUTO_PROMOTE_OPT",
 +  "AUTO_REPLACE_OPT",
 +  "BACKEND_OPT",
 +  "BLK_OS_OPT",
 +  "CAPAB_MASTER_OPT",
 +  "CAPAB_VM_OPT",
 +  "CLEANUP_OPT",
 +  "cli_option",
 +  "CLUSTER_DOMAIN_SECRET_OPT",
 +  "COMMON_CREATE_OPTS",
 +  "COMMON_OPTS",
 +  "COMPRESS_OPT",
 +  "COMPRESSION_TOOLS_OPT",
 +  "CONFIRM_OPT",
 +  "CP_SIZE_OPT",
 +  "DEBUG_OPT",
 +  "DEBUG_SIMERR_OPT",
 +  "DEFAULT_IALLOCATOR_OPT",
 +  "DEFAULT_IALLOCATOR_PARAMS_OPT",
 +  "DISK_OPT",
 +  "DISK_PARAMS_OPT",
 +  "DISK_STATE_OPT",
 +  "DISK_TEMPLATE_OPT",
 +  "DISKIDX_OPT",
 +  "DRAINED_OPT",
 +  "DRBD_HELPER_OPT",
 +  "DRY_RUN_OPT",
 +  "DST_NODE_OPT",
 +  "EARLY_RELEASE_OPT",
 +  "ENABLED_DATA_COLLECTORS_OPT",
 +  "ENABLED_DISK_TEMPLATES_OPT",
 +  "ENABLED_HV_OPT",
 +  "ENABLED_USER_SHUTDOWN_OPT",
 +  "ERROR_CODES_OPT",
 +  "EXT_PARAMS_OPT",
 +  "FAILURE_ONLY_OPT",
 +  "FIELDS_OPT",
 +  "FILESTORE_DIR_OPT",
 +  "FILESTORE_DRIVER_OPT",
 +  "FORCE_FAILOVER_OPT",
 +  "FORCE_FILTER_OPT",
 +  "FORCE_OPT",
 +  "FORCE_VARIANT_OPT",
 +  "GATEWAY6_OPT",
 +  "GATEWAY_OPT",
 +  "GLOBAL_FILEDIR_OPT",
 +  "GLOBAL_GLUSTER_FILEDIR_OPT",
 +  "GLOBAL_SHARED_FILEDIR_OPT",
 +  "HELPER_SHUTDOWN_TIMEOUT_OPT",
 +  "HELPER_STARTUP_TIMEOUT_OPT",
 +  "HID_OS_OPT",
 +  "HOTPLUG_IF_POSSIBLE_OPT",
 +  "HOTPLUG_OPT",
 +  "HV_STATE_OPT",
 +  "HVLIST_OPT",
 +  "HVOPTS_OPT",
 +  "HYPERVISOR_OPT",
 +  "IALLOCATOR_OPT",
 +  "IDENTIFY_DEFAULTS_OPT",
 +  "IGNORE_CONSIST_OPT",
 +  "IGNORE_ERRORS_OPT",
 +  "IGNORE_FAILURES_OPT",
 +  "IGNORE_HVVERSIONS_OPT",
 +  "IGNORE_IPOLICY_OPT",
 +  "IGNORE_OFFLINE_OPT",
 +  "IGNORE_REMOVE_FAILURES_OPT",
 +  "IGNORE_SECONDARIES_OPT",
 +  "IGNORE_SIZE_OPT",
 +  "INCLUDEDEFAULTS_OPT",
 +  "INSTALL_IMAGE_OPT",
 +  "INSTANCE_COMMUNICATION_NETWORK_OPT",
 +  "INSTANCE_COMMUNICATION_OPT",
 +  "INSTANCE_POLICY_OPTS",
 +  "INTERVAL_OPT",
 +  "IPOLICY_BOUNDS_SPECS_STR",
 +  "IPOLICY_DISK_TEMPLATES",
 +  "IPOLICY_SPINDLE_RATIO",
 +  "IPOLICY_STD_SPECS_OPT",
 +  "IPOLICY_STD_SPECS_STR",
 +  "IPOLICY_VCPU_RATIO",
 +  "MAC_PREFIX_OPT",
 +  "MAINTAIN_NODE_HEALTH_OPT",
 +  "MASTER_NETDEV_OPT",
 +  "MASTER_NETMASK_OPT",
 +  "MAX_TRACK_OPT",
 +  "MC_OPT",
 +  "MIGRATION_MODE_OPT",
 +  "MODIFY_ETCHOSTS_OPT",
 +  "NET_OPT",
 +  "NETWORK6_OPT",
 +  "NETWORK_OPT",
 +  "NEW_CLUSTER_CERT_OPT",
 +  "NEW_CLUSTER_DOMAIN_SECRET_OPT",
 +  "NEW_CONFD_HMAC_KEY_OPT",
 +  "NEW_NODE_CERT_OPT",
 +  "NEW_PRIMARY_OPT",
 +  "NEW_RAPI_CERT_OPT",
 +  "NEW_SECONDARY_OPT",
 +  "NEW_SPICE_CERT_OPT",
 +  "NEW_SSH_KEY_OPT",
 +  "NIC_PARAMS_OPT",
 +  "NO_INSTALL_OPT",
 +  "NO_REMEMBER_OPT",
 +  "NOCONFLICTSCHECK_OPT",
 +  "NODE_FORCE_JOIN_OPT",
 +  "NODE_LIST_OPT",
 +  "NODE_PARAMS_OPT",
 +  "NODE_PLACEMENT_OPT",
 +  "NODE_POWERED_OPT",
 +  "NODEGROUP_OPT",
 +  "NODEGROUP_OPT_NAME",
 +  "NOHDR_OPT",
 +  "NOIPCHECK_OPT",
 +  "NOMODIFY_ETCHOSTS_OPT",
 +  "NOMODIFY_SSH_SETUP_OPT",
 +  "NONAMECHECK_OPT",
 +  "NONICS_OPT",
 +  "NONLIVE_OPT",
 +  "NONPLUS1_OPT",
 +  "NORUNTIME_CHGS_OPT",
 +  "NOSHUTDOWN_OPT",
 +  "NOSSH_KEYCHECK_OPT",
 +  "NOSTART_OPT",
 +  "NOVOTING_OPT",
 +  "NWSYNC_OPT",
 +  "OFFLINE_INST_OPT",
 +  "OFFLINE_OPT",
 +  "ON_PRIMARY_OPT",
 +  "ON_SECONDARY_OPT",
 +  "ONLINE_INST_OPT",
 +  "OOB_TIMEOUT_OPT",
 +  "OPT_COMPL_ALL",
 +  "OPT_COMPL_INST_ADD_NODES",
 +  "OPT_COMPL_MANY_NODES",
 +  "OPT_COMPL_ONE_EXTSTORAGE",
 +  "OPT_COMPL_ONE_FILTER",
 +  "OPT_COMPL_ONE_IALLOCATOR",
 +  "OPT_COMPL_ONE_INSTANCE",
 +  "OPT_COMPL_ONE_NETWORK",
 +  "OPT_COMPL_ONE_NODE",
 +  "OPT_COMPL_ONE_NODEGROUP",
 +  "OPT_COMPL_ONE_OS",
 +  "OS_OPT",
 +  "OS_SIZE_OPT",
 +  "OSPARAMS_OPT",
 +  "OSPARAMS_PRIVATE_OPT",
 +  "OSPARAMS_SECRET_OPT",
 +  "POWER_DELAY_OPT",
 +  "PREALLOC_WIPE_DISKS_OPT",
 +  "PRIMARY_IP_VERSION_OPT",
 +  "PRIMARY_ONLY_OPT",
 +  "PRINT_JOBID_OPT",
 +  "PRIORITY_OPT",
 +  "RAPI_CERT_OPT",
 +  "READD_OPT",
 +  "REASON_OPT",
 +  "REBOOT_TYPE_OPT",
 +  "REMOVE_INSTANCE_OPT",
 +  "REMOVE_RESERVED_IPS_OPT",
 +  "REMOVE_UIDS_OPT",
 +  "RESERVED_LVS_OPT",
 +  "ROMAN_OPT",
 +  "RQL_OPT",
 +  "RUNTIME_MEM_OPT",
 +  "SECONDARY_IP_OPT",
 +  "SECONDARY_ONLY_OPT",
 +  "SELECT_OS_OPT",
 +  "SEP_OPT",
 +  "SEQUENTIAL_OPT",
 +  "SHOW_MACHINE_OPT",
 +  "SHOWCMD_OPT",
 +  "SHUTDOWN_TIMEOUT_OPT",
 +  "SINGLE_NODE_OPT",
 +  "SPECS_CPU_COUNT_OPT",
 +  "SPECS_DISK_COUNT_OPT",
 +  "SPECS_DISK_SIZE_OPT",
 +  "SPECS_MEM_SIZE_OPT",
 +  "SPECS_NIC_COUNT_OPT",
 +  "SPICE_CACERT_OPT",
 +  "SPICE_CERT_OPT",
 +  "SPLIT_ISPECS_OPTS",
 +  "SRC_DIR_OPT",
 +  "SRC_NODE_OPT",
 +  "STARTUP_PAUSED_OPT",
 +  "STATIC_OPT",
 +  "SUBMIT_OPT",
 +  "SUBMIT_OPTS",
 +  "SYNC_OPT",
 +  "TAG_ADD_OPT",
 +  "TAG_SRC_OPT",
 +  "TIMEOUT_OPT",
 +  "TO_GROUP_OPT",
 +  "TRANSPORT_COMPRESSION_OPT",
 +  "UIDPOOL_OPT",
 +  "USE_EXTERNAL_MIP_SCRIPT",
 +  "USE_REPL_NET_OPT",
 +  "USEUNITS_OPT",
 +  "VERBOSE_OPT",
 +  "VERIFY_CLUTTER_OPT",
 +  "VG_NAME_OPT",
 +  "WFSYNC_OPT",
 +  "YES_DOIT_OPT",
 +  "ZERO_FREE_SPACE_OPT",
 +  "ZEROING_IMAGE_OPT",
 +  "ZEROING_TIMEOUT_FIXED_OPT",
 +  "ZEROING_TIMEOUT_PER_MIB_OPT",
 +  ]
 +
 +
 +NO_PREFIX = "no_"
 +UN_PREFIX = "-"
 +
 +
 +#: Priorities (sorted)
 +_PRIORITY_NAMES = [
 +  ("low", constants.OP_PRIO_LOW),
 +  ("normal", constants.OP_PRIO_NORMAL),
 +  ("high", constants.OP_PRIO_HIGH),
 +  ]
 +
 +#: Priority dictionary for easier lookup
 +# TODO: Replace this and _PRIORITY_NAMES with a single sorted dictionary once
 +# we migrate to Python 2.6
 +_PRIONAME_TO_VALUE = dict(_PRIORITY_NAMES)
 +
 +
 +def check_unit(option, opt, value): # pylint: disable=W0613
 +  """OptParsers custom converter for units.
 +
 +  """
 +  try:
 +    return utils.ParseUnit(value)
 +  except errors.UnitParseError, err:
 +    raise OptionValueError("option %s: %s" % (opt, err))
 +
 +
 +def _SplitKeyVal(opt, data, parse_prefixes):
 +  """Convert a KeyVal string into a dict.
 +
 +  This function will convert a key=val[,...] string into a dict. Empty
 +  values will be converted specially: keys which have the prefix 'no_'
 +  will have the value=False and the prefix stripped, keys with the prefix
 +  "-" will have value=None and the prefix stripped, and the others will
 +  have value=True.
 +
 +  @type opt: string
 +  @param opt: a string holding the option name for which we process the
 +      data, used in building error messages
 +  @type data: string
 +  @param data: a string of the format key=val,key=val,...
 +  @type parse_prefixes: bool
 +  @param parse_prefixes: whether to handle prefixes specially
 +  @rtype: dict
 +  @return: {key=val, key=val}
 +  @raises errors.ParameterError: if there are duplicate keys
 +
 +  """
 +  kv_dict = {}
 +  if data:
 +    for elem in utils.UnescapeAndSplit(data, sep=","):
 +      if "=" in elem:
 +        key, val = elem.split("=", 1)
 +      elif parse_prefixes:
 +        if elem.startswith(NO_PREFIX):
 +          key, val = elem[len(NO_PREFIX):], False
 +        elif elem.startswith(UN_PREFIX):
 +          key, val = elem[len(UN_PREFIX):], None
 +        else:
 +          key, val = elem, True
 +      else:
 +        raise errors.ParameterError("Missing value for key '%s' in option %s" %
 +                                    (elem, opt))
 +      if key in kv_dict:
 +        raise errors.ParameterError("Duplicate key '%s' in option %s" %
 +                                    (key, opt))
 +      kv_dict[key] = val
 +  return kv_dict
 +
 +
 +def _SplitIdentKeyVal(opt, value, parse_prefixes):
 +  """Helper function to parse "ident:key=val,key=val" options.
 +
 +  @type opt: string
 +  @param opt: option name, used in error messages
 +  @type value: string
 +  @param value: expected to be in the format "ident:key=val,key=val,..."
 +  @type parse_prefixes: bool
 +  @param parse_prefixes: whether to handle prefixes specially (see
 +      L{_SplitKeyVal})
 +  @rtype: tuple
 +  @return: (ident, {key=val, key=val})
 +  @raises errors.ParameterError: in case of duplicates or other parsing errors
 +
 +  """
 +  if ":" not in value:
 +    ident, rest = value, ""
 +  else:
 +    ident, rest = value.split(":", 1)
 +
 +  if parse_prefixes and ident.startswith(NO_PREFIX):
 +    if rest:
 +      msg = "Cannot pass options when removing parameter groups: %s" % value
 +      raise errors.ParameterError(msg)
 +    retval = (ident[len(NO_PREFIX):], False)
 +  elif (parse_prefixes and ident.startswith(UN_PREFIX) and
 +        (len(ident) <= len(UN_PREFIX) or not ident[len(UN_PREFIX)].isdigit())):
 +    if rest:
 +      msg = "Cannot pass options when removing parameter groups: %s" % value
 +      raise errors.ParameterError(msg)
 +    retval = (ident[len(UN_PREFIX):], None)
 +  else:
 +    kv_dict = _SplitKeyVal(opt, rest, parse_prefixes)
 +    retval = (ident, kv_dict)
 +  return retval
 +
 +
 +def check_ident_key_val(option, opt, value):  # pylint: disable=W0613
 +  """Custom parser for ident:key=val,key=val options.
 +
 +  This will store the parsed values as a tuple (ident, {key: val}). As such,
 +  multiple uses of this option via action=append is possible.
 +
 +  """
 +  return _SplitIdentKeyVal(opt, value, True)
 +
 +
 +def check_key_val(option, opt, value):  # pylint: disable=W0613
 +  """Custom parser class for key=val,key=val options.
 +
 +  This will store the parsed values as a dict {key: val}.
 +
 +  """
 +  return _SplitKeyVal(opt, value, True)
 +
 +
 +def check_key_private_val(option, opt, value):  # pylint: disable=W0613
 +  """Custom parser class for private and secret key=val,key=val options.
 +
 +  This will store the parsed values as a dict {key: val}.
 +
 +  """
 +  return serializer.PrivateDict(_SplitKeyVal(opt, value, True))
 +
 +
 +def _SplitListKeyVal(opt, value):
 +  retval = {}
 +  for elem in value.split("/"):
 +    if not elem:
 +      raise errors.ParameterError("Empty section in option '%s'" % opt)
 +    (ident, valdict) = _SplitIdentKeyVal(opt, elem, False)
 +    if ident in retval:
 +      msg = ("Duplicated parameter '%s' in parsing %s: %s" %
 +             (ident, opt, elem))
 +      raise errors.ParameterError(msg)
 +    retval[ident] = valdict
 +  return retval
 +
 +
 +def check_multilist_ident_key_val(_, opt, value):
 +  """Custom parser for "ident:key=val,key=val/ident:key=val//ident:.." options.
 +
 +  @rtype: list of dictionary
 +  @return: [{ident: {key: val, key: val}, ident: {key: val}}, {ident:..}]
 +
 +  """
 +  retval = []
 +  for line in value.split("//"):
 +    retval.append(_SplitListKeyVal(opt, line))
 +  return retval
 +
 +
 +def check_bool(option, opt, value): # pylint: disable=W0613
 +  """Custom parser for yes/no options.
 +
 +  This will store the parsed value as either True or False.
 +
 +  """
 +  value = value.lower()
 +  if value == constants.VALUE_FALSE or value == "no":
 +    return False
 +  elif value == constants.VALUE_TRUE or value == "yes":
 +    return True
 +  else:
 +    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)
 +
 +
 +def check_maybefloat(option, opt, value): # pylint: disable=W0613
 +  """Custom parser for float numbers which might be also defaults.
 +
 +  """
 +  value = value.lower()
 +
 +  if value == constants.VALUE_DEFAULT:
 +    return value
 +  else:
 +    return float(value)
 +
 +
 +def check_json(option, opt, value): # pylint: disable=W0613
 +  """Custom parser for JSON arguments.
 +
 +  Takes a string containing JSON, returns a Python object.
 +
 +  """
 +  return simplejson.loads(value)
 +
 +
 +def check_filteraction(option, opt, value): # pylint: disable=W0613
 +  """Custom parser for filter rule actions.
 +
 +  Takes a string, returns an action as a Python object (list or string).
 +
 +  The string "RATE_LIMIT n" becomes `["RATE_LIMIT", n]`.
 +  All other strings stay as they are.
 +
 +  """
 +  match = re.match(r"RATE_LIMIT\s+(\d+)", value)
 +  if match:
 +    n = int(match.group(1))
 +    return ["RATE_LIMIT", n]
 +  else:
 +    return 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_EXTSTORAGE,
 + OPT_COMPL_ONE_FILTER,
 + OPT_COMPL_ONE_IALLOCATOR,
 + OPT_COMPL_ONE_NETWORK,
 + OPT_COMPL_INST_ADD_NODES,
 + OPT_COMPL_ONE_NODEGROUP) = range(100, 110)
 +
 +OPT_COMPL_ALL = compat.UniqueFrozenset([
 +  OPT_COMPL_MANY_NODES,
 +  OPT_COMPL_ONE_NODE,
 +  OPT_COMPL_ONE_INSTANCE,
 +  OPT_COMPL_ONE_OS,
 +  OPT_COMPL_ONE_EXTSTORAGE,
 +  OPT_COMPL_ONE_FILTER,
 +  OPT_COMPL_ONE_IALLOCATOR,
 +  OPT_COMPL_ONE_NETWORK,
 +  OPT_COMPL_INST_ADD_NODES,
 +  OPT_COMPL_ONE_NODEGROUP,
 +  ])
 +
 +
 +class CliOption(Option):
 +  """Custom option class for optparse.
 +
 +  """
 +  ATTRS = Option.ATTRS + [
 +    "completion_suggest",
 +    ]
 +  TYPES = Option.TYPES + (
 +    "multilistidentkeyval",
 +    "identkeyval",
 +    "keyval",
 +    "keyprivateval",
 +    "unit",
 +    "bool",
 +    "list",
 +    "maybefloat",
 +    "json",
 +    "filteraction",
 +    )
 +  TYPE_CHECKER = Option.TYPE_CHECKER.copy()
 +  TYPE_CHECKER["multilistidentkeyval"] = check_multilist_ident_key_val
 +  TYPE_CHECKER["identkeyval"] = check_ident_key_val
 +  TYPE_CHECKER["keyval"] = check_key_val
 +  TYPE_CHECKER["keyprivateval"] = check_key_private_val
 +  TYPE_CHECKER["unit"] = check_unit
 +  TYPE_CHECKER["bool"] = check_bool
 +  TYPE_CHECKER["list"] = check_list
 +  TYPE_CHECKER["maybefloat"] = check_maybefloat
 +  TYPE_CHECKER["json"] = check_json
 +  TYPE_CHECKER["filteraction"] = check_filteraction
 +
 +
 +# optparse.py sets make_option, so we do it for our own option class, too
 +cli_option = CliOption
 +
 +
 +_YORNO = "yes|no"
 +
 +DEBUG_OPT = cli_option("-d", "--debug", default=0, action="count",
 +                       help="Increase debugging level")
 +
 +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 h/m/g/t)")
 +
 +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")
 +
 +IGNORE_OFFLINE_OPT = cli_option("--ignore-offline", dest="ignore_offline",
 +                                  action="store_true", default=False,
 +                                  help=("Ignore offline nodes and do as much"
 +                                        " as possible"))
 +
 +TAG_ADD_OPT = cli_option("--tags", dest="tags",
 +                         default=None, help="Comma-separated list of instance"
 +                                            " tags")
 +
 +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"))
 +
 +PRINT_JOBID_OPT = cli_option("--print-jobid", dest="print_jobid",
 +                             default=False, action="store_true",
 +                             help=("Additionally print the job as first line"
 +                                   " on stdout (for scripting)."))
 +
 +SEQUENTIAL_OPT = cli_option("--sequential", dest="sequential",
 +                            default=False, action="store_true",
 +                            help=("Execute all resulting jobs sequentially"))
 +
 +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 if 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!)")
 +
 +WFSYNC_OPT = cli_option("--wait-for-sync", dest="wait_for_sync",
 +                        default=False, action="store_true",
 +                        help="Wait for disks to sync")
 +
 +ONLINE_INST_OPT = cli_option("--online", dest="online_inst",
 +                             action="store_true", default=False,
 +                             help="Enable offline instance")
 +
 +OFFLINE_INST_OPT = cli_option("--offline", dest="offline_inst",
 +                              action="store_true", default=False,
 +                              help="Disable down instance")
 +
 +DISK_TEMPLATE_OPT = cli_option("-t", "--disk-template", dest="disk_template",
 +                               help=("Custom disk setup (%s)" %
 +                                     utils.CommaJoin(constants.DISK_TEMPLATES)),
 +                               default=None, metavar="TEMPL",
 +                               choices=list(constants.DISK_TEMPLATES))
 +
 +EXT_PARAMS_OPT = cli_option("-e", "--ext-params", dest="ext_params",
 +                            default={}, type="keyval",
 +                            help="Parameters for ExtStorage template"
 +                            " conversions in the format:"
 +                            " provider=prvdr[,param1=val1,param2=val2,...]")
 +
 +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="<DIR>")
 +
 +FILESTORE_DRIVER_OPT = cli_option("--file-driver", dest="file_driver",
 +                                  help="Driver to use for image files",
 +                                  default=None, metavar="<DRIVER>",
 +                                  choices=list(constants.FILE_DRIVER))
 +
 +IALLOCATOR_OPT = cli_option("-I", "--iallocator", metavar="<NAME>",
 +                            help="Select nodes for the instance automatically"
 +                            " using the <NAME> iallocator plugin",
 +                            default=None, type="string",
 +                            completion_suggest=OPT_COMPL_ONE_IALLOCATOR)
 +
 +DEFAULT_IALLOCATOR_OPT = cli_option("-I", "--default-iallocator",
 +                                    metavar="<NAME>",
 +                                    help="Set the default instance"
 +                                    " allocator plugin",
 +                                    default=None, type="string",
 +                                    completion_suggest=OPT_COMPL_ONE_IALLOCATOR)
 +
 +DEFAULT_IALLOCATOR_PARAMS_OPT = cli_option("--default-iallocator-params",
 +                                           dest="default_iallocator_params",
 +                                           help="iallocator template"
 +                                           " parameters, in the format"
 +                                           " template:option=value,"
 +                                           " option=value,...",
 +                                           type="keyval",
-                                            default={})
++                                           default=None)
 +
 +OS_OPT = cli_option("-o", "--os-type", dest="os", help="What OS to run",
 +                    metavar="<os>",
 +                    completion_suggest=OPT_COMPL_ONE_OS)
 +
 +OSPARAMS_OPT = cli_option("-O", "--os-parameters", dest="osparams",
 +                          type="keyval", default={},
 +                          help="OS parameters")
 +
 +OSPARAMS_PRIVATE_OPT = cli_option("--os-parameters-private",
 +                                  dest="osparams_private",
 +                                  type="keyprivateval",
 +                                  default=serializer.PrivateDict(),
 +                                  help="Private OS parameters"
 +                                       " (won't be logged)")
 +
 +OSPARAMS_SECRET_OPT = cli_option("--os-parameters-secret",
 +                                 dest="osparams_secret",
 +                                 type="keyprivateval",
 +                                 default=serializer.PrivateDict(),
 +                                 help="Secret OS parameters (won't be logged or"
 +                                      " saved; you must supply these for every"
 +                                      " operation.)")
 +
 +FORCE_VARIANT_OPT = cli_option("--force-variant", dest="force_variant",
 +                               action="store_true", default=False,
 +                               help="Force an unknown variant")
 +
 +NO_INSTALL_OPT = cli_option("--no-install", dest="no_install",
 +                            action="store_true", default=False,
 +                            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")
 +
 +HVOPTS_OPT = cli_option("-H", "--hypervisor-parameters", type="keyval",
 +                        default={}, dest="hvparams",
 +                        help="Hypervisor parameters")
 +
 +DISK_PARAMS_OPT = cli_option("-D", "--disk-parameters", dest="diskparams",
 +                             help="Disk template parameters, in the format"
 +                             " template:option=value,option=value,...",
 +                             type="identkeyval", action="append", default=[])
 +
 +SPECS_MEM_SIZE_OPT = cli_option("--specs-mem-size", dest="ispecs_mem_size",
 +                                 type="keyval", default={},
 +                                 help="Memory size specs: list of key=value,"
 +                                " where key is one of min, max, std"
 +                                 " (in MB or using a unit)")
 +
 +SPECS_CPU_COUNT_OPT = cli_option("--specs-cpu-count", dest="ispecs_cpu_count",
 +                                 type="keyval", default={},
 +                                 help="CPU count specs: list of key=value,"
 +                                 " where key is one of min, max, std")
 +
 +SPECS_DISK_COUNT_OPT = cli_option("--specs-disk-count",
 +                                  dest="ispecs_disk_count",
 +                                  type="keyval", default={},
 +                                  help="Disk count specs: list of key=value,"
 +                                  " where key is one of min, max, std")
 +
 +SPECS_DISK_SIZE_OPT = cli_option("--specs-disk-size", dest="ispecs_disk_size",
 +                                 type="keyval", default={},
 +                                 help="Disk size specs: list of key=value,"
 +                                 " where key is one of min, max, std"
 +                                 " (in MB or using a unit)")
 +
 +SPECS_NIC_COUNT_OPT = cli_option("--specs-nic-count", dest="ispecs_nic_count",
 +                                 type="keyval", default={},
 +                                 help="NIC count specs: list of key=value,"
 +                                 " where key is one of min, max, std")
 +
 +IPOLICY_BOUNDS_SPECS_STR = "--ipolicy-bounds-specs"
 +IPOLICY_BOUNDS_SPECS_OPT = cli_option(IPOLICY_BOUNDS_SPECS_STR,
 +                                      dest="ipolicy_bounds_specs",
 +                                      type="multilistidentkeyval", default=None,
 +                                      help="Complete instance specs limits")
 +
 +IPOLICY_STD_SPECS_STR = "--ipolicy-std-specs"
 +IPOLICY_STD_SPECS_OPT = cli_option(IPOLICY_STD_SPECS_STR,
 +                                   dest="ipolicy_std_specs",
 +                                   type="keyval", default=None,
 +                                   help="Complete standard instance specs")
 +
 +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="maybefloat", default=None,
 +                                 help="The maximum allowed vcpu-to-cpu ratio")
 +
 +IPOLICY_SPINDLE_RATIO = cli_option("--ipolicy-spindle-ratio",
 +                                   dest="ipolicy_spindle_ratio",
 +                                   type="maybefloat", default=None,
 +                                   help=("The maximum allowed instances to"
 +                                         " spindle ratio"))
 +
 +HYPERVISOR_OPT = cli_option("-H", "--hypervisor-parameters", dest="hypervisor",
 +                            help="Hypervisor and hypervisor options, in the"
 +                            " format hypervisor:option=value,option=value,...",
 +                            default=None, type="identkeyval")
 +
 +HVLIST_OPT = cli_option("-H", "--hypervisor-parameters", dest="hvparams",
 +                        help="Hypervisor and hypervisor options, in the"
 +                        " format hypervisor:option=value,option=value,...",
 +                        default=[], action="append", type="identkeyval")
 +
 +NOIPCHECK_OPT = cli_option("--no-ip-check", dest="ip_check", default=True,
 +                           action="store_false",
 +                           help="Don't check that the instance's IP"
 +                           " is alive")
 +
 +NONAMECHECK_OPT = cli_option("--no-name-check", dest="name_check",
 +                             default=True, action="store_false",
 +                             help="Don't check that the instance's name"
 +                             " is resolvable")
 +
 +NET_OPT = cli_option("--net",
 +                     help="NIC parameters", default=[],
 +                     dest="nics", action="append", type="identkeyval")
 +
 +DISK_OPT = cli_option("--disk", help="Disk parameters", default=[],
 +                      dest="disks", action="append", type="identkeyval")
 +
 +DISKIDX_OPT = cli_option("--disks", dest="disks", default=None,
 +                         help="Comma-separated list of disks"
 +                         " indices to act on (e.g. 0,2) (optional,"
 +                         " defaults to all disks)")
 +
 +OS_SIZE_OPT = cli_option("-s", "--os-size", dest="sd_size",
 +                         help="Enforces a single-disk configuration using the"
 +                         " given disk size, in MiB unless a suffix is used",
 +                         default=None, type="unit", metavar="<size>")
 +
 +IGNORE_CONSIST_OPT = cli_option("--ignore-consistency",
 +                                dest="ignore_consistency",
 +                                action="store_true", default=False,
 +                                help="Ignore the consistency of the disks on"
 +                                " the secondary")
 +
 +IGNORE_HVVERSIONS_OPT = cli_option("--ignore-hvversions",
 +                                   dest="ignore_hvversions",
 +                                   action="store_true", default=False,
 +                                   help="Ignore imcompatible hypervisor"
 +                                   " versions between source and target")
 +
 +ALLOW_FAILOVER_OPT = cli_option("--allow-failover",
 +                                dest="allow_failover",
 +                                action="store_true", default=False,
 +                                help="If migration is not possible fallback to"
 +                                     " failover")
 +
 +FORCE_FAILOVER_OPT = cli_option("--force-failover",
 +                                dest="force_failover",
 +                                action="store_true", default=False,
 +                                help="Do not use migration, always use"
 +                                     " failover")
 +
 +NONLIVE_OPT = cli_option("--non-live", dest="live",
 +                         default=True, action="store_false",
 +                         help="Do a non-live migration (this usually means"
 +                         " freeze the instance, save the state, transfer and"
 +                         " only then resume running on the secondary node)")
 +
 +MIGRATION_MODE_OPT = cli_option("--migration-mode", dest="migration_mode",
 +                                default=None,
 +                                choices=list(constants.HT_MIGRATION_MODES),
 +                                help="Override default migration mode (choose"
 +                                " either live or non-live")
 +
 +NODE_PLACEMENT_OPT = cli_option("-n", "--node", dest="node",
 +                                help="Target node and optional secondary node",
 +                                metavar="<pnode>[:<snode>]",
 +                                completion_suggest=OPT_COMPL_INST_ADD_NODES)
 +
 +NODE_LIST_OPT = cli_option("-n", "--node", dest="nodes", default=[],
 +                           action="append", metavar="<node>",
 +                           help="Use only this node (can be used multiple"
 +                           " times, if not given defaults to all nodes)",
 +                           completion_suggest=OPT_COMPL_ONE_NODE)
 +
 +NODEGROUP_OPT_NAME = "--node-group"
 +NODEGROUP_OPT = cli_option("-g", NODEGROUP_OPT_NAME,
 +                           dest="nodegroup",
 +                           help="Node group (name or uuid)",
 +                           metavar="<nodegroup>",
 +                           default=None, type="string",
 +                           completion_suggest=OPT_COMPL_ONE_NODEGROUP)
 +
 +SINGLE_NODE_OPT = cli_option("-n", "--node", dest="node", help="Target node",
 +                             metavar="<node>",
 +                             completion_suggest=OPT_COMPL_ONE_NODE)
 +
 +NOSTART_OPT = cli_option("--no-start", dest="start", default=True,
 +                         action="store_false",
 +                         help="Don't start the instance after creation")
 +
 +SHOWCMD_OPT = cli_option("--show-cmd", dest="show_command",
 +                         action="store_true", default=False,
 +                         help="Show command instead of executing it")
 +
 +CLEANUP_OPT = cli_option("--cleanup", dest="cleanup",
 +                         default=False, action="store_true",
 +                         help="Instead of performing the migration/failover,"
 +                         " try to recover from a failed cleanup. This is safe"
 +                         " to run even if the instance is healthy, but it"
 +                         " will create extra replication traffic and "
 +                         " disrupt briefly the replication (like during the"
 +                         " migration/failover")
 +
 +STATIC_OPT = cli_option("-s", "--static", dest="static",
 +                        action="store_true", default=False,
 +                        help="Only show configuration data, not runtime data")
 +
 +ALL_OPT = cli_option("--all", dest="show_all",
 +                     default=False, action="store_true",
 +                     help="Show info on all instances on the cluster."
 +                     " This can take a long time to run, use wisely")
 +
 +SELECT_OS_OPT = cli_option("--select-os", dest="select_os",
 +                           action="store_true", default=False,
 +                           help="Interactive OS reinstall, lists available"
 +                           " OS templates for selection")
 +
 +IGNORE_FAILURES_OPT = cli_option("--ignore-failures", dest="ignore_failures",
 +                                 action="store_true", default=False,
 +                                 help="Remove the instance from the cluster"
 +                                 " configuration even if there are failures"
 +                                 " during the removal process")
 +
 +IGNORE_REMOVE_FAILURES_OPT = cli_option("--ignore-remove-failures",
 +                                        dest="ignore_remove_failures",
 +                                        action="store_true", default=False,
 +                                        help="Remove the instance from the"
 +                                        " cluster configuration even if there"
 +                                        " are failures during the removal"
 +                                        " process")
 +
 +REMOVE_INSTANCE_OPT = cli_option("--remove-instance", dest="remove_instance",
 +                                 action="store_true", default=False,
 +                                 help="Remove the instance from the cluster")
 +
 +DST_NODE_OPT = cli_option("-n", "--target-node", dest="dst_node",
 +                               help="Specifies the new node for the instance",
 +                               metavar="NODE", default=None,
 +                               completion_suggest=OPT_COMPL_ONE_NODE)
 +
 +NEW_SECONDARY_OPT = cli_option("-n", "--new-secondary", dest="dst_node",
 +                               help="Specifies the new secondary node",
 +                               metavar="NODE", default=None,
 +                               completion_suggest=OPT_COMPL_ONE_NODE)
 +
 +NEW_PRIMARY_OPT = cli_option("--new-primary", dest="new_primary_node",
 +                             help="Specifies the new primary node",
 +                             metavar="<node>", default=None,
 +                             completion_suggest=OPT_COMPL_ONE_NODE)
 +
 +ON_PRIMARY_OPT = cli_option("-p", "--on-primary", dest="on_primary",
 +                            default=False, action="store_true",
 +                            help="Replace the disk(s) on the primary"
 +                                 " node (applies only to internally mirrored"
 +                                 " disk templates, e.g. %s)" %
 +                                 utils.CommaJoin(constants.DTS_INT_MIRROR))
 +
 +ON_SECONDARY_OPT = cli_option("-s", "--on-secondary", dest="on_secondary",
 +                              default=False, action="store_true",
 +                              help="Replace the disk(s) on the secondary"
 +                                   " node (applies only to internally mirrored"
 +                                   " disk templates, e.g. %s)" %
 +                                   utils.CommaJoin(constants.DTS_INT_MIRROR))
 +
 +AUTO_PROMOTE_OPT = cli_option("--auto-promote", dest="auto_promote",
 +                              default=False, action="store_true",
 +                              help="Lock all nodes and auto-promote as needed"
 +                              " to MC status")
 +
 +AUTO_REPLACE_OPT = cli_option("-a", "--auto", dest="auto",
 +                              default=False, action="store_true",
 +                              help="Automatically replace faulty disks"
 +                                   " (applies only to internally mirrored"
 +                                   " disk templates, e.g. %s)" %
 +                                   utils.CommaJoin(constants.DTS_INT_MIRROR))
 +
 +IGNORE_SIZE_OPT = cli_option("--ignore-size", dest="ignore_size",
 +                             default=False, action="store_true",
 +                             help="Ignore current recorded size"
 +                             " (useful for forcing activation when"
 +                             " the recorded size is wrong)")
 +
 +SRC_NODE_OPT = cli_option("--src-node", dest="src_node", help="Source node",
 +                          metavar="<node>",
 +                          completion_suggest=OPT_COMPL_ONE_NODE)
 +
 +SRC_DIR_OPT = cli_option("--src-dir", dest="src_dir", help="Source directory",
 +                         metavar="<dir>")
 +
 +SECONDARY_IP_OPT = cli_option("-s", "--secondary-ip", dest="secondary_ip",
 +                              help="Specify the secondary ip for the node",
 +                              metavar="ADDRESS", default=None)
 +
 +READD_OPT = cli_option("--readd", dest="readd",
 +                       default=False, action="store_true",
 +                       help="Readd old node after replacing it")
 +
 +NOSSH_KEYCHECK_OPT = cli_option("--no-ssh-key-check", dest="ssh_key_check",
 +                                default=True, action="store_false",
 +                                help="Disable SSH key fingerprint checking")
 +
 +NODE_FORCE_JOIN_OPT = cli_option("--force-join", dest="force_join",
 +                                 default=False, action="store_true",
 +                                 help="Force the joining of a node")
 +
 +MC_OPT = cli_option("-C", "--master-candidate", dest="master_candidate",
 +                    type="bool", default=None, metavar=_YORNO,
 +                    help="Set the master_candidate flag on the node")
 +
 +OFFLINE_OPT = cli_option("-O", "--offline", dest="offline", metavar=_YORNO,
 +                         type="bool", default=None,
 +                         help=("Set the offline flag on the node"
 +                               " (cluster does not communicate with offline"
 +                               " nodes)"))
 +
 +DRAINED_OPT = cli_option("-D", "--drained", dest="drained", metavar=_YORNO,
 +                         type="bool", default=None,
 +                         help=("Set the drained flag on the node"
 +                               " (excluded from allocation operations)"))
 +
 +CAPAB_MASTER_OPT = cli_option("--master-capable", dest="master_capable",
 +                              type="bool", default=None, metavar=_YORNO,
 +                              help="Set the master_capable flag on the node")
 +
 +CAPAB_VM_OPT = cli_option("--vm-capable", dest="vm_capable",
 +                          type="bool", default=None, metavar=_YORNO,
 +                          help="Set the vm_capable flag on the node")
 +
 +ALLOCATABLE_OPT = cli_option("--allocatable", dest="allocatable",
 +                             type="bool", default=None, metavar=_YORNO,
 +                             help="Set the allocatable flag on a volume")
 +
 +ENABLED_HV_OPT = cli_option("--enabled-hypervisors",
 +                            dest="enabled_hypervisors",
 +                            help="Comma-separated list of hypervisors",
 +                            type="string", default=None)
 +
 +ENABLED_DISK_TEMPLATES_OPT = cli_option("--enabled-disk-templates",
 +                                        dest="enabled_disk_templates",
 +                                        help="Comma-separated list of "
 +                                             "disk templates",
 +                                        type="string", default=None)
 +
 +ENABLED_USER_SHUTDOWN_OPT = cli_option("--user-shutdown",
 +                                       default=None,
 +                                       dest="enabled_user_shutdown",
 +                                       help="Whether user shutdown is enabled",
 +                                       type="bool")
 +
 +NIC_PARAMS_OPT = cli_option("-N", "--nic-parameters", dest="nicparams",
 +                            type="keyval", default={},
 +                            help="NIC parameters")
 +
 +CP_SIZE_OPT = cli_option("-C", "--candidate-pool-size", default=None,
 +                         dest="candidate_pool_size", type="int",
 +                         help="Set the candidate pool size")
 +
 +RQL_OPT = cli_option("--max-running-jobs", dest="max_running_jobs",
 +                     type="int", help="Set the maximal number of jobs to "
 +                                      "run simultaneously")
 +
 +MAX_TRACK_OPT = cli_option("--max-tracked-jobs", dest="max_tracked_jobs",
 +                           type="int", help="Set the maximal number of jobs to "
 +                                            "be tracked simultaneously for "
 +                                            "scheduling")
 +
 +COMPRESSION_TOOLS_OPT = \
 +    cli_option("--compression-tools",
 +               dest="compression_tools", type="string", default=None,
 +               help="Comma-separated list of compression tools which are"
 +                    " allowed to be used by Ganeti in various operations")
 +
 +VG_NAME_OPT = cli_option("--vg-name", dest="vg_name",
 +                         help=("Enables LVM and specifies the volume group"
 +                               " name (cluster-wide) for disk allocation"
 +                               " [%s]" % constants.DEFAULT_VG),
 +                         metavar="VG", default=None)
 +
 +YES_DOIT_OPT = cli_option("--yes-do-it", "--ya-rly", dest="yes_do_it",
 +                          help="Destroy cluster", action="store_true")
 +
 +NOVOTING_OPT = cli_option("--no-voting", dest="no_voting",
 +                          help="Skip node agreement check (dangerous)",
 +                          action="store_true", default=False)
 +
 +MAC_PREFIX_OPT = cli_option("-m", "--mac-prefix", dest="mac_prefix",
 +                            help="Specify the mac prefix for the instance IP"
 +                            " addresses, in the format XX:XX:XX",
 +                            metavar="PREFIX",
 +                            default=None)
 +
 +MASTER_NETDEV_OPT = cli_option("--master-netdev", dest="master_netdev",
 +                               help="Specify the node interface (cluster-wide)"
 +                               " on which the master IP address will be added"
 +                               " (cluster init default: %s)" %
 +                               constants.DEFAULT_BRIDGE,
 +                               metavar="NETDEV",
 +                               default=None)
 +
 +MASTER_NETMASK_OPT = cli_option("--master-netmask", dest="master_netmask",
 +                                help="Specify the netmask of the master IP",
 +                                metavar="NETMASK",
 +                                default=None)
 +
 +USE_EXTERNAL_MIP_SCRIPT = cli_option("--use-external-mip-script",
 +                                     dest="use_external_mip_script",
 +                                     help="Specify whether to run a"
 +                                     " user-provided script for the master"
 +                                     " IP address turnup and"
 +                                     " turndown operations",
 +                                     type="bool", metavar=_YORNO, default=None)
 +
 +GLOBAL_FILEDIR_OPT = cli_option("--file-storage-dir", dest="file_storage_dir",
 +                                help="Specify the default directory (cluster-"
 +                                "wide) for storing the file-based disks [%s]" %
 +                                pathutils.DEFAULT_FILE_STORAGE_DIR,
 +                                metavar="DIR",
 +                                default=None)
 +
 +GLOBAL_SHARED_FILEDIR_OPT = cli_option(
 +  "--shared-file-storage-dir",
 +  dest="shared_file_storage_dir",
 +  help="Specify the default directory (cluster-wide) for storing the"
 +  " shared file-based disks [%s]" %
 +  pathutils.DEFAULT_SHARED_FILE_STORAGE_DIR,
 +  metavar="SHAREDDIR", default=None)
 +
 +GLOBAL_GLUSTER_FILEDIR_OPT = cli_option(
 +  "--gluster-storage-dir",
 +  dest="gluster_storage_dir",
 +  help="Specify the default directory (cluster-wide) for mounting Gluster"
 +  " file systems [%s]" %
 +  pathutils.DEFAULT_GLUSTER_STORAGE_DIR,
 +  metavar="GLUSTERDIR",
 +  default=pathutils.DEFAULT_GLUSTER_STORAGE_DIR)
 +
 +NOMODIFY_ETCHOSTS_OPT = cli_option("--no-etc-hosts", dest="modify_etc_hosts",
 +                                   help="Don't modify %s" % pathutils.ETC_HOSTS,
 +                                   action="store_false", default=True)
 +
 +MODIFY_ETCHOSTS_OPT = \
 + cli_option("--modify-etc-hosts", dest="modify_etc_hosts", metavar=_YORNO,
 +            default=None, type="bool",
 +            help="Defines whether the cluster should autonomously modify"
 +            " and keep in sync the /etc/hosts file of the nodes")
 +
 +NOMODIFY_SSH_SETUP_OPT = cli_option("--no-ssh-init", dest="modify_ssh_setup",
 +                                    help="Don't initialize SSH keys",
 +                                    action="store_false", default=True)
 +
 +ERROR_CODES_OPT = cli_option("--error-codes", dest="error_codes",
 +                             help="Enable parseable error messages",
 +                             action="store_true", default=False)
 +
 +NONPLUS1_OPT = cli_option("--no-nplus1-mem", dest="skip_nplusone_mem",
 +                          help="Skip N+1 memory redundancy tests",
 +                          action="store_true", default=False)
 +
 +REBOOT_TYPE_OPT = cli_option("-t", "--type", dest="reboot_type",
 +                             help="Type of reboot: soft/hard/full",
 +                             default=constants.INSTANCE_REBOOT_HARD,
 +                             metavar="<REBOOT>",
 +                             choices=list(constants.REBOOT_TYPES))
 +
 +IGNORE_SECONDARIES_OPT = cli_option("--ignore-secondaries",
 +                                    dest="ignore_secondaries",
 +                                    default=False, action="store_true",
 +                                    help="Ignore errors from secondaries")
 +
 +NOSHUTDOWN_OPT = cli_option("--noshutdown", dest="shutdown",
 +                            action="store_false", default=True,
 +                            help="Don't shutdown the instance (unsafe)")
 +
 +TIMEOUT_OPT = cli_option("--timeout", dest="timeout", type="int",
 +                         default=constants.DEFAULT_SHUTDOWN_TIMEOUT,
 +                         help="Maximum time to wait")
 +
 +COMPRESS_OPT = cli_option("--compress", dest="compress",
 +                          type="string", default=constants.IEC_NONE,
 +                          help="The compression mode to use")
 +
 +TRANSPORT_COMPRESSION_OPT = \
 +    cli_option("--transport-compression", dest="transport_compression",
 +               type="string", default=constants.IEC_NONE,
 +               help="The compression mode to use during transport")
 +
 +SHUTDOWN_TIMEOUT_OPT = cli_option("--shutdown-timeout",
 +                                  dest="shutdown_timeout", type="int",
 +                                  default=constants.DEFAULT_SHUTDOWN_TIMEOUT,
 +                                  help="Maximum time to wait for instance"
 +                                  " shutdown")
 +
 +INTERVAL_OPT = cli_option("--interval", dest="interval", type="int",
 +                          default=None,
 +                          help=("Number of seconds between repetions of the"
 +                                " command"))
 +
 +EARLY_RELEASE_OPT = cli_option("--early-release",
 +                               dest="early_release", default=False,
 +                               action="store_true",
 +                               help="Release the locks on the secondary"
 +                               " node(s) early")
 +
 +NEW_CLUSTER_CERT_OPT = cli_option("--new-cluster-certificate",
 +                                  dest="new_cluster_cert",
 +                                  default=False, action="store_true",
 +                                  help="Generate a new cluster certificate")
 +
 +NEW_NODE_CERT_OPT = cli_option(
 +  "--new-node-certificates", dest="new_node_cert", default=False,
 +  action="store_true", help="Generate new node certificates (for all nodes)")
 +
 +NEW_SSH_KEY_OPT = cli_option(
 +  "--new-ssh-keys", dest="new_ssh_keys", default=False,
 +  action="store_true", help="Generate new node SSH keys (for all nodes)")
 +
 +RAPI_CERT_OPT = cli_option("--rapi-certificate", dest="rapi_cert",
 +                           default=None,
 +                           help="File containing new RAPI certificate")
 +
 +NEW_RAPI_CERT_OPT = cli_option("--new-rapi-certificate", dest="new_rapi_cert",
 +                               default=None, action="store_true",
 +                               help=("Generate a new self-signed RAPI"
 +                                     " certificate"))
 +
 +SPICE_CERT_OPT = cli_option("--spice-certificate", dest="spice_cert",
 +                            default=None,
 +                            help="File containing new SPICE certificate")
 +
 +SPICE_CACERT_OPT = cli_option("--spice-ca-certificate", dest="spice_cacert",
 +                              default=None,
 +                              help="File containing the certificate of the CA"
 +                              " which signed the SPICE certificate")
 +
 +NEW_SPICE_CERT_OPT = cli_option("--new-spice-certificate",
 +                                dest="new_spice_cert", default=None,
 +                                action="store_true",
 +                                help=("Generate a new self-signed SPICE"
 +                                      " certificate"))
 +
 +NEW_CONFD_HMAC_KEY_OPT = cli_option("--new-confd-hmac-key",
 +                                    dest="new_confd_hmac_key",
 +                                    default=False, action="store_true",
 +                                    help=("Create a new HMAC key for %s" %
 +                                          constants.CONFD))
 +
 +CLUSTER_DOMAIN_SECRET_OPT = cli_option("--cluster-domain-secret",
 +                                       dest="cluster_domain_secret",
 +                                       default=None,
 +                                       help=("Load new new cluster domain"
 +                                             " secret from file"))
 +
 +NEW_CLUSTER_DOMAIN_SECRET_OPT = cli_option("--new-cluster-domain-secret",
 +                                           dest="new_cluster_domain_secret",
 +                                           default=False, action="store_true",
 +                                           help=("Create a new cluster domain"
 +                                                 " secret"))
 +
 +USE_REPL_NET_OPT = cli_option("--use-replication-network",
 +                              dest="use_replication_network",
 +                              help="Whether to use the replication network"
 +                              " for talking to the nodes",
 +                              action="store_true", default=False)
 +
 +MAINTAIN_NODE_HEALTH_OPT = \
 +    cli_option("--maintain-node-health", dest="maintain_node_health",
 +               metavar=_YORNO, default=None, type="bool",
 +               help="Configure the cluster to automatically maintain node"
 +               " health, by shutting down unknown instances, shutting down"
 +               " unknown DRBD devices, etc.")
 +
 +IDENTIFY_DEFAULTS_OPT = \
 +    cli_option("--identify-defaults", dest="identify_defaults",
 +               default=False, action="store_true",
 +               help="Identify which saved instance parameters are equal to"
 +               " the current cluster defaults and set them as such, instead"
 +               " of marking them as overridden")
 +
 +UIDPOOL_OPT = cli_option("--uid-pool", default=None,
 +                         action="store", dest="uid_pool",
 +                         help=("A list of user-ids or user-id"
 +                               " ranges separated by commas"))
 +
 +ADD_UIDS_OPT = cli_option("--add-uids", default=None,
 +                          action="store", dest="add_uids",
 +                          help=("A list of user-ids or user-id"
 +                                " ranges separated by commas, to be"
 +                                " added to the user-id pool"))
 +
 +REMOVE_UIDS_OPT = cli_option("--remove-uids", default=None,
 +                             action="store", dest="remove_uids",
 +                             help=("A list of user-ids or user-id"
 +                                   " ranges separated by commas, to be"
 +                                   " removed from the user-id pool"))
 +
 +RESERVED_LVS_OPT = cli_option("--reserved-lvs", default=None,
 +                              action="store", dest="reserved_lvs",
 +                              help=("A comma-separated list of reserved"
 +                                    " logical volumes names, that will be"
 +                                    " ignored by cluster verify"))
 +
 +ROMAN_OPT = cli_option("--roman",
 +                       dest="roman_integers", default=False,
 +                       action="store_true",
 +                       help="Use roman numbers for positive integers")
 +
 +DRBD_HELPER_OPT = cli_option("--drbd-usermode-helper", dest="drbd_helper",
 +                             action="store", default=None,
 +                             help="Specifies usermode helper for DRBD")
 +
 +PRIMARY_IP_VERSION_OPT = \
 +    cli_option("--primary-ip-version", default=constants.IP4_VERSION,
 +               action="store", dest="primary_ip_version",
 +               metavar="%d|%d" % (constants.IP4_VERSION,
 +                                  constants.IP6_VERSION),
 +               help="Cluster-wide IP version for primary IP")
 +
 +SHOW_MACHINE_OPT = cli_option("-M", "--show-machine-names", default=False,
 +                              action="store_true",
 +                              help="Show machine name for every line in output")
 +
 +FAILURE_ONLY_OPT = cli_option("--failure-only", default=False,
 +                              action="store_true",
 +                              help=("Hide successful results and show failures"
 +                                    " only (determined by the exit code)"))
 +
 +REASON_OPT = cli_option("--reason", default=[],
 +                        help="The reason for executing the command")
 +
 +
 +def _PriorityOptionCb(option, _, value, parser):
 +  """Callback for processing C{--priority} option.
 +
 +  """
 +  value = _PRIONAME_TO_VALUE[value]
 +
 +  setattr(parser.values, option.dest, value)
 +
 +
 +PRIORITY_OPT = cli_option("--priority", default=None, dest="priority",
 +                          metavar="|".join(name for name, _ in _PRIORITY_NAMES),
 +                          choices=_PRIONAME_TO_VALUE.keys(),
 +                          action="callback", type="choice",
 +                          callback=_PriorityOptionCb,
 +                          help="Priority for opcode processing")
 +
 +OPPORTUNISTIC_OPT = cli_option("--opportunistic-locking",
 +                               dest="opportunistic_locking",
 +                               action="store_true", default=False,
 +                               help="Opportunistically acquire locks")
 +
 +HID_OS_OPT = cli_option("--hidden", dest="hidden",
 +                        type="bool", default=None, metavar=_YORNO,
 +                        help="Sets the hidden flag on the OS")
 +
 +BLK_OS_OPT = cli_option("--blacklisted", dest="blacklisted",
 +                        type="bool", default=None, metavar=_YORNO,
 +                        help="Sets the blacklisted flag on the OS")
 +
 +PREALLOC_WIPE_DISKS_OPT = cli_option("--prealloc-wipe-disks", default=None,
 +                                     type="bool", metavar=_YORNO,
 +                                     dest="prealloc_wipe_disks",
 +                                     help=("Wipe disks prior to instance"
 +                                           " creation"))
 +
 +NODE_PARAMS_OPT = cli_option("--node-parameters", dest="ndparams",
 +                             type="keyval", default=None,
 +                             help="Node parameters")
 +
 +ALLOC_POLICY_OPT = cli_option("--alloc-policy", dest="alloc_policy",
 +                              action="store", metavar="POLICY", default=None,
 +                              help="Allocation policy for the node group")
 +
 +NODE_POWERED_OPT = cli_option("--node-powered", default=None,
 +                              type="bool", metavar=_YORNO,
 +                              dest="node_powered",
 +                              help="Specify if the SoR for node is powered")
 +
 +OOB_TIMEOUT_OPT = cli_option("--oob-timeout", dest="oob_timeout", type="int",
 +                             default=constants.OOB_TIMEOUT,
 +                             help="Maximum time to wait for out-of-band helper")
 +
 +POWER_DELAY_OPT = cli_option("--power-delay", dest="power_delay", type="float",
 +                             default=constants.OOB_POWER_DELAY,
 +                             help="Time in seconds to wait between power-ons")
 +
 +FORCE_FILTER_OPT = cli_option("-F", "--filter", dest="force_filter",
 +                              action="store_true", default=False,
 +                              help=("Whether command argument should be treated"
 +                                    " as filter"))
 +
 +NO_REMEMBER_OPT = cli_option("--no-remember",
 +                             dest="no_remember",
 +                             action="store_true", default=False,
 +                             help="Perform but do not record the change"
 +                             " in the configuration")
 +
 +PRIMARY_ONLY_OPT = cli_option("-p", "--primary-only",
 +                              default=False, action="store_true",
 +                              help="Evacuate primary instances only")
 +
 +SECONDARY_ONLY_OPT = cli_option("-s", "--secondary-only",
 +                                default=False, action="store_true",
 +                                help="Evacuate secondary instances only"
 +                                     " (applies only to internally mirrored"
 +                                     " disk templates, e.g. %s)" %
 +                                     utils.CommaJoin(constants.DTS_INT_MIRROR))
 +
 +STARTUP_PAUSED_OPT = cli_option("--paused", dest="startup_paused",
 +                                action="store_true", default=False,
 +                                help="Pause instance at startup")
 +
 +TO_GROUP_OPT = cli_option("--to", dest="to", metavar="<group>",
 +                          help="Destination node group (name or uuid)",
 +                          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")
 +
 +DISK_STATE_OPT = cli_option("--disk-state", default=[], dest="disk_state",
 +                            action="append",
 +                            help=("Specify disk state information in the"
 +                                  " format"
 +                                  " storage_type/identifier:option=value,...;"
 +                                  " note this is unused for now"),
 +                            type="identkeyval")
 +
 +HV_STATE_OPT = cli_option("--hypervisor-state", default=[], dest="hv_state",
 +                          action="append",
 +                          help=("Specify hypervisor state information in the"
 +                                " format hypervisor:option=value,...;"
 +                                " note this is unused for now"),
 +                          type="identkeyval")
 +
 +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="<size>")
 +
 +ABSOLUTE_OPT = cli_option("--absolute", dest="absolute",
 +                          action="store_true", default=False,
 +                          help="Marks the grow as absolute instead of the"
 +                          " (default) relative mode")
 +
 +NETWORK_OPT = cli_option("--network",
 +                         action="store", default=None, dest="network",
 +                         help="IP network in CIDR notation")
 +
 +GATEWAY_OPT = cli_option("--gateway",
 +                         action="store", default=None, dest="gateway",
 +                         help="IP address of the router (gateway)")
 +
 +ADD_RESERVED_IPS_OPT = cli_option("--add-reserved-ips",
 +                                  action="store", default=None,
 +                                  dest="add_reserved_ips",
 +                                  help="Comma-separated list of"
 +                                  " reserved IPs to add")
 +
 +REMOVE_RESERVED_IPS_OPT = cli_option("--remove-reserved-ips",
 +                                     action="store", default=None,
 +                                     dest="remove_reserved_ips",
 +                                     help="Comma-delimited list of"
 +                                     " reserved IPs to remove")
 +
 +NETWORK6_OPT = cli_option("--network6",
 +                          action="store", default=None, dest="network6",
 +                          help="IP network in CIDR notation")
 +
 +GATEWAY6_OPT = cli_option("--gateway6",
 +                          action="store", default=None, dest="gateway6",
 +                          help="IP6 address of the router (gateway)")
 +
 +NOCONFLICTSCHECK_OPT = cli_option("--no-conflicts-check",
 +                                  dest="conflicts_check",
 +                                  default=True,
 +                                  action="store_false",
 +                                  help="Don't check for conflicting IPs")
 +
 +INCLUDEDEFAULTS_OPT = cli_option("--include-defaults", dest="include_defaults",
 +                                 default=False, action="store_true",
 +                                 help="Include default values")
 +
 +HOTPLUG_OPT = cli_option("--hotplug", dest="hotplug",
 +                         action="store_true", default=False,
 +                         help="Hotplug supported devices (NICs and Disks)")
 +
 +HOTPLUG_IF_POSSIBLE_OPT = cli_option("--hotplug-if-possible",
 +                                     dest="hotplug_if_possible",
 +                                     action="store_true", default=False,
 +                                     help="Hotplug devices in case"
 +                                          " hotplug is supported")
 +
 +INSTALL_IMAGE_OPT = \
 +    cli_option("--install-image",
 +               dest="install_image",
 +               action="store",
 +               type="string",
 +               default=None,
 +               help="The OS image to use for running the OS scripts safely")
 +
 +INSTANCE_COMMUNICATION_OPT = \
 +    cli_option("-c", "--communication",
 +               dest="instance_communication",
 +               help=constants.INSTANCE_COMMUNICATION_DOC,
 +               type="bool")
 +
 +INSTANCE_COMMUNICATION_NETWORK_OPT = \
 +    cli_option("--instance-communication-network",
 +               dest="instance_communication_network",
 +               type="string",
 +               help="Set the network name for instance communication")
 +
 +ZEROING_IMAGE_OPT = \
 +    cli_option("--zeroing-image",
 +               dest="zeroing_image", action="store", default=None,
 +               help="The OS image to use to zero instance disks")
 +
 +ZERO_FREE_SPACE_OPT = \
 +    cli_option("--zero-free-space",
 +               dest="zero_free_space", action="store_true", default=False,
 +               help="Whether to zero the free space on the disks of the "
 +                    "instance prior to the export")
 +
 +HELPER_STARTUP_TIMEOUT_OPT = \
 +    cli_option("--helper-startup-timeout",
 +               dest="helper_startup_timeout", action="store", type="int",
 +               help="Startup timeout for the helper VM")
 +
 +HELPER_SHUTDOWN_TIMEOUT_OPT = \
 +    cli_option("--helper-shutdown-timeout",
 +               dest="helper_shutdown_timeout", action="store", type="int",
 +               help="Shutdown timeout for the helper VM")
 +
 +ZEROING_TIMEOUT_FIXED_OPT = \
 +    cli_option("--zeroing-timeout-fixed",
 +               dest="zeroing_timeout_fixed", action="store", type="int",
 +               help="The fixed amount of time to wait before assuming that the "
 +                    "zeroing failed")
 +
 +ZEROING_TIMEOUT_PER_MIB_OPT = \
 +    cli_option("--zeroing-timeout-per-mib",
 +               dest="zeroing_timeout_per_mib", action="store", type="float",
 +               help="The amount of time to wait per MiB of data to zero, in "
 +                    "addition to the fixed timeout")
 +
 +ENABLED_DATA_COLLECTORS_OPT = \
 +    cli_option("--enabled-data-collectors",
 +               dest="enabled_data_collectors", type="keyval",
 +               default={},
 +               help="Deactivate or reactivate a data collector for reporting, "
 +               "in the format collector=bool, where collector is one of %s."
 +               % ", ".join(constants.DATA_COLLECTOR_NAMES))
 +
 +VERIFY_CLUTTER_OPT = cli_option(
 +    "--verify-ssh-clutter", default=False, dest="verify_clutter",
 +    help="Verify that Ganeti did not clutter"
 +    " up the 'authorized_keys' file", action="store_true")
 +
 +
 +#: Options provided by all commands
 +COMMON_OPTS = [DEBUG_OPT, REASON_OPT]
 +
 +# options related to asynchronous job handling
 +
 +SUBMIT_OPTS = [
 +  SUBMIT_OPT,
 +  PRINT_JOBID_OPT,
 +  ]
 +
 +# common options for creating instances. add and import then add their own
 +# specific ones.
 +COMMON_CREATE_OPTS = [
 +  BACKEND_OPT,
 +  DISK_OPT,
 +  DISK_TEMPLATE_OPT,
 +  FILESTORE_DIR_OPT,
 +  FILESTORE_DRIVER_OPT,
 +  HYPERVISOR_OPT,
 +  IALLOCATOR_OPT,
 +  NET_OPT,
 +  NODE_PLACEMENT_OPT,
 +  NODEGROUP_OPT,
 +  NOIPCHECK_OPT,
 +  NOCONFLICTSCHECK_OPT,
 +  NONAMECHECK_OPT,
 +  NONICS_OPT,
 +  NWSYNC_OPT,
 +  OSPARAMS_OPT,
 +  OSPARAMS_PRIVATE_OPT,
 +  OSPARAMS_SECRET_OPT,
 +  OS_SIZE_OPT,
 +  OPPORTUNISTIC_OPT,
 +  SUBMIT_OPT,
 +  PRINT_JOBID_OPT,
 +  TAG_ADD_OPT,
 +  DRY_RUN_OPT,
 +  PRIORITY_OPT,
 +  ]
 +
 +# common instance policy options
 +INSTANCE_POLICY_OPTS = [
 +  IPOLICY_BOUNDS_SPECS_OPT,
 +  IPOLICY_DISK_TEMPLATES,
 +  IPOLICY_VCPU_RATIO,
 +  IPOLICY_SPINDLE_RATIO,
 +  ]
 +
 +# instance policy split specs options
 +SPLIT_ISPECS_OPTS = [
 +  SPECS_CPU_COUNT_OPT,
 +  SPECS_DISK_COUNT_OPT,
 +  SPECS_DISK_SIZE_OPT,
 +  SPECS_MEM_SIZE_OPT,
 +  SPECS_NIC_COUNT_OPT,
 +  ]
Simple merge
@@@ -923,61 -816,49 +943,49 @@@ type IAllocatorParams = Container JSVal
  -- | The master candidate client certificate digests
  type CandidateCertificates = Container String
  
- -- | Disk state parameters.
- --
- -- As according to the documentation this option is unused by Ganeti,
- -- the content is just a 'JSValue'.
- type DiskState = Container JSValue
- -- | Hypervisor state parameters.
- --
- -- As according to the documentation this option is unused by Ganeti,
- -- the content is just a 'JSValue'.
- type HypervisorState = Container JSValue
  -- * Cluster definitions
  $(buildObject "Cluster" "cluster" $
 -  [ simpleField "rsahostkeypub"                  [t| String                 |]
 +  [ simpleField "rsahostkeypub"                  [t| String                  |]
    , optionalField $
 -    simpleField "dsahostkeypub"                  [t| String                 |]
 -  , simpleField "highest_used_port"              [t| Int                    |]
 -  , simpleField "tcpudp_port_pool"               [t| [Int]                  |]
 -  , simpleField "mac_prefix"                     [t| String                 |]
 +    simpleField "dsahostkeypub"                  [t| String                  |]
 +  , simpleField "highest_used_port"              [t| Int                     |]
 +  , simpleField "tcpudp_port_pool"               [t| [Int]                   |]
 +  , simpleField "mac_prefix"                     [t| String                  |]
    , optionalField $
 -    simpleField "volume_group_name"              [t| String                 |]
 -  , simpleField "reserved_lvs"                   [t| [String]               |]
 +    simpleField "volume_group_name"              [t| String                  |]
 +  , simpleField "reserved_lvs"                   [t| [String]                |]
    , optionalField $
 -    simpleField "drbd_usermode_helper"           [t| String                 |]
 -  , simpleField "master_node"                    [t| String                 |]
 -  , simpleField "master_ip"                      [t| String                 |]
 -  , simpleField "master_netdev"                  [t| String                 |]
 -  , simpleField "master_netmask"                 [t| Int                    |]
 -  , simpleField "use_external_mip_script"        [t| Bool                   |]
 -  , simpleField "cluster_name"                   [t| String                 |]
 -  , simpleField "file_storage_dir"               [t| String                 |]
 -  , simpleField "shared_file_storage_dir"        [t| String                 |]
 -  , simpleField "gluster_storage_dir"            [t| String                 |]
 -  , simpleField "enabled_hypervisors"            [t| [Hypervisor]           |]
 -  , simpleField "hvparams"                       [t| ClusterHvParams        |]
 -  , simpleField "os_hvp"                         [t| OsHvParams             |]
 -  , simpleField "beparams"                       [t| ClusterBeParams        |]
 -  , simpleField "osparams"                       [t| ClusterOsParams        |]
 -  , simpleField "osparams_private_cluster"       [t| ClusterOsParamsPrivate |]
 -  , simpleField "nicparams"                      [t| ClusterNicParams       |]
 -  , simpleField "ndparams"                       [t| FilledNDParams         |]
 -  , simpleField "diskparams"                     [t| GroupDiskParams        |]
 -  , simpleField "candidate_pool_size"            [t| Int                    |]
 -  , simpleField "modify_etc_hosts"               [t| Bool                   |]
 -  , simpleField "modify_ssh_setup"               [t| Bool                   |]
 -  , simpleField "maintain_node_health"           [t| Bool                   |]
 -  , simpleField "uid_pool"                       [t| UidPool                |]
 -  , simpleField "default_iallocator"             [t| String                 |]
 -  , simpleField "default_iallocator_params"      [t| IAllocatorParams       |]
 -  , simpleField "hidden_os"                      [t| [String]               |]
 -  , simpleField "blacklisted_os"                 [t| [String]               |]
 -  , simpleField "primary_ip_family"              [t| IpFamily               |]
 -  , simpleField "prealloc_wipe_disks"            [t| Bool                   |]
 -  , simpleField "ipolicy"                        [t| FilledIPolicy          |]
 +    simpleField "drbd_usermode_helper"           [t| String                  |]
 +  , simpleField "master_node"                    [t| String                  |]
 +  , simpleField "master_ip"                      [t| String                  |]
 +  , simpleField "master_netdev"                  [t| String                  |]
 +  , simpleField "master_netmask"                 [t| Int                     |]
 +  , simpleField "use_external_mip_script"        [t| Bool                    |]
 +  , simpleField "cluster_name"                   [t| String                  |]
 +  , simpleField "file_storage_dir"               [t| String                  |]
 +  , simpleField "shared_file_storage_dir"        [t| String                  |]
 +  , simpleField "gluster_storage_dir"            [t| String                  |]
 +  , simpleField "enabled_hypervisors"            [t| [Hypervisor]            |]
 +  , simpleField "hvparams"                       [t| ClusterHvParams         |]
 +  , simpleField "os_hvp"                         [t| OsHvParams              |]
 +  , simpleField "beparams"                       [t| ClusterBeParams         |]
 +  , simpleField "osparams"                       [t| ClusterOsParams         |]
 +  , simpleField "osparams_private_cluster"       [t| ClusterOsParamsPrivate  |]
 +  , simpleField "nicparams"                      [t| ClusterNicParams        |]
 +  , simpleField "ndparams"                       [t| FilledNDParams          |]
 +  , simpleField "diskparams"                     [t| GroupDiskParams         |]
 +  , simpleField "candidate_pool_size"            [t| Int                     |]
 +  , simpleField "modify_etc_hosts"               [t| Bool                    |]
 +  , simpleField "modify_ssh_setup"               [t| Bool                    |]
 +  , simpleField "maintain_node_health"           [t| Bool                    |]
 +  , simpleField "uid_pool"                       [t| UidPool                 |]
 +  , simpleField "default_iallocator"             [t| String                  |]
 +  , simpleField "default_iallocator_params"      [t| IAllocatorParams        |]
 +  , simpleField "hidden_os"                      [t| [String]                |]
 +  , simpleField "blacklisted_os"                 [t| [String]                |]
 +  , simpleField "primary_ip_family"              [t| IpFamily                |]
 +  , simpleField "prealloc_wipe_disks"            [t| Bool                    |]
 +  , simpleField "ipolicy"                        [t| FilledIPolicy           |]
    , defaultField [| emptyContainer |] $
      simpleField "hv_state_static"                [t| HypervisorState        |]
    , defaultField [| emptyContainer |] $
Simple merge
Simple merge