3 {-| External data loader
5 This module holds the external data loading, and thus is the only one
6 depending (via the specialized Text\/Rapi\/Luxi modules) on the actual
7 libraries implementing the low-level protocols.
13 Copyright (C) 2009 Google Inc.
15 This program is free software; you can redistribute it and/or modify
16 it under the terms of the GNU General Public License as published by
17 the Free Software Foundation; either version 2 of the License, or
18 (at your option) any later version.
20 This program is distributed in the hope that it will be useful, but
21 WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 General Public License for more details.
25 You should have received a copy of the GNU General Public License
26 along with this program; if not, write to the Free Software
27 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
32 module Ganeti.HTools.ExtLoader
36 import Data.Maybe (isJust, fromJust)
38 import System.Posix.Env
41 import Text.Printf (printf, hPrintf)
43 import qualified Ganeti.HTools.Luxi as Luxi
45 import qualified Ganeti.HTools.Rapi as Rapi
47 import qualified Ganeti.HTools.Simu as Simu
48 import qualified Ganeti.HTools.Text as Text
49 import qualified Ganeti.HTools.Loader as Loader
50 import qualified Ganeti.HTools.Instance as Instance
51 import qualified Ganeti.HTools.Node as Node
53 import Ganeti.HTools.Types
54 import Ganeti.HTools.CLI
55 import Ganeti.HTools.Utils (sepSplit, tryRead)
57 -- | Parse the environment and return the node\/instance names.
59 -- This also hardcodes here the default node\/instance file names.
60 parseEnv :: () -> IO (String, String)
62 a <- getEnvDefault "HTOOLS_NODES" "nodes"
63 b <- getEnvDefault "HTOOLS_INSTANCES" "instances"
67 wrapIO :: IO (Result a) -> IO (Result a)
68 wrapIO = flip catch (return . Bad . show)
70 parseUtilisation :: String -> Result (String, DynUtil)
71 parseUtilisation line =
72 let columns = sepSplit ' ' line
74 [name, cpu, mem, dsk, net] -> do
75 rcpu <- tryRead name cpu
76 rmem <- tryRead name mem
77 rdsk <- tryRead name dsk
78 rnet <- tryRead name net
79 let du = DynUtil { cpuWeight = rcpu, memWeight = rmem
80 , dskWeight = rdsk, netWeight = rnet }
82 _ -> Bad $ "Cannot parse line " ++ line
84 -- | External tool data loader from a variety of sources.
85 loadExternalData :: Options
86 -> IO (Node.List, Instance.List, [String], String)
87 loadExternalData opts = do
88 (env_node, env_inst) <- parseEnv ()
89 let nodef = if optNodeSet opts then optNodeFile opts
91 instf = if optInstSet opts then optInstFile opts
93 mhost = optMaster opts
95 simdata = optNodeSim opts
97 setLuxi = isJust lsock
98 setSim = isJust simdata
99 setFiles = optNodeSet opts || optInstSet opts
100 allSet = filter id [setRapi, setLuxi, setFiles]
101 exTags = case optExTags opts of
103 Just etl -> map (++ ":") etl
105 when (length allSet > 1) $
107 hPutStrLn stderr ("Error: Only one of the rapi, luxi, and data" ++
108 " files options should be given.")
109 exitWith $ ExitFailure 1
111 util_contents <- (case optDynuFile opts of
112 Just path -> readFile path
113 Nothing -> return "")
114 let util_data = mapM parseUtilisation $ lines util_contents
115 util_data' <- (case util_data of
118 hPutStrLn stderr ("Error: can't parse utilisation" ++
120 exitWith $ ExitFailure 1)
125 return $ Bad "RAPI/curl backend disabled at compile time"
127 wrapIO $ Rapi.loadData mhost
129 | setLuxi -> wrapIO $ Luxi.loadData $ fromJust lsock
130 | setSim -> Simu.loadData $ fromJust simdata
131 | otherwise -> wrapIO $ Text.loadData nodef instf
133 let ldresult = input_data >>= Loader.mergeData util_data' exTags
134 (loaded_nl, il, tags, csf) <-
138 hPrintf stderr "Error: failed to load data. Details:\n%s\n" s
139 exitWith $ ExitFailure 1
141 let (fix_msgs, fixed_nl) = Loader.checkData loaded_nl il
143 unless (null fix_msgs || optVerbose opts == 0) $ do
144 hPutStrLn stderr "Warning: cluster has inconsistent data:"
145 hPutStrLn stderr . unlines . map (printf " - %s") $ fix_msgs
147 return (fixed_nl, il, tags, csf)