def Exec(self, feedback_fn):
    """Move an instance.

    The move is done by shutting it down on its present node, copying
    the data over (slow) and starting it on the new node.

    """
    source_node = self.cfg.GetNodeInfo(self.instance.primary_node)
    target_node = self.cfg.GetNodeInfo(self.target_node_uuid)

    self.LogInfo("Shutting down instance %s on source node %s",
                 self.instance.name, source_node.name)

    assert (self.owned_locks(locking.LEVEL_NODE) ==
            self.owned_locks(locking.LEVEL_NODE_RES))

    result = self.rpc.call_instance_shutdown(source_node.uuid, self.instance,
                                             self.op.shutdown_timeout,
                                             self.op.reason)
    if self.op.ignore_consistency:
      result.Warn("Could not shutdown instance %s on node %s. Proceeding"
                  " anyway. Please make sure node %s is down. Error details" %
                  (self.instance.name, source_node.name, source_node.name),
                  self.LogWarning)
    else:
      result.Raise("Could not shutdown instance %s on node %s" %
                   (self.instance.name, source_node.name))

    # create the target disks
    try:
      CreateDisks(self, self.instance, target_node_uuid=target_node.uuid)
    except errors.OpExecError:
      self.LogWarning("Device creation failed")
      for disk_uuid in self.instance.disks:
        self.cfg.ReleaseDRBDMinors(disk_uuid)
      raise

    errs = []
    transfers = []
    # activate, get path, create transfer jobs
    disks = self.cfg.GetInstanceDisks(self.instance.uuid)
    for idx, disk in enumerate(disks):
      # FIXME: pass debug option from opcode to backend
      dt = masterd.instance.DiskTransfer("disk/%s" % idx,
                                         constants.IEIO_RAW_DISK,
                                         (disk, self.instance),
                                         constants.IEIO_RAW_DISK,
                                         (disk, self.instance),
                                         None)
      transfers.append(dt)
      self.cfg.Update(disk, feedback_fn)

    import_result = \
      masterd.instance.TransferInstanceData(self, feedback_fn,
                                            source_node.uuid,
                                            target_node.uuid,
                                            target_node.secondary_ip,
                                            self.op.compress,
                                            self.instance, transfers)
    if not compat.all(import_result):
      errs.append("Failed to transfer instance data")

    if errs:
      self.LogWarning("Some disks failed to copy, aborting")
      try:
        RemoveDisks(self, self.instance, target_node_uuid=target_node.uuid)
      finally:
        for disk_uuid in self.instance.disks:
          self.cfg.ReleaseDRBDMinors(disk_uuid)
        raise errors.OpExecError("Errors during disk copy: %s" %
                                 (",".join(errs),))

    self.instance.primary_node = target_node.uuid
    self.cfg.Update(self.instance, feedback_fn)
    for disk in disks:
      self.cfg.SetDiskNodes(disk.uuid, [target_node.uuid])

    self.LogInfo("Removing the disks on the original node")
    RemoveDisks(self, self.instance, target_node_uuid=source_node.uuid)

    # Only start the instance if it's marked as up
    if self.instance.admin_state == constants.ADMINST_UP:
      self.LogInfo("Starting instance %s on node %s",
                   self.instance.name, target_node.name)

      disks_ok, _, _ = AssembleInstanceDisks(self, self.instance,
                                             ignore_secondaries=True)
      if not disks_ok:
        ShutdownInstanceDisks(self, self.instance)
        raise errors.OpExecError("Can't activate the instance's disks")

      result = self.rpc.call_instance_start(target_node.uuid,
                                            (self.instance, None, None), False,
                                            self.op.reason)
      msg = result.fail_msg
      if msg:
        ShutdownInstanceDisks(self, self.instance)
        raise errors.OpExecError("Could not start instance %s on node %s: %s" %
                                 (self.instance.name, target_node.name, msg))
dataset/ETHPy150Open ganeti/ganeti/lib/cmdlib/instance.py/LUInstanceMove.Exec/original