@OrFail("Upgrading disk nodes")
  def UpgradeDiskNodes(self):
    """Specify the nodes from which a disk is accessible in its definition.

    For every disk that is attached to an instance, get the UUIDs of the nodes
    that it's accessible from. There are three main cases:
    1) Internally mirrored disks (DRBD):
    These disks are accessible from two nodes, so the nodes list will include
    these. Their children (data, meta) are also accessible from two nodes,
    therefore they will inherit the nodes of the parent.
    2) Externally mirrored disks (Blockdev, Ext, Gluster, RBD, Shared File):
    These disks should be accessible from any node in the cluster, therefore the
    nodes list will be empty.
    3) Single-node disks (Plain, File):
    These disks are accessible from one node only, therefore the nodes list will
    consist only of the primary instance node.
    """
    disks = self.config_data["disks"]
    for instance in self.config_data["instances"].itervalues():
      # Get all disk nodes for an instance
      instance_node = set([instance["primary_node"]])
      disk_nodes = set()
      for disk_uuid in instance["disks"]:
        disk_nodes |= self._ComputeAllNodes(disks[disk_uuid])
      all_nodes = list(instance_node | disk_nodes)

      # Populate the `nodes` list field of each disk.
      for disk_uuid in instance["disks"]:
        disk = disks[disk_uuid]
        if "nodes" in disk:
          # The "nodes" field has already been added for this disk.
          continue

        if disk["dev_type"] in constants.DTS_INT_MIRROR:
          self._RecursiveUpdateNodes(disk, all_nodes)
        elif disk["dev_type"] in (constants.DT_PLAIN, constants.DT_FILE):
          disk["nodes"] = all_nodes
        else:
          disk["nodes"] = []
dataset/ETHPy150Open ganeti/ganeti/lib/tools/cfgupgrade.py/CfgUpgrade.UpgradeDiskNodes/original