return [(d.ToDict(), uid) for d, uid in value]
-def BuildVgInfoQuery(cfg):
- """Build a query about the default VG for C{node_info}.
+def _AddSpindlesToLegacyNodeInfo(result, space_info):
+ """Extracts the spindle information from the space info and adds
+ it to the result dictionary.
+
+ @type result: dict of strings
+ @param result: dictionary holding the result of the legacy node info
+ @type space_info: list of dicts of strings
+ @param space_info: list, each row holding space information of one storage
+ unit
+ @rtype: None
+ @return: does not return anything, manipulates the C{result} variable
- The result of the RPC can be parsed with L{MakeLegacyNodeInfo}.
+ """
+ lvm_pv_info = utils.storage.LookupSpaceInfoByStorageType(
+ space_info, constants.ST_LVM_PV)
+ if lvm_pv_info:
+ result["spindles_free"] = lvm_pv_info["storage_free"]
+ result["spindles_total"] = lvm_pv_info["storage_size"]
+ else:
+ raise errors.OpExecError("No spindle storage information available.")
- @type cfg: L{config.ConfigWriter}
- @param cfg: Cluster configuration
- @rtype: list
- @return: argument suitable for L{rpc.RpcRunner.call_node_info}
+
+def _AddDefaultStorageInfoToLegacyNodeInfo(result, space_info):
+ """Extracts the storage space information of the default storage type from
+ the space info and adds it to the result dictionary.
+
+ @see: C{_AddSpindlesToLegacyNodeInfo} for parameter information.
"""
- vg_name = cfg.GetVGName()
- if vg_name:
- ret = [
- (constants.ST_LVM_VG, vg_name),
- (constants.ST_LVM_PV, vg_name),
- ]
+ # Check if there is at least one row for non-spindle storage info.
+ no_defaults = (len(space_info) < 1) or \
+ (space_info[0]["type"] == constants.ST_LVM_PV and len(space_info) == 1)
+
+ default_space_info = None
+ if no_defaults:
+ logging.warning("No storage info provided for default storage type.")
else:
- ret = []
- return ret
+ default_space_info = space_info[0]
+ if default_space_info:
+ result["name"] = default_space_info["name"]
+ result["storage_free"] = default_space_info["storage_free"]
+ result["storage_size"] = default_space_info["storage_size"]
-def MakeLegacyNodeInfo(data, require_vg_info=True):
+
+def MakeLegacyNodeInfo(data, require_spindles=False):
"""Formats the data returned by L{rpc.RpcRunner.call_node_info}.
Converts the data into a single dictionary. This is fine for most use cases,
but some require information from more than one volume group or hypervisor.
- @param require_vg_info: raise an error if the returnd vg_info
- doesn't have any values
+ @param require_spindles: add spindle storage information to the legacy node
+ info
"""
- (bootid, vgs_info, (hv_info, )) = data
+ (bootid, space_info, (hv_info, )) = data
ret = utils.JoinDisjointDicts(hv_info, {"bootid": bootid})
- if require_vg_info or vgs_info:
- (vg0_info, vg0_spindles) = vgs_info
- ret = utils.JoinDisjointDicts(vg0_info, ret)
- ret["spindles_free"] = vg0_spindles["vg_free"]
- ret["spindles_total"] = vg0_spindles["vg_size"]
+ if require_spindles:
+ _AddSpindlesToLegacyNodeInfo(ret, space_info)
+ _AddDefaultStorageInfoToLegacyNodeInfo(ret, space_info)
return ret
return [annotation_fn(disk.Copy(), ld_params) for disk in disks]
-def _GetESFlag(cfg, node_uuid):
+def _GetExclusiveStorageFlag(cfg, node_uuid):
ni = cfg.GetNodeInfo(node_uuid)
if ni is None:
raise errors.OpPrereqError("Invalid node name %s" % node_uuid,
return cfg.GetNdParams(ni)[constants.ND_EXCLUSIVE_STORAGE]
+def _AddExclusiveStorageFlagToLvmStorageUnits(storage_units, es_flag):
+ """Adds the exclusive storage flag to lvm units.
+
+ This function creates a copy of the storage_units lists, with the
+ es_flag being added to all lvm storage units.
+
+ @type storage_units: list of pairs (string, string)
+ @param storage_units: list of 'raw' storage units, consisting only of
+ (storage_type, storage_key)
+ @type es_flag: boolean
+ @param es_flag: exclusive storage flag
+ @rtype: list of tuples (string, string, list)
+ @return: list of storage units (storage_type, storage_key, params) with
+ the params containing the es_flag for lvm-vg storage units
+
+ """
+ result = []
+ for (storage_type, storage_key) in storage_units:
+ if storage_type == constants.ST_LVM_VG:
+ result.append((storage_type, storage_key, es_flag))
+ else:
+ result.append((storage_type, storage_key, []))
+ return result
+
+
def GetExclusiveStorageForNodes(cfg, node_uuids):
"""Return the exclusive storage flag for all the given nodes.
@type node_uuids: list or tuple
@param node_uuids: node UUIDs for which to read the flag
@rtype: dict
- @return: mapping from node names to exclusive storage flags
+ @return: mapping from node uuids to exclusive storage flags
@raise errors.OpPrereqError: if any given node name has no corresponding
node
"""
- getflag = lambda n: _GetESFlag(cfg, n)
+ getflag = lambda n: _GetExclusiveStorageFlag(cfg, n)
flags = map(getflag, node_uuids)
return dict(zip(node_uuids, flags))
+def PrepareStorageUnitsForNodes(cfg, storage_units, node_uuids):
+ """Return the lvm storage unit for all the given nodes.
+
+ Main purpose of this function is to map the exclusive storage flag, which
+ can be different for each node, to the default LVM storage unit.
+
+ @type cfg: L{config.ConfigWriter}
+ @param cfg: cluster configuration
+ @type storage_units: list of pairs (string, string)
+ @param storage_units: list of 'raw' storage units, e.g. pairs of
+ (storage_type, storage_key)
+ @type node_uuids: list or tuple
+ @param node_uuids: node UUIDs for which to read the flag
+ @rtype: dict
+ @return: mapping from node uuids to a list of storage units which include
+ the exclusive storage flag for lvm storage
+ @raise errors.OpPrereqError: if any given node name has no corresponding
+ node
+
+ """
+ getunit = lambda n: _AddExclusiveStorageFlagToLvmStorageUnits(
+ storage_units, _GetExclusiveStorageFlag(cfg, n))
+ flags = map(getunit, node_uuids)
+ return dict(zip(node_uuids, flags))
+
+
#: Generic encoders
_ENCODERS = {
rpc_defs.ED_OBJECT_DICT: _ObjectToDict,
# Encoders annotating disk parameters
rpc_defs.ED_DISKS_DICT_DP: self._DisksDictDP,
+ rpc_defs.ED_MULTI_DISKS_DICT_DP: self._MultiDiskDictDP,
rpc_defs.ED_SINGLE_DISK_DICT_DP: self._SingleDiskDictDP,
# Encoders with special requirements
for disk in AnnotateDiskParams(instance.disk_template,
disks, diskparams)]
+ def _MultiDiskDictDP(self, disks_insts):
+ """Wrapper for L{AnnotateDiskParams}.
+
+ Supports a list of (disk, instance) tuples.
+ """
+ return [disk for disk_inst in disks_insts
+ for disk in self._DisksDictDP(disk_inst)]
+
def _SingleDiskDictDP(self, (disk, instance)):
"""Wrapper for L{AnnotateDiskParams}.