Revision 81bcbbd3 htools/Ganeti/HTools/Program/Hcheck.hs
b/htools/Ganeti/HTools/Program/Hcheck.hs | ||
---|---|---|
150 | 150 |
printBool True False = "0" |
151 | 151 |
printBool False b = show b |
152 | 152 |
|
153 |
-- | Print mapping from group idx to group uuid (only in machine readable mode). |
|
153 |
-- | Print mapping from group idx to group uuid (only in machine |
|
154 |
-- readable mode). |
|
154 | 155 |
printGroupsMappings :: Group.List -> IO () |
155 | 156 |
printGroupsMappings gl = do |
156 | 157 |
let extract_vals = \g -> (printf "GROUP_UUID_%d" $ Group.idx g :: String, |
157 |
printf "%s" $ Group.uuid g :: String)
|
|
158 |
Group.uuid g)
|
|
158 | 159 |
printpairs = map extract_vals (Container.elems gl) |
159 | 160 |
printKeysHTC printpairs |
160 | 161 |
|
... | ... | |
186 | 187 |
|
187 | 188 |
-- | Extract name or idx from group. |
188 | 189 |
extractGroupData :: Bool -> Group.Group -> String |
189 |
extractGroupData True grp = printf "%d" $ Group.idx grp
|
|
190 |
extractGroupData True grp = show $ Group.idx grp
|
|
190 | 191 |
extractGroupData False grp = Group.name grp |
191 | 192 |
|
192 | 193 |
-- | Prepare values for group. |
193 | 194 |
prepareGroupValues :: [Int] -> Double -> [String] |
194 | 195 |
prepareGroupValues stats score = |
195 |
map (printf "%d") stats ++ [printf "%.8f" score]
|
|
196 |
map show stats ++ [printf "%.8f" score]
|
|
196 | 197 |
|
197 | 198 |
-- | Prepare values for cluster. |
198 | 199 |
prepareClusterValues :: Bool -> [Int] -> [Bool] -> [String] |
199 | 200 |
prepareClusterValues machineread stats bstats = |
200 |
map (printf "%d") stats ++ map (printBool machineread) bstats
|
|
201 |
map show stats ++ map (printBool machineread) bstats
|
|
201 | 202 |
|
202 | 203 |
-- | Print all the statistics on a group level. |
203 | 204 |
printGroupStats :: Int -> Bool -> Phase -> Group.Group -> [Int] -> Double |
... | ... | |
221 | 222 |
instances residing on offline nodes. |
222 | 223 |
|
223 | 224 |
-} |
224 |
perGroupChecks :: Int -> Bool -> Phase -> Group.List ->
|
|
225 |
(Gdx, (Node.List, Instance.List)) -> IO ([Int])
|
|
225 |
perGroupChecks :: Int -> Bool -> Phase -> Group.List |
|
226 |
-> (Gdx, (Node.List, Instance.List)) -> IO ([Int])
|
|
226 | 227 |
perGroupChecks verbose machineread phase gl (gidx, (nl, il)) = do |
227 | 228 |
let grp = Container.find gidx gl |
228 | 229 |
offnl = filter Node.offline (Container.elems nl) |
... | ... | |
241 | 242 |
return groupstats |
242 | 243 |
|
243 | 244 |
-- | Use Hbal's iterateDepth to simulate group rebalance. |
244 |
executeSimulation :: Options -> Cluster.Table -> Double ->
|
|
245 |
Gdx -> Node.List -> Instance.List ->
|
|
246 |
IO ( (Gdx, (Node.List, Instance.List)) )
|
|
245 |
executeSimulation :: Options -> Cluster.Table -> Double |
|
246 |
-> Gdx -> Node.List -> Instance.List
|
|
247 |
-> IO (Gdx, (Node.List, Instance.List))
|
|
247 | 248 |
executeSimulation opts ini_tbl min_cv gidx nl il = do |
248 | 249 |
let imlen = maximum . map (length . Instance.alias) $ Container.elems il |
249 | 250 |
nmlen = maximum . map (length . Node.alias) $ Container.elems nl |
... | ... | |
261 | 262 |
|
262 | 263 |
-- | Simulate group rebalance if group's score is not good |
263 | 264 |
maybeSimulateGroupRebalance :: Options -> (Gdx, (Node.List, Instance.List)) |
264 |
-> IO ((Gdx, (Node.List, Instance.List)))
|
|
265 |
-> IO (Gdx, (Node.List, Instance.List))
|
|
265 | 266 |
maybeSimulateGroupRebalance opts (gidx, (nl, il)) = do |
266 | 267 |
let ini_cv = Cluster.compCV nl |
267 | 268 |
ini_tbl = Cluster.Table nl il ini_cv [] |
268 | 269 |
min_cv = optMinScore opts |
269 |
if (ini_cv < min_cv)
|
|
270 |
if ini_cv < min_cv
|
|
270 | 271 |
then return (gidx, (nl, il)) |
271 | 272 |
else executeSimulation opts ini_tbl min_cv gidx nl il |
272 | 273 |
|
... | ... | |
274 | 275 |
maybeSimulateRebalance :: Bool -- ^ Whether to simulate rebalance |
275 | 276 |
-> Options -- ^ Command line options |
276 | 277 |
-> [(Gdx, (Node.List, Instance.List))] -- ^ Group data |
277 |
-> IO([(Gdx, (Node.List, Instance.List))])
|
|
278 |
-> IO [(Gdx, (Node.List, Instance.List))]
|
|
278 | 279 |
maybeSimulateRebalance True opts cluster = |
279 | 280 |
mapM (maybeSimulateGroupRebalance opts) cluster |
280 | 281 |
maybeSimulateRebalance False _ cluster = return cluster |
... | ... | |
302 | 303 |
|
303 | 304 |
when machineread $ printGroupsMappings gl |
304 | 305 |
|
305 |
groupsstats <- mapM (perGroupChecks verbose machineread Initial gl) splitcluster |
|
306 |
groupsstats <- mapM (perGroupChecks verbose machineread Initial gl) |
|
307 |
splitcluster |
|
306 | 308 |
let clusterstats = map sum (transpose groupsstats) :: [Int] |
307 | 309 |
needrebalance = clusterNeedsRebalance clusterstats |
308 | 310 |
canrebalance = length splitinstances == 0 |
... | ... | |
311 | 313 |
|
312 | 314 |
when nosimulation $ do |
313 | 315 |
unless (verbose == 0 || machineread) $ |
314 |
printf "Running in no-simulation mode. Exiting.\n"
|
|
316 |
putStrLn "Running in no-simulation mode. Exiting."
|
|
315 | 317 |
|
316 | 318 |
when (length splitinstances > 0) $ do |
317 | 319 |
unless (verbose == 0 || machineread) $ |
318 |
printf "Split instances found, simulation of re-balancing not possible\n" |
|
320 |
putStrLn "Split instances found, simulation of re-balancing\ |
|
321 |
\ not possible" |
|
319 | 322 |
|
320 | 323 |
unless needrebalance $ do |
321 | 324 |
unless (verbose == 0 || machineread) $ |
322 |
printf "No need to rebalance cluster, no problems found. Exiting.\n"
|
|
325 |
putStrLn "No need to rebalance cluster, no problems found. Exiting."
|
|
323 | 326 |
|
324 | 327 |
let exitOK = nosimulation || not needrebalance |
325 |
simulate = not nosimulation && length splitinstances == 0 && needrebalance |
|
328 |
simulate = not nosimulation && length splitinstances == 0 |
|
329 |
&& needrebalance |
|
326 | 330 |
|
327 | 331 |
rebalancedcluster <- maybeSimulateRebalance simulate opts splitcluster |
328 | 332 |
|
Also available in: Unified diff