From eba4d783c6ceb8a67c6abdf82c09af6a17637eec Mon Sep 17 00:00:00 2001 From: Thomas Thrainer Date: Mon, 5 Aug 2013 12:11:21 +0200 Subject: [PATCH] Support multi instance allocs without iallocator If all instances in the multi allocation request have already their primary and secondary node set, there is no need for an iallocator. Thus don't require it in this case and omit the call to it all together. Signed-off-by: Thomas Thrainer Reviewed-by: Michele Tartara --- lib/cmdlib.py | 94 +++++++++++++++++++++++++++++++-------------------------- 1 file changed, 52 insertions(+), 42 deletions(-) diff --git a/lib/cmdlib.py b/lib/cmdlib.py index 5c12c81..837deb7 100644 --- a/lib/cmdlib.py +++ b/lib/cmdlib.py @@ -11262,9 +11262,9 @@ class LUInstanceMultiAlloc(NoHooksLU): " pnode/snode while others do not", errors.ECODE_INVAL) - if self.op.iallocator is None: + if not has_nodes and self.op.iallocator is None: default_iallocator = self.cfg.GetDefaultIAllocator() - if default_iallocator and has_nodes: + if default_iallocator: self.op.iallocator = default_iallocator else: raise errors.OpPrereqError("No iallocator or nodes on the instances" @@ -11317,35 +11317,36 @@ class LUInstanceMultiAlloc(NoHooksLU): """Check prerequisite. """ - cluster = self.cfg.GetClusterInfo() - default_vg = self.cfg.GetVGName() - ec_id = self.proc.GetECId() + if self.op.iallocator: + cluster = self.cfg.GetClusterInfo() + default_vg = self.cfg.GetVGName() + ec_id = self.proc.GetECId() - if self.op.opportunistic_locking: - # Only consider nodes for which a lock is held - node_whitelist = list(self.owned_locks(locking.LEVEL_NODE)) - else: - node_whitelist = None + if self.op.opportunistic_locking: + # Only consider nodes for which a lock is held + node_whitelist = list(self.owned_locks(locking.LEVEL_NODE)) + else: + node_whitelist = None - insts = [_CreateInstanceAllocRequest(op, _ComputeDisks(op, default_vg), - _ComputeNics(op, cluster, None, - self.cfg, ec_id), - _ComputeFullBeParams(op, cluster), - node_whitelist) - for op in self.op.instances] + insts = [_CreateInstanceAllocRequest(op, _ComputeDisks(op, default_vg), + _ComputeNics(op, cluster, None, + self.cfg, ec_id), + _ComputeFullBeParams(op, cluster), + node_whitelist) + for op in self.op.instances] - req = iallocator.IAReqMultiInstanceAlloc(instances=insts) - ial = iallocator.IAllocator(self.cfg, self.rpc, req) + req = iallocator.IAReqMultiInstanceAlloc(instances=insts) + ial = iallocator.IAllocator(self.cfg, self.rpc, req) - ial.Run(self.op.iallocator) + ial.Run(self.op.iallocator) - if not ial.success: - raise errors.OpPrereqError("Can't compute nodes using" - " iallocator '%s': %s" % - (self.op.iallocator, ial.info), - errors.ECODE_NORES) + if not ial.success: + raise errors.OpPrereqError("Can't compute nodes using" + " iallocator '%s': %s" % + (self.op.iallocator, ial.info), + errors.ECODE_NORES) - self.ia_result = ial.result + self.ia_result = ial.result if self.op.dry_run: self.dry_run_result = objects.FillDict(self._ConstructPartialResult(), { @@ -11356,34 +11357,43 @@ class LUInstanceMultiAlloc(NoHooksLU): """Contructs the partial result. """ - (allocatable, failed) = self.ia_result + if self.op.iallocator: + (allocatable, failed_insts) = self.ia_result + allocatable_insts = map(compat.fst, allocatable) + else: + allocatable_insts = [op.instance_name for op in self.op.instances] + failed_insts = [] + return { - opcodes.OpInstanceMultiAlloc.ALLOCATABLE_KEY: - map(compat.fst, allocatable), - opcodes.OpInstanceMultiAlloc.FAILED_KEY: failed, + opcodes.OpInstanceMultiAlloc.ALLOCATABLE_KEY: allocatable_insts, + opcodes.OpInstanceMultiAlloc.FAILED_KEY: failed_insts, } def Exec(self, feedback_fn): """Executes the opcode. """ - op2inst = dict((op.instance_name, op) for op in self.op.instances) - (allocatable, failed) = self.ia_result - jobs = [] - for (name, nodes) in allocatable: - op = op2inst.pop(name) + if self.op.iallocator: + op2inst = dict((op.instance_name, op) for op in self.op.instances) + (allocatable, failed) = self.ia_result - if len(nodes) > 1: - (op.pnode, op.snode) = nodes - else: - (op.pnode,) = nodes + for (name, nodes) in allocatable: + op = op2inst.pop(name) + + if len(nodes) > 1: + (op.pnode, op.snode) = nodes + else: + (op.pnode,) = nodes - jobs.append([op]) + jobs.append([op]) - missing = set(op2inst.keys()) - set(failed) - assert not missing, \ - "Iallocator did return incomplete result: %s" % utils.CommaJoin(missing) + missing = set(op2inst.keys()) - set(failed) + assert not missing, \ + "Iallocator did return incomplete result: %s" % \ + utils.CommaJoin(missing) + else: + jobs.extend([op] for op in self.op.instances) return ResultWithJobs(jobs, **self._ConstructPartialResult()) -- 1.7.10.4