+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
+
+ """
+ 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.")
+
+
+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.
+
+ """
+ # 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:
+ 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_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_spindles: add spindle storage information to the legacy node
+ info
+
+ """
+ (bootid, space_info, (hv_info, )) = data
+
+ ret = utils.JoinDisjointDicts(hv_info, {"bootid": bootid})
+
+ if require_spindles:
+ _AddSpindlesToLegacyNodeInfo(ret, space_info)
+ _AddDefaultStorageInfoToLegacyNodeInfo(ret, space_info)
+
+ return ret
+
+
+def _AnnotateDParamsDRBD(disk, (drbd_params, data_params, meta_params)):
+ """Annotates just DRBD disks layouts.
+
+ """
+ assert disk.dev_type == constants.DT_DRBD8
+
+ disk.params = objects.FillDict(drbd_params, disk.params)
+ (dev_data, dev_meta) = disk.children
+ dev_data.params = objects.FillDict(data_params, dev_data.params)
+ dev_meta.params = objects.FillDict(meta_params, dev_meta.params)
+
+ return disk
+
+
+def _AnnotateDParamsGeneric(disk, (params, )):
+ """Generic disk parameter annotation routine.
+
+ """
+ assert disk.dev_type != constants.DT_DRBD8
+
+ disk.params = objects.FillDict(params, disk.params)
+
+ return disk
+
+
+def AnnotateDiskParams(template, disks, disk_params):
+ """Annotates the disk objects with the disk parameters.
+
+ @param template: The disk template used
+ @param disks: The list of disks objects to annotate
+ @param disk_params: The disk paramaters for annotation
+ @returns: A list of disk objects annotated
+
+ """
+ ld_params = objects.Disk.ComputeLDParams(template, disk_params)
+
+ if template == constants.DT_DRBD8:
+ annotation_fn = _AnnotateDParamsDRBD
+ elif template == constants.DT_DISKLESS:
+ annotation_fn = lambda disk, _: disk
+ else:
+ annotation_fn = _AnnotateDParamsGeneric
+
+ return [annotation_fn(disk.Copy(), ld_params) for disk in disks]
+
+
+def _GetExclusiveStorageFlag(cfg, node_uuid):
+ ni = cfg.GetNodeInfo(node_uuid)
+ if ni is None:
+ raise errors.OpPrereqError("Invalid node name %s" % node_uuid,
+ errors.ECODE_NOENT)
+ 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 in [constants.ST_LVM_VG, constants.ST_LVM_PV]:
+ 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 cfg: L{config.ConfigWriter}
+ @param cfg: cluster configuration
+ @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 exclusive storage flags
+ @raise errors.OpPrereqError: if any given node name has no corresponding
+ node
+
+ """
+ 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))
+
+