Commit f8c9fa5c authored by Iustin Pop's avatar Iustin Pop
Browse files

Switch gnt-node evacuate to the new opcode

This switches gnt-node to the new opcode, and in the process also
enables multi-node arguments for it.
Signed-off-by: default avatarIustin Pop <>
Reviewed-by: default avatarMichael Hanselmann <>
parent f7e7689f
......@@ -148,12 +148,12 @@
<arg>--iallocator <replaceable>NAME</replaceable></arg>
<arg>--new-secondary <replaceable>destination_node</replaceable></arg>
<arg choice="req"><replaceable>node</replaceable></arg>
<arg choice="req" rep="repeat"><replaceable>node</replaceable></arg>
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
......@@ -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,
src_node, sinst = result[0]
if not sinst:
ToStderr("No secondary instances on node %s, exiting.", src_node)
op = opcodes.OpNodeEvacuationStrategy(nodes=args,
result = SubmitOpCode(op, cl=cl, opts=opts)
if not result:
# no instances to migrate
ToStderr("No secondary instances on node(s) %s, exiting.",
return constants.EXIT_SUCCESS
if dst_node is not None:
result = cl.QueryNodes(names=[dst_node], fields=["name"],
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
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),
return constants.EXIT_CONFIRMATION
op = opcodes.OpEvacuateNode(node_name=args[0], remote_node=dst_node,
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=[],
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
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,
EvacuateNode, [ArgNode(min=1)],
"[-f] {-I <iallocator> | -n <dst>} <node>",
"Relocate the secondary instances from a node"
" to other nodes (only for instances with drbd disk template)"),
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment