+def MakeLegacyNodeInfo(data):
+ """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.
+
+ """
+ (bootid, (vg_info, ), (hv_info, )) = data
+
+ return utils.JoinDisjointDicts(utils.JoinDisjointDicts(vg_info, hv_info), {
+ "bootid": bootid,
+ })
+
+
+def _AnnotateDParamsDRBD(disk, (drbd_params, data_params, meta_params)):
+ """Annotates just DRBD disks layouts.
+
+ """
+ assert disk.dev_type == constants.LD_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.LD_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 _GetESFlag(cfg, nodename):
+ ni = cfg.GetNodeInfo(nodename)
+ if ni is None:
+ raise errors.OpPrereqError("Invalid node name %s" % nodename,
+ errors.ECODE_NOENT)
+ return cfg.GetNdParams(ni)[constants.ND_EXCLUSIVE_STORAGE]
+
+
+def GetExclusiveStorageForNodeNames(cfg, nodelist):
+ """Return the exclusive storage flag for all the given nodes.
+
+ @type cfg: L{config.ConfigWriter}
+ @param cfg: cluster configuration
+ @type nodelist: list or tuple
+ @param nodelist: node names for which to read the flag
+ @rtype: dict
+ @return: mapping from node names to exclusive storage flags
+ @raise errors.OpPrereqError: if any given node name has no corresponding node
+
+ """
+ getflag = lambda n: _GetESFlag(cfg, n)
+ flags = map(getflag, nodelist)
+ return dict(zip(nodelist, flags))
+
+