From 27579978966f3fa3cf3c935b5bcd797259107f96 Mon Sep 17 00:00:00 2001 From: Iustin Pop <iustin@google.com> Date: Wed, 23 Apr 2008 11:03:58 +0000 Subject: [PATCH] Send required_nodes field to the iallocator scripts This patch adds the 'required_nodes' field in the request dict for the iallocator. This means that the handmade-checks in the create instance can be simplified, and that the dumb allocator can be made simple. Therefore the patch also modifies it. The patch also sends the disk_space_total to the script in realocate mode and a small fix for showing errors (include stderr too). Reviewed-by: ultrotter --- doc/examples/dumb-allocator | 25 +++++++++++------------- lib/cmdlib.py | 38 +++++++++++++++++++++++++++---------- 2 files changed, 39 insertions(+), 24 deletions(-) diff --git a/doc/examples/dumb-allocator b/doc/examples/dumb-allocator index 641c41835..53b9cd2da 100755 --- a/doc/examples/dumb-allocator +++ b/doc/examples/dumb-allocator @@ -74,20 +74,17 @@ def main(): request = data["request"] req_type = request["type"] if req_type != "allocate": - print >> sys.stderr, "Unsupported allocator mode '%s'" % req_type - return 1 - - npri = SelectNode(nodes, request, []) - if npri is None: - return OutputError("Can't find a suitable primary node", exit_code=0) - - result_nodes = [npri] - if request["disk_template"] == "drbd": - nsec = SelectNode(nodes, request, result_nodes) - if nsec is None: - return OutputError("Can't find a suitable secondary node (%s selected" - " as primary)" % npri, exit_code=0) - result_nodes.append(nsec) + return OutputError("Unsupported allocator mode '%s'" % req_type) + + result_nodes = [] + while len(result_nodes) < request["required_nodes"]: + new_selection = SelectNode(nodes, request, result_nodes) + if new_selection is None: + return OutputError("Can't find a suitable node for position %s" + " (already selected: %s)" % + (len(result_nodes) + 1, ", ".join(result_nodes)), + exit_code=0) + result_nodes.append(new_selection) result = { "success": True, diff --git a/lib/cmdlib.py b/lib/cmdlib.py index c56877dcb..58b6404d7 100644 --- a/lib/cmdlib.py +++ b/lib/cmdlib.py @@ -3159,20 +3159,16 @@ class LUCreateInstance(LogicalUnit): raise errors.OpPrereqError("Can't compute nodes using" " iallocator '%s': %s" % (self.op.iallocator, ial.info)) - req_nodes = 1 - if self.op.disk_template in constants.DTS_NET_MIRROR: - req_nodes += 1 - - if len(ial.nodes) != req_nodes: + if len(ial.nodes) != ial.required_nodes: raise errors.OpPrereqError("iallocator '%s' returned invalid number" " of nodes (%s), required %s" % - (len(ial.nodes), req_nodes)) + (len(ial.nodes), ial.required_nodes)) self.op.pnode = ial.nodes[0] logger.ToStdout("Selected nodes for the instance: %s" % (", ".join(ial.nodes),)) logger.Info("Selected nodes for instance %s via iallocator %s: %s" % (self.op.instance_name, self.op.iallocator, ial.nodes)) - if req_nodes == 2: + if ial.required_nodes == 2: self.op.snode = ial.nodes[1] def BuildHooksEnv(self): @@ -4742,6 +4738,8 @@ class IAllocator(object): self.mode = self.name = None self.mem_size = self.disks = self.disk_template = None self.os = self.tags = self.nics = self.vcpus = None + # computed fields + self.required_nodes = None # init result fields self.success = self.info = self.nodes = None for key in kwargs: @@ -4842,6 +4840,10 @@ class IAllocator(object): disk_space = _ComputeDiskSize(self.disk_template, self.disks[0]["size"], self.disks[1]["size"]) + if self.disk_template in constants.DTS_NET_MIRROR: + self.required_nodes = 2 + else: + self.required_nodes = 1 request = { "type": "allocate", "name": self.name, @@ -4853,6 +4855,7 @@ class IAllocator(object): "disks": self.disks, "disk_space_total": disk_space, "nics": self.nics, + "required_nodes": self.required_nodes, } data["request"] = request @@ -4866,12 +4869,27 @@ class IAllocator(object): done. """ - data = self.in_data + instance = self.cfg.GetInstanceInfo(self.name) + if instance is None: + raise errors.ProgrammerError("Unknown instance '%s' passed to" + " IAllocator" % self.name) + + if instance.disk_template not in constants.DTS_NET_MIRROR: + raise errors.OpPrereqError("Can't relocate non-mirrored instances") + + self.required_nodes = 1 + + disk_space = _ComputeDiskSize(instance.disk_template, + instance.disks[0].size, + instance.disks[1].size) + request = { "type": "replace_secondary", "name": self.name, + "disk_space_total": disk_space, + "required_nodes": self.required_nodes, } - data["request"] = request + self.in_data["request"] = request def _BuildInputData(self): """Build input data structures. @@ -4905,7 +4923,7 @@ class IAllocator(object): if result.failed: raise errors.OpExecError("Instance allocator call failed: %s," " output: %s" % - (result.fail_reason, result.stdout)) + (result.fail_reason, result.output)) finally: os.unlink(fin_name) self.out_text = result.stdout -- GitLab