Xen: remove two end-of-line semicolons
[ganeti-local] / lib / cli.py
index 167f28c..af05684 100644 (file)
@@ -32,16 +32,16 @@ from cStringIO import StringIO
 from ganeti import utils
 from ganeti import logger
 from ganeti import errors
-from ganeti import mcpu
 from ganeti import constants
 from ganeti import opcodes
 from ganeti import luxi
+from ganeti import ssconf
 
 from optparse import (OptionParser, make_option, TitledHelpFormatter,
-                      Option, OptionValueError, SUPPRESS_HELP)
+                      Option, OptionValueError)
 
 __all__ = ["DEBUG_OPT", "NOHDR_OPT", "SEP_OPT", "GenericMain",
-           "SubmitOpCode", "SubmitJob", "SubmitQuery",
+           "SubmitOpCode", "GetClient",
            "cli_option", "GenerateTable", "AskUser",
            "ARGS_NONE", "ARGS_FIXED", "ARGS_ATLEAST", "ARGS_ANY", "ARGS_ONE",
            "USEUNITS_OPT", "FIELDS_OPT", "FORCE_OPT",
@@ -369,56 +369,63 @@ def AskUser(text, choices=None):
   return answer
 
 
-def SubmitOpCode(op, proc=None, feedback_fn=None):
-  """Function to submit an opcode.
+def SubmitOpCode(op, cl=None, feedback_fn=None):
+  """Legacy function to submit an opcode.
 
   This is just a simple wrapper over the construction of the processor
   instance. It should be extended to better handle feedback and
   interaction functions.
 
   """
-  # TODO: Fix feedback_fn situation.
-  cl = luxi.Client()
-  job = opcodes.Job(op_list=[op])
-  jid = SubmitJob(job)
+  if cl is None:
+    cl = GetClient()
 
-  query = {
-    "object": "jobs",
-    "fields": ["status"],
-    "names": [jid],
-    }
+  job_id = cl.SubmitJob([op])
 
+  lastmsg = None
   while True:
-    jdata = SubmitQuery(query)
-    if not jdata:
+    jobs = cl.QueryJobs([job_id], ["status", "ticker"])
+    if not jobs:
       # job not found, go away!
-      raise errors.JobLost("Job with id %s lost" % jid)
+      raise errors.JobLost("Job with id %s lost" % job_id)
 
-    status = jdata[0][0]
-    if status in (opcodes.Job.STATUS_SUCCESS, opcodes.Job.STATUS_FAIL):
+    # TODO: Handle canceled and archived jobs
+    status = jobs[0][0]
+    if status in (constants.JOB_STATUS_SUCCESS, constants.JOB_STATUS_ERROR):
       break
+    msg = jobs[0][1]
+    if msg is not None and msg != lastmsg:
+      if callable(feedback_fn):
+        feedback_fn(msg)
+      else:
+        print "%s %s" % (time.ctime(msg[0]), msg[2])
+    lastmsg = msg
     time.sleep(1)
 
-  query["fields"].extend(["op_list", "op_status", "op_result"])
-  jdata = SubmitQuery(query)
-  if not jdata:
-    raise errors.JobLost("Job with id %s lost" % jid)
-  status, op_list, op_status, op_result = jdata[0]
-  if status != opcodes.Job.STATUS_SUCCESS:
-    raise errors.OpExecError(op_result[0])
-  return op_result[0]
+  jobs = cl.QueryJobs([job_id], ["status", "opresult"])
+  if not jobs:
+    raise errors.JobLost("Job with id %s lost" % job_id)
 
-
-def SubmitJob(job, cl=None):
-  if cl is None:
-    cl = luxi.Client()
-  return cl.SubmitJob(job)
+  status, result = jobs[0]
+  if status == constants.JOB_STATUS_SUCCESS:
+    return result[0]
+  else:
+    raise errors.OpExecError(result)
 
 
-def SubmitQuery(data, cl=None):
-  if cl is None:
-    cl = luxi.Client()
-  return cl.Query(data)
+def GetClient():
+  # TODO: Cache object?
+  try:
+    client = luxi.Client()
+  except luxi.NoMasterError:
+    master, myself = ssconf.GetMasterAndMyself()
+    if master != myself:
+      raise errors.OpPrereqError("This is not the master node, please connect"
+                                 " to node '%s' and rerun the command" %
+                                 master)
+    else:
+      raise
+  return client
 
 
 def FormatError(err):
@@ -515,7 +522,8 @@ def GenericMain(commands, override=None, aliases=None):
     for key, val in override.iteritems():
       setattr(options, key, val)
 
-  logger.SetupLogging(program=binary, debug=options.debug)
+  logger.SetupLogging(constants.LOG_COMMANDS, debug=options.debug,
+                      stderr_logging=True, program=binary)
 
   utils.debug = options.debug