Merge branch 'devel-2.4'
[ganeti-local] / lib / config.py
index 64ec123..7d81b37 100644 (file)
@@ -219,7 +219,7 @@ class ConfigWriter:
     if mac in all_macs:
       raise errors.ReservationError("mac already in use")
     else:
-      self._temporary_macs.Reserve(mac, ec_id)
+      self._temporary_macs.Reserve(ec_id, mac)
 
   @locking.ssynchronized(_config_lock, shared=1)
   def ReserveLV(self, lv_name, ec_id):
@@ -233,7 +233,7 @@ class ConfigWriter:
     if lv_name in all_lvs:
       raise errors.ReservationError("LV already in use")
     else:
-      self._temporary_lvs.Reserve(lv_name, ec_id)
+      self._temporary_lvs.Reserve(ec_id, lv_name)
 
   @locking.ssynchronized(_config_lock, shared=1)
   def GenerateDRBDSecret(self, ec_id):
@@ -1071,6 +1071,17 @@ class ConfigWriter:
     """
     return self._config_data.nodegroups.keys()
 
+  @locking.ssynchronized(_config_lock, shared=1)
+  def GetNodeGroupMembersByNodes(self, nodes):
+    """Get nodes which are member in the same nodegroups as the given nodes.
+
+    """
+    ngfn = lambda node_name: self._UnlockedGetNodeInfo(node_name).group
+    return frozenset(member_name
+                     for node_name in nodes
+                     for member_name in
+                       self._UnlockedGetNodeGroup(ngfn(node_name)).members)
+
   @locking.ssynchronized(_config_lock)
   def AddInstance(self, instance, ec_id):
     """Add an instance to the config.
@@ -1243,6 +1254,25 @@ class ConfigWriter:
     return self._UnlockedGetInstanceInfo(instance_name)
 
   @locking.ssynchronized(_config_lock, shared=1)
+  def GetInstanceNodeGroups(self, instance_name, primary_only=False):
+    """Returns set of node group UUIDs for instance's nodes.
+
+    @rtype: frozenset
+
+    """
+    instance = self._UnlockedGetInstanceInfo(instance_name)
+    if not instance:
+      raise errors.ConfigurationError("Unknown instance '%s'" % instance_name)
+
+    if primary_only:
+      nodes = [instance.primary_node]
+    else:
+      nodes = instance.all_nodes
+
+    return frozenset(self._UnlockedGetNodeInfo(node_name).group
+                     for node_name in nodes)
+
+  @locking.ssynchronized(_config_lock, shared=1)
   def GetAllInstancesInfo(self):
     """Get the configuration of all instances.
 
@@ -1346,6 +1376,26 @@ class ConfigWriter:
         sec.append(inst.name)
     return (pri, sec)
 
+  @locking.ssynchronized(_config_lock, shared=1)
+  def GetNodeGroupInstances(self, uuid, primary_only=False):
+    """Get the instances of a node group.
+
+    @param uuid: Node group UUID
+    @param primary_only: Whether to only consider primary nodes
+    @rtype: frozenset
+    @return: List of instance names in node group
+
+    """
+    if primary_only:
+      nodes_fn = lambda inst: [inst.primary_node]
+    else:
+      nodes_fn = lambda inst: inst.all_nodes
+
+    return frozenset(inst.name
+                     for inst in self._config_data.instances.values()
+                     for node_name in nodes_fn(inst)
+                     if self._UnlockedGetNodeInfo(node_name).group == uuid)
+
   def _UnlockedGetNodeList(self):
     """Return the list of nodes which are in the configuration.
 
@@ -1410,6 +1460,17 @@ class ConfigWriter:
                     for node in self._UnlockedGetNodeList()])
     return my_dict
 
+  @locking.ssynchronized(_config_lock, shared=1)
+  def GetNodeGroupsFromNodes(self, nodes):
+    """Returns groups for a list of nodes.
+
+    @type nodes: list of string
+    @param nodes: List of node names
+    @rtype: frozenset
+
+    """
+    return frozenset(self._UnlockedGetNodeInfo(name).group for name in nodes)
+
   def _UnlockedGetMasterCandidateStats(self, exceptions=None):
     """Get the number of current and maximum desired and possible candidates.
 
@@ -1744,7 +1805,7 @@ class ConfigWriter:
                   self._config_data.nodegroups.values()]
     nodegroups_data = fn(utils.NiceSort(nodegroups))
 
-    return {
+    ssconf_values = {
       constants.SS_CLUSTER_NAME: cluster.cluster_name,
       constants.SS_CLUSTER_TAGS: cluster_tags,
       constants.SS_FILE_STORAGE_DIR: cluster.file_storage_dir,
@@ -1767,6 +1828,13 @@ class ConfigWriter:
       constants.SS_UID_POOL: uid_pool,
       constants.SS_NODEGROUPS: nodegroups_data,
       }
+    bad_values = [(k, v) for k, v in ssconf_values.items()
+                  if not isinstance(v, (str, basestring))]
+    if bad_values:
+      err = utils.CommaJoin("%s=%s" % (k, v) for k, v in bad_values)
+      raise errors.ConfigurationError("Some ssconf key(s) have non-string"
+                                      " values: %s" % err)
+    return ssconf_values
 
   @locking.ssynchronized(_config_lock, shared=1)
   def GetSsconfValues(self):