Add 'Read' instances for most objects
[ganeti-local] / Ganeti / HTools / Simu.hs
index 6c01726..f129a36 100644 (file)
@@ -6,7 +6,7 @@ This module holds the code for parsing a cluster description.
 
 {-
 
-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
@@ -35,37 +35,58 @@ 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
-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