Statistics
| Branch: | Tag: | Revision:

root / hail.hs @ a182df55

History | View | Annotate | Download (3.7 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 Data.Maybe (isJust, fromJust)
31
import Monad
32
import System
33
import System.IO
34
import qualified System
35

    
36
import Text.Printf (printf)
37

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

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

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

    
50
processResults :: (Monad m) =>
51
                  RqType -> Cluster.AllocSolution
52
               -> m (String, Cluster.AllocSolution)
53
processResults _ (_, _, []) = fail "No valid allocation solutions"
54
processResults (Evacuate _) as@(fstats, successes, sols) =
55
    let best = fst $ head sols
56
        tfails = length fstats
57
        info = printf "for last allocation, successes %d, failures %d,\
58
                      \ best score: %.8f" successes tfails best::String
59
    in return (info, as)
60

    
61
processResults _ as@(fstats, successes, sols) =
62
    case sols of
63
      (best, (_, _, w)):[] ->
64
          let tfails = length fstats
65
              info = printf "successes %d, failures %d,\
66
                            \ best score: %.8f for node(s) %s"
67
                            successes tfails
68
                            best (intercalate "/" . map Node.name $ w)::String
69
          in return (info, as)
70
      _ -> fail "Internal error: multiple allocation solutions"
71

    
72
-- | Process a request and return new node lists
73
processRequest :: Request
74
               -> Result Cluster.AllocSolution
75
processRequest request =
76
  let Request rqtype nl il _ _ = request
77
  in case rqtype of
78
       Allocate xi reqn -> Cluster.tryAlloc nl il xi reqn
79
       Relocate idx reqn exnodes -> Cluster.tryReloc nl il idx reqn exnodes
80
       Evacuate exnodes -> Cluster.tryEvac nl il exnodes
81

    
82
-- | Main function.
83
main :: IO ()
84
main = do
85
  cmd_args <- System.getArgs
86
  (opts, args) <- parseOpts cmd_args "hail" options
87

    
88
  when (null args) $ do
89
         hPutStrLn stderr "Error: this program needs an input file."
90
         exitWith $ ExitFailure 1
91

    
92
  let input_file = head args
93
      shownodes = optShowNodes opts
94
  input_data <- readFile input_file
95

    
96
  request <- case (parseData input_data) of
97
               Bad err -> do
98
                 hPutStrLn stderr $ "Error: " ++ err
99
                 exitWith $ ExitFailure 1
100
               Ok rq -> return rq
101

    
102
  let Request rq nl _ _ csf = request
103

    
104
  when (isJust shownodes) $ do
105
         hPutStrLn stderr "Initial cluster status:"
106
         hPutStrLn stderr $ Cluster.printNodes nl (fromJust shownodes)
107

    
108
  let sols = processRequest request >>= processResults rq
109
  let (ok, info, rn) =
110
          case sols of
111
            Ok (ginfo, (_, _, sn)) -> (True, "Request successful: " ++ ginfo,
112
                                       map snd sn)
113
            Bad s -> (False, "Request failed: " ++ s, [])
114
      resp = formatResponse ok info csf rq rn
115
  putStrLn resp