Commit 2922d2c5 authored by René Nussbaumer's avatar René Nussbaumer
Browse files

hinfo: Adding basic skeleton based on hbal



It prints the information which hbal prints in a nice formatted manner and of
course without doing any actions. An example output looks like this:

$ hinfo -m xen.example.com
Loaded 4 nodes, 2 instances
Cluster has 1 node group(s)
Cluster coefficients:
   Field                Value Weight
   free_mem_cv     0.00195342  x1.00
   free_disk_cv    0.00000000  x1.00
   n1_cnt          0.00000000  x1.00
   reserved_mem_cv 0.00195342  x1.00
   offline_all_cnt 0.00000000  x4.00
   offline_pri_cnt 0.00000000 x16.00
   vcpu_ratio_cv   0.12500000  x1.00
   cpu_load_cv     0.50000000  x1.00
   mem_load_cv     0.50000000  x1.00
   disk_load_cv    0.00000000  x1.00
   net_load_cv     0.50000000  x1.00
   pri_tags_score  0.00000000  x2.00
Cluster score: 1.62890685
Signed-off-by: default avatarRené Nussbaumer <rn@google.com>
Reviewed-by: default avatarIustin Pop <iustin@google.com>
parent 4f511a13
......@@ -347,7 +347,7 @@ docrst = \
doc/walkthrough.rst
HS_PROGS = htools/htools
HS_BIN_ROLES = hbal hscan hspace
HS_BIN_ROLES = hbal hscan hspace hinfo
HS_ALL_PROGS = $(HS_PROGS) htools/test
HS_PROG_SRCS = $(patsubst %,%.hs,$(HS_ALL_PROGS))
......@@ -389,6 +389,7 @@ HS_LIB_SRCS = \
htools/Ganeti/HTools/Program.hs \
htools/Ganeti/HTools/Program/Hail.hs \
htools/Ganeti/HTools/Program/Hbal.hs \
htools/Ganeti/HTools/Program/Hinfo.hs \
htools/Ganeti/HTools/Program/Hscan.hs \
htools/Ganeti/HTools/Program/Hspace.hs \
htools/Ganeti/BasicTypes.hs \
......
......@@ -1330,14 +1330,19 @@ printInsts nl il =
formatTable (header:map helper sil) isnum
-- | Shows statistics for a given node list.
printStats :: Node.List -> String
printStats nl =
printStats :: String -> Node.List -> String
printStats lp nl =
let dcvs = compDetailedCV $ Container.elems nl
(weights, names) = unzip detailedCVInfo
hd = zip3 (weights ++ repeat 1) (names ++ repeat "unknown") dcvs
formatted = map (\(w, header, val) ->
printf "%s=%.8f(x%.2f)" header val w::String) hd
in intercalate ", " formatted
header = [ "Field", "Value", "Weight" ]
formatted = map (\(w, h, val) ->
[ h
, printf "%.8f" val
, printf "x%.2f" w
]) hd
in unlines . map ((++) lp) . map ((:) ' ' . unwords) $
formatTable (header:formatted) $ False:repeat True
-- | Convert a placement into a list of OpCodes (basically a job).
iMoveToJob :: Node.List -- ^ The node list; only used for node
......
......@@ -33,6 +33,7 @@ import qualified Ganeti.HTools.Program.Hail as Hail
import qualified Ganeti.HTools.Program.Hbal as Hbal
import qualified Ganeti.HTools.Program.Hscan as Hscan
import qualified Ganeti.HTools.Program.Hspace as Hspace
import qualified Ganeti.HTools.Program.Hinfo as Hinfo
-- | Supported binaries.
personalities :: [(String, (Options -> [String] -> IO (), [OptType]))]
......@@ -40,4 +41,5 @@ personalities = [ ("hail", (Hail.main, Hail.options))
, ("hbal", (Hbal.main, Hbal.options))
, ("hscan", (Hscan.main, Hscan.options))
, ("hspace", (Hspace.main, Hspace.options))
, ("hinfo", (Hinfo.main, Hinfo.options))
]
......@@ -373,8 +373,8 @@ main opts args = do
checkNeedRebalance opts ini_cv
if verbose > 2
then printf "Initial coefficients: overall %.8f, %s\n"
ini_cv (Cluster.printStats nl)::IO ()
then printf "Initial coefficients: overall %.8f\n%s"
ini_cv (Cluster.printStats " " nl)::IO ()
else printf "Initial score: %.8f\n" ini_cv
putStrLn "Trying to minimize the CV..."
......@@ -392,8 +392,8 @@ main opts args = do
sol_msg = case () of
_ | null fin_plc -> printf "No solution found\n"
| verbose > 2 ->
printf "Final coefficients: overall %.8f, %s\n"
fin_cv (Cluster.printStats fin_nl)
printf "Final coefficients: overall %.8f\n%s"
fin_cv (Cluster.printStats " " fin_nl)
| otherwise ->
printf "Cluster score improved from %.8f to %.8f\n"
ini_cv fin_cv ::String
......
{-| Cluster information printer.
-}
{-
Copyright (C) 2012 Google Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
-}
module Ganeti.HTools.Program.Hinfo (main, options) where
import Control.Monad
import Data.List
import System.Exit
import System.IO
import Text.Printf (printf)
import qualified Ganeti.HTools.Container as Container
import qualified Ganeti.HTools.Cluster as Cluster
import qualified Ganeti.HTools.Node as Node
import qualified Ganeti.HTools.Instance as Instance
import Ganeti.HTools.CLI
import Ganeti.HTools.ExtLoader
import Ganeti.HTools.Loader
-- | Options list and functions.
options :: [OptType]
options =
[ oPrintNodes
, oPrintInsts
, oDataFile
, oRapiMaster
, oLuxiSocket
, oVerbose
, oQuiet
, oOfflineNode
, oShowVer
, oShowHelp
]
-- | Do a few checks on the cluster data.
checkCluster :: Int -> Node.List -> Instance.List -> IO ()
checkCluster verbose nl il = do
-- nothing to do on an empty cluster
when (Container.null il) $ do
printf "Cluster is empty, exiting.\n"::IO ()
exitWith ExitSuccess
-- hbal doesn't currently handle split clusters
let split_insts = Cluster.findSplitInstances nl il
unless (null split_insts) $ do
hPutStrLn stderr "Found instances belonging to multiple node groups:"
mapM_ (\i -> hPutStrLn stderr $ " " ++ Instance.name i) split_insts
hPutStrLn stderr "Aborting."
exitWith $ ExitFailure 1
printf "Loaded %d nodes, %d instances\n"
(Container.size nl)
(Container.size il)::IO ()
let csf = commonSuffix nl il
when (not (null csf) && verbose > 1) $
printf "Note: Stripping common suffix of '%s' from names\n" csf
-- | Main function.
main :: Options -> [String] -> IO ()
main opts args = do
unless (null args) $ do
hPutStrLn stderr "Error: this program doesn't take any arguments."
exitWith $ ExitFailure 1
let verbose = optVerbose opts
shownodes = optShowNodes opts
showinsts = optShowInsts opts
(ClusterData gl fixed_nl ilf ctags ipol) <- loadExternalData opts
when (verbose > 1) $ do
putStrLn $ "Loaded cluster tags: " ++ intercalate "," ctags
putStrLn $ "Loaded cluster ipolicy: " ++ show ipol
putStrLn $ "Loaded node groups: " ++ show gl
nlf <- setNodeStatus opts fixed_nl
checkCluster verbose nlf ilf
printf "Cluster has %d node group(s)\n" (Container.size gl)::IO ()
maybePrintInsts showinsts "Instances" (Cluster.printInsts nlf ilf)
maybePrintNodes shownodes "Cluster" (Cluster.printNodes nlf)
printf "Cluster coefficients:\n%s" (Cluster.printStats " " nlf)::IO ()
printf "Cluster score: %.8f\n" (Cluster.compCV nlf)
......@@ -424,8 +424,8 @@ main opts args = do
maybePrintNodes (optShowNodes opts) "Initial cluster" (Cluster.printNodes nl)
when (verbose > 2) $
hPrintf stderr "Initial coefficients: overall %.8f, %s\n"
(Cluster.compCV nl) (Cluster.printStats nl)
hPrintf stderr "Initial coefficients: overall %.8f\n%s"
(Cluster.compCV nl) (Cluster.printStats " " nl)
printCluster machine_r (Cluster.totalResources nl) (length all_nodes)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment