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
48 import qualified Ganeti.HTools.Types as T
49 import qualified Ganeti.HTools.Container as Container
50 import qualified Ganeti.Constants as C
52 -- * Type declarations
54 -- | The instance type.
55 data Instance = Instance
56 { name :: String -- ^ The instance name
57 , alias :: String -- ^ The shortened name
58 , mem :: Int -- ^ Memory of the instance
59 , dsk :: Int -- ^ Disk size of instance
60 , vcpus :: Int -- ^ Number of VCPUs
61 , running :: Bool -- ^ Is the instance running?
62 , runSt :: String -- ^ Original (text) run status
63 , pNode :: T.Ndx -- ^ Original primary node
64 , sNode :: T.Ndx -- ^ Original secondary node
65 , idx :: T.Idx -- ^ Internal index
66 , util :: T.DynUtil -- ^ Dynamic resource usage
67 , movable :: Bool -- ^ Can the instance be moved?
68 , autoBalance :: Bool -- ^ Is the instance auto-balanced?
69 , tags :: [String] -- ^ List of instance tags
70 , diskTemplate :: T.DiskTemplate -- ^ The disk template of the instance
71 } deriving (Show, Read)
73 instance T.Element Instance where
78 allNames n = [name n, alias n]
80 -- | Constant holding the running instance states.
81 runningStates :: [String]
82 runningStates = [C.inststRunning, C.inststErrorup]
84 -- | A simple name for the int, instance association list.
85 type AssocList = [(T.Idx, Instance)]
87 -- | A simple name for an instance map.
88 type List = Container.Container Instance
92 -- | Create an instance.
94 -- Some parameters are not initialized by function, and must be set
95 -- later (via 'setIdx' for example).
96 create :: String -> Int -> Int -> Int -> String
97 -> [String] -> Bool -> T.Ndx -> T.Ndx -> T.DiskTemplate -> Instance
98 create name_init mem_init dsk_init vcpus_init run_init tags_init
99 auto_balance_init pn sn dt =
100 Instance { name = name_init
105 , running = run_init `elem` runningStates
113 , autoBalance = auto_balance_init
117 -- | Changes the index.
119 -- This is used only during the building of the data structures.
120 setIdx :: Instance -- ^ The original instance
121 -> T.Idx -- ^ New index
122 -> Instance -- ^ The modified instance
123 setIdx t i = t { idx = i }
125 -- | Changes the name.
127 -- This is used only during the building of the data structures.
128 setName :: Instance -- ^ The original instance
129 -> String -- ^ New name
130 -> Instance -- ^ The modified instance
131 setName t s = t { name = s, alias = s }
133 -- | Changes the alias.
135 -- This is used only during the building of the data structures.
136 setAlias :: Instance -- ^ The original instance
137 -> String -- ^ New alias
138 -> Instance -- ^ The modified instance
139 setAlias t s = t { alias = s }
141 -- * Update functions
143 -- | Changes the primary node of the instance.
144 setPri :: Instance -- ^ the original instance
145 -> T.Ndx -- ^ the new primary node
146 -> Instance -- ^ the modified instance
147 setPri t p = t { pNode = p }
149 -- | Changes the secondary node of the instance.
150 setSec :: Instance -- ^ the original instance
151 -> T.Ndx -- ^ the new secondary node
152 -> Instance -- ^ the modified instance
153 setSec t s = t { sNode = s }
155 -- | Changes both nodes of the instance.
156 setBoth :: Instance -- ^ the original instance
157 -> T.Ndx -- ^ new primary node index
158 -> T.Ndx -- ^ new secondary node index
159 -> Instance -- ^ the modified instance
160 setBoth t p s = t { pNode = p, sNode = s }
162 setMovable :: Instance -- ^ The original instance
163 -> Bool -- ^ New movable flag
164 -> Instance -- ^ The modified instance
165 setMovable t m = t { movable = m }
167 -- | Try to shrink the instance based on the reason why we can't
169 shrinkByType :: Instance -> T.FailMode -> T.Result Instance
170 shrinkByType inst T.FailMem = let v = mem inst - T.unitMem
172 then T.Bad "out of memory"
173 else T.Ok inst { mem = v }
174 shrinkByType inst T.FailDisk = let v = dsk inst - T.unitDsk
176 then T.Bad "out of disk"
177 else T.Ok inst { dsk = v }
178 shrinkByType inst T.FailCPU = let v = vcpus inst - T.unitCpu
180 then T.Bad "out of vcpus"
181 else T.Ok inst { vcpus = v }
182 shrinkByType _ f = T.Bad $ "Unhandled failure mode " ++ show f
184 -- | Return the spec of an instance.
185 specOf :: Instance -> T.RSpec
186 specOf Instance { mem = m, dsk = d, vcpus = c } =
187 T.RSpec { T.rspecCpu = c, T.rspecMem = m, T.rspecDsk = d }
189 -- | Computed the number of nodes for a given disk template
190 requiredNodes :: T.DiskTemplate -> Int
191 requiredNodes T.DTDrbd8 = 2
194 -- | Computes all nodes of an instance.
195 allNodes :: Instance -> [T.Ndx]
196 allNodes inst = case diskTemplate inst of
197 T.DTDrbd8 -> [pNode inst, sNode inst]