Statistics
| Branch: | Tag: | Revision:

root / hail.hs @ f3d53161

History | View | Annotate | Download (3.2 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
      Nothing -> fail "No valid allocation solutions"
54
      Just (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

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

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

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

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

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

    
91
  let Request _ nl _ _ csf = request
92

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

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