Statistics
| Branch: | Tag: | Revision:

root / hail.hs @ 0427285d

History | View | Annotate | Download (2.9 kB)

1
{-| Solver for N+1 cluster errors
2

    
3
-}
4

    
5
{-
6

    
7
Copyright (C) 2009 Google Inc.
8

    
9
This program is free software; you can redistribute it and/or modify
10
it under the terms of the GNU General Public License as published by
11
the Free Software Foundation; either version 2 of the License, or
12
(at your option) any later version.
13

    
14
This program is distributed in the hope that it will be useful, but
15
WITHOUT ANY WARRANTY; without even the implied warranty of
16
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17
General Public License for more details.
18

    
19
You should have received a copy of the GNU General Public License
20
along with this program; if not, write to the Free Software
21
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22
02110-1301, USA.
23

    
24
-}
25

    
26
module Main (main) where
27

    
28
import Data.List
29
import Data.Function
30
import Monad
31
import System
32
import System.IO
33
import qualified System
34

    
35
import Text.Printf (printf)
36

    
37
import qualified Ganeti.HTools.Cluster as Cluster
38
import qualified Ganeti.HTools.Node as Node
39

    
40
import Ganeti.HTools.CLI
41
import Ganeti.HTools.IAlloc
42
import Ganeti.HTools.Types
43
import Ganeti.HTools.Loader (RqType(..), Request(..))
44

    
45
-- | Options list and functions
46
options :: [OptType]
47
options = [oShowVer, oShowHelp]
48

    
49
processResults :: (Monad m) => Cluster.AllocSolution -> m (String, [Node.Node])
50
processResults (fstats, succ, sols) =
51
    case sols of
52
      Nothing -> fail "No valid allocation solutions"
53
      Just (best, (_, _, w)) ->
54
          let tfails = length fstats
55
              info = printf "successes %d, failures %d,\
56
                            \ best score: %.8f for node(s) %s"
57
                            succ tfails
58
                            best (intercalate "/" . map Node.name $ w)::String
59
          in return (info, w)
60

    
61
-- | Process a request and return new node lists
62
processRequest :: Request
63
               -> Result Cluster.AllocSolution
64
processRequest request =
65
  let Request rqtype nl il _ = request
66
  in case rqtype of
67
       Allocate xi reqn -> Cluster.tryAlloc nl il xi reqn
68
       Relocate idx reqn exnodes -> Cluster.tryReloc nl il idx reqn exnodes
69

    
70
-- | Main function.
71
main :: IO ()
72
main = do
73
  cmd_args <- System.getArgs
74
  (_, args) <- parseOpts cmd_args "hail" options
75

    
76
  when (null args) $ do
77
         hPutStrLn stderr "Error: this program needs an input file."
78
         exitWith $ ExitFailure 1
79

    
80
  let input_file = head args
81
  input_data <- readFile input_file
82

    
83
  request <- case (parseData input_data) of
84
               Bad err -> do
85
                 hPutStrLn stderr $ "Error: " ++ err
86
                 exitWith $ ExitFailure 1
87
               Ok rq -> return rq
88

    
89
  let Request _ _ _ csf = request
90
      sols = processRequest request >>= processResults
91
  let (ok, info, rn) =
92
          case sols of
93
            Ok (info, sn) -> (True, "Request successful: " ++ info,
94
                                  map ((++ csf) . Node.name) sn)
95
            Bad s -> (False, "Request failed: " ++ s, [])
96
      resp = formatResponse ok info rn
97
  putStrLn resp