Revision 8d528b7c
b/daemons/ganeti-noded | ||
---|---|---|
484 | 484 |
hr = backend.HooksRunner() |
485 | 485 |
return hr.RunHooks(hpath, phase, env) |
486 | 486 |
|
487 |
# iallocator ----------------- |
|
488 |
|
|
489 |
@staticmethod |
|
490 |
def perspective_iallocator_runner(params): |
|
491 |
"""Run an iallocator script. |
|
492 |
|
|
493 |
""" |
|
494 |
name, idata = params |
|
495 |
iar = backend.IAllocatorRunner() |
|
496 |
return iar.Run(name, idata) |
|
497 |
|
|
487 | 498 |
# test ----------------------- |
488 | 499 |
|
489 | 500 |
@staticmethod |
b/lib/backend.py | ||
---|---|---|
1633 | 1633 |
return rr |
1634 | 1634 |
|
1635 | 1635 |
|
1636 |
class IAllocatorRunner(object): |
|
1637 |
"""IAllocator runner. |
|
1638 |
|
|
1639 |
This class is instantiated on the node side (ganeti-noded) and not on |
|
1640 |
the master side. |
|
1641 |
|
|
1642 |
""" |
|
1643 |
def Run(self, name, idata): |
|
1644 |
"""Run an iallocator script. |
|
1645 |
|
|
1646 |
Return value: tuple of: |
|
1647 |
- run status (one of the IARUN_ constants) |
|
1648 |
- stdout |
|
1649 |
- stderr |
|
1650 |
- fail reason (as from utils.RunResult) |
|
1651 |
|
|
1652 |
""" |
|
1653 |
alloc_script = utils.FindFile(name, constants.IALLOCATOR_SEARCH_PATH, |
|
1654 |
os.path.isfile) |
|
1655 |
if alloc_script is None: |
|
1656 |
return (constants.IARUN_NOTFOUND, None, None, None) |
|
1657 |
|
|
1658 |
fd, fin_name = tempfile.mkstemp(prefix="ganeti-iallocator.") |
|
1659 |
try: |
|
1660 |
os.write(fd, idata) |
|
1661 |
os.close(fd) |
|
1662 |
result = utils.RunCmd([alloc_script, fin_name]) |
|
1663 |
if result.failed: |
|
1664 |
return (constants.IARUN_FAILURE, result.stdout, result.stderr, |
|
1665 |
result.fail_reason) |
|
1666 |
finally: |
|
1667 |
os.unlink(fin_name) |
|
1668 |
|
|
1669 |
return (constants.IARUN_SUCCESS, result.stdout, result.stderr, None) |
|
1670 |
|
|
1671 |
|
|
1636 | 1672 |
class DevCacheManager(object): |
1637 | 1673 |
"""Simple class for managing a cache of block device information. |
1638 | 1674 |
|
b/lib/cmdlib.py | ||
---|---|---|
5005 | 5005 |
|
5006 | 5006 |
self.in_text = serializer.Dump(self.in_data) |
5007 | 5007 |
|
5008 |
def Run(self, name, validate=True): |
|
5008 |
def Run(self, name, validate=True, call_fn=rpc.call_iallocator_runner):
|
|
5009 | 5009 |
"""Run an instance allocator and return the results. |
5010 | 5010 |
|
5011 | 5011 |
""" |
5012 | 5012 |
data = self.in_text |
5013 | 5013 |
|
5014 |
alloc_script = utils.FindFile(name, constants.IALLOCATOR_SEARCH_PATH, |
|
5015 |
os.path.isfile) |
|
5016 |
if alloc_script is None: |
|
5017 |
raise errors.OpExecError("Can't find allocator '%s'" % name) |
|
5014 |
result = call_fn(self.sstore.GetMasterNode(), name, self.in_text) |
|
5018 | 5015 |
|
5019 |
fd, fin_name = tempfile.mkstemp(prefix="ganeti-iallocator.") |
|
5020 |
try: |
|
5021 |
os.write(fd, data) |
|
5022 |
os.close(fd) |
|
5023 |
result = utils.RunCmd([alloc_script, fin_name]) |
|
5024 |
if result.failed: |
|
5016 |
if not isinstance(result, tuple) or len(result) != 4: |
|
5017 |
raise errors.OpExecError("Invalid result from master iallocator runner") |
|
5018 |
|
|
5019 |
rcode, stdout, stderr, fail = result |
|
5020 |
|
|
5021 |
if rcode == constants.IARUN_NOTFOUND: |
|
5022 |
raise errors.OpExecError("Can't find allocator '%s'" % name) |
|
5023 |
elif rcode == constants.IARUN_FAILURE: |
|
5025 | 5024 |
raise errors.OpExecError("Instance allocator call failed: %s," |
5026 | 5025 |
" output: %s" % |
5027 |
(result.fail_reason, result.output)) |
|
5028 |
finally: |
|
5029 |
os.unlink(fin_name) |
|
5030 |
self.out_text = result.stdout |
|
5026 |
(fail, stdout+stderr)) |
|
5027 |
self.out_text = stdout |
|
5031 | 5028 |
if validate: |
5032 | 5029 |
self._ValidateResult() |
5033 | 5030 |
|
b/lib/constants.py | ||
---|---|---|
190 | 190 |
IALLOCATOR_MODE_ALLOC = "allocate" |
191 | 191 |
IALLOCATOR_MODE_RELOC = "relocate" |
192 | 192 |
IALLOCATOR_SEARCH_PATH = _autoconf.IALLOCATOR_SEARCH_PATH |
193 |
IARUN_NOTFOUND = 1 |
|
194 |
IARUN_FAILURE = 2 |
|
195 |
IARUN_SUCCESS = 3 |
b/lib/rpc.py | ||
---|---|---|
577 | 577 |
return result |
578 | 578 |
|
579 | 579 |
|
580 |
def call_iallocator_runner(node, name, idata): |
|
581 |
"""Call an iallocator on a remote node |
|
582 |
|
|
583 |
Args: |
|
584 |
- name: the iallocator name |
|
585 |
- input: the json-encoded input string |
|
586 |
|
|
587 |
This is a single-node call. |
|
588 |
|
|
589 |
""" |
|
590 |
params = [name, idata] |
|
591 |
c = Client("iallocator_runner", params) |
|
592 |
c.connect(node) |
|
593 |
c.run() |
|
594 |
result = c.getresult().get(node, False) |
|
595 |
return result |
|
596 |
|
|
597 |
|
|
580 | 598 |
def call_blockdev_snapshot(node, cf_bdev): |
581 | 599 |
"""Request a snapshot of the given block device. |
582 | 600 |
|
Also available in: Unified diff