From 61bbbed7ba98b6e900cc59a1add4dcd2376826f4 Mon Sep 17 00:00:00 2001 From: Agata Murawska <agatamurawska@google.com> Date: Tue, 15 Nov 2011 11:28:40 +0100 Subject: [PATCH] htools: change behaviour for offline instances Signed-off-by: Agata Murawska <agatamurawska@google.com> Reviewed-by: Iustin Pop <iustin@google.com> --- htools/Ganeti/HTools/Instance.hs | 21 +++++++++++++++++++++ htools/Ganeti/HTools/Loader.hs | 8 +++++--- htools/Ganeti/HTools/Node.hs | 13 ++++++++----- htools/Ganeti/HTools/QC.hs | 30 +++++++++++++++++++++++++++--- htools/Ganeti/HTools/Utils.hs | 5 +++++ 5 files changed, 66 insertions(+), 11 deletions(-) diff --git a/htools/Ganeti/HTools/Instance.hs b/htools/Ganeti/HTools/Instance.hs index 1d7bc7876..22d3c9659 100644 --- a/htools/Ganeti/HTools/Instance.hs +++ b/htools/Ganeti/HTools/Instance.hs @@ -32,6 +32,9 @@ module Ganeti.HTools.Instance , List , create , instanceRunning + , instanceOffline + , instanceDown + , applyIfOnline , setIdx , setName , setAlias @@ -52,6 +55,8 @@ import qualified Ganeti.HTools.Types as T import qualified Ganeti.HTools.Container as Container import qualified Ganeti.Constants as C +import Ganeti.HTools.Utils + -- * Type declarations -- | The instance type. @@ -85,6 +90,22 @@ instanceRunning (Instance {runSt = T.Running}) = True instanceRunning (Instance {runSt = T.ErrorUp}) = True instanceRunning _ = False +-- | Check if instance is offline. +instanceOffline :: Instance -> Bool +instanceOffline (Instance {runSt = T.AdminOffline}) = True +instanceOffline _ = False + +-- | Check if instance is down. +instanceDown :: Instance -> Bool +instanceDown inst | instanceRunning inst = False +instanceDown inst | instanceOffline inst = False +instanceDown _ = True + +-- | Apply the function if the instance is online. Otherwise use +-- the initial value +applyIfOnline :: Instance -> (a -> a) -> a -> a +applyIfOnline = applyIf . not . instanceOffline + -- | Constant holding the local storage templates. -- -- /Note:/ Currently Ganeti only exports node total/free disk space diff --git a/htools/Ganeti/HTools/Loader.hs b/htools/Ganeti/HTools/Loader.hs index 9bbad6e9f..0e5f10a83 100644 --- a/htools/Ganeti/HTools/Loader.hs +++ b/htools/Ganeti/HTools/Loader.hs @@ -306,7 +306,7 @@ checkData nl il = (\ msgs node -> let nname = Node.name node nilst = map (`Container.find` il) (Node.pList node) - dilst = filter (not . Instance.instanceRunning) nilst + dilst = filter Instance.instanceDown nilst adj_mem = sum . map Instance.mem $ dilst delta_mem = truncate (Node.tMem node) - Node.nMem node @@ -329,8 +329,10 @@ checkData nl il = nodeImem :: Node.Node -> Instance.List -> Int nodeImem node il = let rfind = flip Container.find il - in sum . map (Instance.mem . rfind) - $ Node.pList node + il' = map rfind $ Node.pList node + oil' = filter (not . Instance.instanceOffline) il' + in sum . map Instance.mem $ oil' + -- | Compute the amount of disk used by instances on a node (either primary -- or secondary). diff --git a/htools/Ganeti/HTools/Node.hs b/htools/Ganeti/HTools/Node.hs index 5ebfbd72d..c2116d4dd 100644 --- a/htools/Ganeti/HTools/Node.hs +++ b/htools/Ganeti/HTools/Node.hs @@ -310,12 +310,13 @@ removePri :: Node -> Instance.Instance -> Node removePri t inst = let iname = Instance.idx inst new_plist = delete iname (pList t) - new_mem = fMem t + Instance.mem inst + new_mem = Instance.applyIfOnline inst (+ Instance.mem inst) (fMem t) new_dsk = fDsk t + Instance.dsk inst new_mp = fromIntegral new_mem / tMem t new_dp = fromIntegral new_dsk / tDsk t new_failn1 = new_mem <= rMem t - new_ucpu = uCpu t - Instance.vcpus inst + new_ucpu = Instance.applyIfOnline inst + (\x -> x - Instance.vcpus inst) (uCpu t) new_rcpu = fromIntegral new_ucpu / tCpu t new_load = utilLoad t `T.subUtil` Instance.util inst in t { pList = new_plist, fMem = new_mem, fDsk = new_dsk @@ -374,12 +375,13 @@ addPriEx force t inst = let iname = Instance.idx inst uses_disk = Instance.usesLocalStorage inst cur_dsk = fDsk t - new_mem = fMem t - Instance.mem inst + new_mem = Instance.applyIfOnline inst + (\x -> x - Instance.mem inst) (fMem t) new_dsk = if uses_disk then cur_dsk - Instance.dsk inst else cur_dsk new_failn1 = new_mem <= rMem t - new_ucpu = uCpu t + Instance.vcpus inst + new_ucpu = Instance.applyIfOnline inst (+ Instance.vcpus inst) (uCpu t) new_pcpu = fromIntegral new_ucpu / tCpu t new_dp = fromIntegral new_dsk / tDsk t l_cpu = mCpu t @@ -415,7 +417,8 @@ addSecEx force t inst pdx = old_peers = peers t old_mem = fMem t new_dsk = fDsk t - Instance.dsk inst - secondary_needed_mem = if Instance.autoBalance inst + secondary_needed_mem = if Instance.autoBalance inst && + not (Instance.instanceOffline inst) then Instance.mem inst else 0 new_peem = P.find pdx old_peers + secondary_needed_mem diff --git a/htools/Ganeti/HTools/QC.hs b/htools/Ganeti/HTools/QC.hs index a55ba02c2..a03830e6f 100644 --- a/htools/Ganeti/HTools/QC.hs +++ b/htools/Ganeti/HTools/QC.hs @@ -695,7 +695,8 @@ prop_Node_setMcpu node mc = -- | Check that an instance add with too high memory or disk will be -- rejected. prop_Node_addPriFM node inst = Instance.mem inst >= Node.fMem node && - not (Node.failN1 node) + not (Node.failN1 node) && + not (Instance.instanceOffline inst) ==> case Node.addPri node inst'' of Types.OpFail Types.FailMem -> True @@ -715,7 +716,8 @@ prop_Node_addPriFD node inst = Instance.dsk inst >= Node.fDsk node && inst'' = inst' { Instance.dsk = Instance.dsk inst } prop_Node_addPriFC node inst (Positive extra) = - not (Node.failN1 node) ==> + not (Node.failN1 node) && + not (Instance.instanceOffline inst) ==> case Node.addPri node inst'' of Types.OpFail Types.FailCPU -> True _ -> False @@ -726,14 +728,34 @@ prop_Node_addPriFC node inst (Positive extra) = -- | Check that an instance add with too high memory or disk will be -- rejected. prop_Node_addSec node inst pdx = - (Instance.mem inst >= (Node.fMem node - Node.rMem node) || + ((Instance.mem inst >= (Node.fMem node - Node.rMem node) && + not (Instance.instanceOffline inst)) || Instance.dsk inst >= Node.fDsk node) && not (Node.failN1 node) ==> isFailure (Node.addSec node inst pdx) where _types = (node::Node.Node, inst::Instance.Instance, pdx::Int) +-- | Check that an offline instance with reasonable disk size can always +-- be added. +prop_Node_addPriOffline node = + forAll (arbitrary `suchThat` + (\ x -> (Instance.dsk x < Node.fDsk node) && + Instance.instanceOffline x)) $ \inst -> + case Node.addPri node inst of + Types.OpGood _ -> True + _ -> False + +prop_Node_addSecOffline node pdx = + forAll (arbitrary `suchThat` + (\ x -> (Instance.dsk x < Node.fDsk node) && + Instance.instanceOffline x)) $ \inst -> + case Node.addSec node inst pdx of + Types.OpGood _ -> True + _ -> False + -- | Checks for memory reservation changes. prop_Node_rMem inst = + not (Instance.instanceOffline inst) ==> forAll (arbitrary `suchThat` ((> Types.unitMem) . Node.fMem)) $ \node -> -- ab = auto_balance, nb = non-auto_balance -- we use -1 as the primary node of the instance @@ -808,6 +830,8 @@ testSuite "Node" , 'prop_Node_addPriFD , 'prop_Node_addPriFC , 'prop_Node_addSec + , 'prop_Node_addPriOffline + , 'prop_Node_addSecOffline , 'prop_Node_rMem , 'prop_Node_setMdsk , 'prop_Node_tagMaps_idempotent diff --git a/htools/Ganeti/HTools/Utils.hs b/htools/Ganeti/HTools/Utils.hs index 43f9330a5..4b0dd4ac4 100644 --- a/htools/Ganeti/HTools/Utils.hs +++ b/htools/Ganeti/HTools/Utils.hs @@ -30,6 +30,7 @@ module Ganeti.HTools.Utils , stdDev , if' , select + , applyIf , commaJoin , readEitherString , JSRecord @@ -76,6 +77,10 @@ debugXy = seq . debug -- * Miscellaneous +-- | Apply the function if condition holds, otherwise use default value. +applyIf :: Bool -> (a -> a) -> a -> a +applyIf b f x = if b then f x else x + -- | Comma-join a string list. commaJoin :: [String] -> String commaJoin = intercalate "," -- GitLab