Statistics
| Branch: | Tag: | Revision:

root / htools / hail.hs @ 9afa0de1

History | View | Annotate | Download (3.9 kB)

1 585d4420 Iustin Pop
{-| Solver for N+1 cluster errors
2 585d4420 Iustin Pop
3 585d4420 Iustin Pop
-}
4 585d4420 Iustin Pop
5 e2fa2baf Iustin Pop
{-
6 e2fa2baf Iustin Pop
7 4bc33d60 Iustin Pop
Copyright (C) 2009, 2010, 2011 Google Inc.
8 e2fa2baf Iustin Pop
9 e2fa2baf Iustin Pop
This program is free software; you can redistribute it and/or modify
10 e2fa2baf Iustin Pop
it under the terms of the GNU General Public License as published by
11 e2fa2baf Iustin Pop
the Free Software Foundation; either version 2 of the License, or
12 e2fa2baf Iustin Pop
(at your option) any later version.
13 e2fa2baf Iustin Pop
14 e2fa2baf Iustin Pop
This program is distributed in the hope that it will be useful, but
15 e2fa2baf Iustin Pop
WITHOUT ANY WARRANTY; without even the implied warranty of
16 e2fa2baf Iustin Pop
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 e2fa2baf Iustin Pop
General Public License for more details.
18 e2fa2baf Iustin Pop
19 e2fa2baf Iustin Pop
You should have received a copy of the GNU General Public License
20 e2fa2baf Iustin Pop
along with this program; if not, write to the Free Software
21 e2fa2baf Iustin Pop
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22 e2fa2baf Iustin Pop
02110-1301, USA.
23 e2fa2baf Iustin Pop
24 e2fa2baf Iustin Pop
-}
25 e2fa2baf Iustin Pop
26 585d4420 Iustin Pop
module Main (main) where
27 585d4420 Iustin Pop
28 585d4420 Iustin Pop
import Data.List
29 f3d53161 Iustin Pop
import Data.Maybe (isJust, fromJust)
30 585d4420 Iustin Pop
import Monad
31 0903280b Iustin Pop
import System (exitWith, ExitCode(..))
32 585d4420 Iustin Pop
import System.IO
33 585d4420 Iustin Pop
import qualified System
34 585d4420 Iustin Pop
35 585d4420 Iustin Pop
import qualified Ganeti.HTools.Cluster as Cluster
36 0427285d Iustin Pop
37 0427285d Iustin Pop
import Ganeti.HTools.CLI
38 585d4420 Iustin Pop
import Ganeti.HTools.IAlloc
39 e4c5beaf Iustin Pop
import Ganeti.HTools.Types
40 34c00528 Iustin Pop
import Ganeti.HTools.Loader (RqType(..), Request(..), ClusterData(..))
41 01fec0a1 Iustin Pop
import Ganeti.HTools.ExtLoader (loadExternalData)
42 585d4420 Iustin Pop
43 585d4420 Iustin Pop
-- | Options list and functions
44 0427285d Iustin Pop
options :: [OptType]
45 01fec0a1 Iustin Pop
options =
46 01fec0a1 Iustin Pop
    [ oPrintNodes
47 01fec0a1 Iustin Pop
    , oDataFile
48 01fec0a1 Iustin Pop
    , oNodeSim
49 b790839a Iustin Pop
    , oVerbose
50 01fec0a1 Iustin Pop
    , oShowVer
51 01fec0a1 Iustin Pop
    , oShowHelp
52 01fec0a1 Iustin Pop
    ]
53 f826c5e0 Iustin Pop
54 54365762 Iustin Pop
processResults :: (Monad m) =>
55 54365762 Iustin Pop
                  RqType -> Cluster.AllocSolution
56 db4d9a9b Iustin Pop
               -> m Cluster.AllocSolution
57 db4d9a9b Iustin Pop
processResults _ (Cluster.AllocSolution { Cluster.asSolutions = [],
58 db4d9a9b Iustin Pop
                                          Cluster.asLog = msgs }) =
59 db4d9a9b Iustin Pop
  fail $ intercalate ", " msgs
60 db4d9a9b Iustin Pop
61 db4d9a9b Iustin Pop
processResults (Evacuate _) as = return as
62 54365762 Iustin Pop
63 85d0ddc3 Iustin Pop
processResults _ as =
64 85d0ddc3 Iustin Pop
    case Cluster.asSolutions as of
65 db4d9a9b Iustin Pop
      _:[] -> return as
66 23f9ab76 Iustin Pop
      _ -> fail "Internal error: multiple allocation solutions"
67 585d4420 Iustin Pop
68 78694255 Iustin Pop
-- | Process a request and return new node lists
69 f2280553 Iustin Pop
processRequest :: Request
70 478df686 Iustin Pop
               -> Result Cluster.AllocSolution
71 78694255 Iustin Pop
processRequest request =
72 34c00528 Iustin Pop
  let Request rqtype (ClusterData gl nl il _) = request
73 78694255 Iustin Pop
  in case rqtype of
74 aec636b9 Iustin Pop
       Allocate xi reqn -> Cluster.tryMGAlloc gl nl il xi reqn
75 4bc33d60 Iustin Pop
       Relocate idx reqn exnodes -> Cluster.tryMGReloc gl nl il
76 4bc33d60 Iustin Pop
                                    idx reqn exnodes
77 1bc47d38 Iustin Pop
       Evacuate exnodes -> Cluster.tryMGEvac gl nl il exnodes
78 2c3273e7 Iustin Pop
       MultiReloc _ _ -> fail "multi-reloc not handled"
79 78694255 Iustin Pop
80 01fec0a1 Iustin Pop
-- | Reads the request from the data file(s)
81 01fec0a1 Iustin Pop
readRequest :: Options -> [String] -> IO Request
82 01fec0a1 Iustin Pop
readRequest opts args = do
83 01fec0a1 Iustin Pop
  when (null args) $ do
84 01fec0a1 Iustin Pop
         hPutStrLn stderr "Error: this program needs an input file."
85 01fec0a1 Iustin Pop
         exitWith $ ExitFailure 1
86 01fec0a1 Iustin Pop
87 01fec0a1 Iustin Pop
  input_data <- readFile (head args)
88 01fec0a1 Iustin Pop
  r1 <- case (parseData input_data) of
89 01fec0a1 Iustin Pop
          Bad err -> do
90 01fec0a1 Iustin Pop
            hPutStrLn stderr $ "Error: " ++ err
91 01fec0a1 Iustin Pop
            exitWith $ ExitFailure 1
92 01fec0a1 Iustin Pop
          Ok rq -> return rq
93 d5072e4c Iustin Pop
  (if isJust (optDataFile opts) ||  (not . null . optNodeSim) opts
94 d5072e4c Iustin Pop
   then do
95 d5072e4c Iustin Pop
     cdata <- loadExternalData opts
96 d5072e4c Iustin Pop
     let Request rqt _ = r1
97 d5072e4c Iustin Pop
     return $ Request rqt cdata
98 d5072e4c Iustin Pop
   else return r1)
99 01fec0a1 Iustin Pop
100 585d4420 Iustin Pop
-- | Main function.
101 585d4420 Iustin Pop
main :: IO ()
102 585d4420 Iustin Pop
main = do
103 585d4420 Iustin Pop
  cmd_args <- System.getArgs
104 f3d53161 Iustin Pop
  (opts, args) <- parseOpts cmd_args "hail" options
105 585d4420 Iustin Pop
106 01fec0a1 Iustin Pop
  let shownodes = optShowNodes opts
107 b790839a Iustin Pop
      verbose = optVerbose opts
108 585d4420 Iustin Pop
109 01fec0a1 Iustin Pop
  request <- readRequest opts args
110 585d4420 Iustin Pop
111 34c00528 Iustin Pop
  let Request rq cdata = request
112 f3d53161 Iustin Pop
113 b790839a Iustin Pop
  when (verbose > 1) $
114 b790839a Iustin Pop
       hPutStrLn stderr $ "Received request: " ++ show rq
115 b790839a Iustin Pop
116 b790839a Iustin Pop
  when (verbose > 2) $
117 b790839a Iustin Pop
       hPutStrLn stderr $ "Received cluster data: " ++ show cdata
118 b790839a Iustin Pop
119 f3d53161 Iustin Pop
  when (isJust shownodes) $ do
120 f3d53161 Iustin Pop
         hPutStrLn stderr "Initial cluster status:"
121 34c00528 Iustin Pop
         hPutStrLn stderr $ Cluster.printNodes (cdNodes cdata)
122 34c00528 Iustin Pop
                       (fromJust shownodes)
123 f3d53161 Iustin Pop
124 54365762 Iustin Pop
  let sols = processRequest request >>= processResults rq
125 478df686 Iustin Pop
  let (ok, info, rn) =
126 478df686 Iustin Pop
          case sols of
127 db4d9a9b Iustin Pop
            Ok as -> (True, "Request successful: " ++
128 db4d9a9b Iustin Pop
                            intercalate ", " (Cluster.asLog as),
129 db4d9a9b Iustin Pop
                      Cluster.asSolutions as)
130 478df686 Iustin Pop
            Bad s -> (False, "Request failed: " ++ s, [])
131 3e4480e0 Iustin Pop
      resp = formatResponse ok info rq rn
132 ed41c179 Iustin Pop
  putStrLn resp