"GLOBAL_FILEDIR_OPT",
"HID_OS_OPT",
"GLOBAL_SHARED_FILEDIR_OPT",
+ "HOTPLUG_OPT",
"HVLIST_OPT",
"HVOPTS_OPT",
"HYPERVISOR_OPT",
"MASTER_NETMASK_OPT",
"MC_OPT",
"MIGRATION_MODE_OPT",
+ "MODIFY_ETCHOSTS_OPT",
"NET_OPT",
"NETWORK_OPT",
"NETWORK6_OPT",
return retval
-def check_list_ident_key_val(_, opt, value):
- """Custom parser for "ident:key=val,key=val/ident:key=val" options.
+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}}
+ @return: [{ident: {key: val, key: val}, ident: {key: val}}, {ident:..}]
"""
- return _SplitListKeyVal(opt, value)
+ retval = []
+ for line in value.split("//"):
+ retval.append(_SplitListKeyVal(opt, line))
+ return retval
def check_bool(option, opt, value): # pylint: disable=W0613
"completion_suggest",
]
TYPES = Option.TYPES + (
- "listidentkeyval",
+ "multilistidentkeyval",
"identkeyval",
"keyval",
"unit",
"maybefloat",
)
TYPE_CHECKER = Option.TYPE_CHECKER.copy()
- TYPE_CHECKER["listidentkeyval"] = check_list_ident_key_val
+ TYPE_CHECKER["multilistidentkeyval"] = check_multilist_ident_key_val
TYPE_CHECKER["identkeyval"] = check_ident_key_val
TYPE_CHECKER["keyval"] = check_key_val
TYPE_CHECKER["unit"] = check_unit
FILESTORE_DRIVER_OPT = cli_option("--file-driver", dest="file_driver",
help="Driver to use for image files",
- default="loop", metavar="<DRIVER>",
+ default=None, metavar="<DRIVER>",
choices=list(constants.FILE_DRIVER))
IALLOCATOR_OPT = cli_option("-I", "--iallocator", metavar="<NAME>",
IPOLICY_BOUNDS_SPECS_STR = "--ipolicy-bounds-specs"
IPOLICY_BOUNDS_SPECS_OPT = cli_option(IPOLICY_BOUNDS_SPECS_STR,
dest="ipolicy_bounds_specs",
- type="listidentkeyval", default=None,
+ type="multilistidentkeyval", default=None,
help="Complete instance specs limits")
IPOLICY_STD_SPECS_STR = "--ipolicy-std-specs"
CLEANUP_OPT = cli_option("--cleanup", dest="cleanup",
default=False, action="store_true",
- help="Instead of performing the migration, try to"
- " recover from a failed cleanup. This is safe"
+ 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")
+ " migration/failover")
STATIC_OPT = cli_option("-s", "--static", dest="static",
action="store_true", default=False,
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)
default=False, action="store_true",
help="Include default values")
+HOTPLUG_OPT = cli_option("--hotplug", dest="hotplug",
+ action="store_true", default=False,
+ help="Try to hotplug device")
+
#: Options provided by all commands
COMMON_OPTS = [DEBUG_OPT, REASON_OPT]
if iscluster:
eff_ipolicy = custom_ipolicy
- custom_minmax = custom_ipolicy.get(constants.ISPECS_MINMAX, {})
- ret = [
- (key,
- FormatParamsDictInfo(custom_minmax.get(key, {}),
- eff_ipolicy[constants.ISPECS_MINMAX][key]))
- for key in constants.ISPECS_MINMAX_KEYS
- ]
+ minmax_out = []
+ custom_minmax = custom_ipolicy.get(constants.ISPECS_MINMAX)
+ if custom_minmax:
+ for (k, minmax) in enumerate(custom_minmax):
+ minmax_out.append([
+ ("%s/%s" % (key, k),
+ FormatParamsDictInfo(minmax[key], minmax[key]))
+ for key in constants.ISPECS_MINMAX_KEYS
+ ])
+ else:
+ for (k, minmax) in enumerate(eff_ipolicy[constants.ISPECS_MINMAX]):
+ minmax_out.append([
+ ("%s/%s" % (key, k),
+ FormatParamsDictInfo({}, minmax[key]))
+ for key in constants.ISPECS_MINMAX_KEYS
+ ])
+ ret = [("bounds specs", minmax_out)]
+
if iscluster:
stdspecs = custom_ipolicy[constants.ISPECS_STD]
ret.append(
)
ret.append(
- ("enabled disk templates",
+ ("allowed disk templates",
_FormatListInfoDefault(custom_ipolicy.get(constants.IPOLICY_DTS),
eff_ipolicy[constants.IPOLICY_DTS]))
)
if stdspecs:
buf.write(" %s " % IPOLICY_STD_SPECS_STR)
_PrintSpecsParameters(buf, stdspecs)
- minmax = ipolicy.get("minmax")
- if minmax:
+ minmaxes = ipolicy.get("minmax", [])
+ first = True
+ for minmax in minmaxes:
minspecs = minmax.get("min")
maxspecs = minmax.get("max")
if minspecs and maxspecs:
- buf.write(" %s " % IPOLICY_BOUNDS_SPECS_STR)
+ if first:
+ buf.write(" %s " % IPOLICY_BOUNDS_SPECS_STR)
+ first = False
+ else:
+ buf.write("//")
buf.write("min:")
_PrintSpecsParameters(buf, minspecs)
buf.write("/max:")
for key, val in specs.items(): # {min: .. ,max: .., std: ..}
assert key in ispecs
ispecs[key][name] = val
- ipolicy[constants.ISPECS_MINMAX] = {}
+ minmax_out = {}
for key in constants.ISPECS_MINMAX_KEYS:
if fill_all:
- ipolicy[constants.ISPECS_MINMAX][key] = \
+ minmax_out[key] = \
objects.FillDict(constants.ISPECS_MINMAX_DEFAULTS[key], ispecs[key])
else:
- ipolicy[constants.ISPECS_MINMAX][key] = ispecs[key]
+ minmax_out[key] = ispecs[key]
+ ipolicy[constants.ISPECS_MINMAX] = [minmax_out]
if fill_all:
ipolicy[constants.ISPECS_STD] = \
objects.FillDict(constants.IPOLICY_DEFAULTS[constants.ISPECS_STD],
def _GetISpecsInAllowedValues(minmax_ispecs, allowed_values):
ret = None
- if minmax_ispecs and allowed_values and len(minmax_ispecs) == 1:
- for (key, spec) in minmax_ispecs.items():
+ if (minmax_ispecs and allowed_values and len(minmax_ispecs) == 1 and
+ len(minmax_ispecs[0]) == 1):
+ for (key, spec) in minmax_ispecs[0].items():
# This loop is executed exactly once
if key in allowed_values and not spec:
ret = key
if found_allowed is not None:
ipolicy_out[constants.ISPECS_MINMAX] = found_allowed
elif minmax_ispecs is not None:
- minmax_out = {}
- for (key, spec) in minmax_ispecs.items():
- if key not in constants.ISPECS_MINMAX_KEYS:
- msg = "Invalid key in bounds instance specifications: %s" % key
- raise errors.OpPrereqError(msg, errors.ECODE_INVAL)
- minmax_out[key] = _ParseISpec(spec, key, True)
+ minmax_out = []
+ for mmpair in minmax_ispecs:
+ mmpair_out = {}
+ for (key, spec) in mmpair.items():
+ if key not in constants.ISPECS_MINMAX_KEYS:
+ msg = "Invalid key in bounds instance specifications: %s" % key
+ raise errors.OpPrereqError(msg, errors.ECODE_INVAL)
+ mmpair_out[key] = _ParseISpec(spec, key, True)
+ minmax_out.append(mmpair_out)
ipolicy_out[constants.ISPECS_MINMAX] = minmax_out
if std_ispecs is not None:
assert not group_ipolicy # This is not an option for gnt-group