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 System.Console.GetOpt
34 import qualified System
36 import Text.Printf (printf)
38 import qualified Ganeti.HTools.Cluster as Cluster
39 import qualified Ganeti.HTools.Node as Node
40 import qualified Ganeti.HTools.CLI as CLI
41 import Ganeti.HTools.IAlloc
42 import Ganeti.HTools.Types
43 import Ganeti.HTools.Loader (RqType(..), Request(..))
45 -- | Command line options structure.
46 data Options = Options
47 { optShowVer :: Bool -- ^ Just show the program version
48 , optShowHelp :: Bool -- ^ Just show the help
51 -- | Default values for the command line options.
52 defaultOptions :: Options
53 defaultOptions = Options
58 instance CLI.CLIOptions Options where
59 showVersion = optShowVer
60 showHelp = optShowHelp
62 -- | Options list and functions
63 options :: [OptDescr (Options -> Options)]
65 [ Option ['V'] ["version"]
66 (NoArg (\ opts -> opts { optShowVer = True}))
67 "show the version of the program"
68 , Option ['h'] ["help"]
69 (NoArg (\ opts -> opts { optShowHelp = True}))
74 processResults :: (Monad m) => Cluster.AllocSolution -> m (String, [Node.Node])
75 processResults (fstats, succ, sols) =
77 Nothing -> fail "No valid allocation solutions"
78 Just (best, (_, _, w)) ->
79 let tfails = length fstats
80 info = printf "successes %d, failures %d,\
81 \ best score: %.8f for node(s) %s"
83 best (intercalate "/" . map Node.name $ w)::String
86 -- | Process a request and return new node lists
87 processRequest :: Request
88 -> Result Cluster.AllocSolution
89 processRequest request =
90 let Request rqtype nl il _ = request
92 Allocate xi reqn -> Cluster.tryAlloc nl il xi reqn
93 Relocate idx reqn exnodes -> Cluster.tryReloc nl il idx reqn exnodes
98 cmd_args <- System.getArgs
99 (_, args) <- CLI.parseOpts cmd_args "hail" options defaultOptions
101 when (null args) $ do
102 hPutStrLn stderr "Error: this program needs an input file."
103 exitWith $ ExitFailure 1
105 let input_file = head args
106 input_data <- readFile input_file
108 request <- case (parseData input_data) of
110 hPutStrLn stderr $ "Error: " ++ err
111 exitWith $ ExitFailure 1
114 let Request _ _ _ csf = request
115 sols = processRequest request >>= processResults
118 Ok (info, sn) -> (True, "Request successful: " ++ info,
119 map ((++ csf) . Node.name) sn)
120 Bad s -> (False, "Request failed: " ++ s, [])
121 resp = formatResponse ok info rn