Commit 3086220e authored by Michael Hanselmann's avatar Michael Hanselmann

gnt-job list: Switch to query2

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: default avatarMichael Hanselmann <hansmi@google.com>
Reviewed-by: default avatarIustin Pop <iustin@google.com>
parent eba1aaad
......@@ -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"),
......
......@@ -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
~~~~~
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment