From 2a139bb08f33c580243a412936160d872770175e Mon Sep 17 00:00:00 2001
From: Iustin Pop <iustin@google.com>
Date: Wed, 23 Apr 2008 12:05:37 +0000
Subject: [PATCH] Generalize the replace_secondary mode in iallocator

Currently the replace_secondary mode is too restrictive. This patch
changes this to a general 'relocate' mode where the node(s) to be
changed are specified via a new key in the request dict ('nodes') so
that we can change any of the instance's nodes.

Note that for the relocate mode, len(nodes) == required_nodes, so the
required nodes field is redundant, but it is provided for consistency
with the allocate mode.

Reviewed-by: ultrotter
---
 doc/examples/dumb-allocator | 2 +-
 lib/cmdlib.py               | 6 +++++-
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/doc/examples/dumb-allocator b/doc/examples/dumb-allocator
index 9734af397..2996e49ca 100755
--- a/doc/examples/dumb-allocator
+++ b/doc/examples/dumb-allocator
@@ -76,7 +76,7 @@ def main():
   if req_type == "allocate":
     forbidden_nodes = []
     inst_data = request
-  elif req_type == "replace_secondary":
+  elif req_type == "relocate":
     idict = data["instances"][request["name"]]
     forbidden_nodes = idict["nodes"]
     inst_data = idict
diff --git a/lib/cmdlib.py b/lib/cmdlib.py
index 58b6404d7..73907c284 100644
--- a/lib/cmdlib.py
+++ b/lib/cmdlib.py
@@ -4877,6 +4877,9 @@ class IAllocator(object):
     if instance.disk_template not in constants.DTS_NET_MIRROR:
       raise errors.OpPrereqError("Can't relocate non-mirrored instances")
 
+    if len(instance.secondary_nodes) != 1:
+      raise errors.OpPrereqError("Instance has not exactly one secondary node")
+
     self.required_nodes = 1
 
     disk_space = _ComputeDiskSize(instance.disk_template,
@@ -4884,10 +4887,11 @@ class IAllocator(object):
                                   instance.disks[1].size)
 
     request = {
-      "type": "replace_secondary",
+      "type": "relocate",
       "name": self.name,
       "disk_space_total": disk_space,
       "required_nodes": self.required_nodes,
+      "nodes": list(instance.secondary_nodes),
       }
     self.in_data["request"] = request
 
-- 
GitLab