{-
-Copyright (C) 2009 Google Inc.
+Copyright (C) 2009, 2010 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
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
-import qualified Ganeti.HTools.Instance as Instance
--- | Parse the string description into nodes
-parseDesc :: String -> Result (Int, Int, Int, Int)
+-- | Parse the string description into nodes.
+parseDesc :: String -> Result (AllocPolicy, Int, Int, Int, Int)
parseDesc desc =
case sepSplit ',' desc of
- [n, d, m, c] -> do
+ [a, n, d, m, c] -> do
+ apol <- apolFromString a
ncount <- tryRead "node count" n
disk <- tryRead "disk size" d
mem <- tryRead "memory size" m
cpu <- tryRead "cpu count" c
- return (ncount, disk, mem, cpu)
- _ -> fail "Invalid cluster specification"
+ return (apol, ncount, disk, mem, cpu)
+ es -> fail $ printf
+ "Invalid cluster specification, expected 5 comma-separated\
+ \ sections (allocation policy, node count, disk size,\
+ \ memory size, number of CPUs) but got %d: '%s'" (length es) desc
+
+-- | Creates a node group with the given specifications.
+createGroup :: Int -- ^ The group index
+ -> String -- ^ The group specification
+ -> Result (Group.Group, [Node.Node])
+createGroup grpIndex spec = do
+ (apol, ncount, disk, mem, cpu) <- parseDesc spec
+ let nodes = map (\idx ->
+ Node.create (printf "node-%02d-%03d" grpIndex idx)
+ (fromIntegral mem) 0 mem
+ (fromIntegral disk) disk
+ (fromIntegral cpu) False grpIndex
+ ) [1..ncount]
+ grp = Group.create (printf "group-%02d" grpIndex)
+ (printf "fake-uuid-%02d" grpIndex) apol
+ return (grp, nodes)
-- | Builds the cluster data from node\/instance files.
-parseData :: String -- ^ Cluster description in text format
- -> Result (Node.AssocList, Instance.AssocList, [String])
+parseData :: [String] -- ^ Cluster description in text format
+ -> Result ClusterData
parseData ndata = do
- (cnt, disk, mem, cpu) <- parseDesc ndata
- let nodes = map (\idx ->
- let n = Node.create (printf "node%03d" idx)
- (fromIntegral mem) 0 mem
- (fromIntegral disk) disk
- (fromIntegral cpu) False
- in (idx, Node.setIdx n idx)
- ) [1..cnt]
- return (nodes, [], [])
+ 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.fromAssocList ktg)
+ (Container.fromAssocList ktn) Container.empty [])
-- | Builds the cluster data from node\/instance files.
-loadData :: String -- ^ Cluster description in text format
- -> IO (Result (Node.AssocList, Instance.AssocList, [String]))
+loadData :: [String] -- ^ Cluster description in text format
+ -> IO (Result ClusterData)
loadData = -- IO monad, just for consistency with the other loaders
return . parseData