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"),
|