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

Reply via email to