Note that --no-disk-moves and --no-instance-moves are not incompatible, but if both are used no solution can possibly exist.
Signed-off-by: Guido Trotter <[email protected]> --- htools/Ganeti/HTools/Cluster.hs | 28 +++++++++++++++++++--------- htools/Ganeti/HTools/QC.hs | 8 ++++---- htools/hbal.hs | 4 ++-- 3 files changed, 25 insertions(+), 15 deletions(-) diff --git a/htools/Ganeti/HTools/Cluster.hs b/htools/Ganeti/HTools/Cluster.hs index 48e4b6a..fca08ad 100644 --- a/htools/Ganeti/HTools/Cluster.hs +++ b/htools/Ganeti/HTools/Cluster.hs @@ -465,35 +465,42 @@ checkSingleStep ini_tbl target cur_tbl move = -- the current candidate target node, generate the possible moves for -- a instance. possibleMoves :: Bool -- ^ Whether the secondary node is a valid new node + -> Bool -- ^ Whether the primary node is a valid new node -> Ndx -- ^ Target node candidate -> [IMove] -- ^ List of valid result moves -possibleMoves True tdx = + +possibleMoves _ False tdx = + [ReplaceSecondary tdx] + +possibleMoves True True tdx = [ReplaceSecondary tdx, ReplaceAndFailover tdx, ReplacePrimary tdx, FailoverAndReplace tdx] -possibleMoves False tdx = +possibleMoves False True tdx = [ReplaceSecondary tdx, ReplaceAndFailover tdx] -- | Compute the best move for a given instance. checkInstanceMove :: [Ndx] -- ^ Allowed target node indices -> Bool -- ^ Whether disk moves are allowed + -> Bool -- ^ Whether instance moves are allowed -> Table -- ^ Original table -> Instance.Instance -- ^ Instance to move -> Table -- ^ Best new table for this instance -checkInstanceMove nodes_idx disk_moves ini_tbl target = +checkInstanceMove nodes_idx disk_moves inst_moves ini_tbl target = let opdx = Instance.pNode target osdx = Instance.sNode target nodes = filter (\idx -> idx /= opdx && idx /= osdx) nodes_idx - use_secondary = elem osdx nodes_idx + use_secondary = elem osdx nodes_idx && inst_moves aft_failover = if use_secondary -- if allowed to failover then checkSingleStep ini_tbl target ini_tbl Failover else ini_tbl all_moves = if disk_moves - then concatMap (possibleMoves use_secondary) nodes + then concatMap + (possibleMoves use_secondary inst_moves) nodes else [] in -- iterate over the possible nodes for this instance @@ -502,17 +509,19 @@ checkInstanceMove nodes_idx disk_moves ini_tbl target = -- | Compute the best next move. checkMove :: [Ndx] -- ^ Allowed target node indices -> Bool -- ^ Whether disk moves are allowed + -> Bool -- ^ Whether instance moves are allowed -> Table -- ^ The current solution -> [Instance.Instance] -- ^ List of instances still to move -> Table -- ^ The new solution -checkMove nodes_idx disk_moves ini_tbl victims = +checkMove nodes_idx disk_moves inst_moves ini_tbl victims = let Table _ _ _ ini_plc = ini_tbl -- we're using rwhnf from the Control.Parallel.Strategies -- package; we don't need to use rnf as that would force too -- much evaluation in single-threaded cases, and in -- multi-threaded case the weak head normal form is enough to -- spark the evaluation - tables = parMap rwhnf (checkInstanceMove nodes_idx disk_moves ini_tbl) + tables = parMap rwhnf (checkInstanceMove nodes_idx disk_moves + inst_moves ini_tbl) victims -- iterate over all instances, computing the best move best_tbl = foldl' compareTables ini_tbl tables @@ -534,11 +543,12 @@ doNextBalance ini_tbl max_rounds min_score = -- | Run a balance move tryBalance :: Table -- ^ The starting table -> Bool -- ^ Allow disk moves + -> Bool -- ^ Allow instance moves -> Bool -- ^ Only evacuate moves -> Score -- ^ Min gain threshold -> Score -- ^ Min gain -> Maybe Table -- ^ The resulting table and commands -tryBalance ini_tbl disk_moves evac_mode mg_limit min_gain = +tryBalance ini_tbl disk_moves inst_moves evac_mode mg_limit min_gain = let Table ini_nl ini_il ini_cv _ = ini_tbl all_inst = Container.elems ini_il all_inst' = if evac_mode @@ -551,7 +561,7 @@ tryBalance ini_tbl disk_moves evac_mode mg_limit min_gain = reloc_inst = filter Instance.movable all_inst' node_idx = map Node.idx . filter (not . Node.offline) $ Container.elems ini_nl - fin_tbl = checkMove node_idx disk_moves ini_tbl reloc_inst + fin_tbl = checkMove node_idx disk_moves inst_moves ini_tbl reloc_inst (Table _ _ fin_cv _) = fin_tbl in if fin_cv < ini_cv && (ini_cv > mg_limit || ini_cv - fin_cv >= min_gain) diff --git a/htools/Ganeti/HTools/QC.hs b/htools/Ganeti/HTools/QC.hs index 40a7c9f..66cf229 100644 --- a/htools/Ganeti/HTools/QC.hs +++ b/htools/Ganeti/HTools/QC.hs @@ -123,8 +123,8 @@ isNodeBig node size = Node.availDisk node > size * Types.unitDsk && Node.availMem node > size * Types.unitMem && Node.availCpu node > size * Types.unitCpu -canBalance :: Cluster.Table -> Bool -> Bool -> Bool -canBalance tbl dm evac = isJust $ Cluster.tryBalance tbl dm evac 0 0 +canBalance :: Cluster.Table -> Bool -> Bool -> Bool -> Bool +canBalance tbl dm im evac = isJust $ Cluster.tryBalance tbl dm im evac 0 0 -- | Assigns a new fresh instance to a cluster; this is not -- allocation, so no resource checks are done @@ -746,7 +746,7 @@ prop_ClusterAlloc_sane node inst = (xnl, xi, _, cv):[] -> let il' = Container.add (Instance.idx xi) xi il tbl = Cluster.Table xnl il' cv [] - in not (canBalance tbl True False) + in not (canBalance tbl True True False) _ -> False -- | Checks that on a 2-5 node cluster, we can allocate a random @@ -815,7 +815,7 @@ prop_ClusterAllocBalance node = let ynl = Container.add (Node.idx hnode) hnode xnl cv = Cluster.compCV ynl tbl = Cluster.Table ynl il' cv [] - in canBalance tbl True False + in canBalance tbl True True False -- | Checks consistency prop_ClusterCheckConsistency node inst = diff --git a/htools/hbal.hs b/htools/hbal.hs index d6ffa71..a3ba66a 100644 --- a/htools/hbal.hs +++ b/htools/hbal.hs @@ -109,8 +109,8 @@ iterateDepth ini_tbl max_rounds disk_moves inst_moves nmlen imlen let Cluster.Table ini_nl ini_il _ _ = ini_tbl allowed_next = Cluster.doNextBalance ini_tbl max_rounds min_score m_fin_tbl = if allowed_next - then Cluster.tryBalance ini_tbl disk_moves evac_mode - mg_limit min_gain + then Cluster.tryBalance ini_tbl disk_moves inst_moves + evac_mode mg_limit min_gain else Nothing in case m_fin_tbl of -- 1.7.2.5
