1 {-| Module describing an instance.
3 The instance data type holds very few fields, the algorithm
4 intelligence is in the "Node" and "Cluster" modules.
10 Copyright (C) 2009, 2010, 2011 Google Inc.
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
17 This program is distributed in the hope that it will be useful, but
18 WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
29 module Ganeti.HTools.Instance
47 import qualified Ganeti.HTools.Types as T
48 import qualified Ganeti.HTools.Container as Container
49 import qualified Ganeti.Constants as C
51 -- * Type declarations
53 -- | The instance type.
54 data Instance = Instance
55 { name :: String -- ^ The instance name
56 , alias :: String -- ^ The shortened name
57 , mem :: Int -- ^ Memory of the instance
58 , dsk :: Int -- ^ Disk size of instance
59 , vcpus :: Int -- ^ Number of VCPUs
60 , running :: Bool -- ^ Is the instance running?
61 , runSt :: String -- ^ Original (text) run status
62 , pNode :: T.Ndx -- ^ Original primary node
63 , sNode :: T.Ndx -- ^ Original secondary node
64 , idx :: T.Idx -- ^ Internal index
65 , util :: T.DynUtil -- ^ Dynamic resource usage
66 , movable :: Bool -- ^ Can the instance be moved?
67 , autoBalance :: Bool -- ^ Is the instance auto-balanced?
68 , tags :: [String] -- ^ List of instance tags
69 , diskTemplate :: T.DiskTemplate -- ^ The disk template of the instance
70 } deriving (Show, Read)
72 instance T.Element Instance where
77 allNames n = [name n, alias n]
79 -- | Constant holding the running instance states.
80 runningStates :: [String]
81 runningStates = [C.inststRunning, C.inststErrorup]
83 -- | A simple name for the int, instance association list.
84 type AssocList = [(T.Idx, Instance)]
86 -- | A simple name for an instance map.
87 type List = Container.Container Instance
91 -- | Create an instance.
93 -- Some parameters are not initialized by function, and must be set
94 -- later (via 'setIdx' for example).
95 create :: String -> Int -> Int -> Int -> String
96 -> [String] -> Bool -> T.Ndx -> T.Ndx -> T.DiskTemplate -> Instance
97 create name_init mem_init dsk_init vcpus_init run_init tags_init
98 auto_balance_init pn sn dt =
99 Instance { name = name_init
104 , running = run_init `elem` runningStates
112 , autoBalance = auto_balance_init
116 -- | Changes the index.
118 -- This is used only during the building of the data structures.
119 setIdx :: Instance -- ^ The original instance
120 -> T.Idx -- ^ New index
121 -> Instance -- ^ The modified instance
122 setIdx t i = t { idx = i }
124 -- | Changes the name.
126 -- This is used only during the building of the data structures.
127 setName :: Instance -- ^ The original instance
128 -> String -- ^ New name
129 -> Instance -- ^ The modified instance
130 setName t s = t { name = s, alias = s }
132 -- | Changes the alias.
134 -- This is used only during the building of the data structures.
135 setAlias :: Instance -- ^ The original instance
136 -> String -- ^ New alias
137 -> Instance -- ^ The modified instance
138 setAlias t s = t { alias = s }
140 -- * Update functions
142 -- | Changes the primary node of the instance.
143 setPri :: Instance -- ^ the original instance
144 -> T.Ndx -- ^ the new primary node
145 -> Instance -- ^ the modified instance
146 setPri t p = t { pNode = p }
148 -- | Changes the secondary node of the instance.
149 setSec :: Instance -- ^ the original instance
150 -> T.Ndx -- ^ the new secondary node
151 -> Instance -- ^ the modified instance
152 setSec t s = t { sNode = s }
154 -- | Changes both nodes of the instance.
155 setBoth :: Instance -- ^ the original instance
156 -> T.Ndx -- ^ new primary node index
157 -> T.Ndx -- ^ new secondary node index
158 -> Instance -- ^ the modified instance
159 setBoth t p s = t { pNode = p, sNode = s }
161 setMovable :: Instance -- ^ The original instance
162 -> Bool -- ^ New movable flag
163 -> Instance -- ^ The modified instance
164 setMovable t m = t { movable = m }
166 -- | Try to shrink the instance based on the reason why we can't
168 shrinkByType :: Instance -> T.FailMode -> T.Result Instance
169 shrinkByType inst T.FailMem = let v = mem inst - T.unitMem
171 then T.Bad "out of memory"
172 else T.Ok inst { mem = v }
173 shrinkByType inst T.FailDisk = let v = dsk inst - T.unitDsk
175 then T.Bad "out of disk"
176 else T.Ok inst { dsk = v }
177 shrinkByType inst T.FailCPU = let v = vcpus inst - T.unitCpu
179 then T.Bad "out of vcpus"
180 else T.Ok inst { vcpus = v }
181 shrinkByType _ f = T.Bad $ "Unhandled failure mode " ++ show f
183 -- | Return the spec of an instance.
184 specOf :: Instance -> T.RSpec
185 specOf Instance { mem = m, dsk = d, vcpus = c } =
186 T.RSpec { T.rspecCpu = c, T.rspecMem = m, T.rspecDsk = d }
188 -- | Computed the number of nodes for a given disk template
189 requiredNodes :: T.DiskTemplate -> Int
190 requiredNodes T.DTDrbd8 = 2