Revision cabce2f4 htools/Ganeti/HTools/IAlloc.hs

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)

Also available in: Unified diff