Switch gnt-node evacuate to the new opcode
authorIustin Pop <iustin@google.com>
Wed, 17 Feb 2010 16:41:26 +0000 (17:41 +0100)
committerIustin Pop <iustin@google.com>
Mon, 22 Feb 2010 12:50:44 +0000 (13:50 +0100)
This switches gnt-node to the new opcode, and in the process also
enables multi-node arguments for it.

Signed-off-by: Iustin Pop <iustin@google.com>
Reviewed-by: Michael Hanselmann <hansmi@google.com>

man/gnt-node.sgml
scripts/gnt-node

index c1980f2..9f1c8fb 100644 (file)
           <arg>--iallocator <replaceable>NAME</replaceable></arg>
           <arg>--new-secondary <replaceable>destination_node</replaceable></arg>
         </group>
-        <arg choice="req"><replaceable>node</replaceable></arg>
+        <arg choice="req" rep="repeat"><replaceable>node</replaceable></arg>
       </cmdsynopsis>
 
       <para>
         This command will move all secondary instances away from the
-        given node. It works only for instances having a drbd disk
+        given node(s). It works only for instances having a drbd disk
         template.
       </para>
 
index 3e9b0b4..55d36bc 100755 (executable)
@@ -255,41 +255,42 @@ def EvacuateNode(opts, args):
     raise errors.OpPrereqError("One and only one of the -n and -I"
                                " options must be passed", errors.ECODE_INVAL)
 
-  selected_fields = ["name", "sinst_list"]
-  src_node = args[0]
-
-  result = cl.QueryNodes(names=[src_node], fields=selected_fields,
-                         use_locking=False)
-  src_node, sinst = result[0]
-
-  if not sinst:
-    ToStderr("No secondary instances on node %s, exiting.", src_node)
+  op = opcodes.OpNodeEvacuationStrategy(nodes=args,
+                                        iallocator=iallocator,
+                                        remote_node=dst_node)
+
+  result = SubmitOpCode(op, cl=cl, opts=opts)
+  if not result:
+    # no instances to migrate
+    ToStderr("No secondary instances on node(s) %s, exiting.",
+             utils.CommaJoin(args))
     return constants.EXIT_SUCCESS
 
-  if dst_node is not None:
-    result = cl.QueryNodes(names=[dst_node], fields=["name"],
-                           use_locking=False)
-    dst_node = result[0][0]
-
-    if src_node == dst_node:
-      raise errors.OpPrereqError("Evacuate node needs different source and"
-                                 " target nodes (node %s given twice)" %
-                                 src_node, errors.ECODE_INVAL)
-    txt_msg = "to node %s" % dst_node
-  else:
-    txt_msg = "using iallocator %s" % iallocator
-
-  sinst = utils.NiceSort(sinst)
-
-  if not force and not AskUser("Relocate instance(s) %s from node\n"
-                               " %s %s?" %
-                               (",".join("'%s'" % name for name in sinst),
-                               src_node, txt_msg)):
+  if not force and not AskUser("Relocate instance(s) %s from node(s) %s?" %
+                               (",".join("'%s'" % name[0] for name in result),
+                               utils.CommaJoin(args))):
     return constants.EXIT_CONFIRMATION
 
-  op = opcodes.OpEvacuateNode(node_name=args[0], remote_node=dst_node,
-                              iallocator=iallocator)
-  SubmitOpCode(op, cl=cl, opts=opts)
+  jex = JobExecutor(cl=cl, opts=opts)
+  for row in result:
+    iname = row[0]
+    node = row[1]
+    ToStdout("Will relocate instance %s to node %s", iname, node)
+    op = opcodes.OpReplaceDisks(instance_name=iname,
+                                remote_node=node, disks=[],
+                                mode=constants.REPLACE_DISK_CHG,
+                                early_release=opts.early_release)
+    jex.QueueJob(iname, op)
+  results = jex.GetResults()
+  bad_cnt = len([row for row in results if not row[0]])
+  if bad_cnt == 0:
+    ToStdout("All %d instance(s) failed over successfully.", len(results))
+    rcode = constants.EXIT_SUCCESS
+  else:
+    ToStdout("There were errors during the failover:\n"
+             "%d error(s) out of %d instance(s).", bad_cnt, len(results))
+    rcode = constants.EXIT_FAILURE
+  return rcode
 
 
 def FailoverNode(opts, args):
@@ -653,8 +654,8 @@ commands = {
     "[-s ip] [--readd] [--no-ssh-key-check] <node_name>",
     "Add a node to the cluster"),
   'evacuate': (
-    EvacuateNode, ARGS_ONE_NODE,
-    [FORCE_OPT, IALLOCATOR_OPT, NEW_SECONDARY_OPT],
+    EvacuateNode, [ArgNode(min=1)],
+    [FORCE_OPT, IALLOCATOR_OPT, NEW_SECONDARY_OPT, EARLY_RELEASE_OPT],
     "[-f] {-I <iallocator> | -n <dst>} <node>",
     "Relocate the secondary instances from a node"
     " to other nodes (only for instances with drbd disk template)"),