Now "gnt-instance recreate-disks" uses the default iallocator when "." is
specified as the iallocator. For uniformity, the same behavior applies to
these commands:
gnt-node evacuate
gnt-instance migrate
gnt-instance add
"." is used instead of "default" becuse the latter could be a valid name for
an iallocator
Signed-off-by: Bernardo Dal Seno <
bdal...@google.com>
---
lib/cmdlib.py | 17 +++++++++++------
lib/constants.py | 1 +
test/
ganeti.cmdlib_unittest.py | 36 +++++++++++++++++++++++-------------
3 files changed, 35 insertions(+), 19 deletions(-)
diff --git a/lib/cmdlib.py b/lib/cmdlib.py
index ae08146..89fb526 100644
--- a/lib/cmdlib.py
+++ b/lib/cmdlib.py
@@ -1610,8 +1610,9 @@ def _CheckIAllocatorOrNode(lu, iallocator_slot, node_slot):
cluster-wide iallocator if appropriate.
Check that at most one of (iallocator, node) is specified. If none is
- specified, then the LU's opcode's iallocator slot is filled with the
- cluster-wide default iallocator.
+ specified, or the iallocator is constants.DEFAULT_IALLOCATOR_SHORTCUT,
+ then the LU's opcode's iallocator slot is filled with the cluster-wide
+ default iallocator.
@type iallocator_slot: string
@param iallocator_slot: the name of the opcode iallocator slot
@@ -1621,11 +1622,14 @@ def _CheckIAllocatorOrNode(lu, iallocator_slot, node_slot):
"""
node = getattr(lu.op, node_slot, None)
ialloc = getattr(lu.op, iallocator_slot, None)
+ if node == []:
+ node = None
if node is not None and ialloc is not None:
raise errors.OpPrereqError("Do not specify both, iallocator and node",
errors.ECODE_INVAL)
- elif node is None and ialloc is None:
+ elif ((node is None and ialloc is None) or
+ ialloc == constants.DEFAULT_IALLOCATOR_SHORTCUT):
default_iallocator = lu.cfg.GetDefaultIAllocator()
if default_iallocator:
setattr(lu.op, iallocator_slot, default_iallocator)
@@ -7137,9 +7141,10 @@ class LUInstanceRecreateDisks(LogicalUnit):
" once: %s" % utils.CommaJoin(duplicates),
errors.ECODE_INVAL)
- if self.op.iallocator and self.op.nodes:
- raise errors.OpPrereqError("Give either the iallocator or the new"
- " nodes, not both", errors.ECODE_INVAL)
+ # We don't want _CheckIAllocatorOrNode selecting the default iallocator
+ # when neither iallocator nor nodes are specified
+ if self.op.iallocator or self.op.nodes:
+ _CheckIAllocatorOrNode(self, "iallocator", "nodes")
for (idx, params) in self.op.disks:
utils.ForceDictType(params, constants.IDISK_PARAMS_TYPES)
diff --git a/lib/constants.py b/lib/constants.py
index 1d9787c..f3e1870 100644
--- a/lib/constants.py
+++ b/lib/constants.py
@@ -1455,6 +1455,7 @@ VALID_IALLOCATOR_MODES = frozenset([
IALLOCATOR_MODE_MULTI_ALLOC,
])
IALLOCATOR_SEARCH_PATH = _autoconf.IALLOCATOR_SEARCH_PATH
+DEFAULT_IALLOCATOR_SHORTCUT = "."
IALLOCATOR_NEVAC_PRI = "primary-only"
IALLOCATOR_NEVAC_SEC = "secondary-only"
diff --git a/test/
ganeti.cmdlib_unittest.py b/test/
ganeti.cmdlib_unittest.py
index ab5ef6f..f876e53 100755
--- a/test/
ganeti.cmdlib_unittest.py
+++ b/test/
ganeti.cmdlib_unittest.py
@@ -108,23 +108,26 @@ class TestIAllocatorChecks(testutils.GanetiTestCase):
c_i = lambda: cmdlib._CheckIAllocatorOrNode(lu, "iallocator", "node")
# Neither node nor iallocator given
- op.iallocator = None
- op.node = None
- c_i()
- self.assertEqual(lu.op.iallocator, default_iallocator)
- self.assertEqual(lu.op.node, None)
+ for n in (None, []):
+ op.iallocator = None
+ op.node = n
+ c_i()
+ self.assertEqual(lu.op.iallocator, default_iallocator)
+ self.assertEqual(lu.op.node, n)
# Both, iallocator and node given
- op.iallocator = "test"
- op.node = "test"
- self.assertRaises(errors.OpPrereqError, c_i)
+ for a in ("test", constants.DEFAULT_IALLOCATOR_SHORTCUT):
+ op.iallocator = a
+ op.node = "test"
+ self.assertRaises(errors.OpPrereqError, c_i)
# Only iallocator given
- op.iallocator = other_iallocator
- op.node = None
- c_i()
- self.assertEqual(lu.op.iallocator, other_iallocator)
- self.assertEqual(lu.op.node, None)
+ for n in (None, []):
+ op.iallocator = other_iallocator
+ op.node = n
+ c_i()
+ self.assertEqual(lu.op.iallocator, other_iallocator)
+ self.assertEqual(lu.op.node, n)
# Only node given
op.iallocator = None
@@ -133,6 +136,13 @@ class TestIAllocatorChecks(testutils.GanetiTestCase):
self.assertEqual(lu.op.iallocator, None)
self.assertEqual(lu.op.node, "node")
+ # Asked for default iallocator, no node given
+ op.iallocator = constants.DEFAULT_IALLOCATOR_SHORTCUT
+ op.node = None
+ c_i()
+ self.assertEqual(lu.op.iallocator, default_iallocator)
+ self.assertEqual(lu.op.node, None)
+
# No node, iallocator or default iallocator
op.iallocator = None
op.node = None
--
1.7.7.3