{-
-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
module Main (main) where
-import Data.List
-import Data.Function
-import Data.Maybe (isJust, fromJust)
+import Data.Maybe (isJust, fromJust, fromMaybe)
import Monad
-import System
+import System (exitWith, ExitCode(..))
import System.IO
import System.FilePath
import qualified System
#endif
import qualified Ganeti.HTools.Luxi as Luxi
import qualified Ganeti.HTools.Loader as Loader
+import Ganeti.HTools.Text (serializeCluster)
import Ganeti.HTools.CLI
import Ganeti.HTools.Types
, oShowHelp
]
--- | Serialize a single node
-serializeNode :: String -> Node.Node -> String
-serializeNode csf node =
- printf "%s|%.0f|%d|%d|%.0f|%d|%.0f|%c" (Node.name node ++ csf)
- (Node.tMem node) (Node.nMem node) (Node.fMem node)
- (Node.tDsk node) (Node.fDsk node) (Node.tCpu node)
- (if Node.offline node then 'Y' else 'N')
-
--- | Generate node file data from node objects
-serializeNodes :: String -> Node.List -> String
-serializeNodes csf =
- unlines . map (serializeNode csf) . Container.elems
-
--- | Serialize a single instance
-serializeInstance :: String -> Node.List -> Instance.Instance -> String
-serializeInstance csf nl inst =
- let
- iname = Instance.name inst ++ csf
- pnode = Container.nameOf nl (Instance.pNode inst) ++ csf
- sidx = Instance.sNode inst
- snode = (if sidx == Node.noSecondary
- then ""
- else Container.nameOf nl sidx ++ csf)
- in
- printf "%s|%d|%d|%d|%s|%s|%s|%s"
- iname (Instance.mem inst) (Instance.dsk inst)
- (Instance.vcpus inst) (Instance.runSt inst)
- pnode snode (intercalate "," (Instance.tags inst))
-
--- | Generate instance file data from instance objects
-serializeInstances :: String -> Node.List -> Instance.List -> String
-serializeInstances csf nl =
- unlines . map (serializeInstance csf nl) . Container.elems
-
-- | Return a one-line summary of cluster state
printCluster :: Node.List -> Instance.List
-> String
processData :: Result (Node.AssocList, Instance.AssocList, [String])
-> Result (Node.List, Instance.List, String)
processData input_data = do
- (nl, il, _, csf) <- input_data >>= Loader.mergeData [] [] []
+ (nl, il, _) <- input_data >>= Loader.mergeData [] [] []
let (_, fix_nl) = Loader.checkData nl il
- let ndata = serializeNodes csf nl
- idata = serializeInstances csf nl il
- adata = ndata ++ ['\n'] ++ idata
+ adata = serializeCluster nl il
return (fix_nl, il, adata)
-- | Writes cluster data out
-> String
-> Options
-> Result (Node.List, Instance.List, String)
- -> IO ()
+ -> IO Bool
writeData _ name _ (Bad err) =
- printf "\nError for %s: failed to load data. Details:\n%s\n" name err
+ printf "\nError for %s: failed to load data. Details:\n%s\n" name err >>
+ return False
writeData nlen name opts (Ok (nl, il, adata)) = do
- printf "%-*s " nlen name
+ printf "%-*s " nlen name :: IO ()
hFlush stdout
let shownodes = optShowNodes opts
odir = optOutPath opts
when (isJust shownodes) $
putStr $ Cluster.printNodes nl (fromJust shownodes)
writeFile (oname <.> "data") adata
-
+ return True
-- | Main function.
main :: IO ()
"t_disk" "f_disk" "Score"
when (null clusters) $ do
- let lsock = case optLuxi opts of
- Just s -> s
- Nothing -> defaultLuxiSocket
+ let lsock = fromMaybe defaultLuxiSocket (optLuxi opts)
let name = local
input_data <- Luxi.loadData lsock
- writeData nlen name opts (processData input_data)
+ result <- writeData nlen name opts (processData input_data)
+ when (not result) $ exitWith $ ExitFailure 2
#ifndef NO_CURL
- mapM_ (\ name ->
- do
- input_data <- Rapi.loadData name
- writeData nlen name opts (processData input_data)
- ) clusters
+ results <- mapM (\ name ->
+ do
+ input_data <- Rapi.loadData name
+ writeData nlen name opts (processData input_data)
+ ) clusters
+ when (not $ all id results) $ exitWith (ExitFailure 2)
#else
when (not $ null clusters) $ do
putStrLn "RAPI/curl backend disabled at compile time, cannot scan clusters"