"""
-# pylint: disable-msg=R0904
+# pylint: disable=R0904
# R0904: Too many public methods
import os
self._my_hostname = netutils.Hostname.GetSysName()
self._last_cluster_serial = -1
self._cfg_id = None
+ self._context = None
self._OpenConfig(accept_foreign)
+ def _GetRpc(self, address_list):
+ """Returns RPC runner for configuration.
+
+ """
+ return rpc.ConfigRunner(self._context, address_list)
+
+ def SetContext(self, context):
+ """Sets Ganeti context.
+
+ """
+ self._context = context
+
# this method needs to be static, so that we can call it on the class
@staticmethod
def IsCluster():
def GetNdParams(self, node):
"""Get the node params populated with cluster defaults.
- @type node: L{object.Node}
+ @type node: L{objects.Node}
@param node: The node we want to know the params for
@return: A dict with the filled in node params
configuration errors
"""
- # pylint: disable-msg=R0914
+ # pylint: disable=R0914
result = []
seen_macs = []
ports = {}
cluster.SimpleFillND(nodegroup.ndparams),
constants.NDS_PARAMETER_TYPES)
-
# drbd minors check
_, duplicates = self._UnlockedComputeDRBDMap()
for node, minor, instance_a, instance_b in duplicates:
return self._config_data.cluster.master_netdev
@locking.ssynchronized(_config_lock, shared=1)
+ def GetMasterNetmask(self):
+ """Get the netmask of the master node for this cluster.
+
+ """
+ return self._config_data.cluster.master_netmask
+
+ @locking.ssynchronized(_config_lock, shared=1)
+ def GetUseExternalMipScript(self):
+ """Get flag representing whether to use the external master IP setup script.
+
+ """
+ return self._config_data.cluster.use_external_mip_script
+
+ @locking.ssynchronized(_config_lock, shared=1)
def GetFileStorageDir(self):
"""Get the file storage dir for this cluster.
"""
return self._config_data.cluster.primary_ip_family
+ @locking.ssynchronized(_config_lock, shared=1)
+ def GetMasterNetworkParameters(self):
+ """Get network parameters of the master node.
+
+ @rtype: L{object.MasterNetworkParameters}
+ @return: network parameters of the master node
+
+ """
+ cluster = self._config_data.cluster
+ result = objects.MasterNetworkParameters(name=cluster.master_node,
+ ip=cluster.master_ip,
+ netmask=cluster.master_netmask,
+ netdev=cluster.master_netdev,
+ ip_family=cluster.primary_ip_family)
+
+ return result
+
@locking.ssynchronized(_config_lock)
def AddNodeGroup(self, group, ec_id, check_uuid=True):
"""Add a node group to the configuration.
for node_name in nodes)
@locking.ssynchronized(_config_lock, shared=1)
+ def GetMultiInstanceInfo(self, instances):
+ """Get the configuration of multiple instances.
+
+ @param instances: list of instance names
+ @rtype: list
+ @return: list of tuples (instance, instance_info), where
+ instance_info is what would GetInstanceInfo return for the
+ node, while keeping the original order
+
+ """
+ return [(name, self._UnlockedGetInstanceInfo(name)) for name in instances]
+
+ @locking.ssynchronized(_config_lock, shared=1)
def GetAllInstancesInfo(self):
"""Get the configuration of all instances.
for instance in self._UnlockedGetInstanceList()])
return my_dict
+ @locking.ssynchronized(_config_lock, shared=1)
+ def GetInstancesInfoByFilter(self, filter_fn):
+ """Get instance configuration with a filter.
+
+ @type filter_fn: callable
+ @param filter_fn: Filter function receiving instance object as parameter,
+ returning boolean. Important: this function is called while the
+ configuration locks is held. It must not do any complex work or call
+ functions potentially leading to a deadlock. Ideally it doesn't call any
+ other functions and just compares instance attributes.
+
+ """
+ return dict((name, inst)
+ for (name, inst) in self._config_data.instances.items()
+ if filter_fn(inst))
+
@locking.ssynchronized(_config_lock)
def AddNode(self, node, ec_id):
"""Add a node to the configuration.
would GetNodeInfo return for the node
"""
- my_dict = dict([(node, self._UnlockedGetNodeInfo(node))
- for node in self._UnlockedGetNodeList()])
- return my_dict
+ return self._UnlockedGetAllNodesInfo()
+
+ def _UnlockedGetAllNodesInfo(self):
+ """Gets configuration of all nodes.
+
+ @note: See L{GetAllNodesInfo}
+
+ """
+ return dict([(node, self._UnlockedGetNodeInfo(node))
+ for node in self._UnlockedGetNodeList()])
@locking.ssynchronized(_config_lock, shared=1)
def GetNodeGroupsFromNodes(self, nodes):
node_list.append(node_info.name)
addr_list.append(node_info.primary_ip)
- result = rpc.RpcRunner.call_upload_file(node_list, self._cfg_file,
- address_list=addr_list)
+ # TODO: Use dedicated resolver talking to config writer for name resolution
+ result = \
+ self._GetRpc(addr_list).call_upload_file(node_list, self._cfg_file)
for to_node, to_result in result.items():
msg = to_result.fail_msg
if msg:
# Write ssconf files on all nodes (including locally)
if self._last_cluster_serial < self._config_data.cluster.serial_no:
if not self._offline:
- result = rpc.RpcRunner.call_write_ssconf_files(
+ result = self._GetRpc(None).call_write_ssconf_files(
self._UnlockedGetOnlineNodeList(),
self._UnlockedGetSsconfValues())
constants.SS_MASTER_CANDIDATES_IPS: mc_ips_data,
constants.SS_MASTER_IP: cluster.master_ip,
constants.SS_MASTER_NETDEV: cluster.master_netdev,
+ constants.SS_MASTER_NETMASK: str(cluster.master_netmask),
constants.SS_MASTER_NODE: cluster.master_node,
constants.SS_NODE_LIST: node_data,
constants.SS_NODE_PRIMARY_IPS: node_pri_ips_data,