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 Control.Exception
37 import Data.Maybe (isJust, fromJust)
39 import System.Posix.Env
42 import Text.Printf (printf, hPrintf)
44 import qualified Ganeti.HTools.Luxi as Luxi
46 import qualified Ganeti.HTools.Rapi as Rapi
48 import qualified Ganeti.HTools.Simu as Simu
49 import qualified Ganeti.HTools.Text as Text
50 import qualified Ganeti.HTools.Loader as Loader
51 import qualified Ganeti.HTools.Instance as Instance
52 import qualified Ganeti.HTools.Node as Node
54 import Ganeti.HTools.Types
55 import Ganeti.HTools.CLI
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 = handle (return . Bad . show)
70 -- | External tool data loader from a variety of sources.
71 loadExternalData :: Options
72 -> IO (Node.List, Instance.List, String)
73 loadExternalData opts = do
74 (env_node, env_inst) <- parseEnv ()
75 let nodef = if optNodeSet opts then optNodeFile opts
77 instf = if optInstSet opts then optInstFile opts
79 mhost = optMaster opts
81 simdata = optNodeSim opts
83 setLuxi = isJust lsock
84 setSim = isJust simdata
85 setFiles = optNodeSet opts || optInstSet opts
86 allSet = filter id [setRapi, setLuxi, setFiles]
87 when (length allSet > 1) $
89 hPutStrLn stderr ("Error: Only one of the rapi, luxi, and data" ++
90 " files options should be given.")
91 exitWith $ ExitFailure 1
97 return $ Bad "RAPI/curl backend disabled at compile time"
99 wrapIO $ Rapi.loadData mhost
101 | setLuxi -> wrapIO $ Luxi.loadData $ fromJust lsock
102 | setSim -> Simu.loadData $ fromJust simdata
103 | otherwise -> wrapIO $ Text.loadData nodef instf
105 let ldresult = input_data >>= Loader.mergeData
106 (loaded_nl, il, csf) <-
110 hPrintf stderr "Error: failed to load data. Details:\n%s\n" s
111 exitWith $ ExitFailure 1
113 let (fix_msgs, fixed_nl) = Loader.checkData loaded_nl il
115 unless (null fix_msgs || optVerbose opts == 0) $ do
116 hPutStrLn stderr "Warning: cluster has inconsistent data:"
117 hPutStrLn stderr . unlines . map (printf " - %s") $ fix_msgs
119 return (fixed_nl, il, csf)