Commit 941b9309 authored by Iustin Pop's avatar Iustin Pop

RAPI: switch evacuate node to the new model

This patch removes the last use of the old-style OpEvacuateNode. It also
fixes the dry-run mode for this RAPI resource - the dry-run parameter
was not used at all before.
Signed-off-by: default avatarIustin Pop <>
Reviewed-by: default avatarMichael Hanselmann <>
parent 989ba0c4
......@@ -863,6 +863,21 @@ parameters must be passed::
The result value will be a list, each element being a triple of the job
id (for this specific evacuation), the instance which is being evacuated
by this job, and the node to which it is being relocated. In case the
node is already empty, the result will be an empty list (without any
jobs being submitted).
And additional parameter ``early_release`` signifies whether to try to
parallelize the evacuations, at the risk of increasing I/O contention
and increasing the chances of data loss, if the primary node of any of
the instances being evacuated is not fully healthy.
If the dry-run parameter was specified, then the evacuation jobs were
not actually submitted, and the job IDs will be null.
......@@ -1022,7 +1022,7 @@ class GanetiRapiClient(object):
None, None)
def EvacuateNode(self, node, iallocator=None, remote_node=None,
dry_run=False, early_release=False):
"""Evacuates instances from a Ganeti node.
@type node: str
......@@ -1033,11 +1033,16 @@ class GanetiRapiClient(object):
@param remote_node: node to evaucate to
@type dry_run: bool
@param dry_run: whether to perform a dry run
@type early_release: bool
@param early_release: whether to enable parallelization
@rtype: int
@return: job id
@rtype: list
@return: list of (job ID, instance name, new secondary node); if
dry_run was specified, then the actual move jobs were not
submitted and the job IDs will be C{None}
@raises GanetiApiError: if an iallocator and remote_node are both specified
@raises GanetiApiError: if an iallocator and remote_node are both
if iallocator and remote_node:
......@@ -1050,6 +1055,8 @@ class GanetiRapiClient(object):
query.append(("remote_node", remote_node))
if dry_run:
query.append(("dry-run", 1))
if early_release:
query.append(("early_release", 1))
return self._SendRequest(HTTP_POST,
("/%s/nodes/%s/evacuate" %
......@@ -389,12 +389,32 @@ class R_2_nodes_name_evacuate(baserlib.R_Generic):
node_name = self.items[0]
remote_node = self._checkStringVariable("remote_node", default=None)
iallocator = self._checkStringVariable("iallocator", default=None)
early_r = bool(self._checkIntVariable("early_release", default=0))
dry_run = bool(self.dryRun())
op = opcodes.OpEvacuateNode(node_name=node_name,
cl = baserlib.GetClient()
return baserlib.SubmitJob([op])
op = opcodes.OpNodeEvacuationStrategy(nodes=[node_name],
job_id = baserlib.SubmitJob([op], cl)
# we use custom feedback function, instead of print we log the status
result = cli.PollJob(job_id, cl, feedback_fn=baserlib.FeedbackFn)
jobs = []
for iname, node in result:
if dry_run:
jid = None
op = opcodes.OpReplaceDisks(instance_name=iname,
remote_node=node, disks=[],
jid = baserlib.SubmitJob([op])
jobs.append((jid, iname, node))
return jobs
class R_2_nodes_name_migrate(baserlib.R_Generic):
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