#
#

# Copyright (C) 2012, 2013 Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


"""Module implementing the iallocator code."""

from ganeti import compat
from ganeti import constants
from ganeti import errors
from ganeti import ht
from ganeti import outils
from ganeti import opcodes
import ganeti.rpc.node as rpc
from ganeti import serializer
from ganeti import utils

import ganeti.masterd.instance as gmi

import logging

_STRING_LIST = ht.TListOf(ht.TString)
_JOB_LIST = ht.TListOf(ht.TListOf(ht.TStrictDict(True, False, {
   # pylint: disable=E1101
   # Class '...' has no 'OP_ID' member
   "OP_ID": ht.TElemOf([opcodes.OpInstanceFailover.OP_ID,
                        opcodes.OpInstanceMigrate.OP_ID,
                        opcodes.OpInstanceReplaceDisks.OP_ID]),
   })))

_NEVAC_MOVED = \
  ht.TListOf(ht.TAnd(ht.TIsLength(3),
                     ht.TItems([ht.TNonEmptyString,
                                ht.TNonEmptyString,
                                ht.TListOf(ht.TNonEmptyString),
                                ])))
_NEVAC_FAILED = \
  ht.TListOf(ht.TAnd(ht.TIsLength(2),
                     ht.TItems([ht.TNonEmptyString,
                                ht.TMaybeString,
                                ])))
_NEVAC_RESULT = ht.TAnd(ht.TIsLength(3),
                        ht.TItems([_NEVAC_MOVED, _NEVAC_FAILED, _JOB_LIST]))

_INST_NAME = ("name", ht.TNonEmptyString)
_INST_UUID = ("inst_uuid", ht.TNonEmptyString)


class _AutoReqParam(outils.AutoSlots):
  """Meta class for request definitions.

  """
  @classmethod
  def _GetSlots(mcs, attrs):
    """Extract the slots out of REQ_PARAMS.

    """
    params = attrs.setdefault("REQ_PARAMS", [])
    return [slot for (slot, _) in params]


class IARequestBase(outils.ValidatedSlots):
  """A generic IAllocator request object.

  """
  __metaclass__ = _AutoReqParam

  MODE = NotImplemented
  REQ_PARAMS = []
  REQ_RESULT = NotImplemented

  def __init__(self, **kwargs):
    """Constructor for IARequestBase.

    The constructor takes only keyword arguments and will set
    attributes on this object based on the passed arguments. As such,
    it means that you should not pass arguments which are not in the
    REQ_PARAMS attribute for this class.

    """
    outils.ValidatedSlots.__init__(self, **kwargs)

    self.Validate()

  def Validate(self):
    """Validates all parameters of the request.


    This method returns L{None} if the validation succeeds, or raises
    an exception otherwise.

    @rtype: NoneType
    @return: L{None}, if the validation succeeds

    @raise Exception: validation fails

    """
    assert self.MODE in constants.VALID_IALLOCATOR_MODES

    for (param, validator) in self.REQ_PARAMS:
      if not hasattr(self, param):
        raise errors.OpPrereqError("Request is missing '%s' parameter" % param,
                                   errors.ECODE_INVAL)

      value = getattr(self, param)
      if not validator(value):
        raise errors.OpPrereqError(("Request parameter '%s' has invalid"
                                    " type %s/value %s") %
                                    (param, type(value), value),
                                    errors.ECODE_INVAL)

  def GetRequest(self, cfg):
    """Gets the request data dict.

    @param cfg: The configuration instance

    """
    raise NotImplementedError

  def GetExtraParams(self): # pylint: disable=R0201
    """Gets extra parameters to the IAllocator call.

    """
    return {}

  def ValidateResult(self, ia, result):
    """Validates the result of an request.

    @param ia: The IAllocator instance
    @param result: The IAllocator run result
    @raises ResultValidationError: If validation fails

    """
    if ia.success and not self.REQ_RESULT(result):
      raise errors.ResultValidationError("iallocator returned invalid result,"
                                         " expected %s, got %s" %
                                         (self.REQ_RESULT, result))


class IAReqInstanceAlloc(IARequestBase):
  """An instance allocation request.

  """
  # pylint: disable=E1101
  MODE = constants.IALLOCATOR_MODE_ALLOC
  REQ_PARAMS = [
    _INST_NAME,
    ("memory", ht.TNonNegativeInt),
    ("spindle_use", ht.TNonNegativeInt),
    ("disks", ht.TListOf(ht.TDict)),
    ("disk_template", ht.TString),
    ("group_name", ht.TMaybe(ht.TNonEmptyString)),
    ("os", ht.TString),
    ("tags", _STRING_LIST),
    ("nics", ht.TListOf(ht.TDict)),
    ("vcpus", ht.TInt),
    ("hypervisor", ht.TString),
    ("node_whitelist", ht.TMaybeListOf(ht.TNonEmptyString)),
    ]
  REQ_RESULT = ht.TList

  def RequiredNodes(self):
    """Calculates the required nodes based on the disk_template.

    """
    if self.disk_template in constants.DTS_INT_MIRROR:
      return 2
    else:
      return 1

  def GetRequest(self, cfg):
    """Requests a new instance.

    The checks for the completeness of the opcode must have already been
    done.

    """
    for d in self.disks:
      d[constants.IDISK_TYPE] = self.disk_template
    disk_space = gmi.ComputeDiskSize(self.disks)

    return {
      "name": self.name,
      "disk_template": self.disk_template,
      "group_name": self.group_name,
      "tags": self.tags,
      "os": self.os,
      "vcpus": self.vcpus,
      "memory": self.memory,
      "spindle_use": self.spindle_use,
      "disks": self.disks,
      "disk_space_total": disk_space,
      "nics": self.nics,
      "required_nodes": self.RequiredNodes(),
      "hypervisor": self.hypervisor,
      }

  def ValidateResult(self, ia, result):
    """Validates an single instance allocation request.

    """
    IARequestBase.ValidateResult(self, ia, result)

    if ia.success and len(result) != self.RequiredNodes():
      raise errors.ResultValidationError("iallocator returned invalid number"
                                         " of nodes (%s), required %s" %
                                         (len(result), self.RequiredNodes()))


class IAReqInstanceAllocateSecondary(IARequestBase):
  """Request to find a secondary node for plain to DRBD conversion.

  """
  # pylint: disable=E1101
  MODE = constants.IALLOCATOR_MODE_ALLOCATE_SECONDARY
  REQ_PARAMS = [
    _INST_NAME,
    ]
  REQ_RESULT = ht.TString

  def GetRequest(self, cfg):
    return {
      "name": self.name
    }


class IAReqMultiInstanceAlloc(IARequestBase):
  """An multi instance allocation request.

  """
  # pylint: disable=E1101
  MODE = constants.IALLOCATOR_MODE_MULTI_ALLOC
  REQ_PARAMS = [
    ("instances", ht.TListOf(ht.TInstanceOf(IAReqInstanceAlloc))),
    ]
  _MASUCCESS = \
    ht.TListOf(ht.TAnd(ht.TIsLength(2),
                       ht.TItems([ht.TNonEmptyString,
                                  ht.TListOf(ht.TNonEmptyString),
                                  ])))
  _MAFAILED = ht.TListOf(ht.TNonEmptyString)
  REQ_RESULT = ht.TAnd(ht.TList, ht.TIsLength(2),
                       ht.TItems([_MASUCCESS, _MAFAILED]))

  def GetRequest(self, cfg):
    return {
      "instances": [iareq.GetRequest(cfg) for iareq in self.instances],
      }


class IAReqRelocate(IARequestBase):
  """A relocation request.

  """
  # pylint: disable=E1101
  MODE = constants.IALLOCATOR_MODE_RELOC
  REQ_PARAMS = [
    _INST_UUID,
    ("relocate_from_node_uuids", _STRING_LIST),
    ]
  REQ_RESULT = ht.TList

  def GetRequest(self, cfg):
    """Request an relocation of an instance

    The checks for the completeness of the opcode must have already been
    done.

    """
    instance = cfg.GetInstanceInfo(self.inst_uuid)
    disks = cfg.GetInstanceDisks(self.inst_uuid)
    if instance is None:
      raise errors.ProgrammerError("Unknown instance '%s' passed to"
                                   " IAllocator" % self.inst_uuid)

    if not utils.AllDiskOfType(disks, constants.DTS_MIRRORED):
      raise errors.OpPrereqError("Can't relocate non-mirrored instances",
                                 errors.ECODE_INVAL)

    secondary_nodes = cfg.GetInstanceSecondaryNodes(instance.uuid)
    if (utils.AnyDiskOfType(disks, constants.DTS_INT_MIRROR) and
        len(secondary_nodes) != 1):
      raise errors.OpPrereqError("Instance has not exactly one secondary node",
                                 errors.ECODE_STATE)

    disk_sizes = [{constants.IDISK_SIZE: disk.size,
                   constants.IDISK_TYPE: disk.dev_type} for disk in disks]
    disk_space = gmi.ComputeDiskSize(disk_sizes)

    return {
      "name": instance.name,
      "disk_space_total": disk_space,
      "required_nodes": 1,
      "relocate_from": cfg.GetNodeNames(self.relocate_from_node_uuids),
      }

  def ValidateResult(self, ia, result):
    """Validates the result of an relocation request.

    """
    IARequestBase.ValidateResult(self, ia, result)

    node2group = dict((name, ndata["group"])
                      for (name, ndata) in ia.in_data["nodes"].items())

    fn = compat.partial(self._NodesToGroups, node2group,
                        ia.in_data["nodegroups"])

    instance = ia.cfg.GetInstanceInfo(self.inst_uuid)
    request_groups = fn(ia.cfg.GetNodeNames(self.relocate_from_node_uuids) +
                        ia.cfg.GetNodeNames([instance.primary_node]))
    result_groups = fn(result + ia.cfg.GetNodeNames([instance.primary_node]))

    if ia.success and not set(result_groups).issubset(request_groups):
      raise errors.ResultValidationError("Groups of nodes returned by"
                                         " iallocator (%s) differ from original"
                                         " groups (%s)" %
                                         (utils.CommaJoin(result_groups),
                                          utils.CommaJoin(request_groups)))

  @staticmethod
  def _NodesToGroups(node2group, groups, nodes):
    """Returns a list of unique group names for a list of nodes.

    @type node2group: dict
    @param node2group: Map from node name to group UUID
    @type groups: dict
    @param groups: Group information
    @type nodes: list
    @param nodes: Node names

    """
    result = set()

    for node in nodes:
      try:
        group_uuid = node2group[node]
      except KeyError:
        # Ignore unknown node
        pass
      else:
        try:
          group = groups[group_uuid]
        except KeyError:
          # Can't find group, let's use UUID
          group_name = group_uuid
        else:
          group_name = group["name"]

        result.add(group_name)

    return sorted(result)


class IAReqNodeEvac(IARequestBase):
  """A node evacuation request.

  """
  # pylint: disable=E1101
  MODE = constants.IALLOCATOR_MODE_NODE_EVAC
  REQ_PARAMS = [
    ("instances", _STRING_LIST),
    ("evac_mode", ht.TEvacMode),
    ("ignore_soft_errors", ht.TMaybe(ht.TBool)),
    ]
  REQ_RESULT = _NEVAC_RESULT

  def GetRequest(self, cfg):
    """Get data for node-evacuate requests.

    """
    return {
      "instances": self.instances,
      "evac_mode": self.evac_mode,
      }

  def GetExtraParams(self):
    """Get extra iallocator command line options for
    node-evacuate requests.

    """
    if self.ignore_soft_errors:
      return {"ignore-soft-errors": None}
    else:
      return {}


class IAReqGroupChange(IARequestBase):
  """A group change request.

  """
  # pylint: disable=E1101
  MODE = constants.IALLOCATOR_MODE_CHG_GROUP
  REQ_PARAMS = [
    ("instances", _STRING_LIST),
    ("target_groups", _STRING_LIST),
    ]
  REQ_RESULT = _NEVAC_RESULT

  def GetRequest(self, cfg):
    """Get data for node-evacuate requests.

    """
    return {
      "instances": self.instances,
      "target_groups": self.target_groups,
      }


class IAllocator(object):
  """IAllocator framework.

  An IAllocator instance has three sets of attributes:
    - cfg that is needed to query the cluster
    - input data (all members of the _KEYS class attribute are required)
    - four buffer attributes (in|out_data|text), that represent the
      input (to the external script) in text and data structure format,
      and the output from it, again in two formats
    - the result variables from the script (success, info, nodes) for
      easy usage

  """
  # pylint: disable=R0902
  # lots of instance attributes

  def __init__(self, cfg, rpc_runner, req):
    self.cfg = cfg
    self.rpc = rpc_runner
    self.req = req
    # init buffer variables
    self.in_text = self.out_text = self.in_data = self.out_data = None
    # init result fields
    self.success = self.info = self.result = None

    self._BuildInputData(req)

  def _ComputeClusterDataNodeInfo(self, disk_templates, node_list,
                                  cluster_info, hypervisor_name):
    """Prepare and execute node info call.

    @type disk_templates: list of string
    @param disk_templates: the disk templates of the instances to be allocated
    @type node_list: list of strings
    @param node_list: list of nodes' UUIDs
    @type cluster_info: L{objects.Cluster}
    @param cluster_info: the cluster's information from the config
    @type hypervisor_name: string
    @param hypervisor_name: the hypervisor name
    @rtype: same as the result of the node info RPC call
    @return: the result of the node info RPC call

    """
    storage_units_raw = utils.storage.GetStorageUnits(self.cfg, disk_templates)
    storage_units = rpc.PrepareStorageUnitsForNodes(self.cfg, storage_units_raw,
                                                    node_list)
    hvspecs = [(hypervisor_name, cluster_info.hvparams[hypervisor_name])]
    return self.rpc.call_node_info(node_list, storage_units, hvspecs)

  def _ComputeClusterData(self, disk_template=None):
    """Compute the generic allocator input data.

    @type disk_template: list of string
    @param disk_template: the disk templates of the instances to be allocated

    """
    cfg = self.cfg.GetDetachedConfig()
    cluster_info = cfg.GetClusterInfo()
    # cluster data
    data = {
      "version": constants.IALLOCATOR_VERSION,
      "cluster_name": cluster_info.cluster_name,
      "cluster_tags": list(cluster_info.GetTags()),
      "enabled_hypervisors": list(cluster_info.enabled_hypervisors),
      "ipolicy": cluster_info.ipolicy,
      }
    ginfo = cfg.GetAllNodeGroupsInfo()
    ninfo = cfg.GetAllNodesInfo()
    iinfo = cfg.GetAllInstancesInfo()
    i_list = [(inst, cluster_info.FillBE(inst)) for inst in iinfo.values()]

    # node data
    node_list = [n.uuid for n in ninfo.values() if n.vm_capable]

    if isinstance(self.req, IAReqInstanceAlloc):
      hypervisor_name = self.req.hypervisor
    elif isinstance(self.req, IAReqRelocate):
      hypervisor_name = iinfo[self.req.inst_uuid].hypervisor
    else:
      hypervisor_name = cluster_info.primary_hypervisor

    if not disk_template:
      disk_template = cluster_info.enabled_disk_templates[0]

    node_data = self._ComputeClusterDataNodeInfo([disk_template], node_list,
                                                 cluster_info, hypervisor_name)

    node_iinfo = \
      self.rpc.call_all_instances_info(node_list,
                                       cluster_info.enabled_hypervisors,
                                       cluster_info.hvparams)

    data["nodegroups"] = self._ComputeNodeGroupData(cluster_info, ginfo)

    config_ndata = self._ComputeBasicNodeData(cfg, ninfo)
    data["nodes"] = self._ComputeDynamicNodeData(
        ninfo, node_data, node_iinfo, i_list, config_ndata, disk_template)
    assert len(data["nodes"]) == len(ninfo), \
        "Incomplete node data computed"

    data["instances"] = self._ComputeInstanceData(cfg, cluster_info, i_list)

    self.in_data = data

  @staticmethod
  def _ComputeNodeGroupData(cluster, ginfo):
    """Compute node groups data.

    """
    ng = dict((guuid, {
      "name": gdata.name,
      "alloc_policy": gdata.alloc_policy,
      "networks": [net_uuid for net_uuid, _ in gdata.networks.items()],
      "ipolicy": gmi.CalculateGroupIPolicy(cluster, gdata),
      "tags": list(gdata.GetTags()),
      })
      for guuid, gdata in ginfo.items())

    return ng

  @staticmethod
  def _ComputeBasicNodeData(cfg, node_cfg):
    """Compute global node data.

    @rtype: dict
    @returns: a dict of name: (node dict, node config)

    """
    # fill in static (config-based) values
    node_results = dict((ninfo.name, {
      "tags": list(ninfo.GetTags()),
      "primary_ip": ninfo.primary_ip,
      "secondary_ip": ninfo.secondary_ip,
      "offline": ninfo.offline,
      "drained": ninfo.drained,
      "master_candidate": ninfo.master_candidate,
      "group": ninfo.group,
      "master_capable": ninfo.master_capable,
      "vm_capable": ninfo.vm_capable,
      "ndparams": cfg.GetNdParams(ninfo),
      })
      for ninfo in node_cfg.values())

    return node_results

  @staticmethod
  def _GetAttributeFromHypervisorNodeData(hv_info, node_name, attr):
    """Extract an attribute from the hypervisor's node information.

    This is a helper function to extract data from the hypervisor's information
    about the node, as part of the result of a node_info query.

    @type hv_info: dict of strings
    @param hv_info: dictionary of node information from the hypervisor
    @type node_name: string
    @param node_name: name of the node
    @type attr: string
    @param attr: key of the attribute in the hv_info dictionary
    @rtype: integer
    @return: the value of the attribute
    @raises errors.OpExecError: if key not in dictionary or value not
      integer

    """
    if attr not in hv_info:
      raise errors.OpExecError("Node '%s' didn't return attribute"
                               " '%s'" % (node_name, attr))
    value = hv_info[attr]
    if not isinstance(value, int):
      raise errors.OpExecError("Node '%s' returned invalid value"
                               " for '%s': %s" %
                               (node_name, attr, value))
    return value

  @staticmethod
  def _ComputeStorageDataFromSpaceInfoByTemplate(
      space_info, node_name, disk_template):
    """Extract storage data from node info.

    @type space_info: see result of the RPC call node info
    @param space_info: the storage reporting part of the result of the RPC call
      node info
    @type node_name: string
    @param node_name: the node's name
    @type disk_template: string
    @param disk_template: the disk template to report space for
    @rtype: 4-tuple of integers
    @return: tuple of storage info (total_disk, free_disk, total_spindles,
       free_spindles)

    """
    storage_type = constants.MAP_DISK_TEMPLATE_STORAGE_TYPE[disk_template]
    if storage_type not in constants.STS_REPORT:
      total_disk = total_spindles = 0
      free_disk = free_spindles = 0
    else:
      template_space_info = utils.storage.LookupSpaceInfoByDiskTemplate(
          space_info, disk_template)
      if not template_space_info:
        raise errors.OpExecError("Node '%s' didn't return space info for disk"
                                   "template '%s'" % (node_name, disk_template))
      total_disk = template_space_info["storage_size"]
      free_disk = template_space_info["storage_free"]

      total_spindles = 0
      free_spindles = 0
      if disk_template in constants.DTS_LVM:
        lvm_pv_info = utils.storage.LookupSpaceInfoByStorageType(
           space_info, constants.ST_LVM_PV)
        if lvm_pv_info:
          total_spindles = lvm_pv_info["storage_size"]
          free_spindles = lvm_pv_info["storage_free"]
    return (total_disk, free_disk, total_spindles, free_spindles)

  @staticmethod
  def _ComputeStorageDataFromSpaceInfo(space_info, node_name, has_lvm):
    """Extract storage data from node info.

    @type space_info: see result of the RPC call node info
    @param space_info: the storage reporting part of the result of the RPC call
      node info
    @type node_name: string
    @param node_name: the node's name
    @type has_lvm: boolean
    @param has_lvm: whether or not LVM storage information is requested
    @rtype: 4-tuple of integers
    @return: tuple of storage info (total_disk, free_disk, total_spindles,
       free_spindles)

    """
    # TODO: replace this with proper storage reporting
    if has_lvm:
      lvm_vg_info = utils.storage.LookupSpaceInfoByStorageType(
         space_info, constants.ST_LVM_VG)
      if not lvm_vg_info:
        raise errors.OpExecError("Node '%s' didn't return LVM vg space info."
                                 % (node_name))
      total_disk = lvm_vg_info["storage_size"]
      free_disk = lvm_vg_info["storage_free"]
      lvm_pv_info = utils.storage.LookupSpaceInfoByStorageType(
         space_info, constants.ST_LVM_PV)
      if not lvm_pv_info:
        raise errors.OpExecError("Node '%s' didn't return LVM pv space info."
                                 % (node_name))
      total_spindles = lvm_pv_info["storage_size"]
      free_spindles = lvm_pv_info["storage_free"]
    else:
      # we didn't even ask the node for VG status, so use zeros
      total_disk = free_disk = 0
      total_spindles = free_spindles = 0
    return (total_disk, free_disk, total_spindles, free_spindles)

  @staticmethod
  def _ComputeInstanceMemory(instance_list, node_instances_info, node_uuid,
                             input_mem_free):
    """Compute memory used by primary instances.

    @rtype: tuple (int, int, int)
    @returns: A tuple of three integers: 1. the sum of memory used by primary
      instances on the node (including the ones that are currently down), 2.
      the sum of memory used by primary instances of the node that are up, 3.
      the amount of memory that is free on the node considering the current
      usage of the instances.

    """
    i_p_mem = i_p_up_mem = 0
    mem_free = input_mem_free
    for iinfo, beinfo in instance_list:
      if iinfo.primary_node == node_uuid:
        i_p_mem += beinfo[constants.BE_MAXMEM]
        if iinfo.name not in node_instances_info[node_uuid].payload:
          i_used_mem = 0
        else:
          i_used_mem = int(node_instances_info[node_uuid]
                           .payload[iinfo.name]["memory"])
        i_mem_diff = beinfo[constants.BE_MAXMEM] - i_used_mem
        if iinfo.admin_state == constants.ADMINST_UP \
            and not iinfo.forthcoming:
          mem_free -= max(0, i_mem_diff)
          i_p_up_mem += beinfo[constants.BE_MAXMEM]
    return (i_p_mem, i_p_up_mem, mem_free)

  def _ComputeDynamicNodeData(self, node_cfg, node_data, node_iinfo, i_list,
                              node_results, disk_template):
    """Compute global node data.

    @param node_results: the basic node structures as filled from the config

    """
    #TODO(dynmem): compute the right data on MAX and MIN memory
    # make a copy of the current dict
    node_results = dict(node_results)
    for nuuid, nresult in node_data.items():
      ninfo = node_cfg[nuuid]
      assert ninfo.name in node_results, "Missing basic data for node %s" % \
                                         ninfo.name

      if not ninfo.offline:
        nresult.Raise("Can't get data for node %s" % ninfo.name)
        node_iinfo[nuuid].Raise("Can't get node instance info from node %s" %
                                ninfo.name)
        (_, space_info, (hv_info, )) = nresult.payload

        mem_free = self._GetAttributeFromHypervisorNodeData(hv_info, ninfo.name,
                                                            "memory_free")

        (i_p_mem, i_p_up_mem, mem_free) = self._ComputeInstanceMemory(
             i_list, node_iinfo, nuuid, mem_free)
        (total_disk, free_disk, total_spindles, free_spindles) = \
            self._ComputeStorageDataFromSpaceInfoByTemplate(
                space_info, ninfo.name, disk_template)

        # compute memory used by instances
        pnr_dyn = {
          "total_memory": self._GetAttributeFromHypervisorNodeData(
              hv_info, ninfo.name, "memory_total"),
          "reserved_memory": self._GetAttributeFromHypervisorNodeData(
              hv_info, ninfo.name, "memory_dom0"),
          "free_memory": mem_free,
          "total_disk": total_disk,
          "free_disk": free_disk,
          "total_spindles": total_spindles,
          "free_spindles": free_spindles,
          "total_cpus": self._GetAttributeFromHypervisorNodeData(
              hv_info, ninfo.name, "cpu_total"),
          "reserved_cpus": self._GetAttributeFromHypervisorNodeData(
            hv_info, ninfo.name, "cpu_dom0"),
          "i_pri_memory": i_p_mem,
          "i_pri_up_memory": i_p_up_mem,
          }
        pnr_dyn.update(node_results[ninfo.name])
        node_results[ninfo.name] = pnr_dyn

    return node_results

  @staticmethod
  def _ComputeInstanceData(cfg, cluster_info, i_list):
    """Compute global instance data.

    """
    instance_data = {}
    for iinfo, beinfo in i_list:
      nic_data = []
      for nic in iinfo.nics:
        filled_params = cluster_info.SimpleFillNIC(nic.nicparams)
        nic_dict = {
          "mac": nic.mac,
          "ip": nic.ip,
          "mode": filled_params[constants.NIC_MODE],
          "link": filled_params[constants.NIC_LINK],
          }
        if filled_params[constants.NIC_MODE] == constants.NIC_MODE_BRIDGED:
          nic_dict["bridge"] = filled_params[constants.NIC_LINK]
        nic_data.append(nic_dict)
      inst_disks = cfg.GetInstanceDisks(iinfo.uuid)
      inst_disktemplate = cfg.GetInstanceDiskTemplate(iinfo.uuid)
      pir = {
        "tags": list(iinfo.GetTags()),
        "admin_state": iinfo.admin_state,
        "vcpus": beinfo[constants.BE_VCPUS],
        "memory": beinfo[constants.BE_MAXMEM],
        "spindle_use": beinfo[constants.BE_SPINDLE_USE],
        "os": iinfo.os,
        "nodes": [cfg.GetNodeName(iinfo.primary_node)] +
                 cfg.GetNodeNames(
                   cfg.GetInstanceSecondaryNodes(iinfo.uuid)),
        "nics": nic_data,
        "disks": [{constants.IDISK_TYPE: dsk.dev_type,
                   constants.IDISK_SIZE: dsk.size,
                   constants.IDISK_MODE: dsk.mode,
                   constants.IDISK_SPINDLES: dsk.spindles}
                  for dsk in inst_disks],
        "disk_template": inst_disktemplate,
        "disks_active": iinfo.disks_active,
        "hypervisor": iinfo.hypervisor,
        }
      pir["disk_space_total"] = gmi.ComputeDiskSize(pir["disks"])
      instance_data[iinfo.name] = pir

    return instance_data

  def _BuildInputData(self, req):
    """Build input data structures.

    """
    request = req.GetRequest(self.cfg)
    disk_template = None
    if request.get("disk_template") is not None:
      disk_template = request["disk_template"]
    elif isinstance(req, IAReqRelocate):
      disk_template = self.cfg.GetInstanceDiskTemplate(self.req.inst_uuid)
    self._ComputeClusterData(disk_template=disk_template)

    request["type"] = req.MODE

    if isinstance(self.req, IAReqInstanceAlloc):
      node_whitelist = self.req.node_whitelist
    else:
      node_whitelist = None
    if node_whitelist is not None:
      request["restrict-to-nodes"] = node_whitelist

    self.in_data["request"] = request

    self.in_text = serializer.Dump(self.in_data)
    logging.debug("IAllocator request: %s", self.in_text)

  def Run(self, name, validate=True, call_fn=None):
    """Run an instance allocator and return the results.

    """
    if call_fn is None:
      call_fn = self.rpc.call_iallocator_runner

    ial_params = self.cfg.GetDefaultIAllocatorParameters()

    for ial_param in self.req.GetExtraParams().items():
      ial_params[ial_param[0]] = ial_param[1]

    result = call_fn(self.cfg.GetMasterNode(), name, self.in_text, ial_params)
    result.Raise("Failure while running the iallocator script")

    self.out_text = result.payload
    if validate:
      self._ValidateResult()

  def _ValidateResult(self):
    """Process the allocator results.

    This will process and if successful save the result in
    self.out_data and the other parameters.

    """
    try:
      rdict = serializer.Load(self.out_text)
    except Exception, err:
      raise errors.OpExecError("Can't parse iallocator results: %s" % str(err))

    if not isinstance(rdict, dict):
      raise errors.OpExecError("Can't parse iallocator results: not a dict")

    # TODO: remove backwards compatiblity in later versions
    if "nodes" in rdict and "result" not in rdict:
      rdict["result"] = rdict["nodes"]
      del rdict["nodes"]

    for key in "success", "info", "result":
      if key not in rdict:
        raise errors.OpExecError("Can't parse iallocator results:"
                                 " missing key '%s'" % key)
      setattr(self, key, rdict[key])

    self.req.ValidateResult(self, self.result)
    self.out_data = rdict
