LUSetInstanceParams: nic parameters
[ganeti-local] / scripts / gnt-job
index 88bf3ce..2da75a3 100755 (executable)
@@ -28,13 +28,18 @@ import sys
 from ganeti.cli import *
 from ganeti import constants
 from ganeti import errors
 from ganeti.cli import *
 from ganeti import constants
 from ganeti import errors
+from ganeti import utils
 
 
 
 
+#: default list of fields for L{ListJobs}
 _LIST_DEF_FIELDS = ["id", "status", "summary"]
 
 _LIST_DEF_FIELDS = ["id", "status", "summary"]
 
+#: map converting the job status contants to user-visible
+#: names
 _USER_JOB_STATUS = {
   constants.JOB_STATUS_QUEUED: "queued",
   constants.JOB_STATUS_WAITLOCK: "waiting",
 _USER_JOB_STATUS = {
   constants.JOB_STATUS_QUEUED: "queued",
   constants.JOB_STATUS_WAITLOCK: "waiting",
+  constants.JOB_STATUS_CANCELING: "canceling",
   constants.JOB_STATUS_RUNNING: "running",
   constants.JOB_STATUS_CANCELED: "canceled",
   constants.JOB_STATUS_SUCCESS: "success",
   constants.JOB_STATUS_RUNNING: "running",
   constants.JOB_STATUS_CANCELED: "canceled",
   constants.JOB_STATUS_SUCCESS: "success",
@@ -45,6 +50,12 @@ _USER_JOB_STATUS = {
 def ListJobs(opts, args):
   """List the jobs
 
 def ListJobs(opts, args):
   """List the jobs
 
+  @param opts: the command line options selected by the user
+  @type args: list
+  @param args: should be an empty list
+  @rtype: int
+  @return: the desired exit code
+
   """
   if opts.output is None:
     selected_fields = _LIST_DEF_FIELDS
   """
   if opts.output is None:
     selected_fields = _LIST_DEF_FIELDS
@@ -53,7 +64,7 @@ def ListJobs(opts, args):
   else:
     selected_fields = opts.output.split(",")
 
   else:
     selected_fields = opts.output.split(",")
 
-  output = GetClient().QueryJobs(None, selected_fields)
+  output = GetClient().QueryJobs(args, selected_fields)
   if not opts.no_headers:
     # TODO: Implement more fields
     headers = {
   if not opts.no_headers:
     # TODO: Implement more fields
     headers = {
@@ -73,12 +84,12 @@ def ListJobs(opts, args):
   else:
     headers = None
 
   else:
     headers = None
 
-  # we don't have yet unitfields here
-  unitfields = None
-  numfields = None
-
   # change raw values to nicer strings
   # change raw values to nicer strings
-  for row in output:
+  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":
     for idx, field in enumerate(selected_fields):
       val = row[idx]
       if field == "status":
@@ -96,8 +107,7 @@ def ListJobs(opts, args):
       row[idx] = str(val)
 
   data = GenerateTable(separator=opts.separator, headers=headers,
       row[idx] = str(val)
 
   data = GenerateTable(separator=opts.separator, headers=headers,
-                       fields=selected_fields, unitfields=unitfields,
-                       numfields=numfields, data=output)
+                       fields=selected_fields, data=output)
   for line in data:
     ToStdout(line)
 
   for line in data:
     ToStdout(line)
 
@@ -105,6 +115,15 @@ def ListJobs(opts, args):
 
 
 def ArchiveJobs(opts, args):
 
 
 def ArchiveJobs(opts, args):
+  """Archive jobs.
+
+  @param opts: the command line options selected by the user
+  @type args: list
+  @param args: should contain the job IDs to be archived
+  @rtype: int
+  @return: the desired exit code
+
+  """
   client = GetClient()
 
   for job_id in args:
   client = GetClient()
 
   for job_id in args:
@@ -114,6 +133,20 @@ def ArchiveJobs(opts, args):
 
 
 def AutoArchiveJobs(opts, args):
 
 
 def AutoArchiveJobs(opts, args):
+  """Archive jobs based on age.
+
+  This will archive jobs based on their age, or all jobs if a 'all' is
+  passed.
+
+  @param opts: the command line options selected by the user
+  @type args: list
+  @param args: should contain only one element, the age as a time spec
+      that can be parsed by L{ganeti.cli.ParseTimespec} or the
+      keyword I{all}, which will cause all jobs to be archived
+  @rtype: int
+  @return: the desired exit code
+
+  """
   client = GetClient()
 
   age = args[0]
   client = GetClient()
 
   age = args[0]
@@ -123,21 +156,40 @@ def AutoArchiveJobs(opts, args):
   else:
     age = ParseTimespec(age)
 
   else:
     age = ParseTimespec(age)
 
-  client.AutoArchiveJobs(age)
+  (archived_count, jobs_left) = client.AutoArchiveJobs(age)
+  ToStdout("Archived %s jobs, %s unchecked left", archived_count, jobs_left)
+
   return 0
 
 
 def CancelJobs(opts, args):
   return 0
 
 
 def CancelJobs(opts, args):
+  """Cancel not-yet-started jobs.
+
+  @param opts: the command line options selected by the user
+  @type args: list
+  @param args: should contain the job IDs to be cancelled
+  @rtype: int
+  @return: the desired exit code
+
+  """
   client = GetClient()
 
   for job_id in args:
   client = GetClient()
 
   for job_id in args:
-    client.CancelJob(job_id)
+    (success, msg) = client.CancelJob(job_id)
+    ToStdout(msg)
 
 
+  # TODO: Different exit value if not all jobs were canceled?
   return 0
 
 
 def ShowJobs(opts, args):
   return 0
 
 
 def ShowJobs(opts, args):
-  """List the jobs
+  """Show detailed information about jobs.
+
+  @param opts: the command line options selected by the user
+  @type args: list
+  @param args: should contain the job IDs to be queried
+  @rtype: int
+  @return: the desired exit code
 
   """
   def format(level, text):
 
   """
   def format(level, text):
@@ -233,7 +285,7 @@ def ShowJobs(opts, args):
         if key == "OP_ID":
           continue
         if isinstance(val, (tuple, list)):
         if key == "OP_ID":
           continue
         if isinstance(val, (tuple, list)):
-          val = ",".join(val)
+          val = ",".join([str(item) for item in val])
         format(4, "%s: %s" % (key, val))
       if result is None:
         format(3, "No output data")
         format(4, "%s: %s" % (key, val))
       if result is None:
         format(3, "No output data")
@@ -255,15 +307,16 @@ def ShowJobs(opts, args):
       format(3, "Execution log:")
       for serial, log_ts, log_type, log_msg in log:
         time_txt = FormatTimestamp(log_ts)
       format(3, "Execution log:")
       for serial, log_ts, log_type, log_msg in log:
         time_txt = FormatTimestamp(log_ts)
-        encoded = str(log_msg).encode('string_escape')
+        encoded = utils.SafeEncode(log_msg)
         format(4, "%s:%s:%s %s" % (serial, time_txt, log_type, encoded))
   return 0
 
 
 commands = {
         format(4, "%s:%s:%s %s" % (serial, time_txt, log_type, encoded))
   return 0
 
 
 commands = {
-  'list': (ListJobs, ARGS_NONE,
-            [DEBUG_OPT, NOHDR_OPT, SEP_OPT, USEUNITS_OPT, FIELDS_OPT],
-            "", "List the jobs and their status. The available fields are"
+  'list': (ListJobs, ARGS_ANY,
+            [DEBUG_OPT, NOHDR_OPT, SEP_OPT, FIELDS_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"
            " (see the man page for details): id, status, op_list,"
            " op_status, op_result."
            " The default field"