Revision cabce2f4

b/htools/Ganeti/HTools/IAlloc.hs
26 26
module Ganeti.HTools.IAlloc
27 27
    ( parseData
28 28
    , formatResponse
29
    , readRequest
30
    , processRequest
31
    , processResults
29 32
    ) where
30 33

  
31 34
import Data.Either ()
32
import Data.Maybe (fromMaybe)
35
import Data.Maybe (fromMaybe, isJust, fromJust)
36
import Data.List
33 37
import Control.Monad
34 38
import Text.JSON (JSObject, JSValue(JSBool, JSString, JSArray),
35 39
                  makeObj, encodeStrict, decodeStrict,
36 40
                  fromJSObject, toJSString)
41
import System (exitWith, ExitCode(..))
42
import System.IO
43

  
44
import qualified Ganeti.HTools.Cluster as Cluster
37 45
import qualified Ganeti.HTools.Container as Container
38 46
import qualified Ganeti.HTools.Group as Group
39 47
import qualified Ganeti.HTools.Node as Node
40 48
import qualified Ganeti.HTools.Instance as Instance
41 49
import qualified Ganeti.Constants as C
50
import Ganeti.HTools.CLI
42 51
import Ganeti.HTools.Loader
52
import Ganeti.HTools.ExtLoader (loadExternalData)
43 53
import Ganeti.HTools.Utils
44 54
import Ganeti.HTools.Types
45 55

  
......
236 246
        e_info = ("info", JSString . toJSString $ info)
237 247
        e_result = ("result", formatRVal rq elems)
238 248
    in encodeStrict $ makeObj [e_success, e_info, e_result]
249

  
250
processResults :: (Monad m) =>
251
                  RqType -> Cluster.AllocSolution
252
               -> m Cluster.AllocSolution
253
processResults _ (Cluster.AllocSolution { Cluster.asSolutions = [],
254
                                          Cluster.asLog = msgs }) =
255
  fail $ intercalate ", " msgs
256

  
257
processResults (Evacuate _) as = return as
258

  
259
processResults _ as =
260
    case Cluster.asSolutions as of
261
      _:[] -> return as
262
      _ -> fail "Internal error: multiple allocation solutions"
263

  
264
-- | Process a request and return new node lists
265
processRequest :: Request
266
               -> Result Cluster.AllocSolution
267
processRequest request =
268
  let Request rqtype (ClusterData gl nl il _) = request
269
  in case rqtype of
270
       Allocate xi reqn -> Cluster.tryMGAlloc gl nl il xi reqn
271
       Relocate idx reqn exnodes -> Cluster.tryMGReloc gl nl il
272
                                    idx reqn exnodes
273
       Evacuate exnodes -> Cluster.tryMGEvac gl nl il exnodes
274
       MultiReloc _ _ -> fail "multi-reloc not handled"
275
       NodeEvacuate _ _ -> fail "node-evacuate not handled"
276

  
277
-- | Reads the request from the data file(s)
278
readRequest :: Options -> [String] -> IO Request
279
readRequest opts args = do
280
  when (null args) $ do
281
         hPutStrLn stderr "Error: this program needs an input file."
282
         exitWith $ ExitFailure 1
283

  
284
  input_data <- readFile (head args)
285
  r1 <- case parseData input_data of
286
          Bad err -> do
287
            hPutStrLn stderr $ "Error: " ++ err
288
            exitWith $ ExitFailure 1
289
          Ok rq -> return rq
290
  (if isJust (optDataFile opts) ||  (not . null . optNodeSim) opts
291
   then do
292
     cdata <- loadExternalData opts
293
     let Request rqt _ = r1
294
     return $ Request rqt cdata
295
   else return r1)
b/htools/hail.hs
28 28
import Control.Monad
29 29
import Data.List
30 30
import Data.Maybe (isJust, fromJust)
31
import System (exitWith, ExitCode(..))
32 31
import System.IO
33 32
import qualified System
34 33

  
......
37 36
import Ganeti.HTools.CLI
38 37
import Ganeti.HTools.IAlloc
39 38
import Ganeti.HTools.Types
40
import Ganeti.HTools.Loader (RqType(..), Request(..), ClusterData(..))
41
import Ganeti.HTools.ExtLoader (loadExternalData)
39
import Ganeti.HTools.Loader (Request(..), ClusterData(..))
42 40

  
43 41
-- | Options list and functions
44 42
options :: [OptType]
......
51 49
    , oShowHelp
52 50
    ]
53 51

  
54
processResults :: (Monad m) =>
55
                  RqType -> Cluster.AllocSolution
56
               -> m Cluster.AllocSolution
57
processResults _ (Cluster.AllocSolution { Cluster.asSolutions = [],
58
                                          Cluster.asLog = msgs }) =
59
  fail $ intercalate ", " msgs
60

  
61
processResults (Evacuate _) as = return as
62

  
63
processResults _ as =
64
    case Cluster.asSolutions as of
65
      _:[] -> return as
66
      _ -> fail "Internal error: multiple allocation solutions"
67

  
68
-- | Process a request and return new node lists
69
processRequest :: Request
70
               -> Result Cluster.AllocSolution
71
processRequest request =
72
  let Request rqtype (ClusterData gl nl il _) = request
73
  in case rqtype of
74
       Allocate xi reqn -> Cluster.tryMGAlloc gl nl il xi reqn
75
       Relocate idx reqn exnodes -> Cluster.tryMGReloc gl nl il
76
                                    idx reqn exnodes
77
       Evacuate exnodes -> Cluster.tryMGEvac gl nl il exnodes
78
       MultiReloc _ _ -> fail "multi-reloc not handled"
79
       NodeEvacuate _ _ -> fail "node-evacuate not handled"
80

  
81
-- | Reads the request from the data file(s)
82
readRequest :: Options -> [String] -> IO Request
83
readRequest opts args = do
84
  when (null args) $ do
85
         hPutStrLn stderr "Error: this program needs an input file."
86
         exitWith $ ExitFailure 1
87

  
88
  input_data <- readFile (head args)
89
  r1 <- case parseData input_data of
90
          Bad err -> do
91
            hPutStrLn stderr $ "Error: " ++ err
92
            exitWith $ ExitFailure 1
93
          Ok rq -> return rq
94
  (if isJust (optDataFile opts) ||  (not . null . optNodeSim) opts
95
   then do
96
     cdata <- loadExternalData opts
97
     let Request rqt _ = r1
98
     return $ Request rqt cdata
99
   else return r1)
100

  
101 52
-- | Main function.
102 53
main :: IO ()
103 54
main = do

Also available in: Unified diff