Commit 8d528b7c authored by Iustin Pop's avatar Iustin Pop
Browse files

Move iallocator script execution to ganeti-noded

Currently the iallocator execution takes place in the master, which is a
violation of the current architecture, and will create problems with a
threaded master daemon.

This patch moves the execution to the backend, similar to the hooks
runner, by:
  - introducing a new class that handles the execution in the backend
    (and could be used also for listing the allocators, etc.)
  - introducing a new rpc call
  - replacing the actual execution in IAllocator.Run() with a rpc call

This passes burnin with the dumb allocator

Reviewed-by: imsnah
parent 768f0a80
......@@ -484,6 +484,17 @@ class ServerObject(BaseHTTPServer.BaseHTTPRequestHandler):
hr = backend.HooksRunner()
return hr.RunHooks(hpath, phase, env)
# iallocator -----------------
@staticmethod
def perspective_iallocator_runner(params):
"""Run an iallocator script.
"""
name, idata = params
iar = backend.IAllocatorRunner()
return iar.Run(name, idata)
# test -----------------------
@staticmethod
......
......@@ -1633,6 +1633,42 @@ class HooksRunner(object):
return rr
class IAllocatorRunner(object):
"""IAllocator runner.
This class is instantiated on the node side (ganeti-noded) and not on
the master side.
"""
def Run(self, name, idata):
"""Run an iallocator script.
Return value: tuple of:
- run status (one of the IARUN_ constants)
- stdout
- stderr
- fail reason (as from utils.RunResult)
"""
alloc_script = utils.FindFile(name, constants.IALLOCATOR_SEARCH_PATH,
os.path.isfile)
if alloc_script is None:
return (constants.IARUN_NOTFOUND, None, None, None)
fd, fin_name = tempfile.mkstemp(prefix="ganeti-iallocator.")
try:
os.write(fd, idata)
os.close(fd)
result = utils.RunCmd([alloc_script, fin_name])
if result.failed:
return (constants.IARUN_FAILURE, result.stdout, result.stderr,
result.fail_reason)
finally:
os.unlink(fin_name)
return (constants.IARUN_SUCCESS, result.stdout, result.stderr, None)
class DevCacheManager(object):
"""Simple class for managing a cache of block device information.
......
......@@ -5005,29 +5005,26 @@ class IAllocator(object):
self.in_text = serializer.Dump(self.in_data)
def Run(self, name, validate=True):
def Run(self, name, validate=True, call_fn=rpc.call_iallocator_runner):
"""Run an instance allocator and return the results.
"""
data = self.in_text
alloc_script = utils.FindFile(name, constants.IALLOCATOR_SEARCH_PATH,
os.path.isfile)
if alloc_script is None:
raise errors.OpExecError("Can't find allocator '%s'" % name)
result = call_fn(self.sstore.GetMasterNode(), name, self.in_text)
fd, fin_name = tempfile.mkstemp(prefix="ganeti-iallocator.")
try:
os.write(fd, data)
os.close(fd)
result = utils.RunCmd([alloc_script, fin_name])
if result.failed:
if not isinstance(result, tuple) or len(result) != 4:
raise errors.OpExecError("Invalid result from master iallocator runner")
rcode, stdout, stderr, fail = result
if rcode == constants.IARUN_NOTFOUND:
raise errors.OpExecError("Can't find allocator '%s'" % name)
elif rcode == constants.IARUN_FAILURE:
raise errors.OpExecError("Instance allocator call failed: %s,"
" output: %s" %
(result.fail_reason, result.output))
finally:
os.unlink(fin_name)
self.out_text = result.stdout
(fail, stdout+stderr))
self.out_text = stdout
if validate:
self._ValidateResult()
......
......@@ -190,3 +190,6 @@ IALLOCATOR_DIR_OUT = "out"
IALLOCATOR_MODE_ALLOC = "allocate"
IALLOCATOR_MODE_RELOC = "relocate"
IALLOCATOR_SEARCH_PATH = _autoconf.IALLOCATOR_SEARCH_PATH
IARUN_NOTFOUND = 1
IARUN_FAILURE = 2
IARUN_SUCCESS = 3
......@@ -577,6 +577,24 @@ def call_hooks_runner(node_list, hpath, phase, env):
return result
def call_iallocator_runner(node, name, idata):
"""Call an iallocator on a remote node
Args:
- name: the iallocator name
- input: the json-encoded input string
This is a single-node call.
"""
params = [name, idata]
c = Client("iallocator_runner", params)
c.connect(node)
c.run()
result = c.getresult().get(node, False)
return result
def call_blockdev_snapshot(node, cf_bdev):
"""Request a snapshot of the given block device.
......
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