diff --git a/Ganeti/HTools/CLI.hs b/Ganeti/HTools/CLI.hs index 696333aed6d001e13ce19ffd24f1f27e04574b81..cfffee3e724c30b115304b6145100e4b8484ed50 100644 --- a/Ganeti/HTools/CLI.hs +++ b/Ganeti/HTools/CLI.hs @@ -39,8 +39,7 @@ module Ganeti.HTools.CLI , oOneline , oNoHeaders , oOutputDir - , oNodeFile - , oInstFile + , oDataFile , oNodeSim , oRapiMaster , oLuxiSocket @@ -89,10 +88,7 @@ data Options = Options , optOneline :: Bool -- ^ Switch output to a single line , optOutPath :: FilePath -- ^ Path to the output directory , optNoHeaders :: Bool -- ^ Do not show a header line - , optNodeFile :: FilePath -- ^ Path to the nodes file - , optNodeSet :: Bool -- ^ The nodes have been set by options - , optInstFile :: FilePath -- ^ Path to the instances file - , optInstSet :: Bool -- ^ The insts have been set by options + , optDataFile :: Maybe FilePath -- ^ Path to the cluster data file , optNodeSim :: Maybe String -- ^ Cluster simulation mode , optMaxLength :: Int -- ^ Stop after this many steps , optMaster :: String -- ^ Collect data from RAPI @@ -122,10 +118,7 @@ defaultOptions = Options , optOneline = False , optNoHeaders = False , optOutPath = "." - , optNodeFile = "nodes" - , optNodeSet = False - , optInstFile = "instances" - , optInstSet = False + , optDataFile = Nothing , optNodeSim = Nothing , optMaxLength = -1 , optMaster = "" @@ -186,17 +179,10 @@ oOutputDir = Option "d" ["output-dir"] (ReqArg (\ d opts -> Ok opts { optOutPath = d }) "PATH") "directory in which to write output files" -oNodeFile :: OptType -oNodeFile = Option "n" ["nodes"] - (ReqArg (\ f o -> Ok o { optNodeFile = f, - optNodeSet = True }) "FILE") - "the node list FILE" - -oInstFile :: OptType -oInstFile = Option "i" ["instances"] - (ReqArg (\ f o -> Ok o { optInstFile = f, - optInstSet = True }) "FILE") - "the instance list FILE" +oDataFile :: OptType +oDataFile = Option "t" ["text-data"] + (ReqArg (\ f o -> Ok o { optDataFile = Just f }) "FILE") + "the cluster data FILE" oNodeSim :: OptType oNodeSim = Option "" ["simulate"] diff --git a/Ganeti/HTools/ExtLoader.hs b/Ganeti/HTools/ExtLoader.hs index 94c787bd08aff7ed0a9ec0c343cd1be9c2312dc0..a54da1abb038c1146b60f0320b7427cfa6eb8cc1 100644 --- a/Ganeti/HTools/ExtLoader.hs +++ b/Ganeti/HTools/ExtLoader.hs @@ -35,7 +35,6 @@ module Ganeti.HTools.ExtLoader import Data.Maybe (isJust, fromJust) import Monad -import System.Posix.Env import System.IO import System import Text.Printf (printf, hPrintf) @@ -54,15 +53,6 @@ import Ganeti.HTools.Types import Ganeti.HTools.CLI import Ganeti.HTools.Utils (sepSplit, tryRead) --- | Parse the environment and return the node\/instance names. --- --- This also hardcodes here the default node\/instance file names. -parseEnv :: () -> IO (String, String) -parseEnv () = do - a <- getEnvDefault "HTOOLS_NODES" "nodes" - b <- getEnvDefault "HTOOLS_INSTANCES" "instances" - return (a, b) - -- | Error beautifier wrapIO :: IO (Result a) -> IO (Result a) wrapIO = flip catch (return . Bad . show) @@ -85,19 +75,15 @@ parseUtilisation line = loadExternalData :: Options -> IO (Node.List, Instance.List, [String], String) loadExternalData opts = do - (env_node, env_inst) <- parseEnv () - let nodef = if optNodeSet opts then optNodeFile opts - else env_node - instf = if optInstSet opts then optInstFile opts - else env_inst - mhost = optMaster opts + let mhost = optMaster opts lsock = optLuxi opts + tfile = optDataFile opts simdata = optNodeSim opts setRapi = mhost /= "" setLuxi = isJust lsock setSim = isJust simdata - setFiles = optNodeSet opts || optInstSet opts - allSet = filter id [setRapi, setLuxi, setFiles] + setFile = isJust tfile + allSet = filter id [setRapi, setLuxi, setFile] exTags = case optExTags opts of Nothing -> [] Just etl -> map (++ ":") etl @@ -128,7 +114,8 @@ loadExternalData opts = do #endif | setLuxi -> wrapIO $ Luxi.loadData $ fromJust lsock | setSim -> Simu.loadData $ fromJust simdata - | otherwise -> wrapIO $ Text.loadData nodef instf + | setFile -> wrapIO $ Text.loadData $ fromJust tfile + | otherwise -> return $ Bad "No backend selected! Exiting." let ldresult = input_data >>= Loader.mergeData util_data' exTags (loaded_nl, il, tags, csf) <- diff --git a/Ganeti/HTools/Text.hs b/Ganeti/HTools/Text.hs index f686d979120fed7bd40bfe9f96e4bb45b5b1531c..599c07cde97f0e393164bb13bb78888e1e7d9076 100644 --- a/Ganeti/HTools/Text.hs +++ b/Ganeti/HTools/Text.hs @@ -87,16 +87,19 @@ loadTabular lines_data convert_fn = do kerows <- mapM convert_fn rows return $ assignIndices kerows --- | Builds the cluster data from node\/instance files. -loadData :: String -- ^ Node data in string format - -> String -- ^ Instance data in string format +-- | Builds the cluster data from text input. +loadData :: String -- ^ Path to the text file -> IO (Result (Node.AssocList, Instance.AssocList, [String])) -loadData nfile ifile = do -- IO monad - ndata <- readFile nfile - idata <- readFile ifile +loadData afile = do -- IO monad + fdata <- readFile afile + let flines = lines fdata + (nlines, ilines) = break null flines return $ do + ifixed <- case ilines of + [] -> Bad "Invalid format of the input file (no instance data)" + _:xs -> Ok xs {- node file: name t_mem n_mem f_mem t_disk f_disk -} - (ktn, nl) <- loadTabular (lines ndata) loadNode + (ktn, nl) <- loadTabular nlines loadNode {- instance file: name mem disk status pnode snode -} - (_, il) <- loadTabular (lines idata) (loadInst ktn) + (_, il) <- loadTabular ifixed (loadInst ktn) return (nl, il, []) diff --git a/hbal.hs b/hbal.hs index 1c3f9fe49459f8b13ed30a091f519c14e1e08a94..ae4cb80c9b393546dd26feff640a50f91cd5a6b0 100644 --- a/hbal.hs +++ b/hbal.hs @@ -59,8 +59,7 @@ options = , oPrintInsts , oPrintCommands , oOneline - , oNodeFile - , oInstFile + , oDataFile , oRapiMaster , oLuxiSocket , oExecJobs diff --git a/hspace.hs b/hspace.hs index 20818a51d891e584b8510d0c46c525322ae05bd8..dcaf4001642a947fed753f966da5ddbb96bf6553 100644 --- a/hspace.hs +++ b/hspace.hs @@ -50,8 +50,7 @@ import Ganeti.HTools.ExtLoader options :: [OptType] options = [ oPrintNodes - , oNodeFile - , oInstFile + , oDataFile , oNodeSim , oRapiMaster , oLuxiSocket