module Ganeti.HTools.Simu
( loadData
, parseData
) where
import Control.Monad (mplus)
import Text.Printf (printf)
import Ganeti.HTools.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 ->
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 <- mapM (uncurry createGroup) $ zip [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