Revision 3086220e

b/lib/client/gnt_job.py
31 31
from ganeti import errors
32 32
from ganeti import utils
33 33
from ganeti import cli
34
from ganeti import qlang
34 35

  
35 36

  
36 37
#: default list of fields for L{ListJobs}
......
49 50
  }
50 51

  
51 52

  
53
def _FormatStatus(value):
54
  """Formats a job status.
55

  
56
  """
57
  try:
58
    return _USER_JOB_STATUS[value]
59
  except KeyError:
60
    raise errors.ProgrammerError("Unknown job status code '%s'" % value)
61

  
62

  
52 63
def ListJobs(opts, args):
53 64
  """List the jobs
54 65

  
......
61 72
  """
62 73
  selected_fields = ParseFields(opts.output, _LIST_DEF_FIELDS)
63 74

  
64
  output = GetClient().QueryJobs(args, selected_fields)
65
  if not opts.no_headers:
66
    # TODO: Implement more fields
67
    headers = {
68
      "id": "ID",
69
      "status": "Status",
70
      "priority": "Prio",
71
      "ops": "OpCodes",
72
      "opresult": "OpCode_result",
73
      "opstatus": "OpCode_status",
74
      "oplog": "OpCode_log",
75
      "summary": "Summary",
76
      "opstart": "OpCode_start",
77
      "opexec": "OpCode_exec",
78
      "opend": "OpCode_end",
79
      "oppriority": "OpCode_prio",
80
      "start_ts": "Start",
81
      "end_ts": "End",
82
      "received_ts": "Received",
83
      }
84
  else:
85
    headers = None
75
  fmtoverride = {
76
    "status": (_FormatStatus, False),
77
    "summary": (lambda value: ",".join(str(item) for item in value), False),
78
    }
79
  fmtoverride.update(dict.fromkeys(["opstart", "opexec", "opend"],
80
    (lambda value: map(FormatTimestamp, value), None)))
86 81

  
87
  numfields = ["priority"]
82
  return GenericList(constants.QR_JOB, selected_fields, args, None,
83
                     opts.separator, not opts.no_headers,
84
                     format_override=fmtoverride, verbose=opts.verbose,
85
                     force_filter=opts.force_filter, namefield="id")
88 86

  
89
  # change raw values to nicer strings
90
  for row_id, row in enumerate(output):
91
    if row is None:
92
      ToStderr("No such job: %s" % args[row_id])
93
      continue
94 87

  
95
    for idx, field in enumerate(selected_fields):
96
      val = row[idx]
97
      if field == "status":
98
        if val in _USER_JOB_STATUS:
99
          val = _USER_JOB_STATUS[val]
100
        else:
101
          raise errors.ProgrammerError("Unknown job status code '%s'" % val)
102
      elif field == "summary":
103
        val = ",".join(val)
104
      elif field in ("start_ts", "end_ts", "received_ts"):
105
        val = FormatTimestamp(val)
106
      elif field in ("opstart", "opexec", "opend"):
107
        val = [FormatTimestamp(entry) for entry in val]
108

  
109
      row[idx] = str(val)
110

  
111
  data = GenerateTable(separator=opts.separator, headers=headers,
112
                       fields=selected_fields, data=output,
113
                       numfields=numfields)
114
  for line in data:
115
    ToStdout(line)
88
def ListJobFields(opts, args):
89
  """List job fields.
116 90

  
117
  return 0
91
  @param opts: the command line options selected by the user
92
  @type args: list
93
  @param args: fields to list, or empty for all
94
  @rtype: int
95
  @return: the desired exit code
96

  
97
  """
98
  return GenericListFields(constants.QR_JOB, args, opts.separator,
99
                           not opts.no_headers)
118 100

  
119 101

  
120 102
def ArchiveJobs(opts, args):
......
358 340
commands = {
359 341
  "list": (
360 342
    ListJobs, [ArgJobId()],
361
    [NOHDR_OPT, SEP_OPT, FIELDS_OPT],
343
    [NOHDR_OPT, SEP_OPT, FIELDS_OPT, VERBOSE_OPT, FORCE_FILTER_OPT],
362 344
    "[job_id ...]",
363
    "List the jobs and their status. The available fields are"
364
    " (see the man page for details): id, status, op_list,"
365
    " op_status, op_result."
366
    " The default field"
367
    " list is (in order): %s." % utils.CommaJoin(_LIST_DEF_FIELDS)),
345
    "Lists the jobs and their status. The available fields can be shown"
346
    " using the \"list-fields\" command (see the man page for details)."
347
    " The default field list is (in order): %s." %
348
    utils.CommaJoin(_LIST_DEF_FIELDS)),
349
  "list-fields": (
350
    ListJobFields, [ArgUnknown()],
351
    [NOHDR_OPT, SEP_OPT],
352
    "[fields...]",
353
    "Lists all available fields for jobs"),
368 354
  "archive": (
369 355
    ArchiveJobs, [ArgJobId(min=1)], [],
370 356
    "<job-id> [<job-id> ...]", "Archive specified jobs"),
b/man/gnt-job.rst
74 74
The ``-o`` option takes a comma-separated list of output fields.
75 75
The available fields and their meaning are:
76 76

  
77
@QUERY_FIELDS_JOB@
77 78

  
79
If the value of the option starts with the character ``+``, the new
80
fields will be added to the default list. This allows one to quickly
81
see the default list plus a few other fields, instead of retyping
82
the entire list of fields.
78 83

  
79
id
80
    the job id
81

  
82
status
83
    the status of the job
84

  
85
priority
86
    current priority of the job
87

  
88
received_ts
89
    the timestamp the job was received
90

  
91
start_ts
92
    the timestamp when the job was started
93

  
94
end_ts
95
    the timestamp when the job was ended
96

  
97
summary
98
    a summary of the opcodes that define the job
99

  
100
ops
101
    the list of opcodes defining the job
102

  
103
opresult
104
    the list of opcode results
105

  
106
opstatus
107
    the list of opcode statuses
108

  
109
oplog
110
    the list of opcode logs
111

  
112
opstart
113
    the list of opcode start times (before acquiring locks)
114

  
115
opexec
116
    the list of opcode execution start times (after acquiring any
117
    necessary locks)
118 84

  
119
opend
120
    the list of opcode end times
85
LIST-FIELDS
86
~~~~~~~~~~~
121 87

  
122
oppriority
123
    the priority of each opcode
88
**list-fields** [field...]
124 89

  
90
Lists available fields for jobs.
125 91

  
126
If the value of the option starts with the character ``+``, the new
127
fields will be added to the default list. This allows one to quickly
128
see the default list plus a few other fields, instead of retyping
129
the entire list of fields.
130 92

  
131 93
WATCH
132 94
~~~~~

Also available in: Unified diff