"DRAINED_OPT",
"DRY_RUN_OPT",
"DRBD_HELPER_OPT",
+ "DST_NODE_OPT",
"EARLY_RELEASE_OPT",
"ENABLED_HV_OPT",
"ERROR_CODES_OPT",
"FORCE_VARIANT_OPT",
"GLOBAL_FILEDIR_OPT",
"HID_OS_OPT",
+ "GLOBAL_SHARED_FILEDIR_OPT",
"HVLIST_OPT",
"HVOPTS_OPT",
"HYPERVISOR_OPT",
"NEW_RAPI_CERT_OPT",
"NEW_SECONDARY_OPT",
"NIC_PARAMS_OPT",
+ "NODE_FORCE_JOIN_OPT",
"NODE_LIST_OPT",
"NODE_PLACEMENT_OPT",
"NODEGROUP_OPT",
"OSPARAMS_OPT",
"OS_OPT",
"OS_SIZE_OPT",
+ "OOB_TIMEOUT_OPT",
+ "POWER_DELAY_OPT",
"PREALLOC_WIPE_DISKS_OPT",
"PRIMARY_IP_VERSION_OPT",
"PRIORITY_OPT",
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,
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,"
+ " needed when merging clusters")
+
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")
metavar="DIR",
default=constants.DEFAULT_FILE_STORAGE_DIR)
+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]" %
+ constants.DEFAULT_SHARED_FILE_STORAGE_DIR,
+ metavar="SHAREDDIR",
+ default=constants.DEFAULT_SHARED_FILE_STORAGE_DIR)
+
NOMODIFY_ETCHOSTS_OPT = cli_option("--no-etc-hosts", dest="modify_etc_hosts",
help="Don't modify /etc/hosts",
action="store_false", default=True)
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")
+
#: Options provided by all commands
COMMON_OPTS = [DEBUG_OPT]
]
-_RSTATUS_TO_TEXT = {
- constants.RS_UNKNOWN: "(unknown)",
- constants.RS_NODATA: "(nodata)",
- constants.RS_UNAVAIL: "(unavail)",
- constants.RS_OFFLINE: "(offline)",
- }
-
-
def _ParseArgs(argv, commands, aliases):
"""Parser for the command line arguments.
for key, val in override.iteritems():
setattr(options, key, val)
- utils.SetupLogging(constants.LOG_COMMANDS, debug=options.debug,
- stderr_logging=True, program=binary)
+ utils.SetupLogging(constants.LOG_COMMANDS, binary, debug=options.debug,
+ stderr_logging=True)
if old_cmdline:
logging.info("run with arguments '%s'", old_cmdline)
result, err_msg = FormatError(err)
logging.exception("Error during command processing")
ToStderr(err_msg)
+ except KeyboardInterrupt:
+ result = constants.EXIT_FAILURE
+ ToStderr("Aborted. Note that if the operation created any jobs, they"
+ " might have been submitted and"
+ " will continue to run in the background.")
return result
"""Callable class for formatting fields of a query.
"""
- def __init__(self, fn, status_fn):
+ def __init__(self, fn, status_fn, verbose):
"""Initializes this class.
@type fn: callable
@param fn: Formatting function
@type status_fn: callable
@param status_fn: Function to report fields' status
+ @type verbose: boolean
+ @param verbose: whether to use verbose field descriptions or not
"""
self._fn = fn
self._status_fn = status_fn
+ self._verbose = verbose
def __call__(self, data):
"""Returns a field's string representation.
assert value is None, \
"Found value %r for abnormal status %s" % (value, status)
- return FormatResultError(status)
+ return FormatResultError(status, self._verbose)
-def FormatResultError(status):
+def FormatResultError(status, verbose):
"""Formats result status other than L{constants.RS_NORMAL}.
@param status: The result status
+ @type verbose: boolean
+ @param verbose: Whether to return the verbose text
@return: Text of result status
"""
assert status != constants.RS_NORMAL, \
- "FormatResultError called with status equals to constants.RS_NORMAL"
+ "FormatResultError called with status equal to constants.RS_NORMAL"
try:
- return _RSTATUS_TO_TEXT[status]
+ (verbose_text, normal_text) = constants.RSS_DESCRIPTION[status]
except KeyError:
raise NotImplementedError("Unknown status %s" % status)
+ else:
+ if verbose:
+ return verbose_text
+ return normal_text
def FormatQueryResult(result, unit=None, format_override=None, separator=None,
- header=False):
+ header=False, verbose=False):
"""Formats data in L{objects.QueryResponse}.
@type result: L{objects.QueryResponse}
@param separator: String used to separate fields
@type header: bool
@param header: Whether to output header row
+ @type verbose: boolean
+ @param verbose: whether to use verbose field descriptions or not
"""
if unit is None:
assert fdef.title and fdef.name
(fn, align_right) = _GetColumnFormatter(fdef, format_override, unit)
columns.append(TableColumn(fdef.title,
- _QueryColumnFormatter(fn, _RecordStatus),
+ _QueryColumnFormatter(fn, _RecordStatus,
+ verbose),
align_right))
table = FormatTable(result.data, columns, header, separator)
def GenericList(resource, fields, names, unit, separator, header, cl=None,
- format_override=None):
+ format_override=None, verbose=False):
"""Generic implementation for listing all items of a resource.
- @param resource: One of L{constants.QR_OP_LUXI}
+ @param resource: One of L{constants.QR_VIA_LUXI}
@type fields: list of strings
@param fields: List of fields to query for
@type names: list of strings
@type format_override: dict
@param format_override: Dictionary for overriding field formatting functions,
indexed by field name, contents like L{_DEFAULT_FORMAT_QUERY}
+ @type verbose: boolean
+ @param verbose: whether to use verbose field descriptions or not
"""
if cl is None:
(status, data) = FormatQueryResult(response, unit=unit, separator=separator,
header=header,
- format_override=format_override)
+ format_override=format_override,
+ verbose=verbose)
for line in data:
ToStdout(line)
def GenericListFields(resource, fields, separator, header, cl=None):
"""Generic implementation for listing fields for a resource.
- @param resource: One of L{constants.QR_OP_LUXI}
+ @param resource: One of L{constants.QR_VIA_LUXI}
@type fields: list of strings
@param fields: List of fields to query for
@type separator: string or None
columns = [
TableColumn("Name", str, False),
TableColumn("Title", str, False),
- # TODO: Add field description to master daemon
+ TableColumn("Description", str, False),
]
- rows = [[fdef.name, fdef.title] for fdef in response.fields]
+ rows = [[fdef.name, fdef.title, fdef.doc] for fdef in response.fields]
for line in FormatTable(rows, columns, header, separator):
ToStdout(line)