This repository has been archived by the owner on May 3, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
hail.hs
124 lines (100 loc) · 3.72 KB
/
hail.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
{-| Solver for N+1 cluster errors
-}
{-
Copyright (C) 2009, 2010, 2011 Google Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
-}
module Main (main) where
import Data.List
import Data.Maybe (isJust, fromJust)
import Monad
import System (exitWith, ExitCode(..))
import System.IO
import qualified System
import qualified Ganeti.HTools.Cluster as Cluster
import Ganeti.HTools.CLI
import Ganeti.HTools.IAlloc
import Ganeti.HTools.Types
import Ganeti.HTools.Loader (RqType(..), Request(..), ClusterData(..))
import Ganeti.HTools.ExtLoader (loadExternalData)
-- | Options list and functions
options :: [OptType]
options =
[ oPrintNodes
, oDataFile
, oNodeSim
, oShowVer
, oShowHelp
]
processResults :: (Monad m) =>
RqType -> Cluster.AllocSolution
-> m Cluster.AllocSolution
processResults _ (Cluster.AllocSolution { Cluster.asSolutions = [],
Cluster.asLog = msgs }) =
fail $ intercalate ", " msgs
processResults (Evacuate _) as = return as
processResults _ as =
case Cluster.asSolutions as of
_:[] -> return as
_ -> fail "Internal error: multiple allocation solutions"
-- | Process a request and return new node lists
processRequest :: Request
-> Result Cluster.AllocSolution
processRequest request =
let Request rqtype (ClusterData gl nl il _) = request
in case rqtype of
Allocate xi reqn -> Cluster.tryMGAlloc gl nl il xi reqn
Relocate idx reqn exnodes -> Cluster.tryMGReloc gl nl il
idx reqn exnodes
Evacuate exnodes -> Cluster.tryMGEvac gl nl il exnodes
-- | Reads the request from the data file(s)
readRequest :: Options -> [String] -> IO Request
readRequest opts args = do
when (null args) $ do
hPutStrLn stderr "Error: this program needs an input file."
exitWith $ ExitFailure 1
input_data <- readFile (head args)
r1 <- case (parseData input_data) of
Bad err -> do
hPutStrLn stderr $ "Error: " ++ err
exitWith $ ExitFailure 1
Ok rq -> return rq
r2 <- if isJust (optDataFile opts) || (not . null . optNodeSim) opts
then do
cdata <- loadExternalData opts
let Request rqt _ = r1
return $ Request rqt cdata
else return r1
return r2
-- | Main function.
main :: IO ()
main = do
cmd_args <- System.getArgs
(opts, args) <- parseOpts cmd_args "hail" options
let shownodes = optShowNodes opts
request <- readRequest opts args
let Request rq cdata = request
when (isJust shownodes) $ do
hPutStrLn stderr "Initial cluster status:"
hPutStrLn stderr $ Cluster.printNodes (cdNodes cdata)
(fromJust shownodes)
let sols = processRequest request >>= processResults rq
let (ok, info, rn) =
case sols of
Ok as -> (True, "Request successful: " ++
intercalate ", " (Cluster.asLog as),
Cluster.asSolutions as)
Bad s -> (False, "Request failed: " ++ s, [])
resp = formatResponse ok info rq rn
putStrLn resp