Generalise the node/instance listing
[ganeti-local] / Ganeti / HTools / Cluster.hs
index ccc516a..ab21b32 100644 (file)
@@ -41,9 +41,11 @@ module Ganeti.HTools.Cluster
     , printSolution
     , printSolutionLine
     , formatCmds
-    , printNodes
     , involvedNodes
     , splitJobs
+    -- * Display functions
+    , printNodes
+    , printInsts
     -- * Balacing functions
     , checkMove
     , tryBalance
@@ -196,6 +198,10 @@ detailedCVNames = [ "free_mem_cv"
                   , "reserved_mem_cv"
                   , "offline_score"
                   , "vcpu_ratio_cv"
+                  , "cpu_load_cv"
+                  , "mem_load_cv"
+                  , "disk_load_cv"
+                  , "net_load_cv"
                   ]
 
 -- | Compute the mem and disk covariance.
@@ -223,7 +229,15 @@ compDetailedCV nl =
                          fromIntegral (offline_inst + online_inst)::Double
         cpu_l = map Node.pCpu nodes
         cpu_cv = varianceCoeff cpu_l
-    in [mem_cv, dsk_cv, n1_score, res_cv, off_score, cpu_cv]
+        (c_load, m_load, d_load, n_load) = unzip4 $
+            map (\n ->
+                     let DynUtil c1 m1 d1 n1 = Node.utilLoad n
+                         DynUtil c2 m2 d2 n2 = Node.utilPool n
+                     in (c1/c2, m1/m2, d1/d2, n1/n2)
+                ) nodes
+    in [ mem_cv, dsk_cv, n1_score, res_cv, off_score, cpu_cv
+       , varianceCoeff c_load, varianceCoeff m_load
+       , varianceCoeff d_load, varianceCoeff n_load]
 
 -- | Compute the /total/ variance.
 compCV :: Node.List -> Double
@@ -673,16 +687,29 @@ printSolution nl il sol =
 printNodes :: Node.List -> String
 printNodes nl =
     let snl = sortBy (compare `on` Node.idx) (Container.elems nl)
-        m_name = maximum . map (length . Node.name) $ snl
-        helper = Node.list m_name
-        header = printf
-                 "%2s %-*s %5s %5s %5s %5s %5s %5s %5s %5s %4s %4s \
-                 \%3s %3s %6s %6s %5s"
-                 " F" m_name "Name"
-                 "t_mem" "n_mem" "i_mem" "x_mem" "f_mem" "r_mem"
-                 "t_dsk" "f_dsk" "pcpu" "vcpu"
-                 "pri" "sec" "p_fmem" "p_fdsk" "r_cpu"::String
-    in unlines (header:map helper snl)
+        header = ["F", "Name"
+                 , "t_mem", "n_mem", "i_mem", "x_mem", "f_mem", "r_mem"
+                 , "t_dsk", "f_dsk", "pcpu", "vcpu", "pri",  "sec"
+                 , "p_fmem", "p_fdsk", "r_cpu"
+                 , "lCpu", "lMem", "lDsk", "lNet" ]
+        isnum = False:False:repeat True
+    in unlines . map ((:) ' ' .  intercalate " ") $
+       formatTable (header:map Node.list snl) isnum
+
+-- | Print the instance list.
+printInsts :: Node.List -> Instance.List -> String
+printInsts nl il =
+    let sil = sortBy (compare `on` Instance.idx) (Container.elems il)
+        helper inst = [ (Instance.name inst)
+                      , (Container.nameOf nl (Instance.pNode inst))
+                      , (let sdx = Instance.sNode inst
+                         in if sdx == Node.noSecondary
+                            then  ""
+                            else Container.nameOf nl sdx) ]
+        header = ["Name", "Pri_node", "Sec_node"]
+        isnum = repeat False
+    in unlines . map ((:) ' ' . intercalate " ") $
+       formatTable (header:map helper sil) isnum
 
 -- | Shows statistics for a given node list.
 printStats :: Node.List -> String