Safe Haskell | Safe-Infered |
---|
Implementation of cluster-wide logic.
This module holds all pure cluster-logic; I/O related functionality goes into the Main module for the individual binaries.
- data AllocSolution = AllocSolution {
- asFailures :: [FailMode]
- asAllocs :: Int
- asSolution :: Maybe AllocElement
- asLog :: [String]
- data EvacSolution = EvacSolution {}
- type AllocResult = (FailStats, List, List, [Instance], [CStats])
- type AllocSolutionList = [(Instance, AllocSolution)]
- type AllocNodes = Either [Ndx] [(Ndx, [Ndx])]
- emptyAllocSolution :: AllocSolution
- emptyEvacSolution :: EvacSolution
- data Table = Table List List Score [Placement]
- data CStats = CStats {
- csFmem :: Integer
- csFdsk :: Integer
- csAmem :: Integer
- csAdsk :: Integer
- csAcpu :: Integer
- csMmem :: Integer
- csMdsk :: Integer
- csMcpu :: Integer
- csImem :: Integer
- csIdsk :: Integer
- csIcpu :: Integer
- csTmem :: Double
- csTdsk :: Double
- csTcpu :: Double
- csVcpu :: Integer
- csNcpu :: Double
- csXmem :: Integer
- csNmem :: Integer
- csScore :: Score
- csNinst :: Int
- type AllocMethod = List -> List -> Maybe Int -> Instance -> AllocNodes -> [Instance] -> [CStats] -> Result AllocResult
- type EvacInnerState = Either String (List, Instance, Score, Ndx)
- verifyN1 :: [Node] -> [Node]
- computeBadItems :: List -> List -> ([Node], [Instance])
- instanceNodes :: List -> Instance -> (Ndx, Ndx, Node, Node)
- emptyCStats :: CStats
- updateCStats :: CStats -> Node -> CStats
- totalResources :: List -> CStats
- computeAllocationDelta :: CStats -> CStats -> AllocStats
- detailedCVInfo :: [(Double, String)]
- detailedCVWeights :: [Double]
- compDetailedCV :: [Node] -> [Double]
- compCVNodes :: [Node] -> Double
- compCV :: List -> Double
- getOnline :: List -> [Node]
- compareTables :: Table -> Table -> Table
- applyMove :: List -> Instance -> IMove -> OpResult (List, Instance, Ndx, Ndx)
- allocateOnSingle :: List -> Instance -> Ndx -> OpResult AllocElement
- allocateOnPair :: List -> Instance -> Ndx -> Ndx -> OpResult AllocElement
- checkSingleStep :: Table -> Instance -> Table -> IMove -> Table
- possibleMoves :: MirrorType -> Bool -> Bool -> Ndx -> [IMove]
- checkInstanceMove :: [Ndx] -> Bool -> Bool -> Table -> Instance -> Table
- checkMove :: [Ndx] -> Bool -> Bool -> Table -> [Instance] -> Table
- doNextBalance :: Table -> Int -> Score -> Bool
- tryBalance :: Table -> Bool -> Bool -> Bool -> Score -> Score -> Maybe Table
- collapseFailures :: [FailMode] -> FailStats
- bestAllocElement :: Maybe AllocElement -> Maybe AllocElement -> Maybe AllocElement
- concatAllocs :: AllocSolution -> OpResult AllocElement -> AllocSolution
- sumAllocs :: AllocSolution -> AllocSolution -> AllocSolution
- describeSolution :: AllocSolution -> String
- annotateSolution :: AllocSolution -> AllocSolution
- reverseEvacSolution :: EvacSolution -> EvacSolution
- genAllocNodes :: List -> List -> Int -> Bool -> Result AllocNodes
- tryAlloc :: Monad m => List -> List -> Instance -> AllocNodes -> m AllocSolution
- solutionDescription :: (Group, Result AllocSolution) -> [String]
- filterMGResults :: [(Group, Result AllocSolution)] -> [(Group, AllocSolution)]
- sortMGResults :: [(Group, AllocSolution)] -> [(Group, AllocSolution)]
- filterValidGroups :: [(Group, (List, List))] -> Instance -> ([(Group, (List, List))], [String])
- findBestAllocGroup :: List -> List -> List -> Maybe [Gdx] -> Instance -> Int -> Result (Group, AllocSolution, [String])
- tryMGAlloc :: List -> List -> List -> Instance -> Int -> Result AllocSolution
- updateIl :: List -> Maybe AllocElement -> List
- extractNl :: List -> Maybe AllocElement -> List
- allocList :: List -> List -> List -> [(Instance, Int)] -> AllocSolutionList -> Result (List, List, AllocSolutionList)
- failOnSecondaryChange :: Monad m => EvacMode -> DiskTemplate -> m ()
- nodeEvacInstance :: List -> List -> EvacMode -> Instance -> Gdx -> [Ndx] -> Result (List, List, [OpCode])
- evacOneNodeOnly :: List -> List -> Instance -> Gdx -> [Ndx] -> Result (List, List, [OpCode])
- evacOneNodeInner :: List -> Instance -> Gdx -> (Ndx -> IMove) -> EvacInnerState -> Ndx -> EvacInnerState
- evacDrbdAllInner :: List -> List -> Instance -> Gdx -> (Ndx, Ndx) -> Result (List, List, [OpCode], Score)
- availableGroupNodes :: [(Gdx, [Ndx])] -> IntSet -> Gdx -> Result [Ndx]
- updateEvacSolution :: (List, List, EvacSolution) -> Idx -> Result (List, List, [OpCode]) -> (List, List, EvacSolution)
- tryNodeEvac :: List -> List -> List -> EvacMode -> [Idx] -> Result (List, List, EvacSolution)
- tryChangeGroup :: List -> List -> List -> [Gdx] -> [Idx] -> Result (List, List, EvacSolution)
- iterateAlloc :: AllocMethod
- sufficesShrinking :: (Instance -> AllocSolution) -> Instance -> FailMode -> Maybe Instance
- tieredAlloc :: AllocMethod
- computeMoves :: Instance -> String -> IMove -> String -> String -> (String, [String])
- printSolutionLine :: List -> List -> Int -> Int -> Placement -> Int -> (String, [String])
- involvedNodes :: List -> Placement -> [Ndx]
- mergeJobs :: ([JobSet], [Ndx]) -> MoveJob -> ([JobSet], [Ndx])
- splitJobs :: [MoveJob] -> [JobSet]
- formatJob :: Int -> Int -> (Int, MoveJob) -> [String]
- formatCmds :: [JobSet] -> String
- printNodes :: List -> [String] -> String
- printInsts :: List -> List -> String
- printStats :: String -> List -> String
- iMoveToJob :: List -> List -> Idx -> IMove -> [OpCode]
- instanceGroup :: List -> Instance -> Result Gdx
- instancePriGroup :: List -> Instance -> Gdx
- findSplitInstances :: List -> List -> [Instance]
- splitCluster :: List -> List -> [(Gdx, (List, List))]
- nodesToEvacuate :: List -> EvacMode -> [Idx] -> IntSet
Types
data AllocSolution Source
Allocation/relocation solution.
AllocSolution | |
|
data EvacSolution Source
Node evacuation/group change iallocator result type. This result type consists of actual opcodes (a restricted subset) that are transmitted back to Ganeti.
Show EvacSolution |
type AllocResult = (FailStats, List, List, [Instance], [CStats])Source
Allocation results, as used in iterateAlloc
and tieredAlloc
.
type AllocSolutionList = [(Instance, AllocSolution)]Source
Type alias for easier handling.
type AllocNodes = Either [Ndx] [(Ndx, [Ndx])]Source
A type denoting the valid allocation mode/pairs.
For a one-node allocation, this will be a Left [
, whereas
for a two-node allocation, this will be a Ndx
]Right [(
. In the latter case, the list is basically an
association list, grouped by primary node and holding the potential
secondary nodes in the sub-list.
Ndx
,
[Ndx
])]
The complete state for the balancing solution.
Show Table |
Cluster statistics data type.
CStats | |
|
Show CStats |
type AllocMethodSource
= List | Node list |
-> List | Instance list |
-> Maybe Int | Optional allocation limit |
-> Instance | Instance spec for allocation |
-> AllocNodes | Which nodes we should allocate on |
-> [Instance] | Allocated instances |
-> [CStats] | Running cluster stats |
-> Result AllocResult | Allocation result |
A simple type for allocation functions.
Utility functions
computeBadItems :: List -> List -> ([Node], [Instance])Source
Computes the pair of bad nodes and instances.
The bad node list is computed via a simple verifyN1
check, and the
bad instance list is the list of primary and secondary instances of
those nodes.
updateCStats :: CStats -> Node -> CStatsSource
totalResources :: List -> CStatsSource
Compute the total free disk and memory in the cluster.
computeAllocationDelta :: CStats -> CStats -> AllocStatsSource
Compute the delta between two cluster state.
This is used when doing allocations, to understand better the available cluster resources. The return value is a triple of the current used values, the delta that was still allocated, and what was left unallocated.
detailedCVInfo :: [(Double, String)]Source
detailedCVWeights :: [Double]Source
compDetailedCV :: [Node] -> [Double]Source
Compute the mem and disk covariance.
compCVNodes :: [Node] -> DoubleSource
Compute the total variance.
compCV :: List -> DoubleSource
Wrapper over compCVNodes
for callers that have a List
.
Balancing functions
compareTables :: Table -> Table -> TableSource
allocateOnSingle :: List -> Instance -> Ndx -> OpResult AllocElementSource
allocateOnPair :: List -> Instance -> Ndx -> Ndx -> OpResult AllocElementSource
possibleMoves :: MirrorType -> Bool -> Bool -> Ndx -> [IMove]Source
:: [Ndx] | Allowed target node indices |
-> Bool | Whether disk moves are allowed |
-> Bool | Whether instance moves are allowed |
-> Table | The current solution |
-> [Instance] | List of instances still to move |
-> Table | The new solution |
Compute the best next move.
:: Table | The starting table |
-> Int | Remaining length |
-> Score | Score at which to stop |
-> Bool | The resulting table and commands |
Check if we are allowed to go deeper in the balancing.
:: 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 |
Run a balance move.
Allocation functions
collapseFailures :: [FailMode] -> FailStatsSource
Build failure stats out of a list of failures.
bestAllocElement :: Maybe AllocElement -> Maybe AllocElement -> Maybe AllocElementSource
describeSolution :: AllocSolution -> StringSource
:: List | Group list |
-> List | The node map |
-> Int | The number of nodes required |
-> Bool | Whether to drop or not unallocable nodes |
-> Result AllocNodes | The (monadic) result |
Generate the valid node allocation singles or pairs for a new instance.
:: Monad m | |
=> List | The node list |
-> List | The instance list |
-> Instance | The instance to allocate |
-> AllocNodes | The allocation targets |
-> m AllocSolution | Possible solution list |
Try to allocate an instance on the cluster.
solutionDescription :: (Group, Result AllocSolution) -> [String]Source
filterMGResults :: [(Group, Result AllocSolution)] -> [(Group, AllocSolution)]Source
sortMGResults :: [(Group, AllocSolution)] -> [(Group, AllocSolution)]Source
filterValidGroups :: [(Group, (List, List))] -> Instance -> ([(Group, (List, List))], [String])Source
findBestAllocGroup :: List -> List -> List -> Maybe [Gdx] -> Instance -> Int -> Result (Group, AllocSolution, [String])Source
:: List | The group list |
-> List | The node list |
-> List | The instance list |
-> Instance | The instance to allocate |
-> Int | Required number of nodes |
-> Result AllocSolution | Possible solution list |
Try to allocate an instance on a multi-group cluster.
updateIl :: List -> Maybe AllocElement -> ListSource
extractNl :: List -> Maybe AllocElement -> ListSource
:: List | The group list |
-> List | The node list |
-> List | The instance list |
-> [(Instance, Int)] | The instance to allocate |
-> AllocSolutionList | Possible solution list |
-> Result (List, List, AllocSolutionList) | The final solution list |
Try to allocate a list of instances on a multi-group cluster.
failOnSecondaryChange :: Monad m => EvacMode -> DiskTemplate -> m ()Source
nodeEvacInstance :: List -> List -> EvacMode -> Instance -> Gdx -> [Ndx] -> Result (List, List, [OpCode])Source
evacOneNodeInner :: List -> Instance -> Gdx -> (Ndx -> IMove) -> EvacInnerState -> Ndx -> EvacInnerStateSource
evacDrbdAllInner :: List -> List -> Instance -> Gdx -> (Ndx, Ndx) -> Result (List, List, [OpCode], Score)Source
updateEvacSolution :: (List, List, EvacSolution) -> Idx -> Result (List, List, [OpCode]) -> (List, List, EvacSolution)Source
:: List | The cluster groups |
-> List | The node list (cluster-wide, not per group) |
-> List | Instance list (cluster-wide) |
-> EvacMode | The evacuation mode |
-> [Idx] | List of instance (indices) to be evacuated |
-> Result (List, List, EvacSolution) |
Node-evacuation IAllocator mode main function.
:: List | The cluster groups |
-> List | The node list (cluster-wide) |
-> List | Instance list (cluster-wide) |
-> [Gdx] | Target groups; if empty, any groups not being evacuated |
-> [Idx] | List of instance (indices) to be evacuated |
-> Result (List, List, EvacSolution) |
Change-group IAllocator mode main function.
This is very similar to tryNodeEvac
, the only difference is that
we don't choose as target group the current instance group, but
instead:
- at the start of the function, we compute which are the target groups; either no groups were passed in, in which case we choose all groups out of which we don't evacuate instance, or there were some groups passed, in which case we use those
- for each instance, we use
findBestAllocGroup
to choose the best group to hold the instance, and then we do whattryNodeEvac
does, except for this group instead of the current instance group.
Note that the correct behaviour of this function relies on the
function nodeEvacInstance
to be able to do correctly both
intra-group and inter-group moves when passed the ChangeAll
mode.
iterateAlloc :: AllocMethodSource
Standard-sized allocation method.
This places instances of the same size on the cluster until we're out of space. The result will be a list of identically-sized instances.
sufficesShrinking :: (Instance -> AllocSolution) -> Instance -> FailMode -> Maybe InstanceSource
tieredAlloc :: AllocMethodSource
Tiered allocation method.
This places instances on the cluster, and decreases the spec until we can allocate again. The result will be a list of decreasing instance specs.
Formatting functions
computeMoves :: Instance -> String -> IMove -> String -> String -> (String, [String])Source
:: List | The node list |
-> List | The instance list |
-> Int | Maximum node name length |
-> Int | Maximum instance name length |
-> Placement | The current placement |
-> Int | The index of the placement in the solution |
-> (String, [String]) |
Converts a placement to string format.
:: List | Instance list, used for retrieving the instance from its index; note that this must be the original instance list, so that we can retrieve the old nodes |
-> Placement | The placement we're investigating, containing the new nodes and instance index |
-> [Ndx] | Resulting list of node indices |
Return the instance and involved nodes in an instance move.
Note that the output list length can vary, and is not required nor guaranteed to be of any specific length.
splitJobs :: [MoveJob] -> [JobSet]Source
Break a list of moves into independent groups. Note that this will reverse the order of jobs.
formatCmds :: [JobSet] -> StringSource
Given a list of commands, prefix them with gnt-instance
and
also beautify the display a little.
printNodes :: List -> [String] -> StringSource
Print the node list.
printInsts :: List -> List -> StringSource
Print the instance list.
printStats :: String -> List -> StringSource
Shows statistics for a given node list.
:: List | The node list; only used for node names, so any version is good (before or after the operation) |
-> List | The instance list; also used for names only |
-> Idx | The index of the instance being moved |
-> IMove | The actual move to be described |
-> [OpCode] | The list of opcodes equivalent to the given move |
Convert a placement into a list of OpCodes (basically a job).
Node group functions
instancePriGroup :: List -> Instance -> GdxSource
findSplitInstances :: List -> List -> [Instance]Source
Compute the list of badly allocated instances (split across node groups).
splitCluster :: List -> List -> [(Gdx, (List, List))]Source
Splits a cluster into the component node groups.
nodesToEvacuate :: List -> EvacMode -> [Idx] -> IntSetSource