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