def CheckPrereq(self):
    assert self.op.instance_name in self.owned_locks(locking.LEVEL_INSTANCE)
    self.instance = self.cfg.GetInstanceInfo(self.op.instance_uuid)
    self.cluster = self.cfg.GetClusterInfo()
    cluster_hvparams = self.cluster.hvparams[self.instance.hypervisor]

    self.op.disks = self._LookupDiskMods()

    assert self.instance is not None, \
      "Cannot retrieve locked instance %s" % self.op.instance_name

    self.warn = []

    if (self.op.pnode_uuid is not None and
        self.op.pnode_uuid != self.instance.primary_node and
        not self.op.force):
      instance_info = self._GetInstanceInfo(cluster_hvparams)

      if instance_info.fail_msg:
        self.warn.append("Can't get instance runtime information: %s" %
                         instance_info.fail_msg)
      elif instance_info.payload:
        raise errors.OpPrereqError(
            "Instance is still running on %s" %
            self.cfg.GetNodeName(self.instance.primary_node),
            errors.ECODE_STATE)
    pnode_uuid = self.instance.primary_node
    assert pnode_uuid in self.owned_locks(locking.LEVEL_NODE)

    node_uuids = list(self.cfg.GetInstanceNodes(self.instance.uuid))
    pnode_info = self.cfg.GetNodeInfo(pnode_uuid)

    assert pnode_info.group in self.owned_locks(locking.LEVEL_NODEGROUP)
    group_info = self.cfg.GetNodeGroup(pnode_info.group)

    # dictionary with instance information after the modification
    ispec = {}

    self._CheckHotplug()

    self._PrepareNicCommunication()

    # disks processing
    assert not (self.op.disk_template and self.op.disks), \
      "Can't modify disk template and apply disk changes at the same time"

    if self.op.disk_template:
      self._PreCheckDiskTemplate(pnode_info)

    self._PreCheckDisks(ispec)

    self._ProcessHVParams(node_uuids)
    be_old = self._ProcessBeParams()

    self._ValidateCpuParams()
    self._ProcessOsParams(node_uuids)
    self._ProcessMem(cluster_hvparams, be_old, pnode_uuid)

    # make self.cluster visible in the functions below
    cluster = self.cluster

    def _PrepareNicCreate(_, params, private):
      self._PrepareNicModification(params, private, None, None,
                                   {}, cluster, pnode_uuid)
      return (None, None)

    def _PrepareNicAttach(_, __, ___):
      raise errors.OpPrereqError("Attach operation is not supported for NICs",
                                 errors.ECODE_INVAL)

    def _PrepareNicMod(_, nic, params, private):
      self._PrepareNicModification(params, private, nic.ip, nic.network,
                                   nic.nicparams, cluster, pnode_uuid)
      return None

    def _PrepareNicRemove(_, params, __):
      ip = params.ip
      net = params.network
      if net is not None and ip is not None:
        self.cfg.ReleaseIp(net, ip, self.proc.GetECId())

    def _PrepareNicDetach(_, __, ___):
      raise errors.OpPrereqError("Detach operation is not supported for NICs",
                                 errors.ECODE_INVAL)

    # Verify NIC changes (operating on copy)
    nics = [nic.Copy() for nic in self.instance.nics]
    ApplyContainerMods("NIC", nics, None, self.nicmod, _PrepareNicCreate,
                       _PrepareNicAttach, _PrepareNicMod, _PrepareNicRemove,
                       _PrepareNicDetach)
    if len(nics) > constants.MAX_NICS:
      raise errors.OpPrereqError("Instance has too many network interfaces"
                                 " (%d), cannot add more" % constants.MAX_NICS,
                                 errors.ECODE_STATE)

    # Pre-compute NIC changes (necessary to use result in hooks)
    self._nic_chgdesc = []
    if self.nicmod:
      # Operate on copies as this is still in prereq
      nics = [nic.Copy() for nic in self.instance.nics]
      ApplyContainerMods("NIC", nics, self._nic_chgdesc, self.nicmod,
                         self._CreateNewNic, None, self._ApplyNicMods,
                         self._RemoveNic, None)
      # Verify that NIC names are unique and valid
      utils.ValidateDeviceNames("NIC", nics)
      self._new_nics = nics
      ispec[constants.ISPEC_NIC_COUNT] = len(self._new_nics)
    else:
      self._new_nics = None
      ispec[constants.ISPEC_NIC_COUNT] = len(self.instance.nics)

    if not self.op.ignore_ipolicy:
      ipolicy = ganeti.masterd.instance.CalculateGroupIPolicy(self.cluster,
                                                              group_info)

      # Fill ispec with backend parameters
      ispec[constants.ISPEC_SPINDLE_USE] = \
        self.be_new.get(constants.BE_SPINDLE_USE, None)
      ispec[constants.ISPEC_CPU_COUNT] = self.be_new.get(constants.BE_VCPUS,
                                                         None)

      # Copy ispec to verify parameters with min/max values separately
      if self.op.disk_template:
        count = ispec[constants.ISPEC_DISK_COUNT]
        new_disk_types = [self.op.disk_template] * count
      else:
        old_disks = self.cfg.GetInstanceDisks(self.instance.uuid)
        add_disk_count = ispec[constants.ISPEC_DISK_COUNT] - len(old_disks)
        dev_type = self.cfg.GetInstanceDiskTemplate(self.instance.uuid)
        if dev_type == constants.DT_DISKLESS and add_disk_count != 0:
          raise errors.ProgrammerError(
              "Conversion from diskless instance not possible and should have"
              " been caught")

        new_disk_types = ([d.dev_type for d in old_disks] +
                          [dev_type] * add_disk_count)
      ispec_max = ispec.copy()
      ispec_max[constants.ISPEC_MEM_SIZE] = \
        self.be_new.get(constants.BE_MAXMEM, None)
      res_max = ComputeIPolicyInstanceSpecViolation(ipolicy, ispec_max,
                                                    new_disk_types)
      ispec_min = ispec.copy()
      ispec_min[constants.ISPEC_MEM_SIZE] = \
        self.be_new.get(constants.BE_MINMEM, None)
      res_min = ComputeIPolicyInstanceSpecViolation(ipolicy, ispec_min,
                                                    new_disk_types)

      if (res_max or res_min):
        # FIXME: Improve error message by including information about whether
        # the upper or lower limit of the parameter fails the ipolicy.
        msg = ("Instance allocation to group %s (%s) violates policy: %s" %
               (group_info, group_info.name,
                utils.CommaJoin(set(res_max + res_min))))
        raise errors.OpPrereqError(msg, errors.ECODE_INVAL)
Check prerequisites.
dataset/ETHPy150Open ganeti/ganeti/lib/cmdlib/instance_set_params.py/LUInstanceSetParams.CheckPrereq