Statistics
| Branch: | Tag: | Revision:

root / lib / client / gnt_job.py @ f037e9d7

History | View | Annotate | Download (12.2 kB)

1 a09b9e3d Michael Hanselmann
#
2 7a1ecaed Iustin Pop
#
3 7a1ecaed Iustin Pop
4 7a1ecaed Iustin Pop
# Copyright (C) 2006, 2007 Google Inc.
5 7a1ecaed Iustin Pop
#
6 7a1ecaed Iustin Pop
# This program is free software; you can redistribute it and/or modify
7 7a1ecaed Iustin Pop
# it under the terms of the GNU General Public License as published by
8 7a1ecaed Iustin Pop
# the Free Software Foundation; either version 2 of the License, or
9 7a1ecaed Iustin Pop
# (at your option) any later version.
10 7a1ecaed Iustin Pop
#
11 7a1ecaed Iustin Pop
# This program is distributed in the hope that it will be useful, but
12 7a1ecaed Iustin Pop
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 7a1ecaed Iustin Pop
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 7a1ecaed Iustin Pop
# General Public License for more details.
15 7a1ecaed Iustin Pop
#
16 7a1ecaed Iustin Pop
# You should have received a copy of the GNU General Public License
17 7a1ecaed Iustin Pop
# along with this program; if not, write to the Free Software
18 7a1ecaed Iustin Pop
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 7a1ecaed Iustin Pop
# 02110-1301, USA.
20 7a1ecaed Iustin Pop
21 7260cfbe Iustin Pop
"""Job related commands"""
22 7a1ecaed Iustin Pop
23 b459a848 Andrea Spadaccini
# pylint: disable=W0401,W0613,W0614,C0103
24 2f79bd34 Iustin Pop
# W0401: Wildcard import ganeti.cli
25 2d54e29c Iustin Pop
# W0613: Unused argument, since all functions follow the same API
26 2f79bd34 Iustin Pop
# W0614: Unused import %s from wildcard import (since we need cli)
27 7260cfbe Iustin Pop
# C0103: Invalid name gnt-job
28 2f79bd34 Iustin Pop
29 7a1ecaed Iustin Pop
from ganeti.cli import *
30 7a1ecaed Iustin Pop
from ganeti import constants
31 7a1ecaed Iustin Pop
from ganeti import errors
32 26f15862 Iustin Pop
from ganeti import utils
33 e7d6946c Michael Hanselmann
from ganeti import cli
34 3086220e Michael Hanselmann
from ganeti import qlang
35 7a1ecaed Iustin Pop
36 7a1ecaed Iustin Pop
37 917b4e56 Iustin Pop
#: default list of fields for L{ListJobs}
38 60dd1473 Iustin Pop
_LIST_DEF_FIELDS = ["id", "status", "summary"]
39 7a5d3bbd Iustin Pop
40 917b4e56 Iustin Pop
#: map converting the job status contants to user-visible
41 917b4e56 Iustin Pop
#: names
42 af30b2fd Michael Hanselmann
_USER_JOB_STATUS = {
43 af30b2fd Michael Hanselmann
  constants.JOB_STATUS_QUEUED: "queued",
44 47099cd1 Michael Hanselmann
  constants.JOB_STATUS_WAITING: "waiting",
45 fbf0262f Michael Hanselmann
  constants.JOB_STATUS_CANCELING: "canceling",
46 af30b2fd Michael Hanselmann
  constants.JOB_STATUS_RUNNING: "running",
47 af30b2fd Michael Hanselmann
  constants.JOB_STATUS_CANCELED: "canceled",
48 af30b2fd Michael Hanselmann
  constants.JOB_STATUS_SUCCESS: "success",
49 af30b2fd Michael Hanselmann
  constants.JOB_STATUS_ERROR: "error",
50 af30b2fd Michael Hanselmann
  }
51 af30b2fd Michael Hanselmann
52 0ad64cf8 Michael Hanselmann
53 3086220e Michael Hanselmann
def _FormatStatus(value):
54 3086220e Michael Hanselmann
  """Formats a job status.
55 3086220e Michael Hanselmann

56 3086220e Michael Hanselmann
  """
57 3086220e Michael Hanselmann
  try:
58 3086220e Michael Hanselmann
    return _USER_JOB_STATUS[value]
59 3086220e Michael Hanselmann
  except KeyError:
60 3086220e Michael Hanselmann
    raise errors.ProgrammerError("Unknown job status code '%s'" % value)
61 3086220e Michael Hanselmann
62 3086220e Michael Hanselmann
63 7a1ecaed Iustin Pop
def ListJobs(opts, args):
64 7a1ecaed Iustin Pop
  """List the jobs
65 7a1ecaed Iustin Pop

66 917b4e56 Iustin Pop
  @param opts: the command line options selected by the user
67 917b4e56 Iustin Pop
  @type args: list
68 917b4e56 Iustin Pop
  @param args: should be an empty list
69 917b4e56 Iustin Pop
  @rtype: int
70 917b4e56 Iustin Pop
  @return: the desired exit code
71 917b4e56 Iustin Pop

72 7a1ecaed Iustin Pop
  """
73 a4ebd726 Michael Hanselmann
  selected_fields = ParseFields(opts.output, _LIST_DEF_FIELDS)
74 7a1ecaed Iustin Pop
75 3086220e Michael Hanselmann
  fmtoverride = {
76 3086220e Michael Hanselmann
    "status": (_FormatStatus, False),
77 3086220e Michael Hanselmann
    "summary": (lambda value: ",".join(str(item) for item in value), False),
78 3086220e Michael Hanselmann
    }
79 3086220e Michael Hanselmann
  fmtoverride.update(dict.fromkeys(["opstart", "opexec", "opend"],
80 3086220e Michael Hanselmann
    (lambda value: map(FormatTimestamp, value), None)))
81 7a1ecaed Iustin Pop
82 f037e9d7 Michael Hanselmann
  qfilter = qlang.MakeSimpleFilter("status", opts.status_filter)
83 f037e9d7 Michael Hanselmann
84 3086220e Michael Hanselmann
  return GenericList(constants.QR_JOB, selected_fields, args, None,
85 3086220e Michael Hanselmann
                     opts.separator, not opts.no_headers,
86 3086220e Michael Hanselmann
                     format_override=fmtoverride, verbose=opts.verbose,
87 f037e9d7 Michael Hanselmann
                     force_filter=opts.force_filter, namefield="id",
88 f037e9d7 Michael Hanselmann
                     qfilter=qfilter)
89 b8802cc4 Michael Hanselmann
90 dcbd6288 Guido Trotter
91 3086220e Michael Hanselmann
def ListJobFields(opts, args):
92 3086220e Michael Hanselmann
  """List job fields.
93 7a1ecaed Iustin Pop

94 3086220e Michael Hanselmann
  @param opts: the command line options selected by the user
95 3086220e Michael Hanselmann
  @type args: list
96 3086220e Michael Hanselmann
  @param args: fields to list, or empty for all
97 3086220e Michael Hanselmann
  @rtype: int
98 3086220e Michael Hanselmann
  @return: the desired exit code
99 3086220e Michael Hanselmann

100 3086220e Michael Hanselmann
  """
101 3086220e Michael Hanselmann
  return GenericListFields(constants.QR_JOB, args, opts.separator,
102 3086220e Michael Hanselmann
                           not opts.no_headers)
103 7a1ecaed Iustin Pop
104 7a1ecaed Iustin Pop
105 0ad64cf8 Michael Hanselmann
def ArchiveJobs(opts, args):
106 917b4e56 Iustin Pop
  """Archive jobs.
107 917b4e56 Iustin Pop

108 917b4e56 Iustin Pop
  @param opts: the command line options selected by the user
109 917b4e56 Iustin Pop
  @type args: list
110 917b4e56 Iustin Pop
  @param args: should contain the job IDs to be archived
111 917b4e56 Iustin Pop
  @rtype: int
112 917b4e56 Iustin Pop
  @return: the desired exit code
113 917b4e56 Iustin Pop

114 917b4e56 Iustin Pop
  """
115 0ad64cf8 Michael Hanselmann
  client = GetClient()
116 0ad64cf8 Michael Hanselmann
117 aa9f8167 Iustin Pop
  rcode = 0
118 0ad64cf8 Michael Hanselmann
  for job_id in args:
119 aa9f8167 Iustin Pop
    if not client.ArchiveJob(job_id):
120 aa9f8167 Iustin Pop
      ToStderr("Failed to archive job with ID '%s'", job_id)
121 aa9f8167 Iustin Pop
      rcode = 1
122 0ad64cf8 Michael Hanselmann
123 aa9f8167 Iustin Pop
  return rcode
124 0ad64cf8 Michael Hanselmann
125 0ad64cf8 Michael Hanselmann
126 07cd723a Iustin Pop
def AutoArchiveJobs(opts, args):
127 917b4e56 Iustin Pop
  """Archive jobs based on age.
128 917b4e56 Iustin Pop

129 917b4e56 Iustin Pop
  This will archive jobs based on their age, or all jobs if a 'all' is
130 917b4e56 Iustin Pop
  passed.
131 917b4e56 Iustin Pop

132 917b4e56 Iustin Pop
  @param opts: the command line options selected by the user
133 917b4e56 Iustin Pop
  @type args: list
134 917b4e56 Iustin Pop
  @param args: should contain only one element, the age as a time spec
135 c41eea6e Iustin Pop
      that can be parsed by L{ganeti.cli.ParseTimespec} or the
136 c41eea6e Iustin Pop
      keyword I{all}, which will cause all jobs to be archived
137 917b4e56 Iustin Pop
  @rtype: int
138 917b4e56 Iustin Pop
  @return: the desired exit code
139 917b4e56 Iustin Pop

140 917b4e56 Iustin Pop
  """
141 07cd723a Iustin Pop
  client = GetClient()
142 07cd723a Iustin Pop
143 07cd723a Iustin Pop
  age = args[0]
144 07cd723a Iustin Pop
145 d0c8c01d Iustin Pop
  if age == "all":
146 07cd723a Iustin Pop
    age = -1
147 07cd723a Iustin Pop
  else:
148 07cd723a Iustin Pop
    age = ParseTimespec(age)
149 07cd723a Iustin Pop
150 f8ad5591 Michael Hanselmann
  (archived_count, jobs_left) = client.AutoArchiveJobs(age)
151 f8ad5591 Michael Hanselmann
  ToStdout("Archived %s jobs, %s unchecked left", archived_count, jobs_left)
152 f8ad5591 Michael Hanselmann
153 07cd723a Iustin Pop
  return 0
154 07cd723a Iustin Pop
155 07cd723a Iustin Pop
156 d2b92ffc Michael Hanselmann
def CancelJobs(opts, args):
157 917b4e56 Iustin Pop
  """Cancel not-yet-started jobs.
158 917b4e56 Iustin Pop

159 917b4e56 Iustin Pop
  @param opts: the command line options selected by the user
160 917b4e56 Iustin Pop
  @type args: list
161 917b4e56 Iustin Pop
  @param args: should contain the job IDs to be cancelled
162 917b4e56 Iustin Pop
  @rtype: int
163 917b4e56 Iustin Pop
  @return: the desired exit code
164 917b4e56 Iustin Pop

165 917b4e56 Iustin Pop
  """
166 d2b92ffc Michael Hanselmann
  client = GetClient()
167 06fef5e0 Michael Hanselmann
  result = constants.EXIT_SUCCESS
168 d2b92ffc Michael Hanselmann
169 d2b92ffc Michael Hanselmann
  for job_id in args:
170 06fef5e0 Michael Hanselmann
    (success, msg) = client.CancelJob(job_id)
171 06fef5e0 Michael Hanselmann
172 06fef5e0 Michael Hanselmann
    if not success:
173 06fef5e0 Michael Hanselmann
      result = constants.EXIT_FAILURE
174 06fef5e0 Michael Hanselmann
175 b28a3e8b Michael Hanselmann
    ToStdout(msg)
176 d2b92ffc Michael Hanselmann
177 06fef5e0 Michael Hanselmann
  return result
178 d2b92ffc Michael Hanselmann
179 d2b92ffc Michael Hanselmann
180 191712c0 Iustin Pop
def ShowJobs(opts, args):
181 917b4e56 Iustin Pop
  """Show detailed information about jobs.
182 917b4e56 Iustin Pop

183 917b4e56 Iustin Pop
  @param opts: the command line options selected by the user
184 917b4e56 Iustin Pop
  @type args: list
185 917b4e56 Iustin Pop
  @param args: should contain the job IDs to be queried
186 917b4e56 Iustin Pop
  @rtype: int
187 917b4e56 Iustin Pop
  @return: the desired exit code
188 191712c0 Iustin Pop

189 191712c0 Iustin Pop
  """
190 c04bc777 Iustin Pop
  def format_msg(level, text):
191 191712c0 Iustin Pop
    """Display the text indented."""
192 3a24c527 Iustin Pop
    ToStdout("%s%s", "  " * level, text)
193 191712c0 Iustin Pop
194 191712c0 Iustin Pop
  def result_helper(value):
195 191712c0 Iustin Pop
    """Format a result field in a nice way."""
196 191712c0 Iustin Pop
    if isinstance(value, (tuple, list)):
197 1f864b60 Iustin Pop
      return "[%s]" % utils.CommaJoin(value)
198 191712c0 Iustin Pop
    else:
199 191712c0 Iustin Pop
      return str(value)
200 191712c0 Iustin Pop
201 aad81f98 Iustin Pop
  selected_fields = [
202 aad81f98 Iustin Pop
    "id", "status", "ops", "opresult", "opstatus", "oplog",
203 b9b5abcb Iustin Pop
    "opstart", "opexec", "opend", "received_ts", "start_ts", "end_ts",
204 aad81f98 Iustin Pop
    ]
205 191712c0 Iustin Pop
206 eba1aaad Michael Hanselmann
  result = GetClient().Query(constants.QR_JOB, selected_fields,
207 eba1aaad Michael Hanselmann
                             qlang.MakeSimpleFilter("id", args)).data
208 191712c0 Iustin Pop
209 191712c0 Iustin Pop
  first = True
210 191712c0 Iustin Pop
211 eba1aaad Michael Hanselmann
  for entry in result:
212 191712c0 Iustin Pop
    if not first:
213 c04bc777 Iustin Pop
      format_msg(0, "")
214 191712c0 Iustin Pop
    else:
215 191712c0 Iustin Pop
      first = False
216 aad81f98 Iustin Pop
217 eba1aaad Michael Hanselmann
    ((_, job_id), (rs_status, status), (_, ops), (_, opresult), (_, opstatus),
218 eba1aaad Michael Hanselmann
     (_, oplog), (_, opstart), (_, opexec), (_, opend), (_, recv_ts),
219 eba1aaad Michael Hanselmann
     (_, start_ts), (_, end_ts)) = entry
220 eba1aaad Michael Hanselmann
221 eba1aaad Michael Hanselmann
    # Detect non-normal results
222 eba1aaad Michael Hanselmann
    if rs_status != constants.RS_NORMAL:
223 eba1aaad Michael Hanselmann
      format_msg(0, "Job ID %s not found" % job_id)
224 aad81f98 Iustin Pop
      continue
225 aad81f98 Iustin Pop
226 c04bc777 Iustin Pop
    format_msg(0, "Job ID: %s" % job_id)
227 191712c0 Iustin Pop
    if status in _USER_JOB_STATUS:
228 191712c0 Iustin Pop
      status = _USER_JOB_STATUS[status]
229 191712c0 Iustin Pop
    else:
230 2f79bd34 Iustin Pop
      raise errors.ProgrammerError("Unknown job status code '%s'" % status)
231 191712c0 Iustin Pop
232 c04bc777 Iustin Pop
    format_msg(1, "Status: %s" % status)
233 aad81f98 Iustin Pop
234 aad81f98 Iustin Pop
    if recv_ts is not None:
235 c04bc777 Iustin Pop
      format_msg(1, "Received:         %s" % FormatTimestamp(recv_ts))
236 aad81f98 Iustin Pop
    else:
237 c04bc777 Iustin Pop
      format_msg(1, "Missing received timestamp (%s)" % str(recv_ts))
238 aad81f98 Iustin Pop
239 aad81f98 Iustin Pop
    if start_ts is not None:
240 aad81f98 Iustin Pop
      if recv_ts is not None:
241 aad81f98 Iustin Pop
        d1 = start_ts[0] - recv_ts[0] + (start_ts[1] - recv_ts[1]) / 1000000.0
242 aad81f98 Iustin Pop
        delta = " (delta %.6fs)" % d1
243 aad81f98 Iustin Pop
      else:
244 aad81f98 Iustin Pop
        delta = ""
245 c04bc777 Iustin Pop
      format_msg(1, "Processing start: %s%s" %
246 c04bc777 Iustin Pop
                 (FormatTimestamp(start_ts), delta))
247 aad81f98 Iustin Pop
    else:
248 c04bc777 Iustin Pop
      format_msg(1, "Processing start: unknown (%s)" % str(start_ts))
249 aad81f98 Iustin Pop
250 aad81f98 Iustin Pop
    if end_ts is not None:
251 aad81f98 Iustin Pop
      if start_ts is not None:
252 aad81f98 Iustin Pop
        d2 = end_ts[0] - start_ts[0] + (end_ts[1] - start_ts[1]) / 1000000.0
253 aad81f98 Iustin Pop
        delta = " (delta %.6fs)" % d2
254 aad81f98 Iustin Pop
      else:
255 aad81f98 Iustin Pop
        delta = ""
256 c04bc777 Iustin Pop
      format_msg(1, "Processing end:   %s%s" %
257 c04bc777 Iustin Pop
                 (FormatTimestamp(end_ts), delta))
258 aad81f98 Iustin Pop
    else:
259 c04bc777 Iustin Pop
      format_msg(1, "Processing end:   unknown (%s)" % str(end_ts))
260 aad81f98 Iustin Pop
261 aad81f98 Iustin Pop
    if end_ts is not None and recv_ts is not None:
262 aad81f98 Iustin Pop
      d3 = end_ts[0] - recv_ts[0] + (end_ts[1] - recv_ts[1]) / 1000000.0
263 c04bc777 Iustin Pop
      format_msg(1, "Total processing time: %.6f seconds" % d3)
264 aad81f98 Iustin Pop
    else:
265 c04bc777 Iustin Pop
      format_msg(1, "Total processing time: N/A")
266 c04bc777 Iustin Pop
    format_msg(1, "Opcodes:")
267 b9b5abcb Iustin Pop
    for (opcode, result, status, log, s_ts, x_ts, e_ts) in \
268 b9b5abcb Iustin Pop
            zip(ops, opresult, opstatus, oplog, opstart, opexec, opend):
269 c04bc777 Iustin Pop
      format_msg(2, "%s" % opcode["OP_ID"])
270 c04bc777 Iustin Pop
      format_msg(3, "Status: %s" % status)
271 aad81f98 Iustin Pop
      if isinstance(s_ts, (tuple, list)):
272 c04bc777 Iustin Pop
        format_msg(3, "Processing start: %s" % FormatTimestamp(s_ts))
273 aad81f98 Iustin Pop
      else:
274 c04bc777 Iustin Pop
        format_msg(3, "No processing start time")
275 b9b5abcb Iustin Pop
      if isinstance(x_ts, (tuple, list)):
276 c04bc777 Iustin Pop
        format_msg(3, "Execution start:  %s" % FormatTimestamp(x_ts))
277 b9b5abcb Iustin Pop
      else:
278 c04bc777 Iustin Pop
        format_msg(3, "No execution start time")
279 aad81f98 Iustin Pop
      if isinstance(e_ts, (tuple, list)):
280 c04bc777 Iustin Pop
        format_msg(3, "Processing end:   %s" % FormatTimestamp(e_ts))
281 aad81f98 Iustin Pop
      else:
282 c04bc777 Iustin Pop
        format_msg(3, "No processing end time")
283 c04bc777 Iustin Pop
      format_msg(3, "Input fields:")
284 598b5255 Michael Hanselmann
      for key in utils.NiceSort(opcode.keys()):
285 191712c0 Iustin Pop
        if key == "OP_ID":
286 191712c0 Iustin Pop
          continue
287 598b5255 Michael Hanselmann
        val = opcode[key]
288 191712c0 Iustin Pop
        if isinstance(val, (tuple, list)):
289 08db7c5c Iustin Pop
          val = ",".join([str(item) for item in val])
290 c04bc777 Iustin Pop
        format_msg(4, "%s: %s" % (key, val))
291 191712c0 Iustin Pop
      if result is None:
292 c04bc777 Iustin Pop
        format_msg(3, "No output data")
293 191712c0 Iustin Pop
      elif isinstance(result, (tuple, list)):
294 191712c0 Iustin Pop
        if not result:
295 c04bc777 Iustin Pop
          format_msg(3, "Result: empty sequence")
296 191712c0 Iustin Pop
        else:
297 c04bc777 Iustin Pop
          format_msg(3, "Result:")
298 191712c0 Iustin Pop
          for elem in result:
299 c04bc777 Iustin Pop
            format_msg(4, result_helper(elem))
300 191712c0 Iustin Pop
      elif isinstance(result, dict):
301 191712c0 Iustin Pop
        if not result:
302 c04bc777 Iustin Pop
          format_msg(3, "Result: empty dictionary")
303 191712c0 Iustin Pop
        else:
304 d1b47b16 Michael Hanselmann
          format_msg(3, "Result:")
305 191712c0 Iustin Pop
          for key, val in result.iteritems():
306 c04bc777 Iustin Pop
            format_msg(4, "%s: %s" % (key, result_helper(val)))
307 191712c0 Iustin Pop
      else:
308 c04bc777 Iustin Pop
        format_msg(3, "Result: %s" % result)
309 c04bc777 Iustin Pop
      format_msg(3, "Execution log:")
310 3386e7a9 Iustin Pop
      for serial, log_ts, log_type, log_msg in log:
311 3386e7a9 Iustin Pop
        time_txt = FormatTimestamp(log_ts)
312 8a7f1c61 Michael Hanselmann
        encoded = FormatLogMessage(log_type, log_msg)
313 c04bc777 Iustin Pop
        format_msg(4, "%s:%s:%s %s" % (serial, time_txt, log_type, encoded))
314 191712c0 Iustin Pop
  return 0
315 191712c0 Iustin Pop
316 191712c0 Iustin Pop
317 e7d6946c Michael Hanselmann
def WatchJob(opts, args):
318 e7d6946c Michael Hanselmann
  """Follow a job and print its output as it arrives.
319 e7d6946c Michael Hanselmann

320 e7d6946c Michael Hanselmann
  @param opts: the command line options selected by the user
321 e7d6946c Michael Hanselmann
  @type args: list
322 e7d6946c Michael Hanselmann
  @param args: Contains the job ID
323 e7d6946c Michael Hanselmann
  @rtype: int
324 e7d6946c Michael Hanselmann
  @return: the desired exit code
325 e7d6946c Michael Hanselmann

326 e7d6946c Michael Hanselmann
  """
327 e7d6946c Michael Hanselmann
  job_id = args[0]
328 e7d6946c Michael Hanselmann
329 e7d6946c Michael Hanselmann
  msg = ("Output from job %s follows" % job_id)
330 e7d6946c Michael Hanselmann
  ToStdout(msg)
331 e7d6946c Michael Hanselmann
  ToStdout("-" * len(msg))
332 e7d6946c Michael Hanselmann
333 e7d6946c Michael Hanselmann
  retcode = 0
334 e7d6946c Michael Hanselmann
  try:
335 e7d6946c Michael Hanselmann
    cli.PollJob(job_id)
336 e7d6946c Michael Hanselmann
  except errors.GenericError, err:
337 e7d6946c Michael Hanselmann
    (retcode, job_result) = cli.FormatError(err)
338 e7d6946c Michael Hanselmann
    ToStderr("Job %s failed: %s", job_id, job_result)
339 e7d6946c Michael Hanselmann
340 e7d6946c Michael Hanselmann
  return retcode
341 e7d6946c Michael Hanselmann
342 e7d6946c Michael Hanselmann
343 f037e9d7 Michael Hanselmann
_PENDING_OPT = \
344 f037e9d7 Michael Hanselmann
  cli_option("--pending", default=None,
345 f037e9d7 Michael Hanselmann
             action="store_const", dest="status_filter",
346 f037e9d7 Michael Hanselmann
             const=frozenset([
347 f037e9d7 Michael Hanselmann
               constants.JOB_STATUS_QUEUED,
348 f037e9d7 Michael Hanselmann
               constants.JOB_STATUS_WAITING,
349 f037e9d7 Michael Hanselmann
               ]),
350 f037e9d7 Michael Hanselmann
             help="Show only jobs pending execution")
351 f037e9d7 Michael Hanselmann
352 f037e9d7 Michael Hanselmann
_RUNNING_OPT = \
353 f037e9d7 Michael Hanselmann
  cli_option("--running", default=None,
354 f037e9d7 Michael Hanselmann
             action="store_const", dest="status_filter",
355 f037e9d7 Michael Hanselmann
             const=frozenset([
356 f037e9d7 Michael Hanselmann
               constants.JOB_STATUS_RUNNING,
357 f037e9d7 Michael Hanselmann
               ]),
358 f037e9d7 Michael Hanselmann
             help="Show jobs currently running only")
359 f037e9d7 Michael Hanselmann
360 f037e9d7 Michael Hanselmann
_ERROR_OPT = \
361 f037e9d7 Michael Hanselmann
  cli_option("--error", default=None,
362 f037e9d7 Michael Hanselmann
             action="store_const", dest="status_filter",
363 f037e9d7 Michael Hanselmann
             const=frozenset([
364 f037e9d7 Michael Hanselmann
               constants.JOB_STATUS_ERROR,
365 f037e9d7 Michael Hanselmann
               ]),
366 f037e9d7 Michael Hanselmann
             help="Show failed jobs only")
367 f037e9d7 Michael Hanselmann
368 f037e9d7 Michael Hanselmann
_FINISHED_OPT = \
369 f037e9d7 Michael Hanselmann
  cli_option("--finished", default=None,
370 f037e9d7 Michael Hanselmann
             action="store_const", dest="status_filter",
371 f037e9d7 Michael Hanselmann
             const=constants.JOBS_FINALIZED,
372 f037e9d7 Michael Hanselmann
             help="Show finished jobs only")
373 f037e9d7 Michael Hanselmann
374 f037e9d7 Michael Hanselmann
375 7a1ecaed Iustin Pop
commands = {
376 d0c8c01d Iustin Pop
  "list": (
377 6ea815cf Iustin Pop
    ListJobs, [ArgJobId()],
378 f037e9d7 Michael Hanselmann
    [NOHDR_OPT, SEP_OPT, FIELDS_OPT, VERBOSE_OPT, FORCE_FILTER_OPT,
379 f037e9d7 Michael Hanselmann
     _PENDING_OPT, _RUNNING_OPT, _ERROR_OPT, _FINISHED_OPT],
380 6ea815cf Iustin Pop
    "[job_id ...]",
381 3086220e Michael Hanselmann
    "Lists the jobs and their status. The available fields can be shown"
382 3086220e Michael Hanselmann
    " using the \"list-fields\" command (see the man page for details)."
383 3086220e Michael Hanselmann
    " The default field list is (in order): %s." %
384 3086220e Michael Hanselmann
    utils.CommaJoin(_LIST_DEF_FIELDS)),
385 3086220e Michael Hanselmann
  "list-fields": (
386 3086220e Michael Hanselmann
    ListJobFields, [ArgUnknown()],
387 3086220e Michael Hanselmann
    [NOHDR_OPT, SEP_OPT],
388 3086220e Michael Hanselmann
    "[fields...]",
389 3086220e Michael Hanselmann
    "Lists all available fields for jobs"),
390 d0c8c01d Iustin Pop
  "archive": (
391 064c21f8 Iustin Pop
    ArchiveJobs, [ArgJobId(min=1)], [],
392 6ea815cf Iustin Pop
    "<job-id> [<job-id> ...]", "Archive specified jobs"),
393 d0c8c01d Iustin Pop
  "autoarchive": (
394 6ea815cf Iustin Pop
    AutoArchiveJobs,
395 94182b63 Iustin Pop
    [ArgSuggest(min=1, max=1, choices=["1d", "1w", "4w", "all"])],
396 064c21f8 Iustin Pop
    [],
397 6ea815cf Iustin Pop
    "<age>", "Auto archive jobs older than the given age"),
398 d0c8c01d Iustin Pop
  "cancel": (
399 064c21f8 Iustin Pop
    CancelJobs, [ArgJobId(min=1)], [],
400 6ea815cf Iustin Pop
    "<job-id> [<job-id> ...]", "Cancel specified jobs"),
401 d0c8c01d Iustin Pop
  "info": (
402 064c21f8 Iustin Pop
    ShowJobs, [ArgJobId(min=1)], [],
403 6ea815cf Iustin Pop
    "<job-id> [<job-id> ...]",
404 6ea815cf Iustin Pop
    "Show detailed information about the specified jobs"),
405 d0c8c01d Iustin Pop
  "watch": (
406 064c21f8 Iustin Pop
    WatchJob, [ArgJobId(min=1, max=1)], [],
407 6ea815cf Iustin Pop
    "<job-id>", "Follows a job and prints its output as it arrives"),
408 7a1ecaed Iustin Pop
  }
409 7a1ecaed Iustin Pop
410 7a1ecaed Iustin Pop
411 029fe503 Guido Trotter
#: dictionary with aliases for commands
412 029fe503 Guido Trotter
aliases = {
413 029fe503 Guido Trotter
  "show": "info",
414 029fe503 Guido Trotter
  }
415 029fe503 Guido Trotter
416 029fe503 Guido Trotter
417 a09b9e3d Michael Hanselmann
def Main():
418 029fe503 Guido Trotter
  return GenericMain(commands, aliases=aliases)