Statistics
| Branch: | Tag: | Revision:

root / Ganeti / HTools / Types.hs @ ed41c179

History | View | Annotate | Download (2.2 kB)

1
{-| Some common types.
2

    
3
-}
4

    
5
module Ganeti.HTools.Types
6
    where
7

    
8
import qualified Ganeti.HTools.Container as Container
9
import qualified Ganeti.HTools.Instance as Instance
10
import qualified Ganeti.HTools.Node as Node
11

    
12
type NodeList = Container.Container Node.Node
13
type InstanceList = Container.Container Instance.Instance
14

    
15
-- | The type used to hold idx-to-name mappings
16
type NameList = [(Int, String)]
17

    
18
-- | The type used to hold name-to-idx mappings
19
type NameAssoc = [(String, Int)]
20

    
21
type IdxNode = [(Int, Node.Node)]
22
type IdxInstance = [(Int, Instance.Instance)]
23

    
24
{-
25

    
26
This is similar to the JSON library Result type - *very* similar, but
27
we want to use it in multiple places, so we abstract it into a
28
mini-library here
29

    
30
-}
31

    
32
data Result a
33
    = Bad String
34
    | Ok a
35
    deriving (Show)
36

    
37
instance Monad Result where
38
    (>>=) (Bad x) _ = Bad x
39
    (>>=) (Ok x) fn = fn x
40
    return = Ok
41
    fail = Bad
42

    
43
-- | A generic class for nodes and instances
44
class Element a where
45
    name    :: a -> String
46
    idx     :: a -> Int
47
    setName :: a -> String -> a
48
    setIdx  :: a -> Int -> a
49

    
50
-- Let's make nodes elements of the cluster
51
instance Element Node.Node where
52
    name = Node.name
53
    idx = Node.idx
54
    setName = Node.setName
55
    setIdx = Node.setIdx
56

    
57
-- And instances too
58
instance Element Instance.Instance where
59
    name = Instance.name
60
    idx = Instance.idx
61
    setName = Instance.setName
62
    setIdx = Instance.setIdx
63

    
64
-- | Compute the name of an element in a container
65
cNameOf :: (Element a) => Container.Container a -> Container.Key -> String
66
cNameOf c k = name $ Container.find k c
67

    
68
-- | Compute the maximum name length in an Element Container
69
cMaxNamelen :: (Element a) => Container.Container a -> Int
70
cMaxNamelen = maximum . map (length . name) . Container.elems
71

    
72
-- | Find an element by name in a Container; this is a very slow function
73
findByName :: (Element a, Monad m) =>
74
              Container.Container a -> String -> m Container.Key
75
findByName c n =
76
    let all_elems = Container.elems c
77
        result = filter ((== n) . name) all_elems
78
        nems = length result
79
    in
80
      if nems /= 1 then
81
          fail $ "Wrong number of elems (" ++ (show nems) ++
82
                   ") found with name " ++ n
83
      else
84
          return $ idx $ head result