Add initial structure for utilisation balancing
[ganeti-local] / Ganeti / HTools / Types.hs
1 {-| Some common types.
2
3 -}
4
5 {-
6
7 Copyright (C) 2009 Google Inc.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22 02110-1301, USA.
23
24 -}
25
26 module Ganeti.HTools.Types
27     ( Idx
28     , Ndx
29     , NameAssoc
30     , Score
31     , Weight
32     , DynUtil(..)
33     , zeroUtil
34     , addUtil
35     , subUtil
36     , Placement
37     , IMove(..)
38     , MoveJob
39     , JobSet
40     , Result(..)
41     , Element(..)
42     , FailMode(..)
43     , FailStats
44     , OpResult(..)
45     , connTimeout
46     , queryTimeout
47     ) where
48
49 -- | The instance index type.
50 type Idx = Int
51
52 -- | The node index type.
53 type Ndx = Int
54
55 -- | The type used to hold name-to-idx mappings.
56 type NameAssoc = [(String, Int)]
57
58 -- | A separate name for the cluster score type.
59 type Score = Double
60
61 -- | A separate name for a weight metric.
62 type Weight = Double
63
64 -- | The dynamic resource specs of a machine (i.e. load or load
65 -- capacity, as opposed to size).
66 data DynUtil = DynUtil
67     { cpuWeight :: Weight -- ^ Standardised CPU usage
68     , memWeight :: Weight -- ^ Standardised memory load
69     , dskWeight :: Weight -- ^ Standardised disk I/O usage
70     , netWeight :: Weight -- ^ Standardised network usage
71     } deriving (Show)
72
73 -- | Initial empty utilisation
74 zeroUtil :: DynUtil
75 zeroUtil = DynUtil { cpuWeight = 0, memWeight = 0
76                    , dskWeight = 0, netWeight = 0 }
77
78 addUtil :: DynUtil -> DynUtil -> DynUtil
79 addUtil (DynUtil a1 a2 a3 a4) (DynUtil b1 b2 b3 b4) =
80     DynUtil (a1+b1) (a2+b2) (a3+b3) (a4+b4)
81
82 subUtil :: DynUtil -> DynUtil -> DynUtil
83 subUtil (DynUtil a1 a2 a3 a4) (DynUtil b1 b2 b3 b4) =
84     DynUtil (a1-b1) (a2-b2) (a3-b3) (a4-b4)
85
86 -- | The description of an instance placement. It contains the
87 -- instance index, the new primary and secondary node, the move being
88 -- performed and the score of the cluster after the move.
89 type Placement = (Idx, Ndx, Ndx, IMove, Score)
90
91 -- | An instance move definition
92 data IMove = Failover                -- ^ Failover the instance (f)
93            | ReplacePrimary Ndx      -- ^ Replace primary (f, r:np, f)
94            | ReplaceSecondary Ndx    -- ^ Replace secondary (r:ns)
95            | ReplaceAndFailover Ndx  -- ^ Replace secondary, failover (r:np, f)
96            | FailoverAndReplace Ndx  -- ^ Failover, replace secondary (f, r:ns)
97              deriving (Show)
98
99 -- | Formatted solution output for one move (involved nodes and
100 -- commands
101 type MoveJob = ([Ndx], Idx, IMove, [String])
102
103 -- | A list of command elements
104 type JobSet = [MoveJob]
105
106 -- | Connection timeout (when using non-file methods).
107 connTimeout :: Int
108 connTimeout = 15
109
110 -- | The default timeout for queries (when using non-file methods).
111 queryTimeout :: Int
112 queryTimeout = 60
113
114 {-|
115
116 This is similar to the JSON library Result type - *very* similar, but
117 we want to use it in multiple places, so we abstract it into a
118 mini-library here
119
120 -}
121 data Result a
122     = Bad String
123     | Ok a
124     deriving (Show)
125
126 instance Monad Result where
127     (>>=) (Bad x) _ = Bad x
128     (>>=) (Ok x) fn = fn x
129     return = Ok
130     fail = Bad
131
132 -- | Reason for an operation's falure
133 data FailMode = FailMem  -- ^ Failed due to not enough RAM
134               | FailDisk -- ^ Failed due to not enough disk
135               | FailCPU  -- ^ Failed due to not enough CPU capacity
136               | FailN1   -- ^ Failed due to not passing N1 checks
137                 deriving (Eq, Enum, Bounded, Show)
138
139 -- | List with failure statistics
140 type FailStats = [(FailMode, Int)]
141
142 -- | Either-like data-type customized for our failure modes
143 data OpResult a = OpFail FailMode -- ^ Failed operation
144                 | OpGood a        -- ^ Success operation
145
146 instance Monad OpResult where
147     (OpGood x) >>= fn = fn x
148     (OpFail y) >>= _ = OpFail y
149     return = OpGood
150
151 -- | A generic class for items that have updateable names and indices.
152 class Element a where
153     -- | Returns the name of the element
154     nameOf  :: a -> String
155     -- | Returns the index of the element
156     idxOf   :: a -> Int
157     -- | Updates the name of the element
158     setName :: a -> String -> a
159     -- | Updates the index of the element
160     setIdx  :: a -> Int -> a