Revision 0cc3d742 src/Ganeti/HTools/Program/Hspace.hs
b/src/Ganeti/HTools/Program/Hspace.hs | ||
---|---|---|
128 | 128 |
cpuEff :: Cluster.CStats -> Double |
129 | 129 |
cpuEff = effFn Cluster.csIcpu (fromIntegral . Cluster.csVcpu) |
130 | 130 |
|
131 |
-- | Spindles efficiency. |
|
132 |
spnEff :: Cluster.CStats -> Double |
|
133 |
spnEff = effFn Cluster.csIspn Cluster.csTspn |
|
134 |
|
|
131 | 135 |
-- | Holds data for converting a 'Cluster.CStats' structure into |
132 | 136 |
-- detailed statistics. |
133 | 137 |
statsData :: [(String, Cluster.CStats -> String)] |
... | ... | |
147 | 151 |
\cs -> printf "%d" (Cluster.csFdsk cs - Cluster.csAdsk cs)) |
148 | 152 |
, ("DSK_INST", printf "%d" . Cluster.csIdsk) |
149 | 153 |
, ("DSK_EFF", printf "%.8f" . dskEff) |
154 |
, ("SPN_FREE", printf "%d" . Cluster.csFspn) |
|
155 |
, ("SPN_INST", printf "%d" . Cluster.csIspn) |
|
156 |
, ("SPN_EFF", printf "%.8f" . spnEff) |
|
150 | 157 |
, ("CPU_INST", printf "%d" . Cluster.csIcpu) |
151 | 158 |
, ("CPU_EFF", printf "%.8f" . cpuEff) |
152 | 159 |
, ("MNODE_MEM_AVAIL", printf "%d" . Cluster.csMmem) |
... | ... | |
160 | 167 |
, ("CPU", printf "%d" . rspecCpu) |
161 | 168 |
] |
162 | 169 |
|
170 |
-- | 'RSpec' formatting information including spindles. |
|
171 |
specDataSpn :: [(String, RSpec -> String)] |
|
172 |
specDataSpn = specData ++ [("SPN", printf "%d" . rspecSpn)] |
|
173 |
|
|
163 | 174 |
-- | List holding 'Cluster.CStats' formatting information. |
164 | 175 |
clusterData :: [(String, Cluster.CStats -> String)] |
165 | 176 |
clusterData = [ ("MEM", printf "%.0f" . Cluster.csTmem) |
... | ... | |
168 | 179 |
, ("VCPU", printf "%d" . Cluster.csVcpu) |
169 | 180 |
] |
170 | 181 |
|
182 |
-- | 'Cluster.CStats' formatting information including spindles |
|
183 |
clusterDataSpn :: [(String, Cluster.CStats -> String)] |
|
184 |
clusterDataSpn = clusterData ++ [("SPN", printf "%.0f" . Cluster.csTspn)] |
|
185 |
|
|
171 | 186 |
-- | Function to print stats for a given phase. |
172 | 187 |
printStats :: Phase -> Cluster.CStats -> [(String, String)] |
173 | 188 |
printStats ph cs = |
... | ... | |
182 | 197 |
printFRScores ini_nl fin_nl sreason = do |
183 | 198 |
printf " - most likely failure reason: %s\n" $ failureReason sreason::IO () |
184 | 199 |
printClusterScores ini_nl fin_nl |
185 |
printClusterEff (Cluster.totalResources fin_nl) |
|
200 |
printClusterEff (Cluster.totalResources fin_nl) (Node.haveExclStorage fin_nl)
|
|
186 | 201 |
|
187 | 202 |
-- | Print final stats and related metrics. |
188 | 203 |
printResults :: Bool -> Node.List -> Node.List -> Int -> Int |
... | ... | |
233 | 248 |
-- | Formats a spec map to strings. |
234 | 249 |
formatSpecMap :: [(RSpec, Int)] -> [String] |
235 | 250 |
formatSpecMap = |
236 |
map (\(spec, cnt) -> printf "%d,%d,%d=%d" (rspecMem spec) |
|
237 |
(rspecDsk spec) (rspecCpu spec) cnt) |
|
251 |
map (\(spec, cnt) -> printf "%d,%d,%d,%d=%d" (rspecMem spec)
|
|
252 |
(rspecDsk spec) (rspecCpu spec) (rspecSpn spec) cnt)
|
|
238 | 253 |
|
239 | 254 |
-- | Formats \"key-metrics\" values. |
240 | 255 |
formatRSpec :: String -> AllocInfo -> [(String, String)] |
... | ... | |
243 | 258 |
, ("KM_" ++ s ++ "_NPU", show $ allocInfoNCpus r) |
244 | 259 |
, ("KM_" ++ s ++ "_MEM", show $ allocInfoMem r) |
245 | 260 |
, ("KM_" ++ s ++ "_DSK", show $ allocInfoDisk r) |
261 |
, ("KM_" ++ s ++ "_SPN", show $ allocInfoSpn r) |
|
246 | 262 |
] |
247 | 263 |
|
248 | 264 |
-- | Shows allocations stats. |
... | ... | |
269 | 285 |
, show (Instance.mem i) |
270 | 286 |
, show (Instance.dsk i) |
271 | 287 |
, show (Instance.vcpus i) |
288 |
, if Node.haveExclStorage nl |
|
289 |
then case Instance.getTotalSpindles i of |
|
290 |
Nothing -> "?" |
|
291 |
Just sp -> show sp |
|
292 |
else "" |
|
272 | 293 |
] |
273 | 294 |
|
274 | 295 |
-- | Optionally print the allocation map. |
... | ... | |
282 | 303 |
-- This is the numberic-or-not field |
283 | 304 |
-- specification; the first three fields are |
284 | 305 |
-- strings, whereas the rest are numeric |
285 |
[False, False, False, True, True, True] |
|
306 |
[False, False, False, True, True, True, True]
|
|
286 | 307 |
|
287 | 308 |
-- | Formats nicely a list of resources. |
288 | 309 |
formatResources :: a -> [(String, a->String)] -> String |
... | ... | |
290 | 311 |
intercalate ", " . map (\(a, fn) -> a ++ " " ++ fn res) |
291 | 312 |
|
292 | 313 |
-- | Print the cluster resources. |
293 |
printCluster :: Bool -> Cluster.CStats -> Int -> IO () |
|
294 |
printCluster True ini_stats node_count = do |
|
295 |
printKeysHTS $ map (\(a, fn) -> ("CLUSTER_" ++ a, fn ini_stats)) clusterData |
|
314 |
printCluster :: Bool -> Cluster.CStats -> Int -> Bool -> IO () |
|
315 |
printCluster True ini_stats node_count _ = do |
|
316 |
printKeysHTS $ map (\(a, fn) -> ("CLUSTER_" ++ a, fn ini_stats)) |
|
317 |
clusterDataSpn |
|
296 | 318 |
printKeysHTS [("CLUSTER_NODES", printf "%d" node_count)] |
297 | 319 |
printKeysHTS $ printStats PInitial ini_stats |
298 | 320 |
|
299 |
printCluster False ini_stats node_count = do |
|
321 |
printCluster False ini_stats node_count print_spn = do |
|
322 |
let cldata = if print_spn then clusterDataSpn else clusterData |
|
300 | 323 |
printf "The cluster has %d nodes and the following resources:\n %s.\n" |
301 |
node_count (formatResources ini_stats clusterData)::IO ()
|
|
324 |
node_count (formatResources ini_stats cldata)::IO ()
|
|
302 | 325 |
printf "There are %s initial instances on the cluster.\n" |
303 | 326 |
(if inst_count > 0 then show inst_count else "no" ) |
304 | 327 |
where inst_count = Cluster.csNinst ini_stats |
305 | 328 |
|
306 | 329 |
-- | Prints the normal instance spec. |
307 |
printISpec :: Bool -> RSpec -> SpecType -> DiskTemplate -> IO () |
|
308 |
printISpec True ispec spec disk_template = do |
|
309 |
printKeysHTS $ map (\(a, fn) -> (prefix ++ "_" ++ a, fn ispec)) specData |
|
330 |
printISpec :: Bool -> RSpec -> SpecType -> DiskTemplate -> Bool -> IO ()
|
|
331 |
printISpec True ispec spec disk_template _ = do
|
|
332 |
printKeysHTS $ map (\(a, fn) -> (prefix ++ "_" ++ a, fn ispec)) specDataSpn
|
|
310 | 333 |
printKeysHTS [ (prefix ++ "_RQN", printf "%d" req_nodes) ] |
311 | 334 |
printKeysHTS [ (prefix ++ "_DISK_TEMPLATE", |
312 | 335 |
diskTemplateToRaw disk_template) ] |
313 | 336 |
where req_nodes = Instance.requiredNodes disk_template |
314 | 337 |
prefix = specPrefix spec |
315 | 338 |
|
316 |
printISpec False ispec spec disk_template = |
|
317 |
printf "%s instance spec is:\n %s, using disk\ |
|
318 |
\ template '%s'.\n" |
|
319 |
(specDescription spec) |
|
320 |
(formatResources ispec specData) (diskTemplateToRaw disk_template) |
|
339 |
printISpec False ispec spec disk_template print_spn = |
|
340 |
let spdata = if print_spn then specDataSpn else specData |
|
341 |
in printf "%s instance spec is:\n %s, using disk\ |
|
342 |
\ template '%s'.\n" |
|
343 |
(specDescription spec) |
|
344 |
(formatResources ispec spdata) (diskTemplateToRaw disk_template) |
|
321 | 345 |
|
322 | 346 |
-- | Prints the tiered results. |
323 | 347 |
printTiered :: Bool -> [(RSpec, Int)] |
... | ... | |
329 | 353 |
|
330 | 354 |
printTiered False spec_map ini_nl fin_nl sreason = do |
331 | 355 |
_ <- printf "Tiered allocation results:\n" |
356 |
let spdata = if Node.haveExclStorage ini_nl then specDataSpn else specData |
|
332 | 357 |
if null spec_map |
333 | 358 |
then putStrLn " - no instances allocated" |
334 | 359 |
else mapM_ (\(ispec, cnt) -> |
335 | 360 |
printf " - %3d instances of spec %s\n" cnt |
336 |
(formatResources ispec specData)) spec_map
|
|
361 |
(formatResources ispec spdata)) spec_map
|
|
337 | 362 |
printFRScores ini_nl fin_nl sreason |
338 | 363 |
|
339 | 364 |
-- | Displays the initial/final cluster scores. |
... | ... | |
343 | 368 |
printf " - final cluster score: %.8f\n" $ Cluster.compCV fin_nl |
344 | 369 |
|
345 | 370 |
-- | Displays the cluster efficiency. |
346 |
printClusterEff :: Cluster.CStats -> IO () |
|
347 |
printClusterEff cs = |
|
371 |
printClusterEff :: Cluster.CStats -> Bool -> IO () |
|
372 |
printClusterEff cs print_spn = do |
|
373 |
let format = [("memory", memEff), |
|
374 |
("disk", dskEff), |
|
375 |
("vcpu", cpuEff)] ++ |
|
376 |
[("spindles", spnEff) | print_spn] |
|
377 |
len = maximum $ map (length . fst) format |
|
348 | 378 |
mapM_ (\(s, fn) -> |
349 |
printf " - %s usage efficiency: %5.2f%%\n" s (fn cs * 100)) |
|
350 |
[("memory", memEff), |
|
351 |
(" disk", dskEff), |
|
352 |
(" vcpu", cpuEff)] |
|
379 |
printf " - %*s usage efficiency: %5.2f%%\n" len s (fn cs * 100)) |
|
380 |
format |
|
353 | 381 |
|
354 | 382 |
-- | Computes the most likely failure reason. |
355 | 383 |
failureReason :: [(FailMode, Int)] -> String |
... | ... | |
377 | 405 |
let name = specName mode |
378 | 406 |
descr = name ++ " allocation" |
379 | 407 |
ldescr = "after " ++ map toLower descr |
408 |
excstor = Node.haveExclStorage new_nl |
|
380 | 409 |
|
381 |
printISpec (optMachineReadable opts) spec mode dt |
|
410 |
printISpec (optMachineReadable opts) spec mode dt excstor
|
|
382 | 411 |
|
383 | 412 |
printAllocationMap (optVerbose opts) descr new_nl new_ixes |
384 | 413 |
|
... | ... | |
446 | 475 |
(Cluster.compCV nl) (Cluster.printStats " " nl) |
447 | 476 |
|
448 | 477 |
printCluster machine_r (Cluster.totalResources nl) (length all_nodes) |
478 |
(Node.haveExclStorage nl) |
|
449 | 479 |
|
450 | 480 |
let stop_allocation = case Cluster.computeBadItems nl il of |
451 | 481 |
([], _) -> Nothing |
Also available in: Unified diff