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