Revision da4a52a3 lib/config.py

b/lib/config.py
665 665
    _helper_ipolicy("cluster", cluster.ipolicy, True)
666 666

  
667 667
    # per-instance checks
668
    for instance_name in data.instances:
669
      instance = data.instances[instance_name]
670
      if instance.name != instance_name:
671
        result.append("instance '%s' is indexed by wrong name '%s'" %
672
                      (instance.name, instance_name))
668
    for instance_uuid in data.instances:
669
      instance = data.instances[instance_uuid]
670
      if instance.uuid != instance_uuid:
671
        result.append("instance '%s' is indexed by wrong UUID '%s'" %
672
                      (instance.name, instance_uuid))
673 673
      if instance.primary_node not in data.nodes:
674 674
        result.append("instance '%s' has invalid primary node '%s'" %
675
                      (instance_name, instance.primary_node))
675
                      (instance.name, instance.primary_node))
676 676
      for snode in instance.secondary_nodes:
677 677
        if snode not in data.nodes:
678 678
          result.append("instance '%s' has invalid secondary node '%s'" %
679
                        (instance_name, snode))
679
                        (instance.name, snode))
680 680
      for idx, nic in enumerate(instance.nics):
681 681
        if nic.mac in seen_macs:
682 682
          result.append("instance '%s' has NIC %d mac %s duplicate" %
683
                        (instance_name, idx, nic.mac))
683
                        (instance.name, idx, nic.mac))
684 684
        else:
685 685
          seen_macs.append(nic.mac)
686 686
        if nic.nicparams:
......
693 693
      # disk template checks
694 694
      if not instance.disk_template in data.cluster.enabled_disk_templates:
695 695
        result.append("instance '%s' uses the disabled disk template '%s'." %
696
                      (instance_name, instance.disk_template))
696
                      (instance.name, instance.disk_template))
697 697

  
698 698
      # parameter checks
699 699
      if instance.beparams:
......
961 961
    """Compute the used DRBD minor/nodes.
962 962

  
963 963
    @rtype: (dict, list)
964
    @return: dictionary of node_uuid: dict of minor: instance_name;
964
    @return: dictionary of node_uuid: dict of minor: instance_uuid;
965 965
        the returned dict will have all the nodes in it (even if with
966 966
        an empty list), and a list of duplicates; if the duplicates
967 967
        list is not empty, the configuration is corrupted and its caller
968 968
        should raise an exception
969 969

  
970 970
    """
971
    def _AppendUsedPorts(get_node_name_fn, instance_name, disk, used):
971
    def _AppendUsedMinors(get_node_name_fn, instance, disk, used):
972 972
      duplicates = []
973 973
      if disk.dev_type == constants.LD_DRBD8 and len(disk.logical_id) >= 5:
974 974
        node_a, node_b, _, minor_a, minor_b = disk.logical_id[:5]
975
        for node_uuid, port in ((node_a, minor_a), (node_b, minor_b)):
975
        for node_uuid, minor in ((node_a, minor_a), (node_b, minor_b)):
976 976
          assert node_uuid in used, \
977 977
            ("Node '%s' of instance '%s' not found in node list" %
978
             (get_node_name_fn(node_uuid), instance_name))
979
          if port in used[node_uuid]:
980
            duplicates.append((node_uuid, port, instance_name,
981
                               used[node_uuid][port]))
978
             (get_node_name_fn(node_uuid), instance.name))
979
          if minor in used[node_uuid]:
980
            duplicates.append((node_uuid, minor, instance.uuid,
981
                               used[node_uuid][minor]))
982 982
          else:
983
            used[node_uuid][port] = instance_name
983
            used[node_uuid][minor] = instance.uuid
984 984
      if disk.children:
985 985
        for child in disk.children:
986
          duplicates.extend(_AppendUsedPorts(get_node_name_fn, instance_name,
987
                                             child, used))
986
          duplicates.extend(_AppendUsedMinors(get_node_name_fn, instance, child,
987
                                              used))
988 988
      return duplicates
989 989

  
990 990
    duplicates = []
991
    my_dict = dict((node, {}) for node in self._config_data.nodes)
991
    my_dict = dict((node_uuid, {}) for node_uuid in self._config_data.nodes)
992 992
    for instance in self._config_data.instances.itervalues():
993 993
      for disk in instance.disks:
994
        duplicates.extend(_AppendUsedPorts(self._UnlockedGetNodeName,
995
                                           instance.name, disk, my_dict))
996
    for (node, minor), instance in self._temporary_drbds.iteritems():
997
      if minor in my_dict[node] and my_dict[node][minor] != instance:
998
        duplicates.append((node, minor, instance, my_dict[node][minor]))
994
        duplicates.extend(_AppendUsedMinors(self._UnlockedGetNodeName,
995
                                            instance, disk, my_dict))
996
    for (node_uuid, minor), inst_uuid in self._temporary_drbds.iteritems():
997
      if minor in my_dict[node_uuid] and my_dict[node_uuid][minor] != inst_uuid:
998
        duplicates.append((node_uuid, minor, inst_uuid,
999
                           my_dict[node_uuid][minor]))
999 1000
      else:
1000
        my_dict[node][minor] = instance
1001
        my_dict[node_uuid][minor] = inst_uuid
1001 1002
    return my_dict, duplicates
1002 1003

  
1003 1004
  @locking.ssynchronized(_config_lock)
......
1006 1007

  
1007 1008
    This is just a wrapper over L{_UnlockedComputeDRBDMap}.
1008 1009

  
1009
    @return: dictionary of node_uuid: dict of minor: instance_name;
1010
    @return: dictionary of node_uuid: dict of minor: instance_uuid;
1010 1011
        the returned dict will have all the nodes in it (even if with
1011 1012
        an empty list).
1012 1013

  
......
1018 1019
    return d_map
1019 1020

  
1020 1021
  @locking.ssynchronized(_config_lock)
1021
  def AllocateDRBDMinor(self, node_uuids, instance):
1022
  def AllocateDRBDMinor(self, node_uuids, inst_uuid):
1022 1023
    """Allocate a drbd minor.
1023 1024

  
1024 1025
    The free minor will be automatically computed from the existing
......
1026 1027
    multiple minors. The result is the list of minors, in the same
1027 1028
    order as the passed nodes.
1028 1029

  
1029
    @type instance: string
1030
    @param instance: the instance for which we allocate minors
1030
    @type inst_uuid: string
1031
    @param inst_uuid: the instance for which we allocate minors
1031 1032

  
1032 1033
    """
1033
    assert isinstance(instance, basestring), \
1034
           "Invalid argument '%s' passed to AllocateDRBDMinor" % instance
1034
    assert isinstance(inst_uuid, basestring), \
1035
           "Invalid argument '%s' passed to AllocateDRBDMinor" % inst_uuid
1035 1036

  
1036 1037
    d_map, duplicates = self._UnlockedComputeDRBDMap()
1037 1038
    if duplicates:
......
1043 1044
      if not ndata:
1044 1045
        # no minors used, we can start at 0
1045 1046
        result.append(0)
1046
        ndata[0] = instance
1047
        self._temporary_drbds[(nuuid, 0)] = instance
1047
        ndata[0] = inst_uuid
1048
        self._temporary_drbds[(nuuid, 0)] = inst_uuid
1048 1049
        continue
1049 1050
      keys = ndata.keys()
1050 1051
      keys.sort()
......
1060 1061
             ("Attempt to reuse allocated DRBD minor %d on node %s,"
1061 1062
              " already allocated to instance %s" %
1062 1063
              (minor, nuuid, d_map[nuuid][minor]))
1063
      ndata[minor] = instance
1064
      ndata[minor] = inst_uuid
1064 1065
      # double-check minor against reservation
1065 1066
      r_key = (nuuid, minor)
1066 1067
      assert r_key not in self._temporary_drbds, \
1067 1068
             ("Attempt to reuse reserved DRBD minor %d on node %s,"
1068 1069
              " reserved for instance %s" %
1069 1070
              (minor, nuuid, self._temporary_drbds[r_key]))
1070
      self._temporary_drbds[r_key] = instance
1071
      self._temporary_drbds[r_key] = inst_uuid
1071 1072
      result.append(minor)
1072 1073
    logging.debug("Request to allocate drbd minors, input: %s, returning %s",
1073 1074
                  node_uuids, result)
1074 1075
    return result
1075 1076

  
1076
  def _UnlockedReleaseDRBDMinors(self, instance):
1077
  def _UnlockedReleaseDRBDMinors(self, inst_uuid):
1077 1078
    """Release temporary drbd minors allocated for a given instance.
1078 1079

  
1079
    @type instance: string
1080
    @param instance: the instance for which temporary minors should be
1081
                     released
1080
    @type inst_uuid: string
1081
    @param inst_uuid: the instance for which temporary minors should be
1082
                      released
1082 1083

  
1083 1084
    """
1084
    assert isinstance(instance, basestring), \
1085
    assert isinstance(inst_uuid, basestring), \
1085 1086
           "Invalid argument passed to ReleaseDRBDMinors"
1086
    for key, name in self._temporary_drbds.items():
1087
      if name == instance:
1087
    for key, uuid in self._temporary_drbds.items():
1088
      if uuid == inst_uuid:
1088 1089
        del self._temporary_drbds[key]
1089 1090

  
1090 1091
  @locking.ssynchronized(_config_lock)
1091
  def ReleaseDRBDMinors(self, instance):
1092
  def ReleaseDRBDMinors(self, inst_uuid):
1092 1093
    """Release temporary drbd minors allocated for a given instance.
1093 1094

  
1094 1095
    This should be called on the error paths, on the success paths
......
1097 1098

  
1098 1099
    This function is just a wrapper over L{_UnlockedReleaseDRBDMinors}.
1099 1100

  
1100
    @type instance: string
1101
    @param instance: the instance for which temporary minors should be
1102
                     released
1101
    @type inst_uuid: string
1102
    @param inst_uuid: the instance for which temporary minors should be
1103
                      released
1103 1104

  
1104 1105
    """
1105
    self._UnlockedReleaseDRBDMinors(instance)
1106
    self._UnlockedReleaseDRBDMinors(inst_uuid)
1106 1107

  
1107 1108
  @locking.ssynchronized(_config_lock, shared=1)
1108 1109
  def GetConfigVersion(self):
......
1426 1427
                                        " MAC address '%s' already in use." %
1427 1428
                                        (instance.name, nic.mac))
1428 1429

  
1429
    self._EnsureUUID(instance, ec_id)
1430
    self._CheckUniqueUUID(instance, include_temporary=False)
1430 1431

  
1431 1432
    instance.serial_no = 1
1432 1433
    instance.ctime = instance.mtime = time.time()
1433
    self._config_data.instances[instance.name] = instance
1434
    self._config_data.instances[instance.uuid] = instance
1434 1435
    self._config_data.cluster.serial_no += 1
1435
    self._UnlockedReleaseDRBDMinors(instance.name)
1436
    self._UnlockedReleaseDRBDMinors(instance.uuid)
1436 1437
    self._UnlockedCommitTemporaryIps(ec_id)
1437 1438
    self._WriteConfig()
1438 1439

  
......
1445 1446
    """
1446 1447
    if not item.uuid:
1447 1448
      item.uuid = self._GenerateUniqueID(ec_id)
1448
    elif item.uuid in self._AllIDs(include_temporary=True):
1449
    else:
1450
      self._CheckUniqueUUID(item, include_temporary=True)
1451

  
1452
  def _CheckUniqueUUID(self, item, include_temporary):
1453
    """Checks that the UUID of the given object is unique.
1454

  
1455
    @param item: the instance or node to be checked
1456
    @param include_temporary: whether temporarily generated UUID's should be
1457
              included in the check. If the UUID of the item to be checked is
1458
              a temporarily generated one, this has to be C{False}.
1459

  
1460
    """
1461
    if not item.uuid:
1462
      raise errors.ConfigurationError("'%s' must have an UUID" % (item.name,))
1463
    if item.uuid in self._AllIDs(include_temporary=include_temporary):
1449 1464
      raise errors.ConfigurationError("Cannot add '%s': UUID %s already"
1450 1465
                                      " in use" % (item.name, item.uuid))
1451 1466

  
1452
  def _SetInstanceStatus(self, instance_name, status, disks_active):
1467
  def _SetInstanceStatus(self, inst_uuid, status, disks_active):
1453 1468
    """Set the instance's status to a given value.
1454 1469

  
1455 1470
    """
1456
    if instance_name not in self._config_data.instances:
1471
    if inst_uuid not in self._config_data.instances:
1457 1472
      raise errors.ConfigurationError("Unknown instance '%s'" %
1458
                                      instance_name)
1459
    instance = self._config_data.instances[instance_name]
1473
                                      inst_uuid)
1474
    instance = self._config_data.instances[inst_uuid]
1460 1475

  
1461 1476
    if status is None:
1462 1477
      status = instance.admin_state
......
1475 1490
      self._WriteConfig()
1476 1491

  
1477 1492
  @locking.ssynchronized(_config_lock)
1478
  def MarkInstanceUp(self, instance_name):
1493
  def MarkInstanceUp(self, inst_uuid):
1479 1494
    """Mark the instance status to up in the config.
1480 1495

  
1481 1496
    This also sets the instance disks active flag.
1482 1497

  
1483 1498
    """
1484
    self._SetInstanceStatus(instance_name, constants.ADMINST_UP, True)
1499
    self._SetInstanceStatus(inst_uuid, constants.ADMINST_UP, True)
1485 1500

  
1486 1501
  @locking.ssynchronized(_config_lock)
1487
  def MarkInstanceOffline(self, instance_name):
1502
  def MarkInstanceOffline(self, inst_uuid):
1488 1503
    """Mark the instance status to down in the config.
1489 1504

  
1490 1505
    This also clears the instance disks active flag.
1491 1506

  
1492 1507
    """
1493
    self._SetInstanceStatus(instance_name, constants.ADMINST_OFFLINE, False)
1508
    self._SetInstanceStatus(inst_uuid, constants.ADMINST_OFFLINE, False)
1494 1509

  
1495 1510
  @locking.ssynchronized(_config_lock)
1496
  def RemoveInstance(self, instance_name):
1511
  def RemoveInstance(self, inst_uuid):
1497 1512
    """Remove the instance from the configuration.
1498 1513

  
1499 1514
    """
1500
    if instance_name not in self._config_data.instances:
1501
      raise errors.ConfigurationError("Unknown instance '%s'" % instance_name)
1515
    if inst_uuid not in self._config_data.instances:
1516
      raise errors.ConfigurationError("Unknown instance '%s'" % inst_uuid)
1502 1517

  
1503 1518
    # If a network port has been allocated to the instance,
1504 1519
    # return it to the pool of free ports.
1505
    inst = self._config_data.instances[instance_name]
1520
    inst = self._config_data.instances[inst_uuid]
1506 1521
    network_port = getattr(inst, "network_port", None)
1507 1522
    if network_port is not None:
1508 1523
      self._config_data.cluster.tcpudp_port_pool.add(network_port)
1509 1524

  
1510
    instance = self._UnlockedGetInstanceInfo(instance_name)
1525
    instance = self._UnlockedGetInstanceInfo(inst_uuid)
1511 1526

  
1512 1527
    for nic in instance.nics:
1513 1528
      if nic.network and nic.ip:
1514 1529
        # Return all IP addresses to the respective address pools
1515 1530
        self._UnlockedCommitIp(constants.RELEASE_ACTION, nic.network, nic.ip)
1516 1531

  
1517
    del self._config_data.instances[instance_name]
1532
    del self._config_data.instances[inst_uuid]
1518 1533
    self._config_data.cluster.serial_no += 1
1519 1534
    self._WriteConfig()
1520 1535

  
1521 1536
  @locking.ssynchronized(_config_lock)
1522
  def RenameInstance(self, old_name, new_name):
1537
  def RenameInstance(self, inst_uuid, new_name):
1523 1538
    """Rename an instance.
1524 1539

  
1525 1540
    This needs to be done in ConfigWriter and not by RemoveInstance
......
1527 1542
    rename.
1528 1543

  
1529 1544
    """
1530
    if old_name not in self._config_data.instances:
1531
      raise errors.ConfigurationError("Unknown instance '%s'" % old_name)
1545
    if inst_uuid not in self._config_data.instances:
1546
      raise errors.ConfigurationError("Unknown instance '%s'" % inst_uuid)
1532 1547

  
1533
    # Operate on a copy to not loose instance object in case of a failure
1534
    inst = self._config_data.instances[old_name].Copy()
1548
    inst = self._config_data.instances[inst_uuid]
1535 1549
    inst.name = new_name
1536 1550

  
1537 1551
    for (idx, disk) in enumerate(inst.disks):
......
1543 1557
                                          "disk%s" % idx))
1544 1558
        disk.physical_id = disk.logical_id
1545 1559

  
1546
    # Actually replace instance object
1547
    del self._config_data.instances[old_name]
1548
    self._config_data.instances[inst.name] = inst
1549

  
1550 1560
    # Force update of ssconf files
1551 1561
    self._config_data.cluster.serial_no += 1
1552 1562

  
1553 1563
    self._WriteConfig()
1554 1564

  
1555 1565
  @locking.ssynchronized(_config_lock)
1556
  def MarkInstanceDown(self, instance_name):
1566
  def MarkInstanceDown(self, inst_uuid):
1557 1567
    """Mark the status of an instance to down in the configuration.
1558 1568

  
1559 1569
    This does not touch the instance disks active flag, as shut down instances
1560 1570
    can still have active disks.
1561 1571

  
1562 1572
    """
1563
    self._SetInstanceStatus(instance_name, constants.ADMINST_DOWN, None)
1573
    self._SetInstanceStatus(inst_uuid, constants.ADMINST_DOWN, None)
1564 1574

  
1565 1575
  @locking.ssynchronized(_config_lock)
1566
  def MarkInstanceDisksActive(self, instance_name):
1576
  def MarkInstanceDisksActive(self, inst_uuid):
1567 1577
    """Mark the status of instance disks active.
1568 1578

  
1569 1579
    """
1570
    self._SetInstanceStatus(instance_name, None, True)
1580
    self._SetInstanceStatus(inst_uuid, None, True)
1571 1581

  
1572 1582
  @locking.ssynchronized(_config_lock)
1573
  def MarkInstanceDisksInactive(self, instance_name):
1583
  def MarkInstanceDisksInactive(self, inst_uuid):
1574 1584
    """Mark the status of instance disks inactive.
1575 1585

  
1576 1586
    """
1577
    self._SetInstanceStatus(instance_name, None, False)
1587
    self._SetInstanceStatus(inst_uuid, None, False)
1578 1588

  
1579 1589
  def _UnlockedGetInstanceList(self):
1580 1590
    """Get the list of instances.
......
1588 1598
  def GetInstanceList(self):
1589 1599
    """Get the list of instances.
1590 1600

  
1591
    @return: array of instances, ex. ['instance2.example.com',
1592
        'instance1.example.com']
1601
    @return: array of instances, ex. ['instance2-uuid', 'instance1-uuid']
1593 1602

  
1594 1603
    """
1595 1604
    return self._UnlockedGetInstanceList()
......
1598 1607
    """Attempt to expand an incomplete instance name.
1599 1608

  
1600 1609
    """
1601
    # Locking is done in L{ConfigWriter.GetInstanceList}
1602
    return _MatchNameComponentIgnoreCase(short_name, self.GetInstanceList())
1610
    # Locking is done in L{ConfigWriter.GetAllInstancesInfo}
1611
    all_insts = self.GetAllInstancesInfo().values()
1612
    expanded_name = _MatchNameComponentIgnoreCase(
1613
                      short_name, [inst.name for inst in all_insts])
1614

  
1615
    if expanded_name is not None:
1616
      # there has to be exactly one instance with that name
1617
      inst = (filter(lambda n: n.name == expanded_name, all_insts)[0])
1618
      return (inst.uuid, inst.name)
1619
    else:
1620
      return None
1603 1621

  
1604
  def _UnlockedGetInstanceInfo(self, instance_name):
1622
  def _UnlockedGetInstanceInfo(self, inst_uuid):
1605 1623
    """Returns information about an instance.
1606 1624

  
1607 1625
    This function is for internal use, when the config lock is already held.
1608 1626

  
1609 1627
    """
1610
    if instance_name not in self._config_data.instances:
1628
    if inst_uuid not in self._config_data.instances:
1611 1629
      return None
1612 1630

  
1613
    return self._config_data.instances[instance_name]
1631
    return self._config_data.instances[inst_uuid]
1614 1632

  
1615 1633
  @locking.ssynchronized(_config_lock, shared=1)
1616
  def GetInstanceInfo(self, instance_name):
1634
  def GetInstanceInfo(self, inst_uuid):
1617 1635
    """Returns information about an instance.
1618 1636

  
1619 1637
    It takes the information from the configuration file. Other information of
1620 1638
    an instance are taken from the live systems.
1621 1639

  
1622
    @param instance_name: name of the instance, e.g.
1623
        I{instance1.example.com}
1640
    @param inst_uuid: UUID of the instance
1624 1641

  
1625 1642
    @rtype: L{objects.Instance}
1626 1643
    @return: the instance object
1627 1644

  
1628 1645
    """
1629
    return self._UnlockedGetInstanceInfo(instance_name)
1646
    return self._UnlockedGetInstanceInfo(inst_uuid)
1630 1647

  
1631 1648
  @locking.ssynchronized(_config_lock, shared=1)
1632
  def GetInstanceNodeGroups(self, instance_name, primary_only=False):
1649
  def GetInstanceNodeGroups(self, inst_uuid, primary_only=False):
1633 1650
    """Returns set of node group UUIDs for instance's nodes.
1634 1651

  
1635 1652
    @rtype: frozenset
1636 1653

  
1637 1654
    """
1638
    instance = self._UnlockedGetInstanceInfo(instance_name)
1655
    instance = self._UnlockedGetInstanceInfo(inst_uuid)
1639 1656
    if not instance:
1640
      raise errors.ConfigurationError("Unknown instance '%s'" % instance_name)
1657
      raise errors.ConfigurationError("Unknown instance '%s'" % inst_uuid)
1641 1658

  
1642 1659
    if primary_only:
1643 1660
      nodes = [instance.primary_node]
......
1648 1665
                     for node_uuid in nodes)
1649 1666

  
1650 1667
  @locking.ssynchronized(_config_lock, shared=1)
1651
  def GetInstanceNetworks(self, instance_name):
1668
  def GetInstanceNetworks(self, inst_uuid):
1652 1669
    """Returns set of network UUIDs for instance's nics.
1653 1670

  
1654 1671
    @rtype: frozenset
1655 1672

  
1656 1673
    """
1657
    instance = self._UnlockedGetInstanceInfo(instance_name)
1674
    instance = self._UnlockedGetInstanceInfo(inst_uuid)
1658 1675
    if not instance:
1659
      raise errors.ConfigurationError("Unknown instance '%s'" % instance_name)
1676
      raise errors.ConfigurationError("Unknown instance '%s'" % inst_uuid)
1660 1677

  
1661 1678
    networks = set()
1662 1679
    for nic in instance.nics:
......
1666 1683
    return frozenset(networks)
1667 1684

  
1668 1685
  @locking.ssynchronized(_config_lock, shared=1)
1669
  def GetMultiInstanceInfo(self, instances):
1686
  def GetMultiInstanceInfo(self, inst_uuids):
1687
    """Get the configuration of multiple instances.
1688

  
1689
    @param inst_uuids: list of instance UUIDs
1690
    @rtype: list
1691
    @return: list of tuples (instance UUID, instance_info), where
1692
        instance_info is what would GetInstanceInfo return for the
1693
        node, while keeping the original order
1694

  
1695
    """
1696
    return [(uuid, self._UnlockedGetInstanceInfo(uuid)) for uuid in inst_uuids]
1697

  
1698
  @locking.ssynchronized(_config_lock, shared=1)
1699
  def GetMultiInstanceInfoByName(self, inst_names):
1670 1700
    """Get the configuration of multiple instances.
1671 1701

  
1672
    @param instances: list of instance names
1702
    @param inst_names: list of instance names
1673 1703
    @rtype: list
1674 1704
    @return: list of tuples (instance, instance_info), where
1675 1705
        instance_info is what would GetInstanceInfo return for the
1676 1706
        node, while keeping the original order
1677 1707

  
1678 1708
    """
1679
    return [(name, self._UnlockedGetInstanceInfo(name)) for name in instances]
1709
    result = []
1710
    for name in inst_names:
1711
      instance = self._UnlockedGetInstanceInfoByName(name)
1712
      result.append((instance.uuid, instance))
1713
    return result
1680 1714

  
1681 1715
  @locking.ssynchronized(_config_lock, shared=1)
1682 1716
  def GetAllInstancesInfo(self):
......
1687 1721
              would GetInstanceInfo return for the node
1688 1722

  
1689 1723
    """
1690
    my_dict = dict([(instance, self._UnlockedGetInstanceInfo(instance))
1691
                    for instance in self._UnlockedGetInstanceList()])
1724
    return self._UnlockedGetAllInstancesInfo()
1725

  
1726
  def _UnlockedGetAllInstancesInfo(self):
1727
    my_dict = dict([(inst_uuid, self._UnlockedGetInstanceInfo(inst_uuid))
1728
                    for inst_uuid in self._UnlockedGetInstanceList()])
1692 1729
    return my_dict
1693 1730

  
1694 1731
  @locking.ssynchronized(_config_lock, shared=1)
......
1703 1740
      other functions and just compares instance attributes.
1704 1741

  
1705 1742
    """
1706
    return dict((name, inst)
1707
                for (name, inst) in self._config_data.instances.items()
1743
    return dict((uuid, inst)
1744
                for (uuid, inst) in self._config_data.instances.items()
1708 1745
                if filter_fn(inst))
1709 1746

  
1747
  @locking.ssynchronized(_config_lock, shared=1)
1748
  def GetInstanceInfoByName(self, inst_name):
1749
    """Get the L{objects.Instance} object for a named instance.
1750

  
1751
    @param inst_name: name of the instance to get information for
1752
    @type inst_name: string
1753
    @return: the corresponding L{objects.Instance} instance or None if no
1754
          information is available
1755

  
1756
    """
1757
    return self._UnlockedGetInstanceInfoByName(inst_name)
1758

  
1759
  def _UnlockedGetInstanceInfoByName(self, inst_name):
1760
    for inst in self._UnlockedGetAllInstancesInfo().values():
1761
      if inst.name == inst_name:
1762
        return inst
1763
    return None
1764

  
1765
  def _UnlockedGetInstanceName(self, inst_uuid):
1766
    inst_info = self._UnlockedGetInstanceInfo(inst_uuid)
1767
    if inst_info is None:
1768
      raise errors.OpExecError("Unknown instance: %s" % inst_uuid)
1769
    return inst_info.name
1770

  
1771
  @locking.ssynchronized(_config_lock, shared=1)
1772
  def GetInstanceName(self, inst_uuid):
1773
    """Gets the instance name for the passed instance.
1774

  
1775
    @param inst_uuid: instance UUID to get name for
1776
    @type inst_uuid: string
1777
    @rtype: string
1778
    @return: instance name
1779

  
1780
    """
1781
    return self._UnlockedGetInstanceName(inst_uuid)
1782

  
1783
  @locking.ssynchronized(_config_lock, shared=1)
1784
  def GetInstanceNames(self, inst_uuids):
1785
    """Gets the instance names for the passed list of nodes.
1786

  
1787
    @param inst_uuids: list of instance UUIDs to get names for
1788
    @type inst_uuids: list of strings
1789
    @rtype: list of strings
1790
    @return: list of instance names
1791

  
1792
    """
1793
    return self._UnlockedGetInstanceNames(inst_uuids)
1794

  
1795
  def _UnlockedGetInstanceNames(self, inst_uuids):
1796
    return [self._UnlockedGetInstanceName(uuid) for uuid in inst_uuids]
1797

  
1710 1798
  @locking.ssynchronized(_config_lock)
1711 1799
  def AddNode(self, node, ec_id):
1712 1800
    """Add a node to the configuration.
......
1751 1839
                      short_name, [node.name for node in all_nodes])
1752 1840

  
1753 1841
    if expanded_name is not None:
1754
      # there has to be exactly one node whith that name
1842
      # there has to be exactly one node with that name
1755 1843
      node = (filter(lambda n: n.name == expanded_name, all_nodes)[0])
1756 1844
      return (node.uuid, node.name)
1757 1845
    else:
......
1802 1890
    sec = []
1803 1891
    for inst in self._config_data.instances.values():
1804 1892
      if inst.primary_node == node_uuid:
1805
        pri.append(inst.name)
1893
        pri.append(inst.uuid)
1806 1894
      if node_uuid in inst.secondary_nodes:
1807
        sec.append(inst.name)
1895
        sec.append(inst.uuid)
1808 1896
    return (pri, sec)
1809 1897

  
1810 1898
  @locking.ssynchronized(_config_lock, shared=1)
......
1814 1902
    @param uuid: Node group UUID
1815 1903
    @param primary_only: Whether to only consider primary nodes
1816 1904
    @rtype: frozenset
1817
    @return: List of instance names in node group
1905
    @return: List of instance UUIDs in node group
1818 1906

  
1819 1907
    """
1820 1908
    if primary_only:
......
1822 1910
    else:
1823 1911
      nodes_fn = lambda inst: inst.all_nodes
1824 1912

  
1825
    return frozenset(inst.name
1913
    return frozenset(inst.uuid
1826 1914
                     for inst in self._config_data.instances.values()
1827 1915
                     for node_uuid in nodes_fn(inst)
1828 1916
                     if self._UnlockedGetNodeInfo(node_uuid).group == uuid)
......
2436 2524

  
2437 2525
    """
2438 2526
    fn = "\n".join
2439
    instance_names = utils.NiceSort(self._UnlockedGetInstanceList())
2527
    instance_names = utils.NiceSort(
2528
                       [inst.name for inst in
2529
                        self._UnlockedGetAllInstancesInfo().values()])
2440 2530
    node_infos = self._UnlockedGetAllNodesInfo().values()
2441 2531
    node_names = [node.name for node in node_infos]
2442 2532
    node_pri_ips = ["%s %s" % (ninfo.name, ninfo.primary_ip)
......
2613 2703
      self._config_data.cluster.mtime = now
2614 2704

  
2615 2705
    if isinstance(target, objects.Instance):
2616
      self._UnlockedReleaseDRBDMinors(target.name)
2706
      self._UnlockedReleaseDRBDMinors(target.uuid)
2617 2707

  
2618 2708
    if ec_id is not None:
2619 2709
      # Commit all ips reserved by OpInstanceSetParams and OpGroupSetParams

Also available in: Unified diff