Commit aac4511a added CheckArguments to LUNodeMigrate with a call to
_CheckIAllocatorOrNode. When no default iallocator is defined,
evacuating a node would always fail:

Migrate instance(s) '...'?
y/[n]/?: y
Failure: prerequisites not met for this operation:
No iallocator or node given and no cluster-wide default iallocator
found; please specify either an iallocator or a node, or set a
cluster-wide default iallocator

This patch adds a new parameter to specify a target node. This doesn't
solve all issues, but will make the most important cases work again in
the meantime. This opcode will receive more work for node group support.

Signed-off-by: Michael Hanselmann <[email protected]>
---
 lib/client/gnt_node.py |    5 +++--
 lib/cmdlib.py          |    2 +-
 lib/opcodes.py         |   11 +++++++----
 3 files changed, 11 insertions(+), 7 deletions(-)

diff --git a/lib/client/gnt_node.py b/lib/client/gnt_node.py
index 6ddc9e4..0b0dbf1 100644
--- a/lib/client/gnt_node.py
+++ b/lib/client/gnt_node.py
@@ -386,7 +386,8 @@ def MigrateNode(opts, args):
   else:
     mode = opts.migration_mode
   op = opcodes.OpNodeMigrate(node_name=args[0], mode=mode,
-                             iallocator=opts.iallocator)
+                             iallocator=opts.iallocator,
+                             target_node=opts.dst_node)
   SubmitOpCode(op, cl=cl, opts=opts)
 
 
@@ -829,7 +830,7 @@ commands = {
     " secondary node (only for instances with drbd disk template)"),
   'migrate': (
     MigrateNode, ARGS_ONE_NODE,
-    [FORCE_OPT, NONLIVE_OPT, MIGRATION_MODE_OPT,
+    [FORCE_OPT, NONLIVE_OPT, MIGRATION_MODE_OPT, DST_NODE_OPT,
      IALLOCATOR_OPT, PRIORITY_OPT],
     "[-f] <node>",
     "Migrate all the primary instance on a node away from it"
diff --git a/lib/cmdlib.py b/lib/cmdlib.py
index f65b3d0..d83a448 100644
--- a/lib/cmdlib.py
+++ b/lib/cmdlib.py
@@ -6648,7 +6648,7 @@ class LUNodeMigrate(LogicalUnit):
   REQ_BGL = False
 
   def CheckArguments(self):
-    _CheckIAllocatorOrNode(self, "iallocator", "remote_node")
+    pass
 
   def ExpandNames(self):
     self.op.node_name = _ExpandNodeName(self.cfg, self.op.node_name)
diff --git a/lib/opcodes.py b/lib/opcodes.py
index df03b19..6a5f3be 100644
--- a/lib/opcodes.py
+++ b/lib/opcodes.py
@@ -118,6 +118,10 @@ _PIpCheckDoc = "Whether to ensure instance's IP address is 
inactive"
 _PNoRemember = ("no_remember", False, ht.TBool,
                 "Do not remember the state change")
 
+#: Target node for instance migration/failover
+_PMigrationTargetNode = ("target_node", None, ht.TMaybeString,
+                         "Target node for shared-storage instances")
+
 #: OP_ID conversion regular expression
 _OPID_RE = re.compile("([a-z])([A-Z])")
 
@@ -874,6 +878,7 @@ class OpNodeMigrate(OpCode):
     _PNodeName,
     _PMigrationMode,
     _PMigrationLive,
+    _PMigrationTargetNode,
     ("iallocator", None, ht.TMaybeString,
      "Iallocator for deciding the target node for shared-storage instances"),
     ]
@@ -1058,10 +1063,9 @@ class OpInstanceFailover(OpCode):
     _PInstanceName,
     _PShutdownTimeout,
     _PIgnoreConsistency,
+    _PMigrationTargetNode,
     ("iallocator", None, ht.TMaybeString,
      "Iallocator for deciding the target node for shared-storage instances"),
-    ("target_node", None, ht.TMaybeString,
-     "Target node for shared-storage instances"),
     ]
 
 
@@ -1080,12 +1084,11 @@ class OpInstanceMigrate(OpCode):
     _PInstanceName,
     _PMigrationMode,
     _PMigrationLive,
+    _PMigrationTargetNode,
     ("cleanup", False, ht.TBool,
      "Whether a previously failed migration should be cleaned up"),
     ("iallocator", None, ht.TMaybeString,
      "Iallocator for deciding the target node for shared-storage instances"),
-    ("target_node", None, ht.TMaybeString,
-     "Target node for shared-storage instances"),
     ("allow_failover", False, ht.TBool,
      "Whether we can fallback to failover if migration is not possible"),
     ]
-- 
1.7.3.5

Reply via email to