module Ganeti.HTools.Backend.Simu
( loadData
, parseData
) where
import Control.Monad (mplus, zipWithM)
import Text.Printf (printf)
import Ganeti.BasicTypes
import Ganeti.Utils
import Ganeti.HTools.Types
import Ganeti.HTools.Loader
import qualified Ganeti.HTools.Container as Container
import qualified Ganeti.HTools.Group as Group
import qualified Ganeti.HTools.Node as Node
apolAbbrev :: String -> Result AllocPolicy
apolAbbrev c | c == "p" = return AllocPreferred
| c == "a" = return AllocLastResort
| c == "u" = return AllocUnallocable
| otherwise = fail $ "Cannot parse AllocPolicy abbreviation '"
++ c ++ "'"
parseDesc :: String -> [String]
-> Result (AllocPolicy, Int, Int, Int, Int, Int)
parseDesc _ [a, n, d, m, c, s] = do
apol <- allocPolicyFromRaw a `mplus` apolAbbrev a
ncount <- tryRead "node count" n
disk <- annotateResult "disk size" (parseUnit d)
mem <- annotateResult "memory size" (parseUnit m)
cpu <- tryRead "cpu count" c
spindles <- tryRead "spindles" s
return (apol, ncount, disk, mem, cpu, spindles)
parseDesc desc [a, n, d, m, c] = parseDesc desc [a, n, d, m, c, "1"]
parseDesc desc es =
fail $ printf
"Invalid cluster specification, expected 6 comma-separated\
\ sections (allocation policy, node count, disk size,\
\ memory size, number of CPUs, spindles) but got %d: '%s'"
(length es) desc
createGroup :: Int
-> String
-> Result (Group.Group, [Node.Node])
createGroup grpIndex spec = do
(apol, ncount, disk, mem, cpu, spindles) <- parseDesc spec $
sepSplit ',' spec
let nodes = map (\idx ->
flip Node.setMaster (grpIndex == 1 && idx == 1) $
Node.create (printf "node-%02d-%03d" grpIndex idx)
(fromIntegral mem) 0 mem
(fromIntegral disk) disk
(fromIntegral cpu) False spindles grpIndex
) [1..ncount]
grp = Group.create (printf "group-%02d" grpIndex)
(printf "fake-uuid-%02d" grpIndex) apol [] defIPolicy []
return (Group.setIdx grp grpIndex, nodes)
parseData :: [String]
-> Result ClusterData
parseData ndata = do
grpNodeData <- zipWithM createGroup [1..] ndata
let (groups, nodes) = unzip grpNodeData
nodes' = concat nodes
let ktn = map (\(idx, n) -> (idx, Node.setIdx n idx))
$ zip [1..] nodes'
ktg = map (\g -> (Group.idx g, g)) groups
return (ClusterData (Container.fromList ktg)
(Container.fromList ktn) Container.empty [] defIPolicy)
loadData :: [String]
-> IO (Result ClusterData)
loadData =
return . parseData