Statistics
| Branch: | Tag: | Revision:

root / hail.hs @ 23f9ab76

History | View | Annotate | Download (3.3 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) => Cluster.AllocSolution -> m (String, [Node.Node])
51
processResults (fstats, successes, sols) =
52
    case sols of
53
      [] -> fail "No valid allocation solutions"
54
      (best, (_, _, w)):[] ->
55
          let tfails = length fstats
56
              info = printf "successes %d, failures %d,\
57
                            \ best score: %.8f for node(s) %s"
58
                            successes tfails
59
                            best (intercalate "/" . map Node.name $ w)::String
60
          in return (info, w)
61
      _ -> fail "Internal error: multiple allocation solutions"
62

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

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

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

    
82
  let input_file = head args
83
      shownodes = optShowNodes opts
84
  input_data <- readFile input_file
85

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

    
92
  let Request _ nl _ _ csf = request
93

    
94
  when (isJust shownodes) $ do
95
         hPutStrLn stderr "Initial cluster status:"
96
         hPutStrLn stderr $ Cluster.printNodes nl (fromJust shownodes)
97

    
98
  let sols = processRequest request >>= processResults
99
  let (ok, info, rn) =
100
          case sols of
101
            Ok (ginfo, sn) -> (True, "Request successful: " ++ ginfo,
102
                                   map ((++ csf) . Node.name) sn)
103
            Bad s -> (False, "Request failed: " ++ s, [])
104
      resp = formatResponse ok info rn
105
  putStrLn resp