Revision 608efcce
b/Ganeti/HTools/Cluster.hs | ||
---|---|---|
52 | 52 |
type Score = Double |
53 | 53 |
|
54 | 54 |
-- | The description of an instance placement. |
55 |
type Placement = (Int, Int, Int, Score)
|
|
55 |
type Placement = (Idx, Ndx, Ndx, Score)
|
|
56 | 56 |
|
57 | 57 |
{- | A cluster solution described as the solution delta and the list |
58 | 58 |
of placements. |
... | ... | |
72 | 72 |
|
73 | 73 |
-- | An instance move definition |
74 | 74 |
data IMove = Failover -- ^ Failover the instance (f) |
75 |
| ReplacePrimary Int -- ^ Replace primary (f, r:np, f)
|
|
76 |
| ReplaceSecondary Int -- ^ Replace secondary (r:ns)
|
|
77 |
| ReplaceAndFailover Int -- ^ Replace secondary, failover (r:np, f)
|
|
78 |
| FailoverAndReplace Int -- ^ Failover, replace secondary (f, r:ns)
|
|
75 |
| ReplacePrimary Ndx -- ^ Replace primary (f, r:np, f)
|
|
76 |
| ReplaceSecondary Ndx -- ^ Replace secondary (r:ns)
|
|
77 |
| ReplaceAndFailover Ndx -- ^ Replace secondary, failover (r:np, f)
|
|
78 |
| FailoverAndReplace Ndx -- ^ Failover, replace secondary (f, r:ns)
|
|
79 | 79 |
deriving (Show) |
80 | 80 |
|
81 | 81 |
-- | The complete state for the balancing solution |
... | ... | |
238 | 238 |
-- Second phase functions |
239 | 239 |
|
240 | 240 |
-- | Single-node relocation cost |
241 |
nodeDelta :: Int -> Int -> Int -> Int
|
|
241 |
nodeDelta :: Ndx -> Ndx -> Ndx -> Int
|
|
242 | 242 |
nodeDelta i p s = |
243 | 243 |
if i == p || i == s then |
244 | 244 |
0 |
... | ... | |
333 | 333 |
|
334 | 334 |
-- | Apply a move |
335 | 335 |
applyMove :: Node.List -> Instance.Instance |
336 |
-> IMove -> (Maybe Node.List, Instance.Instance, Int, Int)
|
|
336 |
-> IMove -> (Maybe Node.List, Instance.Instance, Ndx, Ndx)
|
|
337 | 337 |
-- Failover (f) |
338 | 338 |
applyMove nl inst Failover = |
339 | 339 |
let old_pdx = Instance.pnode inst |
... | ... | |
451 | 451 |
-- | Given the status of the current secondary as a valid new node |
452 | 452 |
-- and the current candidate target node, |
453 | 453 |
-- generate the possible moves for a instance. |
454 |
possibleMoves :: Bool -> Int -> [IMove]
|
|
454 |
possibleMoves :: Bool -> Ndx -> [IMove]
|
|
455 | 455 |
possibleMoves True tdx = |
456 | 456 |
[ReplaceSecondary tdx, |
457 | 457 |
ReplaceAndFailover tdx, |
... | ... | |
463 | 463 |
ReplaceAndFailover tdx] |
464 | 464 |
|
465 | 465 |
-- | Compute the best move for a given instance. |
466 |
checkInstanceMove :: [Int] -- Allowed target node indices
|
|
466 |
checkInstanceMove :: [Ndx] -- Allowed target node indices
|
|
467 | 467 |
-> Table -- Original table |
468 | 468 |
-> Instance.Instance -- Instance to move |
469 | 469 |
-> Table -- Best new table for this instance |
... | ... | |
482 | 482 |
foldl' (checkSingleStep ini_tbl target) aft_failover all_moves |
483 | 483 |
|
484 | 484 |
-- | Compute the best next move. |
485 |
checkMove :: [Int] -- ^ Allowed target node indices
|
|
485 |
checkMove :: [Ndx] -- ^ Allowed target node indices
|
|
486 | 486 |
-> Table -- ^ The current solution |
487 | 487 |
-> [Instance.Instance] -- ^ List of instances still to move |
488 | 488 |
-> Table -- ^ The new solution |
b/Ganeti/HTools/IAlloc.hs | ||
---|---|---|
26 | 26 |
|
27 | 27 |
data RqType |
28 | 28 |
= Allocate Instance.Instance Int |
29 |
| Relocate Int Int [Int]
|
|
29 |
| Relocate Idx Int [Ndx]
|
|
30 | 30 |
deriving (Show) |
31 | 31 |
|
32 | 32 |
data Request = Request RqType Node.List Instance.List String |
b/Ganeti/HTools/Instance.hs | ||
---|---|---|
15 | 15 |
, running :: Bool -- ^ whether the instance |
16 | 16 |
-- is running |
17 | 17 |
, run_st :: String -- ^ original (text) run status |
18 |
, pnode :: Int -- ^ original primary node
|
|
19 |
, snode :: Int -- ^ original secondary node
|
|
20 |
, idx :: Int -- ^ internal index for
|
|
18 |
, pnode :: T.Ndx -- ^ original primary node
|
|
19 |
, snode :: T.Ndx -- ^ original secondary node
|
|
20 |
, idx :: T.Idx -- ^ internal index for
|
|
21 | 21 |
-- book-keeping |
22 | 22 |
} deriving (Show) |
23 | 23 |
|
... | ... | |
28 | 28 |
setIdx = setIdx |
29 | 29 |
|
30 | 30 |
-- | A simple name for the int, instance association list |
31 |
type AssocList = [(Int, Instance)]
|
|
31 |
type AssocList = [(T.Idx, Instance)]
|
|
32 | 32 |
|
33 | 33 |
-- | A simple name for an instance map |
34 | 34 |
type List = Container.Container Instance |
35 | 35 |
|
36 |
create :: String -> Int -> Int -> String -> Int -> Int -> Instance
|
|
36 |
create :: String -> Int -> Int -> String -> T.Ndx -> T.Ndx -> Instance
|
|
37 | 37 |
create name_init mem_init dsk_init run_init pn sn = |
38 | 38 |
Instance { |
39 | 39 |
name = name_init, |
... | ... | |
51 | 51 |
|
52 | 52 |
-- | Changes the primary node of the instance. |
53 | 53 |
setPri :: Instance -- ^ the original instance |
54 |
-> Int -- ^ the new primary node
|
|
54 |
-> T.Ndx -- ^ the new primary node
|
|
55 | 55 |
-> Instance -- ^ the modified instance |
56 | 56 |
setPri t p = t { pnode = p } |
57 | 57 |
|
58 | 58 |
-- | Changes the secondary node of the instance. |
59 | 59 |
setSec :: Instance -- ^ the original instance |
60 |
-> Int -- ^ the new secondary node
|
|
60 |
-> T.Ndx -- ^ the new secondary node
|
|
61 | 61 |
-> Instance -- ^ the modified instance |
62 | 62 |
setSec t s = t { snode = s } |
63 | 63 |
|
64 | 64 |
-- | Changes both nodes of the instance. |
65 | 65 |
setBoth :: Instance -- ^ the original instance |
66 |
-> Int -- ^ new primary node index
|
|
67 |
-> Int -- ^ new secondary node index
|
|
66 |
-> T.Ndx -- ^ new primary node index
|
|
67 |
-> T.Ndx -- ^ new secondary node index
|
|
68 | 68 |
-> Instance -- ^ the modified instance |
69 | 69 |
setBoth t p s = t { pnode = p, snode = s } |
70 | 70 |
|
71 | 71 |
-- | Changes the index. |
72 | 72 |
-- This is used only during the building of the data structures. |
73 | 73 |
setIdx :: Instance -- ^ the original instance |
74 |
-> Int -- ^ new index
|
|
74 |
-> T.Idx -- ^ new index
|
|
75 | 75 |
-> Instance -- ^ the modified instance |
76 | 76 |
setIdx t i = t { idx = i } |
77 | 77 |
|
b/Ganeti/HTools/Loader.hs | ||
---|---|---|
23 | 23 |
import Ganeti.HTools.Types |
24 | 24 |
|
25 | 25 |
-- | Lookups a node into an assoc list |
26 |
lookupNode :: (Monad m) => NameAssoc -> String -> String -> m Int
|
|
26 |
lookupNode :: (Monad m) => [(String, Ndx)] -> String -> String -> m Ndx
|
|
27 | 27 |
lookupNode ktn inst node = |
28 | 28 |
case lookup node ktn of |
29 | 29 |
Nothing -> fail $ "Unknown node '" ++ node ++ "' for instance " ++ inst |
... | ... | |
37 | 37 |
. zip [0..] |
38 | 38 |
|
39 | 39 |
-- | For each instance, add its index to its primary and secondary nodes |
40 |
fixNodes :: [(Int, Node.Node)]
|
|
41 |
-> [(Int, Instance.Instance)]
|
|
42 |
-> [(Int, Node.Node)]
|
|
40 |
fixNodes :: [(Ndx, Node.Node)]
|
|
41 |
-> [(Idx, Instance.Instance)]
|
|
42 |
-> [(Ndx, Node.Node)]
|
|
43 | 43 |
fixNodes nl il = |
44 | 44 |
foldl' (\accu (idx, inst) -> |
45 | 45 |
let |
b/Ganeti/HTools/Node.hs | ||
---|---|---|
48 | 48 |
, x_mem :: Int -- ^ unaccounted memory (MiB) |
49 | 49 |
, t_dsk :: Double -- ^ total disk space (MiB) |
50 | 50 |
, f_dsk :: Int -- ^ free disk space (MiB) |
51 |
, plist :: [Int] -- ^ list of primary instance indices
|
|
52 |
, slist :: [Int] -- ^ list of secondary instance indices
|
|
53 |
, idx :: Int -- ^ internal index for book-keeping
|
|
51 |
, plist :: [T.Idx]-- ^ list of primary instance indices
|
|
52 |
, slist :: [T.Idx]-- ^ list of secondary instance indices
|
|
53 |
, idx :: T.Ndx -- ^ internal index for book-keeping
|
|
54 | 54 |
, peers :: PeerMap.PeerMap -- ^ pnode to instance mapping |
55 | 55 |
, failN1:: Bool -- ^ whether the node has failed n1 |
56 | 56 |
, r_mem :: Int -- ^ maximum memory needed for |
... | ... | |
70 | 70 |
setIdx = setIdx |
71 | 71 |
|
72 | 72 |
-- | A simple name for the int, node association list |
73 |
type AssocList = [(Int, Node)]
|
|
73 |
type AssocList = [(T.Ndx, Node)]
|
|
74 | 74 |
|
75 | 75 |
-- | A simple name for a node map |
76 | 76 |
type List = Container.Container Node |
77 | 77 |
|
78 | 78 |
-- | Constant node index for a non-moveable instance |
79 |
noSecondary :: Int
|
|
79 |
noSecondary :: T.Ndx
|
|
80 | 80 |
noSecondary = -1 |
81 | 81 |
|
82 | 82 |
{- | Create a new node. |
... | ... | |
111 | 111 |
|
112 | 112 |
-- | Changes the index. |
113 | 113 |
-- This is used only during the building of the data structures. |
114 |
setIdx :: Node -> Int -> Node
|
|
114 |
setIdx :: Node -> T.Ndx -> Node
|
|
115 | 115 |
setIdx t i = t {idx = i} |
116 | 116 |
|
117 | 117 |
-- | Changes the name |
... | ... | |
148 | 148 |
computeMaxRes new_peers = PeerMap.maxElem new_peers |
149 | 149 |
|
150 | 150 |
-- | Builds the peer map for a given node. |
151 |
buildPeers :: Node -> Container.Container Instance.Instance -> Int -> Node
|
|
151 |
buildPeers :: Node -> Instance.List -> Int -> Node
|
|
152 | 152 |
buildPeers t il num_nodes = |
153 | 153 |
let mdata = map |
154 | 154 |
(\i_idx -> let inst = Container.find i_idx il |
... | ... | |
214 | 214 |
failN1 = new_failn1, p_mem = new_mp, p_dsk = new_dp} |
215 | 215 |
|
216 | 216 |
-- | Adds a secondary instance. |
217 |
addSec :: Node -> Instance.Instance -> Int -> Maybe Node
|
|
217 |
addSec :: Node -> Instance.Instance -> T.Ndx -> Maybe Node
|
|
218 | 218 |
addSec t inst pdx = |
219 | 219 |
let iname = Instance.idx inst |
220 | 220 |
old_peers = peers t |
... | ... | |
237 | 237 |
p_rem = new_prem} |
238 | 238 |
|
239 | 239 |
-- | Add a primary instance to a node without other updates |
240 |
setPri :: Node -> Int -> Node
|
|
240 |
setPri :: Node -> T.Idx -> Node
|
|
241 | 241 |
setPri t idx = t { plist = idx:(plist t) } |
242 | 242 |
|
243 | 243 |
-- | Add a secondary instance to a node without other updates |
244 |
setSec :: Node -> Int -> Node
|
|
244 |
setSec :: Node -> T.Idx -> Node
|
|
245 | 245 |
setSec t idx = t { slist = idx:(slist t) } |
246 | 246 |
|
247 | 247 |
-- | String converter for the node list functionality. |
b/Ganeti/HTools/PeerMap.hs | ||
---|---|---|
26 | 26 |
import Data.Function |
27 | 27 |
import Data.Ord |
28 | 28 |
|
29 |
type Key = Int |
|
29 |
import Ganeti.HTools.Types |
|
30 |
|
|
31 |
type Key = Ndx |
|
30 | 32 |
type Elem = Int |
31 | 33 |
type PeerMap = [(Key, Elem)] |
32 | 34 |
|
b/Ganeti/HTools/Rapi.hs | ||
---|---|---|
51 | 51 |
nlist <- mapM parseNode arr |
52 | 52 |
return nlist |
53 | 53 |
|
54 |
parseInstance :: [(String, Int)]
|
|
54 |
parseInstance :: [(String, Ndx)]
|
|
55 | 55 |
-> JSObject JSValue |
56 | 56 |
-> Result (String, Instance.Instance) |
57 | 57 |
parseInstance ktn a = do |
b/Ganeti/HTools/Text.hs | ||
---|---|---|
44 | 44 |
|
45 | 45 |
-- | Load an instance from a field list |
46 | 46 |
loadInst :: (Monad m) => |
47 |
[(String, Int)] -> [String] -> m (String, Instance.Instance)
|
|
47 |
[(String, Ndx)] -> [String] -> m (String, Instance.Instance)
|
|
48 | 48 |
loadInst ktn (name:mem:dsk:status:pnode:snode:[]) = do |
49 | 49 |
pidx <- lookupNode ktn name pnode |
50 | 50 |
sidx <- (if null snode then return Node.noSecondary |
b/Ganeti/HTools/Types.hs | ||
---|---|---|
5 | 5 |
module Ganeti.HTools.Types |
6 | 6 |
where |
7 | 7 |
|
8 |
-- | The instance index type |
|
9 |
type Idx = Int |
|
10 |
|
|
11 |
-- | The node index type |
|
12 |
type Ndx = Int |
|
13 |
|
|
8 | 14 |
-- | The type used to hold idx-to-name mappings |
9 | 15 |
type NameList = [(Int, String)] |
10 | 16 |
|
b/hail.hs | ||
---|---|---|
85 | 85 |
tryReloc :: (Monad m) => |
86 | 86 |
Node.List |
87 | 87 |
-> Instance.List |
88 |
-> Idx |
|
88 | 89 |
-> Int |
89 |
-> Int |
|
90 |
-> [Int] |
|
90 |
-> [Ndx] |
|
91 | 91 |
-> m [(Maybe Node.List, [Node.Node])] |
92 | 92 |
tryReloc nl il xid 1 ex_idx = |
93 | 93 |
let all_nodes = getOnline nl |
94 | 94 |
inst = Container.find xid il |
95 | 95 |
ex_idx' = (Instance.pnode inst):ex_idx |
96 |
valid_nodes = filter (not . flip elem ex_idx' . idxOf) all_nodes
|
|
96 |
valid_nodes = filter (not . flip elem ex_idx' . Node.idx) all_nodes
|
|
97 | 97 |
valid_idxes = map Node.idx valid_nodes |
98 | 98 |
sols1 = map (\x -> let (mnl, _, _, _) = |
99 | 99 |
Cluster.applyMove nl inst |
Also available in: Unified diff