Revision 087f5520

b/lib/client/gnt_job.py
286 286
  @return: the desired exit code
287 287

  
288 288
  """
289
  def format_msg(level, text):
290
    """Display the text indented."""
291
    ToStdout("%s%s", "  " * level, text)
292

  
293
  def result_helper(value):
294
    """Format a result field in a nice way."""
295
    if isinstance(value, (tuple, list)):
296
      return "[%s]" % utils.CommaJoin(value)
297
    else:
298
      return str(value)
299

  
300 289
  selected_fields = [
301 290
    "id", "status", "ops", "opresult", "opstatus", "oplog",
302 291
    "opstart", "opexec", "opend", "received_ts", "start_ts", "end_ts",
......
306 295
  cl = GetClient()
307 296
  result = cl.Query(constants.QR_JOB, selected_fields, qfilter).data
308 297

  
309
  first = True
298
  job_info_container = []
310 299

  
311 300
  for entry in result:
312
    if not first:
313
      format_msg(0, "")
314
    else:
315
      first = False
316

  
317 301
    ((_, job_id), (rs_status, status), (_, ops), (_, opresult), (_, opstatus),
318 302
     (_, oplog), (_, opstart), (_, opexec), (_, opend), (_, recv_ts),
319 303
     (_, start_ts), (_, end_ts)) = entry
320 304

  
321 305
    # Detect non-normal results
322 306
    if rs_status != constants.RS_NORMAL:
323
      format_msg(0, "Job ID %s not found" % job_id)
307
      job_info_container.append("Job ID %s not found" % job_id)
324 308
      continue
325 309

  
326
    format_msg(0, "Job ID: %s" % job_id)
310
    # Container for produced data
311
    job_info = [("Job ID", job_id)]
312

  
327 313
    if status in _USER_JOB_STATUS:
328 314
      status = _USER_JOB_STATUS[status]
329 315
    else:
330 316
      raise errors.ProgrammerError("Unknown job status code '%s'" % status)
331 317

  
332
    format_msg(1, "Status: %s" % status)
318
    job_info.append(("Status", status))
333 319

  
334 320
    if recv_ts is not None:
335
      format_msg(1, "Received:         %s" % FormatTimestamp(recv_ts))
321
      job_info.append(("Received", FormatTimestamp(recv_ts)))
336 322
    else:
337
      format_msg(1, "Missing received timestamp (%s)" % str(recv_ts))
323
      job_info.append(("Received", "unknown (%s)" % str(recv_ts)))
338 324

  
339 325
    if start_ts is not None:
340 326
      if recv_ts is not None:
......
342 328
        delta = " (delta %.6fs)" % d1
343 329
      else:
344 330
        delta = ""
345
      format_msg(1, "Processing start: %s%s" %
346
                 (FormatTimestamp(start_ts), delta))
331
      job_info.append(("Processing start", "%s%s" %
332
                       (FormatTimestamp(start_ts), delta)))
347 333
    else:
348
      format_msg(1, "Processing start: unknown (%s)" % str(start_ts))
334
      job_info.append(("Processing start", "unknown (%s)" % str(start_ts)))
349 335

  
350 336
    if end_ts is not None:
351 337
      if start_ts is not None:
......
353 339
        delta = " (delta %.6fs)" % d2
354 340
      else:
355 341
        delta = ""
356
      format_msg(1, "Processing end:   %s%s" %
357
                 (FormatTimestamp(end_ts), delta))
342
      job_info.append(("Processing end", "%s%s" %
343
                       (FormatTimestamp(end_ts), delta)))
358 344
    else:
359
      format_msg(1, "Processing end:   unknown (%s)" % str(end_ts))
345
      job_info.append(("Processing end", "unknown (%s)" % str(end_ts)))
360 346

  
361 347
    if end_ts is not None and recv_ts is not None:
362 348
      d3 = end_ts[0] - recv_ts[0] + (end_ts[1] - recv_ts[1]) / 1000000.0
363
      format_msg(1, "Total processing time: %.6f seconds" % d3)
349
      job_info.append(("Total processing time", "%.6f seconds" % d3))
364 350
    else:
365
      format_msg(1, "Total processing time: N/A")
366
    format_msg(1, "Opcodes:")
351
      job_info.append(("Total processing time", "N/A"))
352

  
353
    opcode_container = []
367 354
    for (opcode, result, status, log, s_ts, x_ts, e_ts) in \
368 355
            zip(ops, opresult, opstatus, oplog, opstart, opexec, opend):
369
      format_msg(2, "%s" % opcode["OP_ID"])
370
      format_msg(3, "Status: %s" % status)
356
      opcode_info = []
357
      opcode_info.append(("Opcode", opcode["OP_ID"]))
358
      opcode_info.append(("Status", status))
359

  
371 360
      if isinstance(s_ts, (tuple, list)):
372
        format_msg(3, "Processing start: %s" % FormatTimestamp(s_ts))
361
        opcode_info.append(("Processing start", FormatTimestamp(s_ts)))
373 362
      else:
374
        format_msg(3, "No processing start time")
363
        opcode_info.append(("Processing start", "N/A"))
364

  
375 365
      if isinstance(x_ts, (tuple, list)):
376
        format_msg(3, "Execution start:  %s" % FormatTimestamp(x_ts))
366
        opcode_info.append(("Execution start", FormatTimestamp(x_ts)))
377 367
      else:
378
        format_msg(3, "No execution start time")
368
        opcode_info.append(("Execution start", "N/A"))
369

  
379 370
      if isinstance(e_ts, (tuple, list)):
380
        format_msg(3, "Processing end:   %s" % FormatTimestamp(e_ts))
371
        opcode_info.append(("Processing end", FormatTimestamp(e_ts)))
381 372
      else:
382
        format_msg(3, "No processing end time")
383
      format_msg(3, "Input fields:")
384
      for key in utils.NiceSort(opcode.keys()):
385
        if key == "OP_ID":
386
          continue
387
        val = opcode[key]
388
        if isinstance(val, (tuple, list)):
389
          val = ",".join([str(item) for item in val])
390
        format_msg(4, "%s: %s" % (key, val))
391
      if result is None:
392
        format_msg(3, "No output data")
393
      elif isinstance(result, (tuple, list)):
394
        if not result:
395
          format_msg(3, "Result: empty sequence")
396
        else:
397
          format_msg(3, "Result:")
398
          for elem in result:
399
            format_msg(4, result_helper(elem))
400
      elif isinstance(result, dict):
401
        if not result:
402
          format_msg(3, "Result: empty dictionary")
403
        else:
404
          format_msg(3, "Result:")
405
          for key, val in result.iteritems():
406
            format_msg(4, "%s: %s" % (key, result_helper(val)))
407
      else:
408
        format_msg(3, "Result: %s" % result)
409
      format_msg(3, "Execution log:")
373
        opcode_info.append(("Processing end", "N/A"))
374

  
375
      opcode_info.append(("Input fields", opcode))
376
      opcode_info.append(("Result", result))
377

  
378
      exec_log_container = []
410 379
      for serial, log_ts, log_type, log_msg in log:
411 380
        time_txt = FormatTimestamp(log_ts)
412 381
        encoded = FormatLogMessage(log_type, log_msg)
413
        format_msg(4, "%s:%s:%s %s" % (serial, time_txt, log_type, encoded))
382

  
383
        # Arranged in this curious way to preserve the brevity for multiple
384
        # logs. This content cannot be exposed as a 4-tuple, as time contains
385
        # the colon, causing some YAML parsers to fail.
386
        exec_log_info = [("Time", time_txt),
387
                         ("Content", (serial, log_type, encoded,)),
388
                        ]
389
        exec_log_container.append(exec_log_info)
390
      opcode_info.append(("Execution log", exec_log_container))
391

  
392
      opcode_container.append(opcode_info)
393

  
394
    job_info.append(("Opcodes", opcode_container))
395
    job_info_container.append(job_info)
396

  
397
  PrintGenericInfo(job_info_container)
398

  
414 399
  return 0
415 400

  
416 401

  

Also available in: Unified diff