While a normal multi-group allocation doesn't need to restrict the list of target groups beyond the unallocable status of some groups, when we relocate instances from one group to the other we need to limit the subset of searched groups. --- htools/Ganeti/HTools/Cluster.hs | 15 ++++++++++++--- 1 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/htools/Ganeti/HTools/Cluster.hs b/htools/Ganeti/HTools/Cluster.hs index d022b5f..b77c18d 100644 --- a/htools/Ganeti/HTools/Cluster.hs +++ b/htools/Ganeti/HTools/Cluster.hs @@ -749,18 +749,27 @@ sortMGResults gl sols = in sortBy (comparing solScore) sols -- | Finds the best group for an instance on a multi-group cluster. +-- +-- Only solutions in @preferred@ and @last_resort@ groups will be +-- accepted as valid, and additionally if the allowed groups parameter +-- is not null then allocation will only be run for those group +-- indices. findBestAllocGroup :: Group.List -- ^ The group list -> Node.List -- ^ The node list -> Instance.List -- ^ The instance list + -> Maybe [Gdx] -- ^ The allowed groups -> Instance.Instance -- ^ The instance to allocate -> Int -- ^ Required number of nodes -> Result (Gdx, AllocSolution, [String]) -findBestAllocGroup mggl mgnl mgil inst cnt = +findBestAllocGroup mggl mgnl mgil allowed_gdxs inst cnt = let groups = splitCluster mgnl mgil + groups' = case allowed_gdxs of + Nothing -> groups + Just gs -> filter ((`elem` gs) . fst) groups sols = map (\(gid, (nl, il)) -> (gid, genAllocNodes mggl nl cnt False >>= tryAlloc nl il inst)) - groups::[(Gdx, Result AllocSolution)] + groups'::[(Gdx, Result AllocSolution)] all_msgs = concatMap (solutionDescription mggl) sols goodSols = filterMGResults mggl sols sortedSols = sortMGResults mggl goodSols @@ -778,7 +787,7 @@ tryMGAlloc :: Group.List -- ^ The group list -> Result AllocSolution -- ^ Possible solution list tryMGAlloc mggl mgnl mgil inst cnt = do (best_group, solution, all_msgs) <- - findBestAllocGroup mggl mgnl mgil inst cnt + findBestAllocGroup mggl mgnl mgil Nothing inst cnt let group_name = Group.name $ Container.find best_group mggl selmsg = "Selected group: " ++ group_name return $ solution { asLog = selmsg:all_msgs } -- 1.7.5.4