Safe HaskellSafe-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 Source

Allocation/relocation solution.




asFailures :: [FailMode]

Failure counts

asAllocs :: Int

Good allocation count

asSolution :: Maybe AllocElement

The actual allocation result

asLog :: [String]

Informational messages

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.




esMoved :: [(Idx, Gdx, [Ndx])]

Instances moved successfully

esFailed :: [(Idx, String)]

Instances which were not relocated

esOpCodes :: [[OpCode]]

List of jobs


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 [Ndx], whereas for a two-node allocation, this will be a Right [(Ndx, [Ndx])]. 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.

data Table Source

The complete state for the balancing solution.


Table List List Score [Placement] 


Show Table 

data CStats Source

Cluster statistics data type.




csFmem :: Integer

Cluster free mem

csFdsk :: Integer

Cluster free disk

csFspn :: Integer

Cluster free spindles

csAmem :: Integer

Cluster allocatable mem

csAdsk :: Integer

Cluster allocatable disk

csAcpu :: Integer

Cluster allocatable cpus

csMmem :: Integer

Max node allocatable mem

csMdsk :: Integer

Max node allocatable disk

csMcpu :: Integer

Max node allocatable cpu

csImem :: Integer

Instance used mem

csIdsk :: Integer

Instance used disk

csIspn :: Integer

Instance used spindles

csIcpu :: Integer

Instance used cpu

csTmem :: Double

Cluster total mem

csTdsk :: Double

Cluster total disk

csTspn :: Double

Cluster total spindles

csTcpu :: Double

Cluster total cpus

csVcpu :: Integer

Cluster total virtual cpus

csNcpu :: Double

Equivalent to csIcpu but in terms of physical CPUs, i.e. normalised used phys CPUs

csXmem :: Integer

Unnacounted for mem

csNmem :: Integer

Node own memory

csScore :: Score

The cluster score

csNinst :: Int

The total number of instances


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.

type EvacInnerState = Either String (List, Instance, Score, Ndx)Source

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.

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.

detailedCVInfoExt :: [((Double, String), ([Double] -> Statistics, Bool))]Source

detailedCVInfo :: [(Double, String)]Source

detailedCVAggregation :: [([Double] -> Statistics, Bool)]Source

compDetailedCV :: [Node] -> [Double]Source

Compute cluster statistics

compCVNodes :: [Node] -> DoubleSource

Compute the total variance.

compCV :: List -> DoubleSource

Wrapper over compCVNodes for callers that have a List.

Balancing functions

possibleMoves :: MirrorType -> Bool -> Bool -> (Bool, Bool) -> Ndx -> [IMove]Source

checkInstanceMove :: [Ndx] -> Bool -> Bool -> Bool -> Table -> Instance -> TableSource



:: [Ndx]

Allowed target node indices

-> Bool

Whether disk moves are allowed

-> Bool

Whether instance moves are allowed

-> Bool

Whether migration is restricted

-> 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

-> Bool

Restrict migration

-> 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.



:: 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.

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.



:: 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.

availableGroupNodes :: [(Gdx, [Ndx])] -> IntSet -> Gdx -> Result [Ndx]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:

  1. 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
  2. for each instance, we use findBestAllocGroup to choose the best group to hold the instance, and then we do what tryNodeEvac 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.

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.

getMoves :: (Table, Table) -> [MoveJob]Source

From two adjacent cluster tables get the list of moves that transitions from to the other

mergeJobs :: ([JobSet], [Ndx]) -> MoveJob -> ([JobSet], [Ndx])Source

splitJobs :: [MoveJob] -> [JobSet]Source

Break a list of moves into independent groups. Note that this will reverse the order of jobs.

formatJob :: Int -> Int -> (Int, MoveJob) -> [String]Source

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

instanceGroup :: List -> Instance -> Result GdxSource

Computes the group of an instance.

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