From 319322a735753064fdc2d31f1d683cd534a3c6cd Mon Sep 17 00:00:00 2001 From: Bernardo Dal Seno <bdalseno@google.com> Date: Mon, 10 Dec 2012 23:27:03 +0100 Subject: [PATCH] Call node_info RPCs with the exclusive_storage flag The flag is read from the configuration and passed to the RPC. Signed-off-by: Bernardo Dal Seno <bdalseno@google.com> Reviewed-by: Iustin Pop <iustin@google.com> --- htools/Ganeti/Query/Node.hs | 12 +++++++++++- htools/Ganeti/Rpc.hs | 9 +++++++-- lib/cmdlib.py | 6 ++++-- lib/masterd/iallocator.py | 3 ++- lib/rpc.py | 25 +++++++++++++++++++++++++ 5 files changed, 49 insertions(+), 6 deletions(-) diff --git a/htools/Ganeti/Query/Node.hs b/htools/Ganeti/Query/Node.hs index d324c39f6..de6ea1a93 100644 --- a/htools/Ganeti/Query/Node.hs +++ b/htools/Ganeti/Query/Node.hs @@ -223,4 +223,14 @@ maybeCollectLiveData False _ nodes = maybeCollectLiveData True cfg nodes = do let vgs = [clusterVolumeGroupName $ configCluster cfg] hvs = [getDefaultHypervisor cfg] - executeRpcCall nodes (RpcCallNodeInfo vgs hvs) + step n (bn, gn, em) = + let ndp' = getNodeNdParams cfg n + in case ndp' of + Just ndp -> (bn, n : gn, + (nodeName n, ndpExclusiveStorage ndp) : em) + Nothing -> (n : bn, gn, em) + (bnodes, gnodes, emap) = foldr step ([], [], []) nodes + rpcres <- executeRpcCall gnodes (RpcCallNodeInfo vgs hvs (Map.fromList emap)) + -- FIXME: The order of nodes in the result could be different from the input + return $ zip bnodes (repeat $ Left (RpcResultError "Broken configuration")) + ++ rpcres diff --git a/htools/Ganeti/Rpc.hs b/htools/Ganeti/Rpc.hs index c0d0cb6bb..284bb5ef7 100644 --- a/htools/Ganeti/Rpc.hs +++ b/htools/Ganeti/Rpc.hs @@ -70,6 +70,8 @@ module Ganeti.Rpc ) where import Control.Arrow (second) +import qualified Data.Map as Map +import Data.Maybe (fromMaybe) import qualified Text.JSON as J import Text.JSON.Pretty (pp_value) @@ -343,6 +345,7 @@ instance Rpc RpcCallInstanceList RpcResultInstanceList where $(buildObject "RpcCallNodeInfo" "rpcCallNodeInfo" [ simpleField "volume_groups" [t| [String] |] , simpleField "hypervisors" [t| [Hypervisor] |] + , simpleField "exclusive_storage" [t| Map.Map String Bool |] ]) $(buildObject "VgInfo" "vgInfo" @@ -371,10 +374,12 @@ instance RpcCall RpcCallNodeInfo where rpcCallName _ = "node_info" rpcCallTimeout _ = rpcTimeoutToRaw Urgent rpcCallAcceptOffline _ = False - rpcCallData _ call = J.encode + rpcCallData n call = J.encode ( rpcCallNodeInfoVolumeGroups call , rpcCallNodeInfoHypervisors call - , False + , fromMaybe (error $ "Programmer error: missing parameter for node named " + ++ nodeName n) + $ Map.lookup (nodeName n) (rpcCallNodeInfoExclusiveStorage call) ) instance Rpc RpcCallNodeInfo RpcResultNodeInfo where diff --git a/lib/cmdlib.py b/lib/cmdlib.py index eb9cb4571..5b963c5fa 100644 --- a/lib/cmdlib.py +++ b/lib/cmdlib.py @@ -5288,8 +5288,9 @@ class _NodeQuery(_QueryBase): # filter out non-vm_capable nodes toquery_nodes = [name for name in nodenames if all_info[name].vm_capable] + es_flags = rpc.GetExclusiveStorageForNodeNames(lu.cfg, toquery_nodes) node_data = lu.rpc.call_node_info(toquery_nodes, [lu.cfg.GetVGName()], - [lu.cfg.GetHypervisorType()], False) + [lu.cfg.GetHypervisorType()], es_flags) live_data = dict((name, rpc.MakeLegacyNodeInfo(nresult.payload)) for (name, nresult) in node_data.items() if not nresult.fail_msg and nresult.payload) @@ -6888,7 +6889,8 @@ def _CheckNodesFreeDiskOnVG(lu, nodenames, vg, requested): or we cannot check the node """ - nodeinfo = lu.rpc.call_node_info(nodenames, [vg], None, False) + es_flags = rpc.GetExclusiveStorageForNodeNames(lu.cfg, nodenames) + nodeinfo = lu.rpc.call_node_info(nodenames, [vg], None, es_flags) for node in nodenames: info = nodeinfo[node] info.Raise("Cannot get current information from node %s" % node, diff --git a/lib/masterd/iallocator.py b/lib/masterd/iallocator.py index 5f339b699..48cbd55ce 100644 --- a/lib/masterd/iallocator.py +++ b/lib/masterd/iallocator.py @@ -430,8 +430,9 @@ class IAllocator(object): hypervisor_name = cluster_info.primary_hypervisor node_whitelist = None + es_flags = rpc.GetExclusiveStorageForNodeNames(cfg, node_list) node_data = self.rpc.call_node_info(node_list, [cfg.GetVGName()], - [hypervisor_name], False) + [hypervisor_name], es_flags) node_iinfo = \ self.rpc.call_all_instances_info(node_list, cluster_info.enabled_hypervisors) diff --git a/lib/rpc.py b/lib/rpc.py index b72ac23e9..0c4bad079 100644 --- a/lib/rpc.py +++ b/lib/rpc.py @@ -631,6 +631,31 @@ def AnnotateDiskParams(template, disks, disk_params): 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)) + + #: Generic encoders _ENCODERS = { rpc_defs.ED_OBJECT_DICT: _ObjectToDict, -- GitLab