Statistics
| Branch: | Tag: | Revision:

root / src / Ganeti / HTools / ExtLoader.hs @ 7ec2f76b

History | View | Annotate | Download (4.6 kB)

1 525bfb36 Iustin Pop
{-| External data loader.
2 e8f89bb6 Iustin Pop
3 e8f89bb6 Iustin Pop
This module holds the external data loading, and thus is the only one
4 cf924b6d Iustin Pop
depending (via the specialized Text\/Rapi\/Luxi modules) on the actual
5 e8f89bb6 Iustin Pop
libraries implementing the low-level protocols.
6 e8f89bb6 Iustin Pop
7 e8f89bb6 Iustin Pop
-}
8 e8f89bb6 Iustin Pop
9 e8f89bb6 Iustin Pop
{-
10 e8f89bb6 Iustin Pop
11 88a10df5 Iustin Pop
Copyright (C) 2009, 2010, 2011, 2012 Google Inc.
12 e8f89bb6 Iustin Pop
13 e8f89bb6 Iustin Pop
This program is free software; you can redistribute it and/or modify
14 e8f89bb6 Iustin Pop
it under the terms of the GNU General Public License as published by
15 e8f89bb6 Iustin Pop
the Free Software Foundation; either version 2 of the License, or
16 e8f89bb6 Iustin Pop
(at your option) any later version.
17 e8f89bb6 Iustin Pop
18 e8f89bb6 Iustin Pop
This program is distributed in the hope that it will be useful, but
19 e8f89bb6 Iustin Pop
WITHOUT ANY WARRANTY; without even the implied warranty of
20 e8f89bb6 Iustin Pop
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21 e8f89bb6 Iustin Pop
General Public License for more details.
22 e8f89bb6 Iustin Pop
23 e8f89bb6 Iustin Pop
You should have received a copy of the GNU General Public License
24 e8f89bb6 Iustin Pop
along with this program; if not, write to the Free Software
25 e8f89bb6 Iustin Pop
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 e8f89bb6 Iustin Pop
02110-1301, USA.
27 e8f89bb6 Iustin Pop
28 e8f89bb6 Iustin Pop
-}
29 e8f89bb6 Iustin Pop
30 e8f89bb6 Iustin Pop
module Ganeti.HTools.ExtLoader
31 ebf38064 Iustin Pop
  ( loadExternalData
32 ebf38064 Iustin Pop
  , commonSuffix
33 ebf38064 Iustin Pop
  , maybeSaveData
34 ebf38064 Iustin Pop
  ) where
35 e8f89bb6 Iustin Pop
36 cc532bdd Iustin Pop
import Control.Monad
37 30d25dd8 Iustin Pop
import Control.Exception
38 e8f89bb6 Iustin Pop
import Data.Maybe (isJust, fromJust)
39 4188449c Iustin Pop
import System.FilePath
40 e8f89bb6 Iustin Pop
import System.IO
41 8cd36391 Iustin Pop
import Text.Printf (hPrintf)
42 e8f89bb6 Iustin Pop
43 879d9290 Iustin Pop
import qualified Ganeti.HTools.Backend.Luxi as Luxi
44 879d9290 Iustin Pop
import qualified Ganeti.HTools.Backend.Rapi as Rapi
45 879d9290 Iustin Pop
import qualified Ganeti.HTools.Backend.Simu as Simu
46 879d9290 Iustin Pop
import qualified Ganeti.HTools.Backend.Text as Text
47 879d9290 Iustin Pop
import qualified Ganeti.HTools.Backend.IAlloc as IAlloc
48 017a0c3d Iustin Pop
import Ganeti.HTools.Loader (mergeData, checkData, ClusterData(..)
49 017a0c3d Iustin Pop
                            , commonSuffix)
50 e8f89bb6 Iustin Pop
51 01e52493 Iustin Pop
import Ganeti.BasicTypes
52 e8f89bb6 Iustin Pop
import Ganeti.HTools.Types
53 e8f89bb6 Iustin Pop
import Ganeti.HTools.CLI
54 26d62e4c Iustin Pop
import Ganeti.Utils (sepSplit, tryRead, exitIfBad, exitWhen)
55 e8f89bb6 Iustin Pop
56 525bfb36 Iustin Pop
-- | Error beautifier.
57 e8f89bb6 Iustin Pop
wrapIO :: IO (Result a) -> IO (Result a)
58 2cdaf225 Iustin Pop
wrapIO = handle (\e -> return . Bad . show $ (e::IOException))
59 e8f89bb6 Iustin Pop
60 179c0828 Iustin Pop
-- | Parses a user-supplied utilisation string.
61 aa8d2e71 Iustin Pop
parseUtilisation :: String -> Result (String, DynUtil)
62 aa8d2e71 Iustin Pop
parseUtilisation line =
63 ebf38064 Iustin Pop
  case sepSplit ' ' line of
64 ebf38064 Iustin Pop
    [name, cpu, mem, dsk, net] ->
65 ebf38064 Iustin Pop
      do
66 ebf38064 Iustin Pop
        rcpu <- tryRead name cpu
67 ebf38064 Iustin Pop
        rmem <- tryRead name mem
68 ebf38064 Iustin Pop
        rdsk <- tryRead name dsk
69 ebf38064 Iustin Pop
        rnet <- tryRead name net
70 ebf38064 Iustin Pop
        let du = DynUtil { cpuWeight = rcpu, memWeight = rmem
71 ebf38064 Iustin Pop
                         , dskWeight = rdsk, netWeight = rnet }
72 ebf38064 Iustin Pop
        return (name, du)
73 ebf38064 Iustin Pop
    _ -> Bad $ "Cannot parse line " ++ line
74 aa8d2e71 Iustin Pop
75 e8f89bb6 Iustin Pop
-- | External tool data loader from a variety of sources.
76 e8f89bb6 Iustin Pop
loadExternalData :: Options
77 017a0c3d Iustin Pop
                 -> IO ClusterData
78 e8f89bb6 Iustin Pop
loadExternalData opts = do
79 16c2369c Iustin Pop
  let mhost = optMaster opts
80 e8f89bb6 Iustin Pop
      lsock = optLuxi opts
81 16c2369c Iustin Pop
      tfile = optDataFile opts
82 e8f89bb6 Iustin Pop
      simdata = optNodeSim opts
83 4892d955 René Nussbaumer
      iallocsrc = optIAllocSrc opts
84 e8f89bb6 Iustin Pop
      setRapi = mhost /= ""
85 e8f89bb6 Iustin Pop
      setLuxi = isJust lsock
86 9983063b Iustin Pop
      setSim = (not . null) simdata
87 16c2369c Iustin Pop
      setFile = isJust tfile
88 4892d955 René Nussbaumer
      setIAllocSrc = isJust iallocsrc
89 16c2369c Iustin Pop
      allSet = filter id [setRapi, setLuxi, setFile]
90 0f15cc76 Iustin Pop
      exTags = case optExTags opts of
91 0f15cc76 Iustin Pop
                 Nothing -> []
92 0f15cc76 Iustin Pop
                 Just etl -> map (++ ":") etl
93 2d1708e0 Guido Trotter
      selInsts = optSelInst opts
94 39f979b8 Iustin Pop
      exInsts = optExInst opts
95 0f15cc76 Iustin Pop
96 88a10df5 Iustin Pop
  exitWhen (length allSet > 1) "Only one of the rapi, luxi, and data\
97 707cd3d7 Helga Velroyen
                               \ files options should be given."
98 e8f89bb6 Iustin Pop
99 3603605a Iustin Pop
  util_contents <- maybe (return "") readFile (optDynuFile opts)
100 88a10df5 Iustin Pop
  util_data <- exitIfBad "can't parse utilisation data" .
101 88a10df5 Iustin Pop
               mapM parseUtilisation $ lines util_contents
102 e8f89bb6 Iustin Pop
  input_data <-
103 ebf38064 Iustin Pop
    case () of
104 ebf38064 Iustin Pop
      _ | setRapi -> wrapIO $ Rapi.loadData mhost
105 2cdaf225 Iustin Pop
        | setLuxi -> wrapIO . Luxi.loadData $ fromJust lsock
106 ebf38064 Iustin Pop
        | setSim -> Simu.loadData simdata
107 2cdaf225 Iustin Pop
        | setFile -> wrapIO . Text.loadData $ fromJust tfile
108 2cdaf225 Iustin Pop
        | setIAllocSrc -> wrapIO . IAlloc.loadData $ fromJust iallocsrc
109 ebf38064 Iustin Pop
        | otherwise -> return $ Bad "No backend selected! Exiting."
110 e8f89bb6 Iustin Pop
111 88a10df5 Iustin Pop
  let ldresult = input_data >>= mergeData util_data exTags selInsts exInsts
112 88a10df5 Iustin Pop
  cdata <- exitIfBad "failed to load data, aborting" ldresult
113 017a0c3d Iustin Pop
  let (fix_msgs, nl) = checkData (cdNodes cdata) (cdInstances cdata)
114 e8f89bb6 Iustin Pop
115 8cd36391 Iustin Pop
  unless (optVerbose opts == 0) $ maybeShowWarnings fix_msgs
116 e8f89bb6 Iustin Pop
117 017a0c3d Iustin Pop
  return cdata {cdNodes = nl}
118 4188449c Iustin Pop
119 4188449c Iustin Pop
-- | Function to save the cluster data to a file.
120 4188449c Iustin Pop
maybeSaveData :: Maybe FilePath -- ^ The file prefix to save to
121 4188449c Iustin Pop
              -> String         -- ^ The suffix (extension) to add
122 4188449c Iustin Pop
              -> String         -- ^ Informational message
123 4188449c Iustin Pop
              -> ClusterData    -- ^ The cluster data
124 4188449c Iustin Pop
              -> IO ()
125 4188449c Iustin Pop
maybeSaveData Nothing _ _ _ = return ()
126 4188449c Iustin Pop
maybeSaveData (Just path) ext msg cdata = do
127 4188449c Iustin Pop
  let adata = Text.serializeCluster cdata
128 4188449c Iustin Pop
      out_path = path <.> ext
129 4188449c Iustin Pop
  writeFile out_path adata
130 4188449c Iustin Pop
  hPrintf stderr "The cluster state %s has been written to file '%s'\n"
131 4188449c Iustin Pop
          msg out_path