Commit 9983063b authored by Iustin Pop's avatar Iustin Pop
Browse files

Simulation backend: allow multiple node groups



This patch changes the behaviour of the --simulation option to be an
incremental option, where each new use defines a new node group. This
allows simulation of more complex clusters.
Signed-off-by: default avatarIustin Pop <iustin@google.com>
Reviewed-by: default avatarBalazs Lecz <leczb@google.com>
parent 54cffd50
...@@ -108,7 +108,7 @@ data Options = Options ...@@ -108,7 +108,7 @@ data Options = Options
, optMinGainLim :: Score -- ^ Limit below which we apply mingain , optMinGainLim :: Score -- ^ Limit below which we apply mingain
, optMinScore :: Score -- ^ The minimum score we aim for , optMinScore :: Score -- ^ The minimum score we aim for
, optNoHeaders :: Bool -- ^ Do not show a header line , optNoHeaders :: Bool -- ^ Do not show a header line
, optNodeSim :: Maybe String -- ^ Cluster simulation mode , optNodeSim :: [String] -- ^ Cluster simulation mode
, optOffline :: [String] -- ^ Names of offline nodes , optOffline :: [String] -- ^ Names of offline nodes
, optOneline :: Bool -- ^ Switch output to a single line , optOneline :: Bool -- ^ Switch output to a single line
, optOutPath :: FilePath -- ^ Path to the output directory , optOutPath :: FilePath -- ^ Path to the output directory
...@@ -144,7 +144,7 @@ defaultOptions = Options ...@@ -144,7 +144,7 @@ defaultOptions = Options
, optMinGainLim = 1e-1 , optMinGainLim = 1e-1
, optMinScore = 1e-9 , optMinScore = 1e-9
, optNoHeaders = False , optNoHeaders = False
, optNodeSim = Nothing , optNodeSim = []
, optOffline = [] , optOffline = []
, optOneline = False , optOneline = False
, optOutPath = "." , optOutPath = "."
...@@ -278,7 +278,7 @@ oNoHeaders = Option "" ["no-headers"] ...@@ -278,7 +278,7 @@ oNoHeaders = Option "" ["no-headers"]
oNodeSim :: OptType oNodeSim :: OptType
oNodeSim = Option "" ["simulate"] oNodeSim = Option "" ["simulate"]
(ReqArg (\ f o -> Ok o { optNodeSim = Just f }) "SPEC") (ReqArg (\ f o -> Ok o { optNodeSim = f:optNodeSim o }) "SPEC")
"simulate an empty cluster, given as 'num_nodes,disk,ram,cpu'" "simulate an empty cluster, given as 'num_nodes,disk,ram,cpu'"
oOfflineNode :: OptType oOfflineNode :: OptType
......
...@@ -83,7 +83,7 @@ loadExternalData opts = do ...@@ -83,7 +83,7 @@ loadExternalData opts = do
simdata = optNodeSim opts simdata = optNodeSim opts
setRapi = mhost /= "" setRapi = mhost /= ""
setLuxi = isJust lsock setLuxi = isJust lsock
setSim = isJust simdata setSim = (not . null) simdata
setFile = isJust tfile setFile = isJust tfile
allSet = filter id [setRapi, setLuxi, setFile] allSet = filter id [setRapi, setLuxi, setFile]
exTags = case optExTags opts of exTags = case optExTags opts of
...@@ -116,7 +116,7 @@ loadExternalData opts = do ...@@ -116,7 +116,7 @@ loadExternalData opts = do
wrapIO $ Rapi.loadData mhost wrapIO $ Rapi.loadData mhost
#endif #endif
| setLuxi -> wrapIO $ Luxi.loadData $ fromJust lsock | setLuxi -> wrapIO $ Luxi.loadData $ fromJust lsock
| setSim -> Simu.loadData $ fromJust simdata | setSim -> Simu.loadData simdata
| setFile -> wrapIO $ Text.loadData $ fromJust tfile | setFile -> wrapIO $ Text.loadData $ fromJust tfile
| otherwise -> return $ Bad "No backend selected! Exiting." | otherwise -> return $ Bad "No backend selected! Exiting."
......
...@@ -40,7 +40,7 @@ import qualified Ganeti.HTools.Group as Group ...@@ -40,7 +40,7 @@ import qualified Ganeti.HTools.Group as Group
import qualified Ganeti.HTools.Node as Node import qualified Ganeti.HTools.Node as Node
import qualified Ganeti.HTools.Instance as Instance import qualified Ganeti.HTools.Instance as Instance
-- | Parse the string description into nodes -- | Parse the string description into nodes.
parseDesc :: String -> Result (Int, Int, Int, Int) parseDesc :: String -> Result (Int, Int, Int, Int)
parseDesc desc = parseDesc desc =
case sepSplit ',' desc of case sepSplit ',' desc of
...@@ -52,24 +52,37 @@ parseDesc desc = ...@@ -52,24 +52,37 @@ parseDesc desc =
return (ncount, disk, mem, cpu) return (ncount, disk, mem, cpu)
_ -> fail "Invalid cluster specification" _ -> fail "Invalid cluster specification"
-- | Builds the cluster data from node\/instance files. -- | Creates a node group with the given specifications.
parseData :: String -- ^ Cluster description in text format createGroup :: Int -- ^ The group index
-> Result (Group.List, Node.List, Instance.List, [String]) -> String -- ^ The group specification
parseData ndata = do -> Result (Group.Group, [Node.Node])
(cnt, disk, mem, cpu) <- parseDesc ndata createGroup grpIndex spec = do
let defgroup = Group.create "default" defaultGroupID AllocPreferred (ncount, disk, mem, cpu) <- parseDesc spec
let nodes = map (\idx -> let nodes = map (\idx ->
let n = Node.create (printf "node%03d" idx) Node.create (printf "node-%02d-%03d" grpIndex idx)
(fromIntegral mem) 0 mem (fromIntegral mem) 0 mem
(fromIntegral disk) disk (fromIntegral disk) disk
(fromIntegral cpu) False 0 (fromIntegral cpu) False grpIndex
in (idx, Node.setIdx n idx) ) [1..ncount]
) [1..cnt] grp = Group.create (printf "group-%02d" grpIndex)
return (Container.fromAssocList [(0, Group.setIdx defgroup 0)], (printf "fake-uuid-%02d" grpIndex) AllocPreferred
Container.fromAssocList nodes, Container.empty, []) return (grp, nodes)
-- | Builds the cluster data from node\/instance files.
parseData :: [String] -- ^ Cluster description in text format
-> Result (Group.List, Node.List, Instance.List, [String])
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 (Container.fromAssocList ktg,
Container.fromAssocList ktn, Container.empty, [])
-- | Builds the cluster data from node\/instance files. -- | Builds the cluster data from node\/instance files.
loadData :: String -- ^ Cluster description in text format loadData :: [String] -- ^ Cluster description in text format
-> IO (Result (Group.List, Node.List, Instance.List, [String])) -> IO (Result (Group.List, Node.List, Instance.List, [String]))
loadData = -- IO monad, just for consistency with the other loaders loadData = -- IO monad, just for consistency with the other loaders
return . parseData return . parseData
...@@ -87,7 +87,7 @@ readRequest opts args = do ...@@ -87,7 +87,7 @@ readRequest opts args = do
hPutStrLn stderr $ "Error: " ++ err hPutStrLn stderr $ "Error: " ++ err
exitWith $ ExitFailure 1 exitWith $ ExitFailure 1
Ok rq -> return rq Ok rq -> return rq
r2 <- if isJust (optDataFile opts) || isJust (optNodeSim opts) r2 <- if isJust (optDataFile opts) || (not . null . optNodeSim) opts
then do then do
(gl, nl, il, ctags) <- loadExternalData opts (gl, nl, il, ctags) <- loadExternalData opts
let Request rqt _ _ _ _ = r1 let Request rqt _ _ _ _ = r1
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment