Add an interface for the drain flag changes/query
authorIustin Pop <iustin@google.com>
Thu, 16 Oct 2008 08:37:00 +0000 (08:37 +0000)
committerIustin Pop <iustin@google.com>
Thu, 16 Oct 2008 08:37:00 +0000 (08:37 +0000)
This adds the set/reset in the jqueue and luxi modules, and a way to
query it in OpQueryConfigValues, and also the comand line interface for
it:
$ gnt-cluster queue info
The drain flag is unset
$ gnt-cluster queue drain
$ gnt-cluster queue info
The drain flag is set
$ gnt-cluster queue undrain
$ gnt-cluster queue info
The drain flag is unset

The choice of making the setting via luxi and not an opcode is that
opcodes can't be executed when drained, but we don't query via luxi
since in the future it might become a cluster property as opposed to a
node one.

Reviewed-by: imsnah

daemons/ganeti-masterd
lib/cmdlib.py
lib/jqueue.py
lib/luxi.py
scripts/gnt-cluster

index 6fdf4e7..fc1411d 100755 (executable)
@@ -252,6 +252,10 @@ class ClientOps:
       op = opcodes.OpQueryConfigValues(output_fields=fields)
       return self._Query(op)
 
+    elif method == luxi.REQ_QUEUE_SET_DRAIN_FLAG:
+      drain_flag = args
+      return queue.SetDrainFlag(drain_flag)
+
     else:
       raise ValueError("Invalid operation")
 
index dafb621..9a1e0bb 100644 (file)
@@ -1891,7 +1891,7 @@ class LUQueryConfigValues(NoHooksLU):
   def ExpandNames(self):
     self.needed_locks = {}
 
-    static_fields = ["cluster_name", "master_node"]
+    static_fields = ["cluster_name", "master_node", "drain_flag"]
     _CheckOutputFields(static=static_fields,
                        dynamic=[],
                        selected=self.op.output_fields)
@@ -1909,11 +1909,14 @@ class LUQueryConfigValues(NoHooksLU):
     values = []
     for field in self.op.output_fields:
       if field == "cluster_name":
-        values.append(self.cfg.GetClusterName())
+        entry = self.cfg.GetClusterName()
       elif field == "master_node":
-        values.append(self.cfg.GetMasterNode())
+        entry = self.cfg.GetMasterNode()
+      elif field == "drain_flag":
+        entry = os.path.exists(constants.JOB_QUEUE_DRAIN_FILE)
       else:
         raise errors.ParameterError(field)
+      values.append(entry)
     return values
 
 
index 478bd78..e5e71b2 100644 (file)
@@ -574,6 +574,20 @@ class JobQueue(object):
     """
     return os.path.exists(constants.JOB_QUEUE_DRAIN_FILE)
 
+  @staticmethod
+  def SetDrainFlag(drain_flag):
+    """Sets the drain flag for the queue.
+
+    This is similar to the function L{backend.JobQueueSetDrainFlag},
+    and in the future we might merge them.
+
+    """
+    if drain_flag:
+      utils.WriteFile(constants.JOB_QUEUE_DRAIN_FILE, data="", close=True)
+    else:
+      utils.RemoveFile(constants.JOB_QUEUE_DRAIN_FILE)
+    return True
+
   @utils.LockedMethod
   @_RequireOpenQueue
   def SubmitJob(self, ops):
index 9117253..7ade2b5 100644 (file)
@@ -54,6 +54,7 @@ REQ_QUERY_INSTANCES = "QueryInstances"
 REQ_QUERY_NODES = "QueryNodes"
 REQ_QUERY_EXPORTS = "QueryExports"
 REQ_QUERY_CONFIG_VALUES = "QueryConfigValues"
+REQ_QUEUE_SET_DRAIN_FLAG = "SetDrainFlag"
 
 DEF_CTMO = 10
 DEF_RWTO = 60
@@ -291,6 +292,9 @@ class Client(object):
 
     return result
 
+  def SetQueueDrainFlag(self, drain_flag):
+    return self.CallMethod(REQ_QUEUE_SET_DRAIN_FLAG, drain_flag)
+
   def SubmitJob(self, ops):
     ops_state = map(lambda op: op.__getstate__(), ops)
     return self.CallMethod(REQ_SUBMIT_JOB, ops_state)
@@ -329,4 +333,5 @@ class Client(object):
   def QueryConfigValues(self, fields):
     return self.CallMethod(REQ_QUERY_CONFIG_VALUES, fields)
 
+
 # TODO: class Server(object)
index fbc8cbf..435e1cb 100755 (executable)
@@ -343,6 +343,24 @@ def SetClusterParams(opts, args):
   return 0
 
 
+def QueueOps(opts, args):
+  """Queue operations.
+
+  """
+  command = args[0]
+  client = GetClient()
+  if command in ("drain", "undrain"):
+    drain_flag = command == "drain"
+    client.SetQueueDrainFlag(drain_flag)
+  elif command == "info":
+    result = client.QueryConfigValues(["drain_flag"])
+    print "The drain flag is",
+    if result[0]:
+      print "set"
+    else:
+      print "unset"
+  return 0
+
 # this is an option common to more than one command, so we declare
 # it here and reuse it
 node_option = make_option("-n", "--node", action="append", dest="nodes",
@@ -443,6 +461,8 @@ commands = {
   'search-tags': (SearchTags, ARGS_ONE,
                   [DEBUG_OPT], "", "Searches the tags on all objects on"
                   " the cluster for a given pattern (regex)"),
+  'queue': (QueueOps, ARGS_ONE, [DEBUG_OPT],
+            "drain|undrain|info", "Change queue properties"),
   'modify': (SetClusterParams, ARGS_NONE,
              [DEBUG_OPT,
               make_option("-g", "--vg-name", dest="vg_name",