RAPI client: fix epydoc formatting
[ganeti-local] / lib / cli.py
index a6b6b91..7fc8d05 100644 (file)
@@ -69,6 +69,7 @@ __all__ = [
   "DRAINED_OPT",
   "DRY_RUN_OPT",
   "DRBD_HELPER_OPT",
+  "DST_NODE_OPT",
   "EARLY_RELEASE_OPT",
   "ENABLED_HV_OPT",
   "ERROR_CODES_OPT",
@@ -79,6 +80,7 @@ __all__ = [
   "FORCE_VARIANT_OPT",
   "GLOBAL_FILEDIR_OPT",
   "HID_OS_OPT",
+  "GLOBAL_SHARED_FILEDIR_OPT",
   "HVLIST_OPT",
   "HVOPTS_OPT",
   "HYPERVISOR_OPT",
@@ -104,6 +106,7 @@ __all__ = [
   "NEW_RAPI_CERT_OPT",
   "NEW_SECONDARY_OPT",
   "NIC_PARAMS_OPT",
+  "NODE_FORCE_JOIN_OPT",
   "NODE_LIST_OPT",
   "NODE_PLACEMENT_OPT",
   "NODEGROUP_OPT",
@@ -131,6 +134,8 @@ __all__ = [
   "OSPARAMS_OPT",
   "OS_OPT",
   "OS_SIZE_OPT",
+  "OOB_TIMEOUT_OPT",
+  "POWER_DELAY_OPT",
   "PREALLOC_WIPE_DISKS_OPT",
   "PRIMARY_IP_VERSION_OPT",
   "PRIORITY_OPT",
@@ -836,6 +841,11 @@ 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,
@@ -886,6 +896,11 @@ 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,"
+                                      " 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")
@@ -965,6 +980,15 @@ GLOBAL_FILEDIR_OPT = cli_option("--file-storage-dir", dest="file_storage_dir",
                                 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)
@@ -1143,6 +1167,14 @@ NODE_POWERED_OPT = cli_option("--node-powered", default=None,
                               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]
@@ -1171,14 +1203,6 @@ COMMON_CREATE_OPTS = [
   ]
 
 
-_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.
 
@@ -1922,8 +1946,8 @@ def GenericMain(commands, override=None, aliases=None):
     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)
@@ -1937,6 +1961,11 @@ def GenericMain(commands, override=None, aliases=None):
     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
 
@@ -2380,17 +2409,20 @@ class _QueryColumnFormatter:
   """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.
@@ -2407,26 +2439,32 @@ class _QueryColumnFormatter:
     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}
@@ -2441,6 +2479,8 @@ def FormatQueryResult(result, unit=None, format_override=None, separator=None,
   @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:
@@ -2463,7 +2503,8 @@ def FormatQueryResult(result, unit=None, format_override=None, separator=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)
@@ -2512,10 +2553,10 @@ def _WarnUnknownFields(fdefs):
 
 
 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
@@ -2531,6 +2572,8 @@ def GenericList(resource, fields, names, unit, separator, header, cl=None,
   @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:
@@ -2545,7 +2588,8 @@ def GenericList(resource, fields, names, unit, separator, header, cl=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)
@@ -2563,7 +2607,7 @@ def GenericList(resource, fields, names, unit, separator, header, cl=None,
 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
@@ -2585,10 +2629,10 @@ def GenericListFields(resource, fields, separator, header, cl=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)