Statistics
| Branch: | Tag: | Revision:

root / Ganeti / HTools / Instance.hs @ c8db97e5

History | View | Annotate | Download (5.1 kB)

1
{-| Module describing an instance.
2

    
3
The instance data type holds very few fields, the algorithm
4
intelligence is in the "Node" and "Cluster" modules.
5

    
6
-}
7

    
8
{-
9

    
10
Copyright (C) 2009 Google Inc.
11

    
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.
16

    
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.
21

    
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
25
02110-1301, USA.
26

    
27
-}
28

    
29
module Ganeti.HTools.Instance
30
    ( Instance(..)
31
    , AssocList
32
    , List
33
    , create
34
    , setIdx
35
    , setName
36
    , setPri
37
    , setSec
38
    , setBoth
39
    , shrinkByType
40
    ) where
41

    
42
import qualified Ganeti.HTools.Types as T
43
import qualified Ganeti.HTools.Container as Container
44

    
45
-- * Type declarations
46

    
47
-- | The instance type
48
data Instance = Instance { name :: String    -- ^ The instance name
49
                         , mem :: Int        -- ^ Memory of the instance
50
                         , dsk :: Int        -- ^ Disk size of instance
51
                         , vcpus :: Int      -- ^ Number of VCPUs
52
                         , running :: Bool   -- ^ Is the instance running?
53
                         , runSt :: String   -- ^ Original (text) run status
54
                         , pNode :: T.Ndx    -- ^ Original primary node
55
                         , sNode :: T.Ndx    -- ^ Original secondary node
56
                         , idx :: T.Idx      -- ^ Internal index
57
                         , util :: T.DynUtil -- ^ Dynamic resource usage
58
                         } deriving (Show)
59

    
60
instance T.Element Instance where
61
    nameOf  = name
62
    idxOf   = idx
63
    setName = setName
64
    setIdx  = setIdx
65

    
66
-- | Base memory unit.
67
unitMem :: Int
68
unitMem = 64
69
-- | Base disk unit.
70
unitDsk :: Int
71
unitDsk = 256
72
-- | Base vcpus unit.
73
unitCpu :: Int
74
unitCpu = 1
75

    
76
-- | A simple name for the int, instance association list.
77
type AssocList = [(T.Idx, Instance)]
78

    
79
-- | A simple name for an instance map.
80
type List = Container.Container Instance
81

    
82
-- * Initialization
83

    
84
-- | Create an instance.
85
--
86
-- Some parameters are not initialized by function, and must be set
87
-- later (via 'setIdx' for example).
88
create :: String -> Int -> Int -> Int -> String -> T.Ndx -> T.Ndx -> Instance
89
create name_init mem_init dsk_init vcpus_init run_init pn sn =
90
    Instance { name = name_init
91
             , mem = mem_init
92
             , dsk = dsk_init
93
             , vcpus = vcpus_init
94
             , running = run_init == "running" || run_init == "ERROR_up"
95
             , runSt = run_init
96
             , pNode = pn
97
             , sNode = sn
98
             , idx = -1
99
             , util = T.zeroUtil
100
             }
101

    
102
-- | Changes the index.
103
--
104
-- This is used only during the building of the data structures.
105
setIdx :: Instance -- ^ The original instance
106
       -> T.Idx    -- ^ New index
107
       -> Instance -- ^ The modified instance
108
setIdx t i = t { idx = i }
109

    
110
-- | Changes the name.
111
--
112
-- This is used only during the building of the data structures.
113
setName :: Instance -- ^ The original instance
114
        -> String   -- ^ New name
115
        -> Instance -- ^ The modified instance
116
setName t s = t { name = s }
117

    
118
-- * Update functions
119

    
120
-- | Changes the primary node of the instance.
121
setPri :: Instance  -- ^ the original instance
122
        -> T.Ndx    -- ^ the new primary node
123
        -> Instance -- ^ the modified instance
124
setPri t p = t { pNode = p }
125

    
126
-- | Changes the secondary node of the instance.
127
setSec :: Instance  -- ^ the original instance
128
        -> T.Ndx    -- ^ the new secondary node
129
        -> Instance -- ^ the modified instance
130
setSec t s = t { sNode = s }
131

    
132
-- | Changes both nodes of the instance.
133
setBoth :: Instance  -- ^ the original instance
134
         -> T.Ndx    -- ^ new primary node index
135
         -> T.Ndx    -- ^ new secondary node index
136
         -> Instance -- ^ the modified instance
137
setBoth t p s = t { pNode = p, sNode = s }
138

    
139
-- | Try to shrink the instance based on the reason why we can't
140
-- allocate it.
141
shrinkByType :: Instance -> T.FailMode -> T.Result Instance
142
shrinkByType inst T.FailMem = let v = mem inst - unitMem
143
                              in if v < unitMem
144
                                 then T.Bad "out of memory"
145
                                 else T.Ok inst { mem = v }
146
shrinkByType inst T.FailDisk = let v = dsk inst - unitDsk
147
                               in if v < unitDsk
148
                                  then T.Bad "out of disk"
149
                                  else T.Ok inst { dsk = v }
150
shrinkByType inst T.FailCPU = let v = vcpus inst - unitCpu
151
                              in if v < unitCpu
152
                                 then T.Bad "out of vcpus"
153
                                 else T.Ok inst { vcpus = v }
154
shrinkByType _ f = T.Bad $ "Unhandled failure mode " ++ show f