Commit 32b8d9c0 authored by Iustin Pop's avatar Iustin Pop
Browse files

Add two functions for checking cluster consistency



For now, we don't support instances allocated across two groups, and we
will reject such clusters. The isClusterConsistent function will return
a list of inconsistent instances, potentially allowing operation without
touch them (but only the rest).
Signed-off-by: default avatarIustin Pop <iustin@google.com>
Reviewed-by: default avatarBalazs Lecz <leczb@google.com>
parent d8bcd0a8
......@@ -61,6 +61,8 @@ module Ganeti.HTools.Cluster
-- * Allocation functions
, iterateAlloc
, tieredAlloc
, instanceGroup
, findSplitInstances
) where
import Data.List
......@@ -830,3 +832,27 @@ iMoveToJob nl il idx move =
ReplaceSecondary ns -> [ opR ns ]
ReplaceAndFailover np -> [ opR np, opF ]
FailoverAndReplace ns -> [ opF, opR ns ]
-- | Computes the group of an instance
instanceGroup :: Node.List -> Instance.Instance -> Result GroupID
instanceGroup nl i =
let sidx = Instance.sNode i
pnode = Container.find (Instance.pNode i) nl
snode = if sidx == Node.noSecondary
then pnode
else Container.find sidx nl
puuid = Node.group pnode
suuid = Node.group snode
in if puuid /= suuid
then fail ("Instance placed accross two node groups, primary " ++ puuid ++
", secondary " ++ suuid)
else return puuid
-- | Compute the list of badly allocated instances (split across node
-- groups)
findSplitInstances :: Node.List -> Instance.List -> [Instance.Instance]
findSplitInstances nl il =
filter (not . isOk . instanceGroup nl) (Container.elems il)
where isOk x = case x of
Bad _ -> False
_ -> True
......@@ -704,6 +704,22 @@ prop_ClusterAllocBalance node =
tbl = Cluster.Table ynl il' cv []
in canBalance tbl True False
-- | Checks consistency
prop_ClusterCheckConsistency node inst =
let nl = makeSmallCluster node 3
[node1, node2, node3] = Container.elems nl
node3' = node3 { Node.group = "other-uuid" }
nl' = Container.add (Node.idx node3') node3' nl
inst1 = Instance.setBoth inst (Node.idx node1) (Node.idx node2)
inst2 = Instance.setBoth inst (Node.idx node1) Node.noSecondary
inst3 = Instance.setBoth inst (Node.idx node1) (Node.idx node3)
ccheck = Cluster.findSplitInstances nl' . Container.fromAssocList
in null (ccheck [(0, inst1)]) &&
null (ccheck [(0, inst2)]) &&
(not . null $ ccheck [(0, inst3)])
testCluster =
[ run prop_Score_Zero
, run prop_CStats_sane
......@@ -711,6 +727,7 @@ testCluster =
, run prop_ClusterCanTieredAlloc
, run prop_ClusterAllocEvac
, run prop_ClusterAllocBalance
, run prop_ClusterCheckConsistency
]
-- | Check that opcode serialization is idempotent
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment