diff --git a/htools/Ganeti/HTools/Cluster.hs b/htools/Ganeti/HTools/Cluster.hs
index 5fc4c4f8557d740a9a056706e3e982a2fd601083..97a0561aede44addabb2742f099701e3190bae4c 100644
--- a/htools/Ganeti/HTools/Cluster.hs
+++ b/htools/Ganeti/HTools/Cluster.hs
@@ -139,6 +139,7 @@ emptyEvacSolution = EvacSolution { esMoved = []
data Table = Table Node.List Instance.List Score [Placement]
deriving (Show, Read)
+-- | Cluster statistics data type.
data CStats = CStats { csFmem :: Integer -- ^ Cluster free mem
, csFdsk :: Integer -- ^ Cluster free disk
, csAmem :: Integer -- ^ Cluster allocatable mem
@@ -278,6 +279,7 @@ detailedCVInfo = [ (1, "free_mem_cv")
, (2, "pri_tags_score")
]
+-- | Holds the weights used by 'compCVNodes' for each metric.
detailedCVWeights :: [Double]
detailedCVWeights = map fst detailedCVInfo
@@ -333,7 +335,6 @@ compCVNodes = sum . zipWith (*) detailedCVWeights . compDetailedCV
compCV :: Node.List -> Double
compCV = compCVNodes . Container.elems
-
-- | Compute online nodes from a 'Node.List'.
getOnline :: Node.List -> [Node.Node]
getOnline = filter (not . Node.offline) . Container.elems
@@ -1314,8 +1315,16 @@ printStats nl =
in intercalate ", " formatted
-- | Convert a placement into a list of OpCodes (basically a job).
-iMoveToJob :: Node.List -> Instance.List
- -> Idx -> IMove -> [OpCodes.OpCode]
+iMoveToJob :: Node.List -- ^ The node list; only used for node
+ -- names, so any version is good
+ -- (before or after the operation)
+ -> Instance.List -- ^ The instance list; also used for
+ -- names only
+ -> Idx -- ^ The index of the instance being
+ -- moved
+ -> IMove -- ^ The actual move to be described
+ -> [OpCodes.OpCode] -- ^ The list of opcodes equivalent to
+ -- the given move
iMoveToJob nl il idx move =
let inst = Container.find idx il
iname = Instance.name inst
diff --git a/htools/Ganeti/HTools/Compat.hs b/htools/Ganeti/HTools/Compat.hs
index 2a35d37c663f5c203b1ab3db19f732f6a35bbc4b..36a0fbfce5c897add063188621d96217c6360a67 100644
--- a/htools/Ganeti/HTools/Compat.hs
+++ b/htools/Ganeti/HTools/Compat.hs
@@ -34,6 +34,11 @@ module Ganeti.HTools.Compat
import qualified Control.Parallel.Strategies
+-- | Wrapper over the function exported from
+-- "Control.Parallel.Strategies".
+--
+-- This wraps either the old or the new name of the function,
+-- depending on the detected library version.
rwhnf :: Control.Parallel.Strategies.Strategy a
#ifdef PARALLEL3
rwhnf = Control.Parallel.Strategies.rseq
diff --git a/htools/Ganeti/HTools/Container.hs b/htools/Ganeti/HTools/Container.hs
index b527015b44049032d3871235bc3c7b522b6b1c67..5b2d3cc9de60a1a5325da078f2d404e51502cefb 100644
--- a/htools/Ganeti/HTools/Container.hs
+++ b/htools/Ganeti/HTools/Container.hs
@@ -59,7 +59,11 @@ import qualified Data.IntMap as IntMap
import qualified Ganeti.HTools.Types as T
+-- | Our key type.
+
type Key = IntMap.Key
+
+-- | Our container type.
type Container = IntMap.IntMap
-- | Locate a key in the map (must exist).
diff --git a/htools/Ganeti/HTools/ExtLoader.hs b/htools/Ganeti/HTools/ExtLoader.hs
index 06cd7df51bd320b12c5c555cc129789e78efea02..0b63a2c18afc49b26ff36e8da97be767c185927e 100644
--- a/htools/Ganeti/HTools/ExtLoader.hs
+++ b/htools/Ganeti/HTools/ExtLoader.hs
@@ -55,6 +55,7 @@ import Ganeti.HTools.Utils (sepSplit, tryRead)
wrapIO :: IO (Result a) -> IO (Result a)
wrapIO = flip catch (return . Bad . show)
+-- | Parses a user-supplied utilisation string.
parseUtilisation :: String -> Result (String, DynUtil)
parseUtilisation line =
case sepSplit ' ' line of
diff --git a/htools/Ganeti/HTools/Group.hs b/htools/Ganeti/HTools/Group.hs
index 82816784a11350bf1642132afb85cfcb03370776..6df5f4c74223863ba710fecd3b0dc68f0c76c1ac 100644
--- a/htools/Ganeti/HTools/Group.hs
+++ b/htools/Ganeti/HTools/Group.hs
@@ -73,6 +73,8 @@ create name_init id_init apol_init =
, idx = -1
}
+-- | Sets the group index.
+--
-- This is used only during the building of the data structures.
setIdx :: Group -> T.Gdx -> Group
setIdx t i = t {idx = i}
diff --git a/htools/Ganeti/HTools/IAlloc.hs b/htools/Ganeti/HTools/IAlloc.hs
index a8fc8af68f651506f0000f468bea71ff602dfcab..d86a6571e61be404cbfd1478e322de3580ea9791 100644
--- a/htools/Ganeti/HTools/IAlloc.hs
+++ b/htools/Ganeti/HTools/IAlloc.hs
@@ -237,7 +237,7 @@ formatNodeEvac gl nl il (fin_nl, fin_il, es) =
" were moved successfully"
in Ok (info, showJSON (mes, fes, Cluster.esOpCodes es), fin_nl, fin_il)
--- | Process a request and return new node lists
+-- | Process a request and return new node lists.
processRequest :: Request -> Result IAllocResult
processRequest request =
let Request rqtype (ClusterData gl nl il _) = request
@@ -251,7 +251,7 @@ processRequest request =
Cluster.tryNodeEvac gl nl il mode xi >>=
formatNodeEvac gl nl il
--- | Reads the request from the data file(s)
+-- | Reads the request from the data file(s).
readRequest :: Options -> [String] -> IO Request
readRequest opts args = do
when (null args) $ do
diff --git a/htools/Ganeti/HTools/Instance.hs b/htools/Ganeti/HTools/Instance.hs
index 4f8d5f56a4da428dd9f8fcb8abf623624e22e380..4ff497fcdb7497ac94027c449ef889b065f918a1 100644
--- a/htools/Ganeti/HTools/Instance.hs
+++ b/htools/Ganeti/HTools/Instance.hs
@@ -159,6 +159,7 @@ setBoth :: Instance -- ^ the original instance
-> Instance -- ^ the modified instance
setBoth t p s = t { pNode = p, sNode = s }
+-- | Sets the movable flag on an instance.
setMovable :: Instance -- ^ The original instance
-> Bool -- ^ New movable flag
-> Instance -- ^ The modified instance
@@ -186,7 +187,7 @@ specOf :: Instance -> T.RSpec
specOf Instance { mem = m, dsk = d, vcpus = c } =
T.RSpec { T.rspecCpu = c, T.rspecMem = m, T.rspecDsk = d }
--- | Computed the number of nodes for a given disk template
+-- | Computed the number of nodes for a given disk template.
requiredNodes :: T.DiskTemplate -> Int
requiredNodes T.DTDrbd8 = 2
requiredNodes _ = 1
diff --git a/htools/Ganeti/HTools/Luxi.hs b/htools/Ganeti/HTools/Luxi.hs
index 9b3fa9c507200c9ad1a8f765b51f406a8e6f1470..ee526be00a2ccdbe6dc2082ee1acab3d8cddaaa3 100644
--- a/htools/Ganeti/HTools/Luxi.hs
+++ b/htools/Ganeti/HTools/Luxi.hs
@@ -88,14 +88,15 @@ queryGroupsMsg :: L.LuxiOp
queryGroupsMsg =
L.QueryGroups [] ["uuid", "name", "alloc_policy"] False
--- | Wraper over callMethod doing node query.
+-- | Wraper over 'callMethod' doing node query.
queryNodes :: L.Client -> IO (Result JSValue)
queryNodes = L.callMethod queryNodesMsg
--- | Wraper over callMethod doing instance query.
+-- | Wraper over 'callMethod' doing instance query.
queryInstances :: L.Client -> IO (Result JSValue)
queryInstances = L.callMethod queryInstancesMsg
+-- | Wrapper over 'callMethod' doing cluster information query.
queryClusterInfo :: L.Client -> IO (Result JSValue)
queryClusterInfo = L.callMethod queryClusterInfoMsg
@@ -167,15 +168,18 @@ parseNode ktg (JSArray [ name, mtotal, mnode, mfree, dtotal, dfree
parseNode _ v = fail ("Invalid node query result: " ++ show v)
+-- | Parses the cluster tags.
getClusterTags :: JSValue -> Result [String]
getClusterTags v = do
let errmsg = "Parsing cluster info"
obj <- annotateResult errmsg $ asJSObject v
tryFromObj errmsg (fromJSObject obj) "tags"
+-- | Parses the cluster groups.
getGroups :: JSValue -> Result [(String, Group.Group)]
getGroups arr = toArray arr >>= mapM parseGroup
+-- | Parses a given group information.
parseGroup :: JSValue -> Result (String, Group.Group)
parseGroup (JSArray [ uuid, name, apol ]) = do
xname <- annotateResult "Parsing new group" (fromJVal name)
diff --git a/htools/Ganeti/HTools/Program/Hail.hs b/htools/Ganeti/HTools/Program/Hail.hs
index ad7c77566367ffa28ab8c522812a71c13d9514ef..1fb9b80d4edbd4cca8c8c024669d764a09a69b3d 100644
--- a/htools/Ganeti/HTools/Program/Hail.hs
+++ b/htools/Ganeti/HTools/Program/Hail.hs
@@ -36,7 +36,7 @@ import Ganeti.HTools.IAlloc
import Ganeti.HTools.Loader (Request(..), ClusterData(..))
import Ganeti.HTools.ExtLoader (maybeSaveData)
--- | Options list and functions
+-- | Options list and functions.
options :: [OptType]
options =
[ oPrintNodes
diff --git a/htools/Ganeti/HTools/Program/Hbal.hs b/htools/Ganeti/HTools/Program/Hbal.hs
index ca6b9d731ef6de78043bcd509fe4f8cbc4c2a156..21bf9995583936a1ea1c77a932d2104c8af9fdcb 100644
--- a/htools/Ganeti/HTools/Program/Hbal.hs
+++ b/htools/Ganeti/HTools/Program/Hbal.hs
@@ -54,7 +54,7 @@ import Ganeti.HTools.Loader
import qualified Ganeti.Luxi as L
import Ganeti.Jobs
--- | Options list and functions
+-- | Options list and functions.
options :: [OptType]
options =
[ oPrintNodes
@@ -133,14 +133,14 @@ iterateDepth ini_tbl max_rounds disk_moves inst_moves nmlen imlen
mg_limit min_gain evac_mode
Nothing -> return (ini_tbl, cmd_strs)
--- | Formats the solution for the oneline display
+-- | Formats the solution for the oneline display.
formatOneline :: Double -> Int -> Double -> String
formatOneline ini_cv plc_len fin_cv =
printf "%.8f %d %.8f %8.3f" ini_cv plc_len fin_cv
(if fin_cv == 0 then 1 else ini_cv / fin_cv)
-- | Polls a set of jobs at a fixed interval until all are finished
--- one way or another
+-- one way or another.
waitForJobs :: L.Client -> [String] -> IO (Result [JobStatus])
waitForJobs client jids = do
sts <- L.queryJobsStatus client jids
@@ -153,11 +153,11 @@ waitForJobs client jids = do
waitForJobs client jids
else return $ Ok s
--- | Check that a set of job statuses is all success
+-- | Check that a set of job statuses is all success.
checkJobsStatus :: [JobStatus] -> Bool
checkJobsStatus = all (== JOB_STATUS_SUCCESS)
--- | Wrapper over execJobSet checking for early termination
+-- | Wrapper over execJobSet checking for early termination.
execWrapper :: String -> Node.List
-> Instance.List -> IORef Int -> [JobSet] -> IO Bool
execWrapper _ _ _ _ [] = return True
@@ -170,7 +170,7 @@ execWrapper master nl il cref alljss = do
return False
else execJobSet master nl il cref alljss)
--- | Execute an entire jobset
+-- | Execute an entire jobset.
execJobSet :: String -> Node.List
-> Instance.List -> IORef Int -> [JobSet] -> IO Bool
execJobSet _ _ _ _ [] = return True
@@ -201,14 +201,14 @@ execJobSet master nl il cref (js:jss) = do
hPutStrLn stderr "Aborting."
return False)
--- | Signal handler for graceful termination
+-- | Signal handler for graceful termination.
hangleSigInt :: IORef Int -> IO ()
hangleSigInt cref = do
writeIORef cref 1
putStrLn ("Cancel request registered, will exit at" ++
" the end of the current job set...")
--- | Signal handler for immediate termination
+-- | Signal handler for immediate termination.
hangleSigTerm :: IORef Int -> IO ()
hangleSigTerm cref = do
-- update the cref to 2, just for consistency
@@ -216,6 +216,7 @@ hangleSigTerm cref = do
putStrLn "Double cancel request, exiting now..."
exitImmediately $ ExitFailure 2
+-- | Runs a job set with handling of signals.
runJobSet :: String -> Node.List -> Instance.List -> [JobSet] -> IO Bool
runJobSet master fin_nl il cmd_jobs = do
cref <- newIORef 0
diff --git a/htools/Ganeti/HTools/Program/Hscan.hs b/htools/Ganeti/HTools/Program/Hscan.hs
index 3fd39cb9d5090ca64e62f2f7c83493bdabe9776d..0dbcf6e08f3bdf6bf5870a7ef5cd0f13772b2b3e 100644
--- a/htools/Ganeti/HTools/Program/Hscan.hs
+++ b/htools/Ganeti/HTools/Program/Hscan.hs
@@ -46,7 +46,7 @@ import Ganeti.HTools.Text (serializeCluster)
import Ganeti.HTools.CLI
import Ganeti.HTools.Types
--- | Options list and functions
+-- | Options list and functions.
options :: [OptType]
options =
[ oPrintNodes
@@ -58,7 +58,7 @@ options =
, oShowHelp
]
--- | Return a one-line summary of cluster state
+-- | Return a one-line summary of cluster state.
printCluster :: Node.List -> Instance.List
-> String
printCluster nl il =
@@ -79,7 +79,7 @@ printCluster nl il =
ccv
--- | Replace slashes with underscore for saving to filesystem
+-- | Replace slashes with underscore for saving to filesystem.
fixSlash :: String -> String
fixSlash = map (\x -> if x == '/' then '_' else x)
@@ -91,7 +91,7 @@ processData input_data = do
let (_, fix_nl) = checkData nl il
return cdata { cdNodes = fix_nl }
--- | Writes cluster data out
+-- | Writes cluster data out.
writeData :: Int
-> String
-> Options
@@ -108,6 +108,7 @@ writeData nlen name opts (Ok cdata) = do
name err >> return False
Ok processed -> writeDataInner nlen name opts cdata processed
+-- | Inner function for writing cluster data to disk.
writeDataInner :: Int
-> String
-> Options
diff --git a/htools/Ganeti/HTools/Program/Hspace.hs b/htools/Ganeti/HTools/Program/Hspace.hs
index 0f865ae7faeb9d9bdec3cc13cf429d4fd99bbafe..a4cb285f93d57950d11622122dec594c9c4860d0 100644
--- a/htools/Ganeti/HTools/Program/Hspace.hs
+++ b/htools/Ganeti/HTools/Program/Hspace.hs
@@ -48,7 +48,7 @@ import Ganeti.HTools.CLI
import Ganeti.HTools.ExtLoader
import Ganeti.HTools.Loader
--- | Options list and functions
+-- | Options list and functions.
options :: [OptType]
options =
[ oPrintNodes
@@ -110,6 +110,8 @@ dskEff = effFn Cluster.csIdsk Cluster.csTdsk
cpuEff :: Cluster.CStats -> Double
cpuEff = effFn Cluster.csIcpu (fromIntegral . Cluster.csVcpu)
+-- | Holds data for converting a 'Cluster.CStats' structure into
+-- detailed statictics.
statsData :: [(String, Cluster.CStats -> String)]
statsData = [ ("SCORE", printf "%.8f" . Cluster.csScore)
, ("INST_CNT", printf "%d" . Cluster.csNinst)
@@ -133,12 +135,14 @@ statsData = [ ("SCORE", printf "%.8f" . Cluster.csScore)
, ("MNODE_DSK_AVAIL", printf "%d" . Cluster.csMdsk)
]
+-- | List holding 'RSpec' formatting information.
specData :: [(String, RSpec -> String)]
specData = [ ("MEM", printf "%d" . rspecMem)
, ("DSK", printf "%d" . rspecDsk)
, ("CPU", printf "%d" . rspecCpu)
]
+-- | List holding 'Cluster.CStats' formatting information.
clusterData :: [(String, Cluster.CStats -> String)]
clusterData = [ ("MEM", printf "%.0f" . Cluster.csTmem)
, ("DSK", printf "%.0f" . Cluster.csTdsk)
@@ -146,7 +150,7 @@ clusterData = [ ("MEM", printf "%.0f" . Cluster.csTmem)
, ("VCPU", printf "%d" . Cluster.csVcpu)
]
--- | Function to print stats for a given phase
+-- | Function to print stats for a given phase.
printStats :: Phase -> Cluster.CStats -> [(String, String)]
printStats ph cs =
map (\(s, fn) -> (printf "%s_%s" kind s, fn cs)) statsData
@@ -211,6 +215,7 @@ formatSpecMap =
map (\(spec, cnt) -> printf "%d,%d,%d=%d" (rspecMem spec)
(rspecDsk spec) (rspecCpu spec) cnt)
+-- | Formats \"key-metrics\" values.
formatRSpec :: Double -> String -> RSpec -> [(String, String)]
formatRSpec m_cpu s r =
[ ("KM_" ++ s ++ "_CPU", show $ rspecCpu r)
@@ -219,6 +224,7 @@ formatRSpec m_cpu s r =
, ("KM_" ++ s ++ "_DSK", show $ rspecDsk r)
]
+-- | Shows allocations stats.
printAllocationStats :: Double -> Node.List -> Node.List -> IO ()
printAllocationStats m_cpu ini_nl fin_nl = do
let ini_stats = Cluster.totalResources ini_nl
@@ -228,17 +234,18 @@ printAllocationStats m_cpu ini_nl fin_nl = do
printKeys $ formatRSpec m_cpu "POOL"ralo
printKeys $ formatRSpec m_cpu "UNAV" runa
--- | Ensure a value is quoted if needed
+-- | Ensure a value is quoted if needed.
ensureQuoted :: String -> String
ensureQuoted v = if not (all (\c -> isAlphaNum c || c == '.') v)
then '\'':v ++ "'"
else v
--- | Format a list of key\/values as a shell fragment
+-- | Format a list of key\/values as a shell fragment.
printKeys :: [(String, String)] -> IO ()
printKeys = mapM_ (\(k, v) ->
printf "HTS_%s=%s\n" (map toUpper k) (ensureQuoted v))
+-- | Converts instance data to a list of strings.
printInstance :: Node.List -> Instance.Instance -> [String]
printInstance nl i = [ Instance.name i
, Container.nameOf nl $ Instance.pNode i
@@ -250,7 +257,7 @@ printInstance nl i = [ Instance.name i
, show (Instance.vcpus i)
]
--- | Optionally print the allocation map
+-- | Optionally print the allocation map.
printAllocationMap :: Int -> String
-> Node.List -> [Instance.Instance] -> IO ()
printAllocationMap verbose msg nl ixes =
@@ -314,11 +321,13 @@ printTiered False spec_map _ ini_nl fin_nl sreason = do
printClusterScores ini_nl fin_nl
printClusterEff (Cluster.totalResources fin_nl)
+-- | Displays the initial/final cluster scores.
printClusterScores :: Node.List -> Node.List -> IO ()
printClusterScores ini_nl fin_nl = do
printf " - initial cluster score: %.8f\n" $ Cluster.compCV ini_nl::IO ()
printf " - final cluster score: %.8f\n" $ Cluster.compCV fin_nl
+-- | Displays the cluster efficiency.
printClusterEff :: Cluster.CStats -> IO ()
printClusterEff cs =
mapM_ (\(s, fn) ->
diff --git a/htools/Ganeti/HTools/Types.hs b/htools/Ganeti/HTools/Types.hs
index af9b79a9a57949f58f4ad3a5589d978ab416f6b9..6452f5b6d6efa2582085d875eff7ee0860443da9 100644
--- a/htools/Ganeti/HTools/Types.hs
+++ b/htools/Ganeti/HTools/Types.hs
@@ -180,7 +180,7 @@ data IMove = Failover -- ^ Failover the instance (f)
| FailoverAndReplace Ndx -- ^ Failover, replace secondary (f, r:ns)
deriving (Show, Read)
--- | Instance disk template type
+-- | Instance disk template type.
data DiskTemplate = DTDiskless
| DTFile
| DTSharedFile
@@ -189,7 +189,7 @@ data DiskTemplate = DTDiskless
| DTDrbd8
deriving (Show, Read, Eq, Enum, Bounded)
--- | Converts a DiskTemplate to String
+-- | Converts a DiskTemplate to String.
dtToString :: DiskTemplate -> String
dtToString DTDiskless = C.dtDiskless
dtToString DTFile = C.dtFile
@@ -198,7 +198,7 @@ dtToString DTPlain = C.dtPlain
dtToString DTBlock = C.dtBlock
dtToString DTDrbd8 = C.dtDrbd8
--- | Converts a DiskTemplate from String
+-- | Converts a DiskTemplate from String.
dtFromString :: (Monad m) => String -> m DiskTemplate
dtFromString s =
case () of
@@ -281,7 +281,7 @@ isOk _ = False
isBad :: Result a -> Bool
isBad = not . isOk
--- | Converter from Either String to 'Result'
+-- | Converter from Either String to 'Result'.
eitherToResult :: Either String a -> Result a
eitherToResult (Left s) = Bad s
eitherToResult (Right v) = Ok v
diff --git a/htools/Ganeti/HTools/Version.hs.in b/htools/Ganeti/HTools/Version.hs.in
index 3785e913b4e5af79b98b0354ff494f6fb3399d72..d0721e77aa01f85c9ded2bae82bd253f598ca4ff 100644
--- a/htools/Ganeti/HTools/Version.hs.in
+++ b/htools/Ganeti/HTools/Version.hs.in
@@ -1,4 +1,6 @@
-- Hey Emacs, this is a -*- haskell -*- file
+{- | Auto-generated module holding version information.
+-}
module Ganeti.HTools.Version
(
diff --git a/htools/test.hs b/htools/test.hs
index d46d22aea89dc250859c4de04398c4e98ed84994..34bd05a174e00a8d0078cf1725f1a79ac2c32d57 100644
--- a/htools/test.hs
+++ b/htools/test.hs
@@ -37,7 +37,7 @@ import Ganeti.HTools.QC
import Ganeti.HTools.CLI
import Ganeti.HTools.Utils (sepSplit)
--- | Options list and functions
+-- | Options list and functions.
options :: [OptType]
options =
[ oReplay
@@ -61,7 +61,7 @@ slow = stdArgs
incIORef :: IORef Int -> IO ()
incIORef ir = atomicModifyIORef ir (\x -> (x + 1, ()))
--- | Wrapper over a test runner with error counting
+-- | Wrapper over a test runner with error counting.
wrapTest :: IORef Int
-> (Args -> IO Result)
-> Args