From 30fded871f2ceda62196b1c71fc3537f77391b15 Mon Sep 17 00:00:00 2001 From: Klaus Aehlig <aehlig@google.com> Date: Tue, 7 May 2013 14:51:48 +0200 Subject: [PATCH] Support construction of the graph of all reboot constraints For online rolling reboots, there are two kind of restrictions. First, we cannot reboot the primary and secondary nodes of an instance together. Secondly, two nodes cannot be rebooted simultaneously, if they are the primary nodes of two instances with the same secondary node. The second condition requires knowledge of all nodes, not only those the graph is to be constructed on. Signed-off-by: Klaus Aehlig <aehlig@google.com> Reviewed-by: Thomas Thrainer <thomasth@google.com> --- src/Ganeti/HTools/Node.hs | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/src/Ganeti/HTools/Node.hs b/src/Ganeti/HTools/Node.hs index a8c1fdb7f..03ec3bb66 100644 --- a/src/Ganeti/HTools/Node.hs +++ b/src/Ganeti/HTools/Node.hs @@ -73,9 +73,11 @@ module Ganeti.HTools.Node , noSecondary , computeGroups , mkNodeGraph + , mkRebootNodeGraph ) where import Control.Monad (liftM, liftM2) +import Control.Applicative ((<$>), (<*>)) import qualified Data.Foldable as Foldable import Data.Function (on) import qualified Data.Graph as Graph @@ -589,14 +591,37 @@ nodesToBounds nl = liftM2 (,) nmin nmax where nmin = fmap (fst . fst) (IntMap.minViewWithKey nl) nmax = fmap (fst . fst) (IntMap.maxViewWithKey nl) +-- | The clique of the primary nodes of the instances with a given secondary. +-- Return the full graph of those nodes that are primary node of at least one +-- instance that has the given node as secondary. +nodeToSharedSecondaryEdge :: Instance.List -> Node -> [Graph.Edge] +nodeToSharedSecondaryEdge il n = (,) <$> primaries <*> primaries + where primaries = map (Instance.pNode . flip Container.find il) $ sList n + + +-- | Predicate of an edge having both vertices in a set of nodes. +filterValid :: List -> [Graph.Edge] -> [Graph.Edge] +filterValid nl = filter $ \(x,y) -> IntMap.member x nl && IntMap.member y nl + -- | Transform a Node + Instance list into a NodeGraph type. -- Returns Nothing if the node list is empty. mkNodeGraph :: List -> Instance.List -> Maybe Graph.Graph mkNodeGraph nl il = - liftM (`Graph.buildG` (filterValid . instancesToEdges $ il)) + liftM (`Graph.buildG` (filterValid nl . instancesToEdges $ il)) (nodesToBounds nl) + +-- | Transform a Nodes + Instances into a NodeGraph with all reboot exclusions. +-- This includes edges between nodes that are the primary nodes of instances +-- that have the same secondary node. Nodes not in the node list will not be +-- part of the graph, but they are still considered for the edges arising from +-- two instances having the same secondary node. +-- Return Nothing if the node list is empty. +mkRebootNodeGraph :: List -> List -> Instance.List -> Maybe Graph.Graph +mkRebootNodeGraph allnodes nl il = + liftM (`Graph.buildG` filterValid nl edges) (nodesToBounds nl) where - filterValid = filter (\(x,y) -> IntMap.member x nl && IntMap.member y nl) + edges = instancesToEdges il `union` + (Container.elems allnodes >>= nodeToSharedSecondaryEdge il) -- * Display functions -- GitLab