def Exec(self, feedback_fn):
    self.feedback_fn = feedback_fn
    # Process here the warnings from CheckPrereq, as we don't have a
    # feedback_fn there.
    # TODO: Replace with self.LogWarning
    for warn in self.warn:
      feedback_fn("WARNING: %s" % warn)

    assert ((self.op.disk_template is None) ^
            bool(self.owned_locks(locking.LEVEL_NODE_RES))), \
      "Not owning any node resource locks"

    result = []

    # New primary node
    if self.op.pnode_uuid:
      self.instance.primary_node = self.op.pnode_uuid

    # runtime memory
    if self.op.runtime_mem:
      rpcres = self.rpc.call_instance_balloon_memory(self.instance.primary_node,
                                                     self.instance,
                                                     self.op.runtime_mem)
      rpcres.Raise("Cannot modify instance runtime memory")
      result.append(("runtime_memory", self.op.runtime_mem))

    # Apply disk changes
    inst_disks = self.cfg.GetInstanceDisks(self.instance.uuid)
    ApplyContainerMods("disk", inst_disks, result, self.diskmod,
                       self._CreateNewDisk, self._AttachDisk, self._ModifyDisk,
                       self._RemoveDisk, self._DetachDisk,
                       post_add_fn=self._PostAddDisk)

    if self.op.disk_template:
      if __debug__:
        check_nodes = set(self.cfg.GetInstanceNodes(self.instance.uuid))
        if self.op.remote_node_uuid:
          check_nodes.add(self.op.remote_node_uuid)
        for level in [locking.LEVEL_NODE, locking.LEVEL_NODE_RES]:
          owned = self.owned_locks(level)
          assert not (check_nodes - owned), \
            ("Not owning the correct locks, owning %r, expected at least %r" %
             (owned, check_nodes))

      r_shut = ShutdownInstanceDisks(self, self.instance)
      if not r_shut:
        raise errors.OpExecError("Cannot shutdown instance disks, unable to"
                                 " proceed with disk template conversion")
      #TODO make heterogeneous conversions work
      mode = (self.cfg.GetInstanceDiskTemplate(self.instance.uuid),
              self.op.disk_template)
      try:
        if mode in self._DISK_CONVERSIONS:
          self._DISK_CONVERSIONS[mode](self, feedback_fn)
        else:
          self._ConvertInstanceDisks(feedback_fn)
      except:
        for disk in inst_disks:
          self.cfg.ReleaseDRBDMinors(disk.uuid)
        raise
      result.append(("disk_template", self.op.disk_template))

      disk_info = self.cfg.GetInstanceDisks(self.instance.uuid)
      assert utils.AllDiskOfType(disk_info, [self.op.disk_template]), \
        ("Expected disk template '%s', found '%s'" %
         (self.op.disk_template,
          self.cfg.GetInstanceDiskTemplate(self.instance.uuid)))

    # Release node and resource locks if there are any (they might already have
    # been released during disk conversion)
    ReleaseLocks(self, locking.LEVEL_NODE)
    ReleaseLocks(self, locking.LEVEL_NODE_RES)

    # Apply NIC changes
    if self._new_nics is not None:
      self.instance.nics = self._new_nics
      result.extend(self._nic_chgdesc)

    # hvparams changes
    if self.op.hvparams:
      self.instance.hvparams = self.hv_inst
      for key, val in self.op.hvparams.iteritems():
        result.append(("hv/%s" % key, val))

    # beparams changes
    if self.op.beparams:
      self.instance.beparams = self.be_inst
      for key, val in self.op.beparams.iteritems():
        result.append(("be/%s" % key, val))

    # OS change
    if self.op.os_name:
      self.instance.os = self.op.os_name

    # osparams changes
    if self.op.osparams:
      self.instance.osparams = self.os_inst
      for key, val in self.op.osparams.iteritems():
        result.append(("os/%s" % key, val))

    if self.op.osparams_private:
      self.instance.osparams_private = self.os_inst_private
      for key, val in self.op.osparams_private.iteritems():
        # Show the Private(...) blurb.
        result.append(("os_private/%s" % key, repr(val)))

    self.cfg.Update(self.instance, feedback_fn, self.proc.GetECId())

    if self.op.offline is None:
      # Ignore
      pass
    elif self.op.offline:
      # Mark instance as offline
      self.instance = self.cfg.MarkInstanceOffline(self.instance.uuid)
      result.append(("admin_state", constants.ADMINST_OFFLINE))
    else:
      # Mark instance as online, but stopped
      self.instance = self.cfg.MarkInstanceDown(self.instance.uuid)
      result.append(("admin_state", constants.ADMINST_DOWN))

    UpdateMetadata(feedback_fn, self.rpc, self.instance)

    assert not (self.owned_locks(locking.LEVEL_NODE_RES) or
                self.owned_locks(locking.LEVEL_NODE)), \
      "All node locks should have been released by now"

    return result
Modifies an instance.
dataset/ETHPy150Open ganeti/ganeti/lib/cmdlib/instance_set_params.py/LUInstanceSetParams.Exec