When looking for an allocation, make htools restrict to those that are globally N+1 redundant. As checking for N+1 redundancy is an expensive operation, we first look for the best allocations and filter out later.
For the time being, we do not change the semantics of iterateAlloc; i.e., for iterateAlloc we will pretend that capacity checks are ignored. Signed-off-by: Klaus Aehlig <[email protected]> --- src/Ganeti/HTools/Cluster.hs | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/src/Ganeti/HTools/Cluster.hs b/src/Ganeti/HTools/Cluster.hs index 9ff8fef..b1147bb 100644 --- a/src/Ganeti/HTools/Cluster.hs +++ b/src/Ganeti/HTools/Cluster.hs @@ -96,8 +96,9 @@ import Ganeti.HTools.AlgorithmParams (AlgorithmOptions(..), defaultOptions) import qualified Ganeti.HTools.Container as Container import Ganeti.HTools.Cluster.AllocationSolution ( AllocElement, GenericAllocSolution(..) , AllocSolution, emptyAllocSolution - , sumAllocs, concatAllocs, extractNl, updateIl - , annotateSolution, solutionDescription, collapseFailures ) + , sumAllocs, extractNl, updateIl + , annotateSolution, solutionDescription, collapseFailures + , emptyAllocCollection, concatAllocCollections, collectionToSolution ) import Ganeti.HTools.Cluster.Evacuate ( EvacSolution(..), emptyEvacSolution , updateEvacSolution, reverseEvacSolution , nodeEvacInstance) @@ -107,6 +108,7 @@ import Ganeti.HTools.Cluster.Metrics ( compCV, compCVfromStats import Ganeti.HTools.Cluster.Moves (setInstanceLocationScore, applyMoveEx) import Ganeti.HTools.Cluster.Utils (splitCluster, instancePriGroup , availableGroupNodes, iMoveToJob) +import Ganeti.HTools.GlobalN1 (allocGlobalN1) import qualified Ganeti.HTools.Instance as Instance import qualified Ganeti.HTools.Nic as Nic import qualified Ganeti.HTools.Node as Node @@ -540,22 +542,31 @@ tryAlloc :: (Monad m) => -> AllocNodes -- ^ The allocation targets -> m AllocSolution -- ^ Possible solution list tryAlloc _ _ _ _ (Right []) = fail "Not enough online nodes" -tryAlloc opts nl _ inst (Right ok_pairs) = +tryAlloc opts nl il inst (Right ok_pairs) = let cstat = compClusterStatistics $ Container.elems nl + n1pred = if algCapacity opts + then allocGlobalN1 nl il + else const True psols = parMap rwhnf (\(p, ss) -> - foldl' (\cstate -> - concatAllocs cstate . - allocateOnPair opts cstat nl inst p) - emptyAllocSolution ss) ok_pairs + collectionToSolution FailN1 n1pred $ + foldl (\cstate -> + concatAllocCollections cstate + . allocateOnPair opts cstat nl inst p) + emptyAllocCollection ss) ok_pairs sols = foldl' sumAllocs emptyAllocSolution psols in return $ annotateSolution sols tryAlloc _ _ _ _ (Left []) = fail "No online nodes" -tryAlloc opts nl _ inst (Left all_nodes) = - let sols = foldl' (\cstate -> - concatAllocs cstate . allocateOnSingle opts nl inst - ) emptyAllocSolution all_nodes - in return $ annotateSolution sols +tryAlloc opts nl il inst (Left all_nodes) = + let sols = foldl (\cstate -> + concatAllocCollections cstate + . allocateOnSingle opts nl inst + ) emptyAllocCollection all_nodes + n1pred = if algCapacity opts + then allocGlobalN1 nl il + else const True + in return . annotateSolution + $ collectionToSolution FailN1 n1pred sols -- | From a list of possibly bad and possibly empty solutions, filter -- only the groups with a valid result. Note that the result will be @@ -779,7 +790,7 @@ iterateAlloc opts nl il limit newinst allocnodes ixes cstats = newidx = Container.size il newi2 = Instance.setIdx (Instance.setName newinst newname) newidx newlimit = fmap (flip (-) 1) limit - in case tryAlloc opts nl il newi2 allocnodes of + in case tryAlloc ( opts { algCapacity = False } ) nl il newi2 allocnodes of Bad s -> Bad s Ok (AllocSolution { asFailures = errs, asSolution = sols3 }) -> let newsol = Ok (collapseFailures errs, nl, il, ixes, cstats) in -- 2.2.0.rc0.207.ga3a616c
