Fix loading of plain instances via iallocator
[ganeti-local] / Ganeti / HTools / Types.hs
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