Switch the text file format to single-file
authorIustin Pop <iustin@google.com>
Thu, 7 Jan 2010 11:33:39 +0000 (12:33 +0100)
committerIustin Pop <iustin@google.com>
Thu, 7 Jan 2010 11:57:26 +0000 (12:57 +0100)
This patch changes from the two separate files to a single file, with
sections separated by a blank line. Currently only the node and instance
data is accepted, later the cluster tags will be read too via this
format.

This makes all the programs accept the new format, but hscan doesn't yet
generate it.

Ganeti/HTools/CLI.hs
Ganeti/HTools/ExtLoader.hs
Ganeti/HTools/Text.hs
hbal.hs
hspace.hs

index 696333a..cfffee3 100644 (file)
@@ -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"]
index 94c787b..a54da1a 100644 (file)
@@ -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) <-
index f686d97..599c07c 100644 (file)
@@ -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 1c3f9fe..ae4cb80 100644 (file)
--- a/hbal.hs
+++ b/hbal.hs
@@ -59,8 +59,7 @@ options =
     , oPrintInsts
     , oPrintCommands
     , oOneline
-    , oNodeFile
-    , oInstFile
+    , oDataFile
     , oRapiMaster
     , oLuxiSocket
     , oExecJobs
index 20818a5..dcaf400 100644 (file)
--- a/hspace.hs
+++ b/hspace.hs
@@ -50,8 +50,7 @@ import Ganeti.HTools.ExtLoader
 options :: [OptType]
 options =
     [ oPrintNodes
-    , oNodeFile
-    , oInstFile
+    , oDataFile
     , oNodeSim
     , oRapiMaster
     , oLuxiSocket