Revision 1c3231aa lib/config.py

b/lib/config.py
760 760
                    (mc_now, mc_max))
761 761

  
762 762
    # node checks
763
    for node_name, node in data.nodes.items():
764
      if node.name != node_name:
765
        result.append("Node '%s' is indexed by wrong name '%s'" %
766
                      (node.name, node_name))
763
    for node_uuid, node in data.nodes.items():
764
      if node.uuid != node_uuid:
765
        result.append("Node '%s' is indexed by wrong UUID '%s'" %
766
                      (node.name, node_uuid))
767 767
      if [node.master_candidate, node.drained, node.offline].count(True) > 1:
768 768
        result.append("Node %s state is invalid: master_candidate=%s,"
769 769
                      " drain=%s, offline=%s" %
......
862 862
    """
863 863
    return self._UnlockedVerifyConfig()
864 864

  
865
  def _UnlockedSetDiskID(self, disk, node_name):
865
  def _UnlockedSetDiskID(self, disk, node_uuid):
866 866
    """Convert the unique ID to the ID needed on the target nodes.
867 867

  
868 868
    This is used only for drbd, which needs ip/port configuration.
......
876 876
    """
877 877
    if disk.children:
878 878
      for child in disk.children:
879
        self._UnlockedSetDiskID(child, node_name)
879
        self._UnlockedSetDiskID(child, node_uuid)
880 880

  
881 881
    if disk.logical_id is None and disk.physical_id is not None:
882 882
      return
883 883
    if disk.dev_type == constants.LD_DRBD8:
884 884
      pnode, snode, port, pminor, sminor, secret = disk.logical_id
885
      if node_name not in (pnode, snode):
885
      if node_uuid not in (pnode, snode):
886 886
        raise errors.ConfigurationError("DRBD device not knowing node %s" %
887
                                        node_name)
887
                                        node_uuid)
888 888
      pnode_info = self._UnlockedGetNodeInfo(pnode)
889 889
      snode_info = self._UnlockedGetNodeInfo(snode)
890 890
      if pnode_info is None or snode_info is None:
......
892 892
                                        " for %s" % str(disk))
893 893
      p_data = (pnode_info.secondary_ip, port)
894 894
      s_data = (snode_info.secondary_ip, port)
895
      if pnode == node_name:
895
      if pnode == node_uuid:
896 896
        disk.physical_id = p_data + s_data + (pminor, secret)
897 897
      else: # it must be secondary, we tested above
898 898
        disk.physical_id = s_data + p_data + (sminor, secret)
......
901 901
    return
902 902

  
903 903
  @locking.ssynchronized(_config_lock)
904
  def SetDiskID(self, disk, node_name):
904
  def SetDiskID(self, disk, node_uuid):
905 905
    """Convert the unique ID to the ID needed on the target nodes.
906 906

  
907 907
    This is used only for drbd, which needs ip/port configuration.
......
911 911
    node.
912 912

  
913 913
    """
914
    return self._UnlockedSetDiskID(disk, node_name)
914
    return self._UnlockedSetDiskID(disk, node_uuid)
915 915

  
916 916
  @locking.ssynchronized(_config_lock)
917 917
  def AddTcpUdpPort(self, port):
......
961 961
    """Compute the used DRBD minor/nodes.
962 962

  
963 963
    @rtype: (dict, list)
964
    @return: dictionary of node_name: dict of minor: instance_name;
964
    @return: dictionary of node_uuid: dict of minor: instance_name;
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
......
1002 1002

  
1003 1003
    This is just a wrapper over L{_UnlockedComputeDRBDMap}.
1004 1004

  
1005
    @return: dictionary of node_name: dict of minor: instance_name;
1005
    @return: dictionary of node_uuid: dict of minor: instance_name;
1006 1006
        the returned dict will have all the nodes in it (even if with
1007 1007
        an empty list).
1008 1008

  
......
1014 1014
    return d_map
1015 1015

  
1016 1016
  @locking.ssynchronized(_config_lock)
1017
  def AllocateDRBDMinor(self, nodes, instance):
1017
  def AllocateDRBDMinor(self, node_uuids, instance):
1018 1018
    """Allocate a drbd minor.
1019 1019

  
1020 1020
    The free minor will be automatically computed from the existing
......
1034 1034
      raise errors.ConfigurationError("Duplicate DRBD ports detected: %s" %
1035 1035
                                      str(duplicates))
1036 1036
    result = []
1037
    for nname in nodes:
1038
      ndata = d_map[nname]
1037
    for nuuid in node_uuids:
1038
      ndata = d_map[nuuid]
1039 1039
      if not ndata:
1040 1040
        # no minors used, we can start at 0
1041 1041
        result.append(0)
1042 1042
        ndata[0] = instance
1043
        self._temporary_drbds[(nname, 0)] = instance
1043
        self._temporary_drbds[(nuuid, 0)] = instance
1044 1044
        continue
1045 1045
      keys = ndata.keys()
1046 1046
      keys.sort()
......
1052 1052
      else:
1053 1053
        minor = ffree
1054 1054
      # double-check minor against current instances
1055
      assert minor not in d_map[nname], \
1055
      assert minor not in d_map[nuuid], \
1056 1056
             ("Attempt to reuse allocated DRBD minor %d on node %s,"
1057 1057
              " already allocated to instance %s" %
1058
              (minor, nname, d_map[nname][minor]))
1058
              (minor, nuuid, d_map[nuuid][minor]))
1059 1059
      ndata[minor] = instance
1060 1060
      # double-check minor against reservation
1061
      r_key = (nname, minor)
1061
      r_key = (nuuid, minor)
1062 1062
      assert r_key not in self._temporary_drbds, \
1063 1063
             ("Attempt to reuse reserved DRBD minor %d on node %s,"
1064 1064
              " reserved for instance %s" %
1065
              (minor, nname, self._temporary_drbds[r_key]))
1065
              (minor, nuuid, self._temporary_drbds[r_key]))
1066 1066
      self._temporary_drbds[r_key] = instance
1067 1067
      result.append(minor)
1068 1068
    logging.debug("Request to allocate drbd minors, input: %s, returning %s",
1069
                  nodes, result)
1069
                  node_uuids, result)
1070 1070
    return result
1071 1071

  
1072 1072
  def _UnlockedReleaseDRBDMinors(self, instance):
......
1120 1120

  
1121 1121
  @locking.ssynchronized(_config_lock, shared=1)
1122 1122
  def GetMasterNode(self):
1123
    """Get the hostname of the master node for this cluster.
1123
    """Get the UUID of the master node for this cluster.
1124 1124

  
1125
    @return: Master hostname
1125
    @return: Master node UUID
1126 1126

  
1127 1127
    """
1128 1128
    return self._config_data.cluster.master_node
1129 1129

  
1130 1130
  @locking.ssynchronized(_config_lock, shared=1)
1131
  def GetMasterNodeName(self):
1132
    """Get the hostname of the master node for this cluster.
1133

  
1134
    @return: Master node hostname
1135

  
1136
    """
1137
    return self._UnlockedGetNodeName(self._config_data.cluster.master_node)
1138

  
1139
  @locking.ssynchronized(_config_lock, shared=1)
1131 1140
  def GetMasterIP(self):
1132 1141
    """Get the IP of the master node for this cluster.
1133 1142

  
......
1214 1223
    """
1215 1224
    cluster = self._config_data.cluster
1216 1225
    result = objects.MasterNetworkParameters(
1217
      name=cluster.master_node, ip=cluster.master_ip,
1226
      uuid=cluster.master_node, ip=cluster.master_ip,
1218 1227
      netmask=cluster.master_netmask, netdev=cluster.master_netdev,
1219 1228
      ip_family=cluster.primary_ip_family)
1220 1229

  
......
1372 1381
    """Get nodes which are member in the same nodegroups as the given nodes.
1373 1382

  
1374 1383
    """
1375
    ngfn = lambda node_name: self._UnlockedGetNodeInfo(node_name).group
1376
    return frozenset(member_name
1377
                     for node_name in nodes
1378
                     for member_name in
1379
                       self._UnlockedGetNodeGroup(ngfn(node_name)).members)
1384
    ngfn = lambda node_uuid: self._UnlockedGetNodeInfo(node_uuid).group
1385
    return frozenset(member_uuid
1386
                     for node_uuid in nodes
1387
                     for member_uuid in
1388
                       self._UnlockedGetNodeGroup(ngfn(node_uuid)).members)
1380 1389

  
1381 1390
  @locking.ssynchronized(_config_lock, shared=1)
1382 1391
  def GetMultiNodeGroupInfo(self, group_uuids):
......
1631 1640
    else:
1632 1641
      nodes = instance.all_nodes
1633 1642

  
1634
    return frozenset(self._UnlockedGetNodeInfo(node_name).group
1635
                     for node_name in nodes)
1643
    return frozenset(self._UnlockedGetNodeInfo(node_uuid).group
1644
                     for node_uuid in nodes)
1636 1645

  
1637 1646
  @locking.ssynchronized(_config_lock, shared=1)
1638 1647
  def GetInstanceNetworks(self, instance_name):
......
1708 1717

  
1709 1718
    node.serial_no = 1
1710 1719
    node.ctime = node.mtime = time.time()
1711
    self._UnlockedAddNodeToGroup(node.name, node.group)
1712
    self._config_data.nodes[node.name] = node
1720
    self._UnlockedAddNodeToGroup(node.uuid, node.group)
1721
    self._config_data.nodes[node.uuid] = node
1713 1722
    self._config_data.cluster.serial_no += 1
1714 1723
    self._WriteConfig()
1715 1724

  
1716 1725
  @locking.ssynchronized(_config_lock)
1717
  def RemoveNode(self, node_name):
1726
  def RemoveNode(self, node_uuid):
1718 1727
    """Remove a node from the configuration.
1719 1728

  
1720 1729
    """
1721
    logging.info("Removing node %s from configuration", node_name)
1730
    logging.info("Removing node %s from configuration", node_uuid)
1722 1731

  
1723
    if node_name not in self._config_data.nodes:
1724
      raise errors.ConfigurationError("Unknown node '%s'" % node_name)
1732
    if node_uuid not in self._config_data.nodes:
1733
      raise errors.ConfigurationError("Unknown node '%s'" % node_uuid)
1725 1734

  
1726
    self._UnlockedRemoveNodeFromGroup(self._config_data.nodes[node_name])
1727
    del self._config_data.nodes[node_name]
1735
    self._UnlockedRemoveNodeFromGroup(self._config_data.nodes[node_uuid])
1736
    del self._config_data.nodes[node_uuid]
1728 1737
    self._config_data.cluster.serial_no += 1
1729 1738
    self._WriteConfig()
1730 1739

  
1731 1740
  def ExpandNodeName(self, short_name):
1732
    """Attempt to expand an incomplete node name.
1741
    """Attempt to expand an incomplete node name into a node UUID.
1733 1742

  
1734 1743
    """
1735
    # Locking is done in L{ConfigWriter.GetNodeList}
1736
    return _MatchNameComponentIgnoreCase(short_name, self.GetNodeList())
1744
    # Locking is done in L{ConfigWriter.GetAllNodesInfo}
1745
    all_nodes = self.GetAllNodesInfo().values()
1746
    expanded_name = _MatchNameComponentIgnoreCase(
1747
                      short_name, [node.name for node in all_nodes])
1737 1748

  
1738
  def _UnlockedGetNodeInfo(self, node_name):
1749
    if expanded_name is not None:
1750
      # there has to be exactly one node whith that name
1751
      node = (filter(lambda n: n.name == expanded_name, all_nodes)[0])
1752
      return (node.uuid, node.name)
1753
    else:
1754
      return None
1755

  
1756
  def _UnlockedGetNodeInfo(self, node_uuid):
1739 1757
    """Get the configuration of a node, as stored in the config.
1740 1758

  
1741 1759
    This function is for internal use, when the config lock is already
1742 1760
    held.
1743 1761

  
1744
    @param node_name: the node name, e.g. I{node1.example.com}
1762
    @param node_uuid: the node UUID
1745 1763

  
1746 1764
    @rtype: L{objects.Node}
1747 1765
    @return: the node object
1748 1766

  
1749 1767
    """
1750
    if node_name not in self._config_data.nodes:
1768
    if node_uuid not in self._config_data.nodes:
1751 1769
      return None
1752 1770

  
1753
    return self._config_data.nodes[node_name]
1771
    return self._config_data.nodes[node_uuid]
1754 1772

  
1755 1773
  @locking.ssynchronized(_config_lock, shared=1)
1756
  def GetNodeInfo(self, node_name):
1774
  def GetNodeInfo(self, node_uuid):
1757 1775
    """Get the configuration of a node, as stored in the config.
1758 1776

  
1759 1777
    This is just a locked wrapper over L{_UnlockedGetNodeInfo}.
1760 1778

  
1761
    @param node_name: the node name, e.g. I{node1.example.com}
1779
    @param node_uuid: the node UUID
1762 1780

  
1763 1781
    @rtype: L{objects.Node}
1764 1782
    @return: the node object
1765 1783

  
1766 1784
    """
1767
    return self._UnlockedGetNodeInfo(node_name)
1785
    return self._UnlockedGetNodeInfo(node_uuid)
1768 1786

  
1769 1787
  @locking.ssynchronized(_config_lock, shared=1)
1770
  def GetNodeInstances(self, node_name):
1788
  def GetNodeInstances(self, node_uuid):
1771 1789
    """Get the instances of a node, as stored in the config.
1772 1790

  
1773
    @param node_name: the node name, e.g. I{node1.example.com}
1791
    @param node_uuid: the node UUID
1774 1792

  
1775 1793
    @rtype: (list, list)
1776 1794
    @return: a tuple with two lists: the primary and the secondary instances
......
1779 1797
    pri = []
1780 1798
    sec = []
1781 1799
    for inst in self._config_data.instances.values():
1782
      if inst.primary_node == node_name:
1800
      if inst.primary_node == node_uuid:
1783 1801
        pri.append(inst.name)
1784
      if node_name in inst.secondary_nodes:
1802
      if node_uuid in inst.secondary_nodes:
1785 1803
        sec.append(inst.name)
1786 1804
    return (pri, sec)
1787 1805

  
......
1802 1820

  
1803 1821
    return frozenset(inst.name
1804 1822
                     for inst in self._config_data.instances.values()
1805
                     for node_name in nodes_fn(inst)
1806
                     if self._UnlockedGetNodeInfo(node_name).group == uuid)
1823
                     for node_uuid in nodes_fn(inst)
1824
                     if self._UnlockedGetNodeInfo(node_uuid).group == uuid)
1807 1825

  
1808 1826
  def _UnlockedGetHvparamsString(self, hvname):
1809 1827
    """Return the string representation of the list of hyervisor parameters of
......
1855 1873
    """
1856 1874
    all_nodes = [self._UnlockedGetNodeInfo(node)
1857 1875
                 for node in self._UnlockedGetNodeList()]
1858
    return [node.name for node in all_nodes if not node.offline]
1876
    return [node.uuid for node in all_nodes if not node.offline]
1859 1877

  
1860 1878
  @locking.ssynchronized(_config_lock, shared=1)
1861 1879
  def GetOnlineNodeList(self):
......
1871 1889
    """
1872 1890
    all_nodes = [self._UnlockedGetNodeInfo(node)
1873 1891
                 for node in self._UnlockedGetNodeList()]
1874
    return [node.name for node in all_nodes if node.vm_capable]
1892
    return [node.uuid for node in all_nodes if node.vm_capable]
1875 1893

  
1876 1894
  @locking.ssynchronized(_config_lock, shared=1)
1877 1895
  def GetNonVmCapableNodeList(self):
......
1880 1898
    """
1881 1899
    all_nodes = [self._UnlockedGetNodeInfo(node)
1882 1900
                 for node in self._UnlockedGetNodeList()]
1883
    return [node.name for node in all_nodes if not node.vm_capable]
1901
    return [node.uuid for node in all_nodes if not node.vm_capable]
1884 1902

  
1885 1903
  @locking.ssynchronized(_config_lock, shared=1)
1886
  def GetMultiNodeInfo(self, nodes):
1904
  def GetMultiNodeInfo(self, node_uuids):
1887 1905
    """Get the configuration of multiple nodes.
1888 1906

  
1889
    @param nodes: list of node names
1907
    @param node_uuids: list of node UUIDs
1890 1908
    @rtype: list
1891 1909
    @return: list of tuples of (node, node_info), where node_info is
1892 1910
        what would GetNodeInfo return for the node, in the original
1893 1911
        order
1894 1912

  
1895 1913
    """
1896
    return [(name, self._UnlockedGetNodeInfo(name)) for name in nodes]
1914
    return [(uuid, self._UnlockedGetNodeInfo(uuid)) for uuid in node_uuids]
1915

  
1916
  def _UnlockedGetAllNodesInfo(self):
1917
    """Gets configuration of all nodes.
1918

  
1919
    @note: See L{GetAllNodesInfo}
1920

  
1921
    """
1922
    return dict([(node_uuid, self._UnlockedGetNodeInfo(node_uuid))
1923
                 for node_uuid in self._UnlockedGetNodeList()])
1897 1924

  
1898 1925
  @locking.ssynchronized(_config_lock, shared=1)
1899 1926
  def GetAllNodesInfo(self):
......
1906 1933
    """
1907 1934
    return self._UnlockedGetAllNodesInfo()
1908 1935

  
1909
  def _UnlockedGetAllNodesInfo(self):
1910
    """Gets configuration of all nodes.
1936
  def _UnlockedGetNodeInfoByName(self, node_name):
1937
    for node in self._UnlockedGetAllNodesInfo().values():
1938
      if node.name == node_name:
1939
        return node
1940
    return None
1911 1941

  
1912
    @note: See L{GetAllNodesInfo}
1942
  @locking.ssynchronized(_config_lock, shared=1)
1943
  def GetNodeInfoByName(self, node_name):
1944
    """Get the L{objects.Node} object for a named node.
1945

  
1946
    @param node_name: name of the node to get information for
1947
    @type node_name: string
1948
    @return: the corresponding L{objects.Node} instance or None if no
1949
          information is available
1950

  
1951
    """
1952
    return self._UnlockedGetNodeInfoByName(node_name)
1953

  
1954
  def _UnlockedGetNodeName(self, node_spec):
1955
    if isinstance(node_spec, objects.Node):
1956
      return node_spec.name
1957
    elif isinstance(node_spec, basestring):
1958
      node_info = self._UnlockedGetNodeInfo(node_spec)
1959
      if node_info is None:
1960
        raise errors.OpExecError("Unknown node: %s" % node_spec)
1961
      return node_info.name
1962
    else:
1963
      raise errors.ProgrammerError("Can't handle node spec '%s'" % node_spec)
1964

  
1965
  @locking.ssynchronized(_config_lock, shared=1)
1966
  def GetNodeName(self, node_spec):
1967
    """Gets the node name for the passed node.
1968

  
1969
    @param node_spec: node to get names for
1970
    @type node_spec: either node UUID or a L{objects.Node} object
1971
    @rtype: string
1972
    @return: node name
1973

  
1974
    """
1975
    return self._UnlockedGetNodeName(node_spec)
1976

  
1977
  def _UnlockedGetNodeNames(self, node_specs):
1978
    return [self._UnlockedGetNodeName(node_spec) for node_spec in node_specs]
1979

  
1980
  @locking.ssynchronized(_config_lock, shared=1)
1981
  def GetNodeNames(self, node_specs):
1982
    """Gets the node names for the passed list of nodes.
1983

  
1984
    @param node_specs: list of nodes to get names for
1985
    @type node_specs: list of either node UUIDs or L{objects.Node} objects
1986
    @rtype: list of strings
1987
    @return: list of node names
1913 1988

  
1914 1989
    """
1915
    return dict([(node, self._UnlockedGetNodeInfo(node))
1916
                 for node in self._UnlockedGetNodeList()])
1990
    return self._UnlockedGetNodeNames(node_specs)
1917 1991

  
1918 1992
  @locking.ssynchronized(_config_lock, shared=1)
1919
  def GetNodeGroupsFromNodes(self, nodes):
1993
  def GetNodeGroupsFromNodes(self, node_uuids):
1920 1994
    """Returns groups for a list of nodes.
1921 1995

  
1922
    @type nodes: list of string
1923
    @param nodes: List of node names
1996
    @type node_uuids: list of string
1997
    @param node_uuids: List of node UUIDs
1924 1998
    @rtype: frozenset
1925 1999

  
1926 2000
    """
1927
    return frozenset(self._UnlockedGetNodeInfo(name).group for name in nodes)
2001
    return frozenset(self._UnlockedGetNodeInfo(uuid).group
2002
                     for uuid in node_uuids)
1928 2003

  
1929 2004
  def _UnlockedGetMasterCandidateStats(self, exceptions=None):
1930 2005
    """Get the number of current and maximum desired and possible candidates.
......
1937 2012
    """
1938 2013
    mc_now = mc_should = mc_max = 0
1939 2014
    for node in self._config_data.nodes.values():
1940
      if exceptions and node.name in exceptions:
2015
      if exceptions and node.uuid in exceptions:
1941 2016
        continue
1942 2017
      if not (node.offline or node.drained) and node.master_capable:
1943 2018
        mc_max += 1
......
1961 2036
    return self._UnlockedGetMasterCandidateStats(exceptions)
1962 2037

  
1963 2038
  @locking.ssynchronized(_config_lock)
1964
  def MaintainCandidatePool(self, exceptions):
2039
  def MaintainCandidatePool(self, exception_node_uuids):
1965 2040
    """Try to grow the candidate pool to the desired size.
1966 2041

  
1967
    @type exceptions: list
1968
    @param exceptions: if passed, list of nodes that should be ignored
2042
    @type exception_node_uuids: list
2043
    @param exception_node_uuids: if passed, list of nodes that should be ignored
1969 2044
    @rtype: list
1970 2045
    @return: list with the adjusted nodes (L{objects.Node} instances)
1971 2046

  
1972 2047
    """
1973
    mc_now, mc_max, _ = self._UnlockedGetMasterCandidateStats(exceptions)
2048
    mc_now, mc_max, _ = self._UnlockedGetMasterCandidateStats(
2049
                          exception_node_uuids)
1974 2050
    mod_list = []
1975 2051
    if mc_now < mc_max:
1976 2052
      node_list = self._config_data.nodes.keys()
1977 2053
      random.shuffle(node_list)
1978
      for name in node_list:
2054
      for uuid in node_list:
1979 2055
        if mc_now >= mc_max:
1980 2056
          break
1981
        node = self._config_data.nodes[name]
2057
        node = self._config_data.nodes[uuid]
1982 2058
        if (node.master_candidate or node.offline or node.drained or
1983
            node.name in exceptions or not node.master_capable):
2059
            node.uuid in exception_node_uuids or not node.master_capable):
1984 2060
          continue
1985 2061
        mod_list.append(node)
1986 2062
        node.master_candidate = True
......
1996 2072

  
1997 2073
    return mod_list
1998 2074

  
1999
  def _UnlockedAddNodeToGroup(self, node_name, nodegroup_uuid):
2075
  def _UnlockedAddNodeToGroup(self, node_uuid, nodegroup_uuid):
2000 2076
    """Add a given node to the specified group.
2001 2077

  
2002 2078
    """
......
2006 2082
      # the meantime. It's ok though, as we'll fail cleanly if the node group
2007 2083
      # is not found anymore.
2008 2084
      raise errors.OpExecError("Unknown node group: %s" % nodegroup_uuid)
2009
    if node_name not in self._config_data.nodegroups[nodegroup_uuid].members:
2010
      self._config_data.nodegroups[nodegroup_uuid].members.append(node_name)
2085
    if node_uuid not in self._config_data.nodegroups[nodegroup_uuid].members:
2086
      self._config_data.nodegroups[nodegroup_uuid].members.append(node_uuid)
2011 2087

  
2012 2088
  def _UnlockedRemoveNodeFromGroup(self, node):
2013 2089
    """Remove a given node from its group.
......
2016 2092
    nodegroup = node.group
2017 2093
    if nodegroup not in self._config_data.nodegroups:
2018 2094
      logging.warning("Warning: node '%s' has unknown node group '%s'"
2019
                      " (while being removed from it)", node.name, nodegroup)
2095
                      " (while being removed from it)", node.uuid, nodegroup)
2020 2096
    nodegroup_obj = self._config_data.nodegroups[nodegroup]
2021
    if node.name not in nodegroup_obj.members:
2097
    if node.uuid not in nodegroup_obj.members:
2022 2098
      logging.warning("Warning: node '%s' not a member of its node group '%s'"
2023
                      " (while being removed from it)", node.name, nodegroup)
2099
                      " (while being removed from it)", node.uuid, nodegroup)
2024 2100
    else:
2025
      nodegroup_obj.members.remove(node.name)
2101
      nodegroup_obj.members.remove(node.uuid)
2026 2102

  
2027 2103
  @locking.ssynchronized(_config_lock)
2028 2104
  def AssignGroupNodes(self, mods):
......
2037 2113

  
2038 2114
    resmod = []
2039 2115

  
2040
    # Try to resolve names/UUIDs first
2041
    for (node_name, new_group_uuid) in mods:
2116
    # Try to resolve UUIDs first
2117
    for (node_uuid, new_group_uuid) in mods:
2042 2118
      try:
2043
        node = nodes[node_name]
2119
        node = nodes[node_uuid]
2044 2120
      except KeyError:
2045
        raise errors.ConfigurationError("Unable to find node '%s'" % node_name)
2121
        raise errors.ConfigurationError("Unable to find node '%s'" % node_uuid)
2046 2122

  
2047 2123
      if node.group == new_group_uuid:
2048 2124
        # Node is being assigned to its current group
2049 2125
        logging.debug("Node '%s' was assigned to its current group (%s)",
2050
                      node_name, node.group)
2126
                      node_uuid, node.group)
2051 2127
        continue
2052 2128

  
2053 2129
      # Try to find current group of node
......
2064 2140
        raise errors.ConfigurationError("Unable to find new group '%s'" %
2065 2141
                                        new_group_uuid)
2066 2142

  
2067
      assert node.name in old_group.members, \
2143
      assert node.uuid in old_group.members, \
2068 2144
        ("Inconsistent configuration: node '%s' not listed in members for its"
2069
         " old group '%s'" % (node.name, old_group.uuid))
2070
      assert node.name not in new_group.members, \
2145
         " old group '%s'" % (node.uuid, old_group.uuid))
2146
      assert node.uuid not in new_group.members, \
2071 2147
        ("Inconsistent configuration: node '%s' already listed in members for"
2072
         " its new group '%s'" % (node.name, new_group.uuid))
2148
         " its new group '%s'" % (node.uuid, new_group.uuid))
2073 2149

  
2074 2150
      resmod.append((node, old_group, new_group))
2075 2151

  
......
2081 2157
      node.group = new_group.uuid
2082 2158

  
2083 2159
      # Update members of involved groups
2084
      if node.name in old_group.members:
2085
        old_group.members.remove(node.name)
2086
      if node.name not in new_group.members:
2087
        new_group.members.append(node.name)
2160
      if node.uuid in old_group.members:
2161
        old_group.members.remove(node.uuid)
2162
      if node.uuid not in new_group.members:
2163
        new_group.members.append(node.uuid)
2088 2164

  
2089 2165
    # Update timestamps and serials (only once per node/group object)
2090 2166
    now = time.time()
......
2135 2211
      raise errors.ConfigurationError("Incomplete configuration"
2136 2212
                                      " (missing cluster.rsahostkeypub)")
2137 2213

  
2138
    if data.cluster.master_node != self._my_hostname and not accept_foreign:
2214
    if not data.cluster.master_node in data.nodes:
2215
      msg = ("The configuration denotes node %s as master, but does not"
2216
             " contain information about this node" %
2217
             data.cluster.master_node)
2218
      raise errors.ConfigurationError(msg)
2219

  
2220
    master_info = data.nodes[data.cluster.master_node]
2221
    if master_info.name != self._my_hostname and not accept_foreign:
2139 2222
      msg = ("The configuration denotes node %s as master, while my"
2140 2223
             " hostname is %s; opening a foreign configuration is only"
2141 2224
             " possible in accept_foreign mode" %
2142
             (data.cluster.master_node, self._my_hostname))
2225
             (master_info.name, self._my_hostname))
2143 2226
      raise errors.ConfigurationError(msg)
2144 2227

  
2145 2228
    self._config_data = data
......
2188 2271
      # nodegroups are being added, and upon normally loading the config,
2189 2272
      # because the members list of a node group is discarded upon
2190 2273
      # serializing/deserializing the object.
2191
      self._UnlockedAddNodeToGroup(node.name, node.group)
2274
      self._UnlockedAddNodeToGroup(node.uuid, node.group)
2192 2275

  
2193 2276
    modified = (oldconf != self._config_data.ToDict())
2194 2277
    if modified:
......
2222 2305
    # since the node list comes from _UnlocketGetNodeList, and we are
2223 2306
    # called with the lock held, so no modifications should take place
2224 2307
    # in between
2225
    for node_name in self._UnlockedGetNodeList():
2226
      if node_name == myhostname:
2227
        continue
2228
      node_info = self._UnlockedGetNodeInfo(node_name)
2229
      if not node_info.master_candidate:
2308
    for node_uuid in self._UnlockedGetNodeList():
2309
      node_info = self._UnlockedGetNodeInfo(node_uuid)
2310
      if node_info.name == myhostname or not node_info.master_candidate:
2230 2311
        continue
2231 2312
      node_list.append(node_info.name)
2232 2313
      addr_list.append(node_info.primary_ip)
......
2293 2374
    if self._last_cluster_serial < self._config_data.cluster.serial_no:
2294 2375
      if not self._offline:
2295 2376
        result = self._GetRpc(None).call_write_ssconf_files(
2296
          self._UnlockedGetOnlineNodeList(),
2377
          self._UnlockedGetNodeNames(self._UnlockedGetOnlineNodeList()),
2297 2378
          self._UnlockedGetSsconfValues())
2298 2379

  
2299 2380
        for nname, nresu in result.items():
......
2352 2433
    """
2353 2434
    fn = "\n".join
2354 2435
    instance_names = utils.NiceSort(self._UnlockedGetInstanceList())
2355
    node_names = utils.NiceSort(self._UnlockedGetNodeList())
2356
    node_info = [self._UnlockedGetNodeInfo(name) for name in node_names]
2436
    node_infos = self._UnlockedGetAllNodesInfo().values()
2437
    node_names = [node.name for node in node_infos]
2357 2438
    node_pri_ips = ["%s %s" % (ninfo.name, ninfo.primary_ip)
2358
                    for ninfo in node_info]
2439
                    for ninfo in node_infos]
2359 2440
    node_snd_ips = ["%s %s" % (ninfo.name, ninfo.secondary_ip)
2360
                    for ninfo in node_info]
2441
                    for ninfo in node_infos]
2361 2442

  
2362 2443
    instance_data = fn(instance_names)
2363
    off_data = fn(node.name for node in node_info if node.offline)
2364
    on_data = fn(node.name for node in node_info if not node.offline)
2365
    mc_data = fn(node.name for node in node_info if node.master_candidate)
2366
    mc_ips_data = fn(node.primary_ip for node in node_info
2444
    off_data = fn(node.name for node in node_infos if node.offline)
2445
    on_data = fn(node.name for node in node_infos if not node.offline)
2446
    mc_data = fn(node.name for node in node_infos if node.master_candidate)
2447
    mc_ips_data = fn(node.primary_ip for node in node_infos
2367 2448
                     if node.master_candidate)
2368 2449
    node_data = fn(node_names)
2369 2450
    node_pri_ips_data = fn(node_pri_ips)
......
2394 2475
      constants.SS_MASTER_IP: cluster.master_ip,
2395 2476
      constants.SS_MASTER_NETDEV: cluster.master_netdev,
2396 2477
      constants.SS_MASTER_NETMASK: str(cluster.master_netmask),
2397
      constants.SS_MASTER_NODE: cluster.master_node,
2478
      constants.SS_MASTER_NODE: self._UnlockedGetNodeName(cluster.master_node),
2398 2479
      constants.SS_NODE_LIST: node_data,
2399 2480
      constants.SS_NODE_PRIMARY_IPS: node_pri_ips_data,
2400 2481
      constants.SS_NODE_SECONDARY_IPS: node_snd_ips_data,
......
2679 2760
    self._config_data.cluster.serial_no += 1
2680 2761
    self._WriteConfig()
2681 2762

  
2682
  def _UnlockedGetGroupNetParams(self, net_uuid, node):
2763
  def _UnlockedGetGroupNetParams(self, net_uuid, node_uuid):
2683 2764
    """Get the netparams (mode, link) of a network.
2684 2765

  
2685 2766
    Get a network's netparams for a given node.
2686 2767

  
2687 2768
    @type net_uuid: string
2688 2769
    @param net_uuid: network uuid
2689
    @type node: string
2690
    @param node: node name
2770
    @type node_uuid: string
2771
    @param node_uuid: node UUID
2691 2772
    @rtype: dict or None
2692 2773
    @return: netparams
2693 2774

  
2694 2775
    """
2695
    node_info = self._UnlockedGetNodeInfo(node)
2776
    node_info = self._UnlockedGetNodeInfo(node_uuid)
2696 2777
    nodegroup_info = self._UnlockedGetNodeGroup(node_info.group)
2697 2778
    netparams = nodegroup_info.networks.get(net_uuid, None)
2698 2779

  
2699 2780
    return netparams
2700 2781

  
2701 2782
  @locking.ssynchronized(_config_lock, shared=1)
2702
  def GetGroupNetParams(self, net_uuid, node):
2783
  def GetGroupNetParams(self, net_uuid, node_uuid):
2703 2784
    """Locking wrapper of _UnlockedGetGroupNetParams()
2704 2785

  
2705 2786
    """
2706
    return self._UnlockedGetGroupNetParams(net_uuid, node)
2787
    return self._UnlockedGetGroupNetParams(net_uuid, node_uuid)
2707 2788

  
2708 2789
  @locking.ssynchronized(_config_lock, shared=1)
2709
  def CheckIPInNodeGroup(self, ip, node):
2790
  def CheckIPInNodeGroup(self, ip, node_uuid):
2710 2791
    """Check IP uniqueness in nodegroup.
2711 2792

  
2712 2793
    Check networks that are connected in the node's node group
......
2715 2796

  
2716 2797
    @type ip: string
2717 2798
    @param ip: ip address
2718
    @type node: string
2719
    @param node: node name
2799
    @type node_uuid: string
2800
    @param node_uuid: node UUID
2720 2801
    @rtype: (string, dict) or (None, None)
2721 2802
    @return: (network name, netparams)
2722 2803

  
2723 2804
    """
2724 2805
    if ip is None:
2725 2806
      return (None, None)
2726
    node_info = self._UnlockedGetNodeInfo(node)
2807
    node_info = self._UnlockedGetNodeInfo(node_uuid)
2727 2808
    nodegroup_info = self._UnlockedGetNodeGroup(node_info.group)
2728 2809
    for net_uuid in nodegroup_info.networks.keys():
2729 2810
      net_info = self._UnlockedGetNetwork(net_uuid)

Also available in: Unified diff