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 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
43 import qualified Ganeti.HTools.Types as T
44 import qualified Ganeti.HTools.Container as Container
46 -- * Type declarations
48 -- | The instance type
49 data Instance = Instance { name :: String -- ^ The instance name
50 , mem :: Int -- ^ Memory of the instance
51 , dsk :: Int -- ^ Disk size of instance
52 , vcpus :: Int -- ^ Number of VCPUs
53 , running :: Bool -- ^ Is the instance running?
54 , runSt :: String -- ^ Original (text) run status
55 , pNode :: T.Ndx -- ^ Original primary node
56 , sNode :: T.Ndx -- ^ Original secondary node
57 , idx :: T.Idx -- ^ Internal index
58 , util :: T.DynUtil -- ^ Dynamic resource usage
61 instance T.Element Instance where
67 -- | Base memory unit.
77 -- | A simple name for the int, instance association list.
78 type AssocList = [(T.Idx, Instance)]
80 -- | A simple name for an instance map.
81 type List = Container.Container Instance
85 -- | Create an instance.
87 -- Some parameters are not initialized by function, and must be set
88 -- later (via 'setIdx' for example).
89 create :: String -> Int -> Int -> Int -> String -> T.Ndx -> T.Ndx -> Instance
90 create name_init mem_init dsk_init vcpus_init run_init pn sn =
91 Instance { name = name_init
95 , running = run_init == "running" || run_init == "ERROR_up"
103 -- | Changes the index.
105 -- This is used only during the building of the data structures.
106 setIdx :: Instance -- ^ The original instance
107 -> T.Idx -- ^ New index
108 -> Instance -- ^ The modified instance
109 setIdx t i = t { idx = i }
111 -- | Changes the name.
113 -- This is used only during the building of the data structures.
114 setName :: Instance -- ^ The original instance
115 -> String -- ^ New name
116 -> Instance -- ^ The modified instance
117 setName t s = t { name = s }
119 -- * Update functions
121 -- | Changes the primary node of the instance.
122 setPri :: Instance -- ^ the original instance
123 -> T.Ndx -- ^ the new primary node
124 -> Instance -- ^ the modified instance
125 setPri t p = t { pNode = p }
127 -- | Changes the secondary node of the instance.
128 setSec :: Instance -- ^ the original instance
129 -> T.Ndx -- ^ the new secondary node
130 -> Instance -- ^ the modified instance
131 setSec t s = t { sNode = s }
133 -- | Changes both nodes of the instance.
134 setBoth :: Instance -- ^ the original instance
135 -> T.Ndx -- ^ new primary node index
136 -> T.Ndx -- ^ new secondary node index
137 -> Instance -- ^ the modified instance
138 setBoth t p s = t { pNode = p, sNode = s }
140 -- | Try to shrink the instance based on the reason why we can't
142 shrinkByType :: Instance -> T.FailMode -> T.Result Instance
143 shrinkByType inst T.FailMem = let v = mem inst - unitMem
145 then T.Bad "out of memory"
146 else T.Ok inst { mem = v }
147 shrinkByType inst T.FailDisk = let v = dsk inst - unitDsk
149 then T.Bad "out of disk"
150 else T.Ok inst { dsk = v }
151 shrinkByType inst T.FailCPU = let v = vcpus inst - unitCpu
153 then T.Bad "out of vcpus"
154 else T.Ok inst { vcpus = v }
155 shrinkByType _ f = T.Bad $ "Unhandled failure mode " ++ show f
157 -- | Return the spec of an instance.
158 specOf :: Instance -> T.RSpec
159 specOf Instance { mem = m, dsk = d, vcpus = c } =
160 T.RSpec { T.rspecCpu = c, T.rspecMem = m, T.rspecDsk = d }