Revision 9f6dcdea Ganeti/HTools/Cluster.hs
b/Ganeti/HTools/Cluster.hs | ||
---|---|---|
104 | 104 |
|
105 | 105 |
-- | Verifies the N+1 status and return the affected nodes. |
106 | 106 |
verifyN1 :: [Node.Node] -> [Node.Node] |
107 |
verifyN1 nl = filter Node.failN1 nl
|
|
107 |
verifyN1 = filter Node.failN1
|
|
108 | 108 |
|
109 | 109 |
{-| Computes the pair of bad nodes and instances. |
110 | 110 |
|
... | ... | |
117 | 117 |
([Node.Node], [Instance.Instance]) |
118 | 118 |
computeBadItems nl il = |
119 | 119 |
let bad_nodes = verifyN1 $ getOnline nl |
120 |
bad_instances = map (\idx -> Container.find idx il) $
|
|
121 |
sort $ nub $ concat $
|
|
122 |
map (\ n -> (Node.slist n) ++ (Node.plist n)) bad_nodes
|
|
120 |
bad_instances = map (\idx -> Container.find idx il) .
|
|
121 |
sort . nub $
|
|
122 |
concatMap (\ n -> Node.slist n ++ Node.plist n) bad_nodes
|
|
123 | 123 |
in |
124 | 124 |
(bad_nodes, bad_instances) |
125 | 125 |
|
... | ... | |
140 | 140 |
cs_amem = x_amem, cs_acpu = x_acpu, cs_adsk = x_adsk, |
141 | 141 |
cs_mmem = x_mmem, cs_mdsk = x_mdsk, cs_mcpu = x_mcpu } |
142 | 142 |
= cs |
143 |
inc_amem = (Node.f_mem node) - (Node.r_mem node)
|
|
143 |
inc_amem = Node.f_mem node - Node.r_mem node
|
|
144 | 144 |
inc_amem' = if inc_amem > 0 then inc_amem else 0 |
145 | 145 |
inc_adsk = Node.availDisk node |
146 |
in CStats { cs_fmem = x_fmem + (Node.f_mem node)
|
|
147 |
, cs_fdsk = x_fdsk + (Node.f_dsk node)
|
|
146 |
in CStats { cs_fmem = x_fmem + Node.f_mem node
|
|
147 |
, cs_fdsk = x_fdsk + Node.f_dsk node
|
|
148 | 148 |
, cs_amem = x_amem + inc_amem' |
149 | 149 |
, cs_adsk = x_adsk + inc_adsk |
150 | 150 |
, cs_acpu = x_acpu |
... | ... | |
168 | 168 |
mem_cv = varianceCoeff mem_l |
169 | 169 |
dsk_cv = varianceCoeff dsk_l |
170 | 170 |
n1_l = length $ filter Node.failN1 nodes |
171 |
n1_score = ((fromIntegral n1_l) /
|
|
172 |
(fromIntegral $ length nodes))::Double
|
|
171 |
n1_score = fromIntegral n1_l /
|
|
172 |
fromIntegral (length nodes)::Double
|
|
173 | 173 |
res_l = map Node.p_rem nodes |
174 | 174 |
res_cv = varianceCoeff res_l |
175 | 175 |
offline_inst = sum . map (\n -> (length . Node.plist $ n) + |
176 | 176 |
(length . Node.slist $ n)) $ offline |
177 | 177 |
online_inst = sum . map (\n -> (length . Node.plist $ n) + |
178 | 178 |
(length . Node.slist $ n)) $ nodes |
179 |
off_score = ((fromIntegral offline_inst) /
|
|
180 |
(fromIntegral $ online_inst + offline_inst))::Double
|
|
179 |
off_score = fromIntegral offline_inst /
|
|
180 |
fromIntegral (online_inst + offline_inst)::Double
|
|
181 | 181 |
cpu_l = map Node.p_cpu nodes |
182 | 182 |
cpu_cv = varianceCoeff cpu_l |
183 | 183 |
in (mem_cv, dsk_cv, n1_score, res_cv, off_score, cpu_cv) |
... | ... | |
233 | 233 |
let tmp_s' = Node.removePri tmp_s inst |
234 | 234 |
new_p <- Node.addPri tgt_n inst |
235 | 235 |
new_s <- Node.addSec tmp_s' inst new_pdx |
236 |
return $ Container.add new_pdx new_p $
|
|
236 |
return . Container.add new_pdx new_p $
|
|
237 | 237 |
Container.addTwo old_pdx int_p old_sdx new_s nl |
238 | 238 |
in (new_nl, Instance.setPri inst new_pdx, new_pdx, old_sdx) |
239 | 239 |
|
... | ... | |
261 | 261 |
new_nl = do -- Maybe monad |
262 | 262 |
new_p <- Node.addPri tgt_n inst |
263 | 263 |
new_s <- Node.addSec int_p inst new_pdx |
264 |
return $ Container.add new_pdx new_p $
|
|
264 |
return . Container.add new_pdx new_p $
|
|
265 | 265 |
Container.addTwo old_pdx new_s old_sdx int_s nl |
266 | 266 |
in (new_nl, Instance.setBoth inst new_pdx old_pdx, new_pdx, old_pdx) |
267 | 267 |
|
... | ... | |
277 | 277 |
new_nl = do -- Maybe monad |
278 | 278 |
new_p <- Node.addPri int_s inst |
279 | 279 |
new_s <- Node.addSec tgt_n inst old_sdx |
280 |
return $ Container.add new_sdx new_s $
|
|
280 |
return . Container.add new_sdx new_s $
|
|
281 | 281 |
Container.addTwo old_sdx new_p old_pdx int_p nl |
282 | 282 |
in (new_nl, Instance.setBoth inst old_sdx new_sdx, old_sdx, new_sdx) |
283 | 283 |
|
... | ... | |
406 | 406 |
in return sols |
407 | 407 |
|
408 | 408 |
tryAlloc _ _ _ reqn = fail $ "Unsupported number of alllocation \ |
409 |
\destinations required (" ++ (show reqn) ++
|
|
409 |
\destinations required (" ++ show reqn ++
|
|
410 | 410 |
"), only two supported" |
411 | 411 |
|
412 | 412 |
-- | Try to allocate an instance on the cluster. |
... | ... | |
420 | 420 |
tryReloc nl il xid 1 ex_idx = |
421 | 421 |
let all_nodes = getOnline nl |
422 | 422 |
inst = Container.find xid il |
423 |
ex_idx' = (Instance.pnode inst):ex_idx
|
|
423 |
ex_idx' = Instance.pnode inst:ex_idx
|
|
424 | 424 |
valid_nodes = filter (not . flip elem ex_idx' . Node.idx) all_nodes |
425 | 425 |
valid_idxes = map Node.idx valid_nodes |
426 | 426 |
sols1 = map (\x -> let (mnl, i, _, _) = |
... | ... | |
430 | 430 |
in return sols1 |
431 | 431 |
|
432 | 432 |
tryReloc _ _ _ reqn _ = fail $ "Unsupported number of relocation \ |
433 |
\destinations required (" ++ (show reqn) ++
|
|
433 |
\destinations required (" ++ show reqn ++
|
|
434 | 434 |
"), only one supported" |
435 | 435 |
|
436 | 436 |
-- * Formatting functions |
... | ... | |
499 | 499 |
opri = Container.nameOf nl $ Instance.pnode inst |
500 | 500 |
osec = Container.nameOf nl $ Instance.snode inst |
501 | 501 |
(moves, cmds) = computeMoves inam opri osec npri nsec |
502 |
ostr = (printf "%s:%s" opri osec)::String
|
|
503 |
nstr = (printf "%s:%s" npri nsec)::String
|
|
502 |
ostr = printf "%s:%s" opri osec::String
|
|
503 |
nstr = printf "%s:%s" npri nsec::String
|
|
504 | 504 |
in |
505 | 505 |
(printf " %3d. %-*s %-*s => %-*s %.8f a=%s" |
506 | 506 |
pos imlen inam pmlen ostr |
... | ... | |
510 | 510 |
-- | Given a list of commands, prefix them with @gnt-instance@ and |
511 | 511 |
-- also beautify the display a little. |
512 | 512 |
formatCmds :: [[String]] -> String |
513 |
formatCmds cmd_strs = |
|
514 |
unlines $ |
|
515 |
concat $ map (\(a, b) -> |
|
516 |
(printf "echo step %d" (a::Int)): |
|
517 |
(printf "check"): |
|
518 |
(map ("gnt-instance " ++) b)) $ |
|
519 |
zip [1..] cmd_strs |
|
513 |
formatCmds = |
|
514 |
unlines . |
|
515 |
concatMap (\(a, b) -> |
|
516 |
printf "echo step %d" (a::Int): |
|
517 |
printf "check": |
|
518 |
map ("gnt-instance " ++) b |
|
519 |
) . |
|
520 |
zip [1..] |
|
520 | 521 |
|
521 | 522 |
-- | Converts a solution to string format. |
522 | 523 |
printSolution :: Node.List |
... | ... | |
528 | 529 |
nmlen = Container.maxNameLen nl |
529 | 530 |
imlen = Container.maxNameLen il |
530 | 531 |
in |
531 |
unzip $ map (uncurry $ printSolutionLine nl il nmlen imlen) $ |
|
532 |
zip sol [1..] |
|
532 |
unzip $ zipWith (printSolutionLine nl il nmlen imlen) sol [1..] |
|
533 | 533 |
|
534 | 534 |
-- | Print the node list. |
535 | 535 |
printNodes :: Node.List -> String |
... | ... | |
537 | 537 |
let snl = sortBy (compare `on` Node.idx) (Container.elems nl) |
538 | 538 |
m_name = maximum . map (length . Node.name) $ snl |
539 | 539 |
helper = Node.list m_name |
540 |
header = (printf
|
|
541 |
"%2s %-*s %5s %5s %5s %5s %5s %5s %5s %5s %4s %4s \
|
|
542 |
\%3s %3s %6s %6s %5s"
|
|
543 |
" F" m_name "Name"
|
|
544 |
"t_mem" "n_mem" "i_mem" "x_mem" "f_mem" "r_mem"
|
|
545 |
"t_dsk" "f_dsk" "pcpu" "vcpu"
|
|
546 |
"pri" "sec" "p_fmem" "p_fdsk" "r_cpu")::String
|
|
547 |
in unlines $ (header:map helper snl)
|
|
540 |
header = printf |
|
541 |
"%2s %-*s %5s %5s %5s %5s %5s %5s %5s %5s %4s %4s \ |
|
542 |
\%3s %3s %6s %6s %5s" |
|
543 |
" F" m_name "Name" |
|
544 |
"t_mem" "n_mem" "i_mem" "x_mem" "f_mem" "r_mem" |
|
545 |
"t_dsk" "f_dsk" "pcpu" "vcpu" |
|
546 |
"pri" "sec" "p_fmem" "p_fdsk" "r_cpu"::String
|
|
547 |
in unlines (header:map helper snl) |
|
548 | 548 |
|
549 | 549 |
-- | Shows statistics for a given node list. |
550 | 550 |
printStats :: Node.List -> String |
Also available in: Unified diff