From 7f60a422a421cf7cf029b0ee0e6bc62bcc8bbbd6 Mon Sep 17 00:00:00 2001
From: Iustin Pop <iustin@google.com>
Date: Wed, 17 Feb 2010 10:23:38 +0100
Subject: [PATCH] Implement IAllocator multi-evacuate mode

This is a new mode that request a solution for the evacuation of
multiple nodes. The external script will be fed a list of names, and is
expected to return a list of [instance, new_node(s)] lists, detailing
the evacuation path of each instance.

Signed-off-by: Iustin Pop <iustin@google.com>
Reviewed-by: Michael Hanselmann <hansmi@google.com>
---
 lib/cmdlib.py    | 19 +++++++++++++++++++
 lib/constants.py |  1 +
 2 files changed, 20 insertions(+)

diff --git a/lib/cmdlib.py b/lib/cmdlib.py
index 98386f07b..b6adbfe25 100644
--- a/lib/cmdlib.py
+++ b/lib/cmdlib.py
@@ -8501,6 +8501,9 @@ class IAllocator(object):
   _RELO_KEYS = [
     "name", "relocate_from",
     ]
+  _EVAC_KEYS = [
+    "evac_nodes",
+    ]
 
   def __init__(self, cfg, rpc, mode, **kwargs):
     self.cfg = cfg
@@ -8514,6 +8517,7 @@ class IAllocator(object):
     self.hypervisor = None
     self.relocate_from = None
     self.name = None
+    self.evac_nodes = None
     # computed fields
     self.required_nodes = None
     # init result fields
@@ -8524,6 +8528,9 @@ class IAllocator(object):
     elif self.mode == constants.IALLOCATOR_MODE_RELOC:
       keyset = self._RELO_KEYS
       fn = self._AddRelocateInstance
+    elif self.mode == constants.IALLOCATOR_MODE_MEVAC:
+      keyset = self._EVAC_KEYS
+      fn = self._AddEvacuateNodes
     else:
       raise errors.ProgrammerError("Unknown mode '%s' passed to the"
                                    " IAllocator" % self.mode)
@@ -8532,6 +8539,7 @@ class IAllocator(object):
         raise errors.ProgrammerError("Invalid input parameter '%s' to"
                                      " IAllocator" % key)
       setattr(self, key, kwargs[key])
+
     for key in keyset:
       if key not in kwargs:
         raise errors.ProgrammerError("Missing input parameter '%s' to"
@@ -8565,6 +8573,8 @@ class IAllocator(object):
       hypervisor_name = self.hypervisor
     elif self.mode == constants.IALLOCATOR_MODE_RELOC:
       hypervisor_name = cfg.GetInstanceInfo(self.name).hypervisor
+    elif self.mode == constants.IALLOCATOR_MODE_MEVAC:
+      hypervisor_name = cluster_info.enabled_hypervisors[0]
 
     node_data = self.rpc.call_node_info(node_list, cfg.GetVGName(),
                                         hypervisor_name)
@@ -8730,6 +8740,15 @@ class IAllocator(object):
       }
     return request
 
+  def _AddEvacuateNodes(self):
+    """Add evacuate nodes data to allocator structure.
+
+    """
+    request = {
+      "evac_nodes": self.evac_nodes
+      }
+    return request
+
   def _BuildInputData(self, fn):
     """Build input data structures.
 
diff --git a/lib/constants.py b/lib/constants.py
index 3f71443dc..47849fcb7 100644
--- a/lib/constants.py
+++ b/lib/constants.py
@@ -558,6 +558,7 @@ IALLOCATOR_DIR_IN = "in"
 IALLOCATOR_DIR_OUT = "out"
 IALLOCATOR_MODE_ALLOC = "allocate"
 IALLOCATOR_MODE_RELOC = "relocate"
+IALLOCATOR_MODE_MEVAC = "multi-evacuate"
 IALLOCATOR_SEARCH_PATH = _autoconf.IALLOCATOR_SEARCH_PATH
 
 # Job queue
-- 
GitLab