hbal: Abort for invalid offline node names
[ganeti-local] / Ganeti / HTools / Utils.hs
1 {-| Utility functions -}
2
3 module Ganeti.HTools.Utils
4     (
5       debug
6     , isLeft
7     , fromLeft
8     , fromRight
9     , sepSplit
10     , swapPairs
11     , varianceCoeff
12     , readData
13     , commaJoin
14     ) where
15
16 import Data.Either
17 import Data.List
18 import Monad
19 import System
20 import System.IO
21
22 import Debug.Trace
23
24 -- | To be used only for debugging, breaks referential integrity.
25 debug :: Show a => a -> a
26 debug x = trace (show x) x
27
28 -- | Check if the given argument is Left something
29 isLeft :: Either a b -> Bool
30 isLeft val =
31     case val of
32       Left _ -> True
33       _ -> False
34
35 fromLeft :: Either a b -> a
36 fromLeft = either (\x -> x) (\_ -> undefined)
37
38 fromRight :: Either a b -> b
39 fromRight = either (\_ -> undefined) id
40
41 -- | Comma-join a string list.
42 commaJoin :: [String] -> String
43 commaJoin = intercalate ","
44
45 -- | Split a string on a separator and return an array.
46 sepSplit :: Char -> String -> [String]
47 sepSplit sep s
48     | x == "" && xs == [] = []
49     | xs == []            = [x]
50     | ys == []            = x:"":[]
51     | otherwise           = x:(sepSplit sep ys)
52     where (x, xs) = break (== sep) s
53           ys = drop 1 xs
54
55 -- | Partial application of sepSplit to @'.'@
56 commaSplit :: String -> [String]
57 commaSplit = sepSplit ','
58
59 -- | Swap a list of @(a, b)@ into @(b, a)@
60 swapPairs :: [(a, b)] -> [(b, a)]
61 swapPairs = map (\ (a, b) -> (b, a))
62
63 -- Simple and slow statistical functions, please replace with better versions
64
65 -- | Mean value of a list.
66 meanValue :: Floating a => [a] -> a
67 meanValue lst = (sum lst) / (fromIntegral $ length lst)
68
69 -- | Standard deviation.
70 stdDev :: Floating a => [a] -> a
71 stdDev lst =
72     let mv = meanValue lst
73         square = (^ (2::Int)) -- silences "defaulting the constraint..."
74         av = sum $ map square $ map (\e -> e - mv) lst
75         bv = sqrt (av / (fromIntegral $ length lst))
76     in bv
77
78 -- | Coefficient of variation.
79 varianceCoeff :: Floating a => [a] -> a
80 varianceCoeff lst = (stdDev lst) / (fromIntegral $ length lst)
81
82 -- | Get a Right result or print the error and exit
83 readData :: (String -> IO (Either String String)) -> String -> IO String
84 readData fn host = do
85   nd <- fn host
86   when (isLeft nd) $
87        do
88          putStrLn $ fromLeft nd
89          exitWith $ ExitFailure 1
90   return $ fromRight nd