Commit 27579978 authored by Iustin Pop's avatar Iustin Pop
Browse files

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
parent b91bde14
......@@ -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,
......
......@@ -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
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment