root / htools / Ganeti / HTools / Program / Hcheck.hs @ d66aa238
History | View | Annotate | Download (11.7 kB)
1 | 22e513e7 | Agata Murawska | {-| Cluster checker. |
---|---|---|---|
2 | 22e513e7 | Agata Murawska | |
3 | 22e513e7 | Agata Murawska | -} |
4 | 22e513e7 | Agata Murawska | |
5 | 22e513e7 | Agata Murawska | {- |
6 | 22e513e7 | Agata Murawska | |
7 | 22e513e7 | Agata Murawska | Copyright (C) 2012 Google Inc. |
8 | 22e513e7 | Agata Murawska | |
9 | 22e513e7 | Agata Murawska | This program is free software; you can redistribute it and/or modify |
10 | 22e513e7 | Agata Murawska | it under the terms of the GNU General Public License as published by |
11 | 22e513e7 | Agata Murawska | the Free Software Foundation; either version 2 of the License, or |
12 | 22e513e7 | Agata Murawska | (at your option) any later version. |
13 | 22e513e7 | Agata Murawska | |
14 | 22e513e7 | Agata Murawska | This program is distributed in the hope that it will be useful, but |
15 | 22e513e7 | Agata Murawska | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | 22e513e7 | Agata Murawska | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
17 | 22e513e7 | Agata Murawska | General Public License for more details. |
18 | 22e513e7 | Agata Murawska | |
19 | 22e513e7 | Agata Murawska | You should have received a copy of the GNU Gene52al Public License |
20 | 22e513e7 | Agata Murawska | along with this program; if not, write to the Free Software |
21 | 22e513e7 | Agata Murawska | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
22 | 22e513e7 | Agata Murawska | 02110-1301, USA. |
23 | 22e513e7 | Agata Murawska | |
24 | 22e513e7 | Agata Murawska | -} |
25 | 22e513e7 | Agata Murawska | |
26 | 22278fa7 | Iustin Pop | module Ganeti.HTools.Program.Hcheck |
27 | 22278fa7 | Iustin Pop | ( main |
28 | 22278fa7 | Iustin Pop | , options |
29 | 22278fa7 | Iustin Pop | , arguments |
30 | 22278fa7 | Iustin Pop | ) where |
31 | 22e513e7 | Agata Murawska | |
32 | 22e513e7 | Agata Murawska | import Control.Monad |
33 | 7568b296 | Iustin Pop | import Data.List (transpose) |
34 | 22e513e7 | Agata Murawska | import System.Exit |
35 | 1213f9d6 | Agata Murawska | import Text.Printf (printf) |
36 | 1213f9d6 | Agata Murawska | |
37 | 1213f9d6 | Agata Murawska | import qualified Ganeti.HTools.Container as Container |
38 | 1213f9d6 | Agata Murawska | import qualified Ganeti.HTools.Cluster as Cluster |
39 | 5cdbde9a | Agata Murawska | import qualified Ganeti.HTools.Group as Group |
40 | 1213f9d6 | Agata Murawska | import qualified Ganeti.HTools.Node as Node |
41 | 1213f9d6 | Agata Murawska | import qualified Ganeti.HTools.Instance as Instance |
42 | 1213f9d6 | Agata Murawska | |
43 | 1213f9d6 | Agata Murawska | import qualified Ganeti.HTools.Program.Hbal as Hbal |
44 | 22e513e7 | Agata Murawska | |
45 | 22278fa7 | Iustin Pop | import Ganeti.Common |
46 | 22e513e7 | Agata Murawska | import Ganeti.HTools.CLI |
47 | 1213f9d6 | Agata Murawska | import Ganeti.HTools.ExtLoader |
48 | 1213f9d6 | Agata Murawska | import Ganeti.HTools.Loader |
49 | 1213f9d6 | Agata Murawska | import Ganeti.HTools.Types |
50 | 707cd3d7 | Helga Velroyen | import Ganeti.Utils |
51 | 22e513e7 | Agata Murawska | |
52 | 22e513e7 | Agata Murawska | -- | Options list and functions. |
53 | d66aa238 | Iustin Pop | options :: IO [OptType] |
54 | 22e513e7 | Agata Murawska | options = |
55 | d66aa238 | Iustin Pop | return |
56 | d66aa238 | Iustin Pop | [ oDataFile |
57 | d66aa238 | Iustin Pop | , oDiskMoves |
58 | d66aa238 | Iustin Pop | , oDynuFile |
59 | d66aa238 | Iustin Pop | , oEvacMode |
60 | d66aa238 | Iustin Pop | , oExInst |
61 | d66aa238 | Iustin Pop | , oExTags |
62 | d66aa238 | Iustin Pop | , oIAllocSrc |
63 | d66aa238 | Iustin Pop | , oInstMoves |
64 | d66aa238 | Iustin Pop | , oLuxiSocket |
65 | d66aa238 | Iustin Pop | , oMachineReadable |
66 | d66aa238 | Iustin Pop | , oMaxCpu |
67 | d66aa238 | Iustin Pop | , oMaxSolLength |
68 | d66aa238 | Iustin Pop | , oMinDisk |
69 | d66aa238 | Iustin Pop | , oMinGain |
70 | d66aa238 | Iustin Pop | , oMinGainLim |
71 | d66aa238 | Iustin Pop | , oMinScore |
72 | d66aa238 | Iustin Pop | , oNoSimulation |
73 | d66aa238 | Iustin Pop | , oOfflineNode |
74 | d66aa238 | Iustin Pop | , oQuiet |
75 | d66aa238 | Iustin Pop | , oRapiMaster |
76 | d66aa238 | Iustin Pop | , oSelInst |
77 | d66aa238 | Iustin Pop | , oVerbose |
78 | d66aa238 | Iustin Pop | ] |
79 | 22e513e7 | Agata Murawska | |
80 | 22278fa7 | Iustin Pop | -- | The list of arguments supported by the program. |
81 | 22278fa7 | Iustin Pop | arguments :: [ArgCompletion] |
82 | 22278fa7 | Iustin Pop | arguments = [] |
83 | 22278fa7 | Iustin Pop | |
84 | 1213f9d6 | Agata Murawska | -- | Check phase - are we before (initial) or after rebalance. |
85 | 1213f9d6 | Agata Murawska | data Phase = Initial |
86 | 1213f9d6 | Agata Murawska | | Rebalanced |
87 | 1213f9d6 | Agata Murawska | |
88 | 22b16dd0 | Agata Murawska | -- | Level of presented statistics. |
89 | 22b16dd0 | Agata Murawska | data Level = GroupLvl |
90 | 22b16dd0 | Agata Murawska | | ClusterLvl |
91 | 22b16dd0 | Agata Murawska | |
92 | 7f119c27 | Iustin Pop | -- | A type alias for a group index and node\/instance lists. |
93 | 7f119c27 | Iustin Pop | type GroupInfo = (Gdx, (Node.List, Instance.List)) |
94 | 7f119c27 | Iustin Pop | |
95 | 7f119c27 | Iustin Pop | -- | A type alias for group stats. |
96 | 7f119c27 | Iustin Pop | type GroupStats = ((Group.Group, Double), [Int]) |
97 | 7f119c27 | Iustin Pop | |
98 | d64acbb5 | Agata Murawska | -- | Prefix for machine readable names. |
99 | 1213f9d6 | Agata Murawska | htcPrefix :: String |
100 | 1213f9d6 | Agata Murawska | htcPrefix = "HCHECK" |
101 | 1213f9d6 | Agata Murawska | |
102 | 1213f9d6 | Agata Murawska | -- | Data showed both per group and per cluster. |
103 | 1213f9d6 | Agata Murawska | commonData :: [(String, String)] |
104 | 1213f9d6 | Agata Murawska | commonData =[ ("N1_FAIL", "Nodes not N+1 happy") |
105 | 1213f9d6 | Agata Murawska | , ("CONFLICT_TAGS", "Nodes with conflicting instances") |
106 | 85890a9d | Iustin Pop | , ("OFFLINE_PRI", "Instances having the primary node offline") |
107 | 85890a9d | Iustin Pop | , ("OFFLINE_SEC", "Instances having a secondary node offline") |
108 | 1213f9d6 | Agata Murawska | ] |
109 | 1213f9d6 | Agata Murawska | |
110 | 1213f9d6 | Agata Murawska | -- | Data showed per group. |
111 | 1213f9d6 | Agata Murawska | groupData :: [(String, String)] |
112 | 1213f9d6 | Agata Murawska | groupData = commonData ++ [("SCORE", "Group score")] |
113 | 1213f9d6 | Agata Murawska | |
114 | 1213f9d6 | Agata Murawska | -- | Data showed per cluster. |
115 | 1213f9d6 | Agata Murawska | clusterData :: [(String, String)] |
116 | 92eacdd8 | Agata Murawska | clusterData = commonData ++ |
117 | b1a9d630 | Iustin Pop | [ ("NEED_REBALANCE", "Cluster is not healthy") ] |
118 | 92eacdd8 | Agata Murawska | |
119 | b5b19d5e | Agata Murawska | -- | Phase-specific prefix for machine readable version. |
120 | b5b19d5e | Agata Murawska | phasePrefix :: Phase -> String |
121 | b5b19d5e | Agata Murawska | phasePrefix Initial = "INIT" |
122 | b5b19d5e | Agata Murawska | phasePrefix Rebalanced = "FINAL" |
123 | b5b19d5e | Agata Murawska | |
124 | b5b19d5e | Agata Murawska | -- | Level-specific prefix for machine readable version. |
125 | b5b19d5e | Agata Murawska | levelPrefix :: Level -> String |
126 | b5b19d5e | Agata Murawska | levelPrefix GroupLvl = "GROUP" |
127 | b5b19d5e | Agata Murawska | levelPrefix ClusterLvl = "CLUSTER" |
128 | b5b19d5e | Agata Murawska | |
129 | 3c0687b5 | Agata Murawska | -- | Machine-readable keys to show depending on given level. |
130 | 3c0687b5 | Agata Murawska | keysData :: Level -> [String] |
131 | 3c0687b5 | Agata Murawska | keysData GroupLvl = map fst groupData |
132 | 3c0687b5 | Agata Murawska | keysData ClusterLvl = map fst clusterData |
133 | 3c0687b5 | Agata Murawska | |
134 | b5b19d5e | Agata Murawska | -- | Description of phases for human readable version. |
135 | b5b19d5e | Agata Murawska | phaseDescr :: Phase -> String |
136 | b5b19d5e | Agata Murawska | phaseDescr Initial = "initially" |
137 | b5b19d5e | Agata Murawska | phaseDescr Rebalanced = "after rebalancing" |
138 | b5b19d5e | Agata Murawska | |
139 | 3c0687b5 | Agata Murawska | -- | Description to show depending on given level. |
140 | 3c0687b5 | Agata Murawska | descrData :: Level -> [String] |
141 | 3c0687b5 | Agata Murawska | descrData GroupLvl = map snd groupData |
142 | 3c0687b5 | Agata Murawska | descrData ClusterLvl = map snd clusterData |
143 | 3c0687b5 | Agata Murawska | |
144 | 3c0687b5 | Agata Murawska | -- | Human readable prefix for statistics. |
145 | 3c0687b5 | Agata Murawska | phaseLevelDescr :: Phase -> Level -> Maybe String -> String |
146 | 3c0687b5 | Agata Murawska | phaseLevelDescr phase GroupLvl (Just name) = |
147 | 3c0687b5 | Agata Murawska | printf "Statistics for group %s %s\n" name $ phaseDescr phase |
148 | 3c0687b5 | Agata Murawska | phaseLevelDescr phase GroupLvl Nothing = |
149 | 3c0687b5 | Agata Murawska | printf "Statistics for group %s\n" $ phaseDescr phase |
150 | 3c0687b5 | Agata Murawska | phaseLevelDescr phase ClusterLvl _ = |
151 | 3c0687b5 | Agata Murawska | printf "Cluster statistics %s\n" $ phaseDescr phase |
152 | 1213f9d6 | Agata Murawska | |
153 | 22b16dd0 | Agata Murawska | -- | Format a list of key, value as a shell fragment. |
154 | 22b16dd0 | Agata Murawska | printKeysHTC :: [(String, String)] -> IO () |
155 | 22b16dd0 | Agata Murawska | printKeysHTC = printKeys htcPrefix |
156 | 22b16dd0 | Agata Murawska | |
157 | 92eacdd8 | Agata Murawska | -- | Prepare string from boolean value. |
158 | 92eacdd8 | Agata Murawska | printBool :: Bool -- ^ Whether the result should be machine readable |
159 | 92eacdd8 | Agata Murawska | -> Bool -- ^ Value to be converted to string |
160 | 92eacdd8 | Agata Murawska | -> String |
161 | 92eacdd8 | Agata Murawska | printBool True True = "1" |
162 | 92eacdd8 | Agata Murawska | printBool True False = "0" |
163 | 92eacdd8 | Agata Murawska | printBool False b = show b |
164 | 92eacdd8 | Agata Murawska | |
165 | 81bcbbd3 | Iustin Pop | -- | Print mapping from group idx to group uuid (only in machine |
166 | 81bcbbd3 | Iustin Pop | -- readable mode). |
167 | 592601b3 | Agata Murawska | printGroupsMappings :: Group.List -> IO () |
168 | 592601b3 | Agata Murawska | printGroupsMappings gl = do |
169 | 5b11f8db | Iustin Pop | let extract_vals g = (printf "GROUP_UUID_%d" $ Group.idx g :: String, |
170 | 5b11f8db | Iustin Pop | Group.uuid g) |
171 | 592601b3 | Agata Murawska | printpairs = map extract_vals (Container.elems gl) |
172 | 592601b3 | Agata Murawska | printKeysHTC printpairs |
173 | 592601b3 | Agata Murawska | |
174 | 3c0687b5 | Agata Murawska | -- | Prepare a single key given a certain level and phase of simulation. |
175 | 3c0687b5 | Agata Murawska | prepareKey :: Level -> Phase -> Maybe String -> String -> String |
176 | 3c0687b5 | Agata Murawska | prepareKey level phase Nothing suffix = |
177 | 3c0687b5 | Agata Murawska | printf "%s_%s_%s" (phasePrefix phase) (levelPrefix level) suffix |
178 | 3c0687b5 | Agata Murawska | prepareKey level phase (Just idx) suffix = |
179 | 3c0687b5 | Agata Murawska | printf "%s_%s_%s_%s" (phasePrefix phase) (levelPrefix level) idx suffix |
180 | 3c0687b5 | Agata Murawska | |
181 | 3c0687b5 | Agata Murawska | -- | Print all the statistics for given level and phase. |
182 | 3c0687b5 | Agata Murawska | printStats :: Int -- ^ Verbosity level |
183 | 3c0687b5 | Agata Murawska | -> Bool -- ^ If the output should be machine readable |
184 | 3c0687b5 | Agata Murawska | -> Level -- ^ Level on which we are printing |
185 | 3c0687b5 | Agata Murawska | -> Phase -- ^ Current phase of simulation |
186 | 3c0687b5 | Agata Murawska | -> [String] -- ^ Values to print |
187 | 3c0687b5 | Agata Murawska | -> Maybe String -- ^ Additional data for groups |
188 | 3c0687b5 | Agata Murawska | -> IO () |
189 | 3c0687b5 | Agata Murawska | printStats _ True level phase values gidx = do |
190 | 3c0687b5 | Agata Murawska | let keys = map (prepareKey level phase gidx) (keysData level) |
191 | 3c0687b5 | Agata Murawska | printKeysHTC $ zip keys values |
192 | 3c0687b5 | Agata Murawska | |
193 | 3c0687b5 | Agata Murawska | printStats verbose False level phase values name = do |
194 | 3c0687b5 | Agata Murawska | let prefix = phaseLevelDescr phase level name |
195 | 3c0687b5 | Agata Murawska | descr = descrData level |
196 | 1213f9d6 | Agata Murawska | unless (verbose == 0) $ do |
197 | 4b77c2a2 | Iustin Pop | putStrLn "" |
198 | 4b77c2a2 | Iustin Pop | putStr prefix |
199 | 2cdaf225 | Iustin Pop | mapM_ (uncurry (printf " %s: %s\n")) (zip descr values) |
200 | 3c0687b5 | Agata Murawska | |
201 | 3c0687b5 | Agata Murawska | -- | Extract name or idx from group. |
202 | 3c0687b5 | Agata Murawska | extractGroupData :: Bool -> Group.Group -> String |
203 | 81bcbbd3 | Iustin Pop | extractGroupData True grp = show $ Group.idx grp |
204 | 3c0687b5 | Agata Murawska | extractGroupData False grp = Group.name grp |
205 | 3c0687b5 | Agata Murawska | |
206 | 3c0687b5 | Agata Murawska | -- | Prepare values for group. |
207 | 3c0687b5 | Agata Murawska | prepareGroupValues :: [Int] -> Double -> [String] |
208 | 3c0687b5 | Agata Murawska | prepareGroupValues stats score = |
209 | 81bcbbd3 | Iustin Pop | map show stats ++ [printf "%.8f" score] |
210 | 3c0687b5 | Agata Murawska | |
211 | 3c0687b5 | Agata Murawska | -- | Prepare values for cluster. |
212 | 3c0687b5 | Agata Murawska | prepareClusterValues :: Bool -> [Int] -> [Bool] -> [String] |
213 | 3c0687b5 | Agata Murawska | prepareClusterValues machineread stats bstats = |
214 | 81bcbbd3 | Iustin Pop | map show stats ++ map (printBool machineread) bstats |
215 | 3c0687b5 | Agata Murawska | |
216 | 3c0687b5 | Agata Murawska | -- | Print all the statistics on a group level. |
217 | 7f119c27 | Iustin Pop | printGroupStats :: Int -> Bool -> Phase -> GroupStats -> IO () |
218 | 4b77c2a2 | Iustin Pop | printGroupStats verbose machineread phase ((grp, score), stats) = do |
219 | 3c0687b5 | Agata Murawska | let values = prepareGroupValues stats score |
220 | 3c0687b5 | Agata Murawska | extradata = extractGroupData machineread grp |
221 | 3c0687b5 | Agata Murawska | printStats verbose machineread GroupLvl phase values (Just extradata) |
222 | 1213f9d6 | Agata Murawska | |
223 | 1213f9d6 | Agata Murawska | -- | Print all the statistics on a cluster (global) level. |
224 | b1a9d630 | Iustin Pop | printClusterStats :: Int -> Bool -> Phase -> [Int] -> Bool -> IO () |
225 | b1a9d630 | Iustin Pop | printClusterStats verbose machineread phase stats needhbal = do |
226 | b1a9d630 | Iustin Pop | let values = prepareClusterValues machineread stats [needhbal] |
227 | 3c0687b5 | Agata Murawska | printStats verbose machineread ClusterLvl phase values Nothing |
228 | caa97388 | Agata Murawska | |
229 | caa97388 | Agata Murawska | -- | Check if any of cluster metrics is non-zero. |
230 | caa97388 | Agata Murawska | clusterNeedsRebalance :: [Int] -> Bool |
231 | caa97388 | Agata Murawska | clusterNeedsRebalance stats = sum stats > 0 |
232 | 1213f9d6 | Agata Murawska | |
233 | 1213f9d6 | Agata Murawska | {- | Check group for N+1 hapiness, conflicts of primaries on nodes and |
234 | 1213f9d6 | Agata Murawska | instances residing on offline nodes. |
235 | 1213f9d6 | Agata Murawska | |
236 | 1213f9d6 | Agata Murawska | -} |
237 | 7f119c27 | Iustin Pop | perGroupChecks :: Group.List -> GroupInfo -> GroupStats |
238 | 4b77c2a2 | Iustin Pop | perGroupChecks gl (gidx, (nl, il)) = |
239 | 5cdbde9a | Agata Murawska | let grp = Container.find gidx gl |
240 | 5cdbde9a | Agata Murawska | offnl = filter Node.offline (Container.elems nl) |
241 | 2cdaf225 | Iustin Pop | n1violated = length . fst $ Cluster.computeBadItems nl il |
242 | 1213f9d6 | Agata Murawska | conflicttags = length $ filter (>0) |
243 | 1213f9d6 | Agata Murawska | (map Node.conflictingPrimaries (Container.elems nl)) |
244 | 1213f9d6 | Agata Murawska | offline_pri = sum . map length $ map Node.pList offnl |
245 | 1213f9d6 | Agata Murawska | offline_sec = length $ map Node.sList offnl |
246 | 1213f9d6 | Agata Murawska | score = Cluster.compCV nl |
247 | 1213f9d6 | Agata Murawska | groupstats = [ n1violated |
248 | 1213f9d6 | Agata Murawska | , conflicttags |
249 | 1213f9d6 | Agata Murawska | , offline_pri |
250 | 1213f9d6 | Agata Murawska | , offline_sec |
251 | 1213f9d6 | Agata Murawska | ] |
252 | 4b77c2a2 | Iustin Pop | in ((grp, score), groupstats) |
253 | 1213f9d6 | Agata Murawska | |
254 | 1213f9d6 | Agata Murawska | -- | Use Hbal's iterateDepth to simulate group rebalance. |
255 | 81bcbbd3 | Iustin Pop | executeSimulation :: Options -> Cluster.Table -> Double |
256 | 81bcbbd3 | Iustin Pop | -> Gdx -> Node.List -> Instance.List |
257 | 7f119c27 | Iustin Pop | -> IO GroupInfo |
258 | 5cc97485 | Agata Murawska | executeSimulation opts ini_tbl min_cv gidx nl il = do |
259 | 5cc97485 | Agata Murawska | let imlen = maximum . map (length . Instance.alias) $ Container.elems il |
260 | 5cc97485 | Agata Murawska | nmlen = maximum . map (length . Node.alias) $ Container.elems nl |
261 | 5cc97485 | Agata Murawska | |
262 | 5cc97485 | Agata Murawska | (fin_tbl, _) <- Hbal.iterateDepth False ini_tbl |
263 | 5cc97485 | Agata Murawska | (optMaxLength opts) |
264 | 5cc97485 | Agata Murawska | (optDiskMoves opts) |
265 | 5cc97485 | Agata Murawska | (optInstMoves opts) |
266 | 5cc97485 | Agata Murawska | nmlen imlen [] min_cv |
267 | 5cc97485 | Agata Murawska | (optMinGainLim opts) (optMinGain opts) |
268 | 5cc97485 | Agata Murawska | (optEvacMode opts) |
269 | 5cc97485 | Agata Murawska | |
270 | 5cc97485 | Agata Murawska | let (Cluster.Table fin_nl fin_il _ _) = fin_tbl |
271 | 5cc97485 | Agata Murawska | return (gidx, (fin_nl, fin_il)) |
272 | 5cc97485 | Agata Murawska | |
273 | 5cc97485 | Agata Murawska | -- | Simulate group rebalance if group's score is not good |
274 | 7f119c27 | Iustin Pop | maybeSimulateGroupRebalance :: Options -> GroupInfo -> IO GroupInfo |
275 | 5cc97485 | Agata Murawska | maybeSimulateGroupRebalance opts (gidx, (nl, il)) = do |
276 | 1213f9d6 | Agata Murawska | let ini_cv = Cluster.compCV nl |
277 | 1213f9d6 | Agata Murawska | ini_tbl = Cluster.Table nl il ini_cv [] |
278 | 1213f9d6 | Agata Murawska | min_cv = optMinScore opts |
279 | 81bcbbd3 | Iustin Pop | if ini_cv < min_cv |
280 | 1213f9d6 | Agata Murawska | then return (gidx, (nl, il)) |
281 | 5cc97485 | Agata Murawska | else executeSimulation opts ini_tbl min_cv gidx nl il |
282 | 1213f9d6 | Agata Murawska | |
283 | ecc39665 | Agata Murawska | -- | Decide whether to simulate rebalance. |
284 | ecc39665 | Agata Murawska | maybeSimulateRebalance :: Bool -- ^ Whether to simulate rebalance |
285 | ecc39665 | Agata Murawska | -> Options -- ^ Command line options |
286 | 7f119c27 | Iustin Pop | -> [GroupInfo] -- ^ Group data |
287 | 7f119c27 | Iustin Pop | -> IO [GroupInfo] |
288 | ecc39665 | Agata Murawska | maybeSimulateRebalance True opts cluster = |
289 | 5cc97485 | Agata Murawska | mapM (maybeSimulateGroupRebalance opts) cluster |
290 | ecc39665 | Agata Murawska | maybeSimulateRebalance False _ cluster = return cluster |
291 | ecc39665 | Agata Murawska | |
292 | 1213f9d6 | Agata Murawska | -- | Prints the final @OK@ marker in machine readable output. |
293 | 1213f9d6 | Agata Murawska | printFinalHTC :: Bool -> IO () |
294 | 1213f9d6 | Agata Murawska | printFinalHTC = printFinal htcPrefix |
295 | 1213f9d6 | Agata Murawska | |
296 | 22e513e7 | Agata Murawska | -- | Main function. |
297 | 22e513e7 | Agata Murawska | main :: Options -> [String] -> IO () |
298 | 1213f9d6 | Agata Murawska | main opts args = do |
299 | 707cd3d7 | Helga Velroyen | unless (null args) $ exitErr "This program doesn't take any arguments." |
300 | 1213f9d6 | Agata Murawska | |
301 | 1213f9d6 | Agata Murawska | let verbose = optVerbose opts |
302 | 1213f9d6 | Agata Murawska | machineread = optMachineReadable opts |
303 | 1213f9d6 | Agata Murawska | nosimulation = optNoSimulation opts |
304 | 1213f9d6 | Agata Murawska | |
305 | 5cdbde9a | Agata Murawska | (ClusterData gl fixed_nl ilf _ _) <- loadExternalData opts |
306 | 1213f9d6 | Agata Murawska | nlf <- setNodeStatus opts fixed_nl |
307 | 1213f9d6 | Agata Murawska | |
308 | b1a9d630 | Iustin Pop | let splitcluster = Cluster.splitCluster nlf ilf |
309 | 1213f9d6 | Agata Murawska | |
310 | 592601b3 | Agata Murawska | when machineread $ printGroupsMappings gl |
311 | 5cdbde9a | Agata Murawska | |
312 | 4b77c2a2 | Iustin Pop | let groupsstats = map (perGroupChecks gl) splitcluster |
313 | 4b77c2a2 | Iustin Pop | clusterstats = map sum . transpose . map snd $ groupsstats |
314 | caa97388 | Agata Murawska | needrebalance = clusterNeedsRebalance clusterstats |
315 | 1213f9d6 | Agata Murawska | |
316 | 66ad857a | Iustin Pop | unless (verbose == 0 || machineread) . |
317 | 66ad857a | Iustin Pop | putStrLn $ if nosimulation |
318 | 66ad857a | Iustin Pop | then "Running in no-simulation mode." |
319 | 66ad857a | Iustin Pop | else if needrebalance |
320 | 66ad857a | Iustin Pop | then "Cluster needs rebalancing." |
321 | 66ad857a | Iustin Pop | else "No need to rebalance cluster, no problems found." |
322 | 4b77c2a2 | Iustin Pop | |
323 | 4b77c2a2 | Iustin Pop | mapM_ (printGroupStats verbose machineread Initial) groupsstats |
324 | 1213f9d6 | Agata Murawska | |
325 | 4b77c2a2 | Iustin Pop | printClusterStats verbose machineread Initial clusterstats needrebalance |
326 | 1213f9d6 | Agata Murawska | |
327 | ecc39665 | Agata Murawska | let exitOK = nosimulation || not needrebalance |
328 | b1a9d630 | Iustin Pop | simulate = not nosimulation && needrebalance |
329 | ecc39665 | Agata Murawska | |
330 | ecc39665 | Agata Murawska | rebalancedcluster <- maybeSimulateRebalance simulate opts splitcluster |
331 | ecc39665 | Agata Murawska | |
332 | ecc39665 | Agata Murawska | when (simulate || machineread) $ do |
333 | 4b77c2a2 | Iustin Pop | let newgroupstats = map (perGroupChecks gl) rebalancedcluster |
334 | 4b77c2a2 | Iustin Pop | newclusterstats = map sum . transpose . map snd $ newgroupstats |
335 | caa97388 | Agata Murawska | newneedrebalance = clusterNeedsRebalance clusterstats |
336 | ecc39665 | Agata Murawska | |
337 | 4b77c2a2 | Iustin Pop | mapM_ (printGroupStats verbose machineread Rebalanced) newgroupstats |
338 | 4b77c2a2 | Iustin Pop | |
339 | caa97388 | Agata Murawska | printClusterStats verbose machineread Rebalanced newclusterstats |
340 | b1a9d630 | Iustin Pop | newneedrebalance |
341 | 1213f9d6 | Agata Murawska | |
342 | 1213f9d6 | Agata Murawska | printFinalHTC machineread |
343 | ecc39665 | Agata Murawska | |
344 | 2cdaf225 | Iustin Pop | unless exitOK . exitWith $ ExitFailure 1 |