1 {-| Solver for N+1 cluster errors
7 Copyright (C) 2009 Google Inc.
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.
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.
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
26 module Main (main) where
33 import qualified System
35 import Text.Printf (printf)
37 import qualified Ganeti.HTools.Cluster as Cluster
38 import qualified Ganeti.HTools.Node as Node
40 import Ganeti.HTools.CLI
41 import Ganeti.HTools.IAlloc
42 import Ganeti.HTools.Types
43 import Ganeti.HTools.Loader (RqType(..), Request(..))
45 -- | Options list and functions
47 options = [oShowVer, oShowHelp]
49 processResults :: (Monad m) => Cluster.AllocSolution -> m (String, [Node.Node])
50 processResults (fstats, successes, sols) =
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"
58 best (intercalate "/" . map Node.name $ w)::String
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
67 Allocate xi reqn -> Cluster.tryAlloc nl il xi reqn
68 Relocate idx reqn exnodes -> Cluster.tryReloc nl il idx reqn exnodes
73 cmd_args <- System.getArgs
74 (_, args) <- parseOpts cmd_args "hail" options
77 hPutStrLn stderr "Error: this program needs an input file."
78 exitWith $ ExitFailure 1
80 let input_file = head args
81 input_data <- readFile input_file
83 request <- case (parseData input_data) of
85 hPutStrLn stderr $ "Error: " ++ err
86 exitWith $ ExitFailure 1
89 let Request _ _ _ csf = request
90 sols = processRequest request >>= processResults
93 Ok (ginfo, sn) -> (True, "Request successful: " ++ ginfo,
94 map ((++ csf) . Node.name) sn)
95 Bad s -> (False, "Request failed: " ++ s, [])
96 resp = formatResponse ok info rn