gnt-job list: Switch to query2
authorMichael Hanselmann <hansmi@google.com>
Wed, 28 Mar 2012 12:37:55 +0000 (14:37 +0200)
committerMichael Hanselmann <hansmi@google.com>
Fri, 30 Mar 2012 12:03:42 +0000 (14:03 +0200)
This brings “gnt-job list” up to the same level as “gnt-instance list”
with filters. Further updates will add more parameters for the most
common filters (e.g. only running jobs).

Also update the man page.

Signed-off-by: Michael Hanselmann <hansmi@google.com>
Reviewed-by: Iustin Pop <iustin@google.com>

lib/client/gnt_job.py
man/gnt-job.rst

index 58d5c5f..5641a05 100644 (file)
@@ -31,6 +31,7 @@ from ganeti import constants
 from ganeti import errors
 from ganeti import utils
 from ganeti import cli
+from ganeti import qlang
 
 
 #: default list of fields for L{ListJobs}
@@ -49,6 +50,16 @@ _USER_JOB_STATUS = {
   }
 
 
+def _FormatStatus(value):
+  """Formats a job status.
+
+  """
+  try:
+    return _USER_JOB_STATUS[value]
+  except KeyError:
+    raise errors.ProgrammerError("Unknown job status code '%s'" % value)
+
+
 def ListJobs(opts, args):
   """List the jobs
 
@@ -61,60 +72,31 @@ def ListJobs(opts, args):
   """
   selected_fields = ParseFields(opts.output, _LIST_DEF_FIELDS)
 
-  output = GetClient().QueryJobs(args, selected_fields)
-  if not opts.no_headers:
-    # TODO: Implement more fields
-    headers = {
-      "id": "ID",
-      "status": "Status",
-      "priority": "Prio",
-      "ops": "OpCodes",
-      "opresult": "OpCode_result",
-      "opstatus": "OpCode_status",
-      "oplog": "OpCode_log",
-      "summary": "Summary",
-      "opstart": "OpCode_start",
-      "opexec": "OpCode_exec",
-      "opend": "OpCode_end",
-      "oppriority": "OpCode_prio",
-      "start_ts": "Start",
-      "end_ts": "End",
-      "received_ts": "Received",
-      }
-  else:
-    headers = None
+  fmtoverride = {
+    "status": (_FormatStatus, False),
+    "summary": (lambda value: ",".join(str(item) for item in value), False),
+    }
+  fmtoverride.update(dict.fromkeys(["opstart", "opexec", "opend"],
+    (lambda value: map(FormatTimestamp, value), None)))
 
-  numfields = ["priority"]
+  return GenericList(constants.QR_JOB, selected_fields, args, None,
+                     opts.separator, not opts.no_headers,
+                     format_override=fmtoverride, verbose=opts.verbose,
+                     force_filter=opts.force_filter, namefield="id")
 
-  # change raw values to nicer strings
-  for row_id, row in enumerate(output):
-    if row is None:
-      ToStderr("No such job: %s" % args[row_id])
-      continue
 
-    for idx, field in enumerate(selected_fields):
-      val = row[idx]
-      if field == "status":
-        if val in _USER_JOB_STATUS:
-          val = _USER_JOB_STATUS[val]
-        else:
-          raise errors.ProgrammerError("Unknown job status code '%s'" % val)
-      elif field == "summary":
-        val = ",".join(val)
-      elif field in ("start_ts", "end_ts", "received_ts"):
-        val = FormatTimestamp(val)
-      elif field in ("opstart", "opexec", "opend"):
-        val = [FormatTimestamp(entry) for entry in val]
-
-      row[idx] = str(val)
-
-  data = GenerateTable(separator=opts.separator, headers=headers,
-                       fields=selected_fields, data=output,
-                       numfields=numfields)
-  for line in data:
-    ToStdout(line)
+def ListJobFields(opts, args):
+  """List job fields.
 
-  return 0
+  @param opts: the command line options selected by the user
+  @type args: list
+  @param args: fields to list, or empty for all
+  @rtype: int
+  @return: the desired exit code
+
+  """
+  return GenericListFields(constants.QR_JOB, args, opts.separator,
+                           not opts.no_headers)
 
 
 def ArchiveJobs(opts, args):
@@ -358,13 +340,17 @@ def WatchJob(opts, args):
 commands = {
   "list": (
     ListJobs, [ArgJobId()],
-    [NOHDR_OPT, SEP_OPT, FIELDS_OPT],
+    [NOHDR_OPT, SEP_OPT, FIELDS_OPT, VERBOSE_OPT, FORCE_FILTER_OPT],
     "[job_id ...]",
-    "List the jobs and their status. The available fields are"
-    " (see the man page for details): id, status, op_list,"
-    " op_status, op_result."
-    " The default field"
-    " list is (in order): %s." % utils.CommaJoin(_LIST_DEF_FIELDS)),
+    "Lists the jobs and their status. The available fields can be shown"
+    " using the \"list-fields\" command (see the man page for details)."
+    " The default field list is (in order): %s." %
+    utils.CommaJoin(_LIST_DEF_FIELDS)),
+  "list-fields": (
+    ListJobFields, [ArgUnknown()],
+    [NOHDR_OPT, SEP_OPT],
+    "[fields...]",
+    "Lists all available fields for jobs"),
   "archive": (
     ArchiveJobs, [ArgJobId(min=1)], [],
     "<job-id> [<job-id> ...]", "Archive specified jobs"),
index 2533f86..c634d0d 100644 (file)
@@ -74,59 +74,21 @@ scripting.
 The ``-o`` option takes a comma-separated list of output fields.
 The available fields and their meaning are:
 
+@QUERY_FIELDS_JOB@
 
+If the value of the option starts with the character ``+``, the new
+fields will be added to the default list. This allows one to quickly
+see the default list plus a few other fields, instead of retyping
+the entire list of fields.
 
-id
-    the job id
-
-status
-    the status of the job
-
-priority
-    current priority of the job
-
-received_ts
-    the timestamp the job was received
-
-start_ts
-    the timestamp when the job was started
-
-end_ts
-    the timestamp when the job was ended
-
-summary
-    a summary of the opcodes that define the job
-
-ops
-    the list of opcodes defining the job
-
-opresult
-    the list of opcode results
-
-opstatus
-    the list of opcode statuses
-
-oplog
-    the list of opcode logs
-
-opstart
-    the list of opcode start times (before acquiring locks)
-
-opexec
-    the list of opcode execution start times (after acquiring any
-    necessary locks)
 
-opend
-    the list of opcode end times
+LIST-FIELDS
+~~~~~~~~~~~
 
-oppriority
-    the priority of each opcode
+**list-fields** [field...]
 
+Lists available fields for jobs.
 
-If the value of the option starts with the character ``+``, the new
-fields will be added to the default list. This allows one to quickly
-see the default list plus a few other fields, instead of retyping
-the entire list of fields.
 
 WATCH
 ~~~~~