Statistics
| Branch: | Tag: | Revision:

root / src / Ganeti / DataCollectors / Lv.hs @ f22b987a

History | View | Annotate | Download (4 kB)

1
{-| Logical Volumes data collector.
2

    
3
-}
4

    
5
{-
6

    
7
Copyright (C) 2013 Google Inc.
8

    
9
This program is free software; you can redistribute it and/or modify
10
it under the terms of the GNU General Public License as published by
11
the Free Software Foundation; either version 2 of the License, or
12
(at your option) any later version.
13

    
14
This program is distributed in the hope that it will be useful, but
15
WITHOUT ANY WARRANTY; without even the implied warranty of
16
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17
General Public License for more details.
18

    
19
You should have received a copy of the GNU General Public License
20
along with this program; if not, write to the Free Software
21
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22
02110-1301, USA.
23

    
24
-}
25

    
26
module Ganeti.DataCollectors.Lv
27
  ( main
28
  , options
29
  , arguments
30
  , dcName
31
  , dcVersion
32
  , dcFormatVersion
33
  , dcCategory
34
  , dcKind
35
  , dcReport
36
  ) where
37

    
38

    
39
import qualified Control.Exception as E
40
import Control.Monad
41
import Data.Attoparsec.Text.Lazy as A
42
import Data.Text.Lazy (pack, unpack)
43
import System.Process
44
import qualified Text.JSON as J
45

    
46
import qualified Ganeti.BasicTypes as BT
47
import Ganeti.Common
48
import Ganeti.DataCollectors.CLI
49
import Ganeti.DataCollectors.Types
50
import Ganeti.Storage.Lvm.LVParser
51
import Ganeti.Storage.Lvm.Types
52
import Ganeti.Utils
53

    
54

    
55
-- | The default setting for the maximum amount of not parsed character to
56
-- print in case of error.
57
-- It is set to use most of the screen estate on a standard 80x25 terminal.
58
-- TODO: add the possibility to set this with a command line parameter.
59
defaultCharNum :: Int
60
defaultCharNum = 80*20
61

    
62
-- | The name of this data collector.
63
dcName :: String
64
dcName = "lv"
65

    
66
-- | The version of this data collector.
67
dcVersion :: DCVersion
68
dcVersion = DCVerBuiltin
69

    
70
-- | The version number for the data format of this data collector.
71
dcFormatVersion :: Int
72
dcFormatVersion = 1
73

    
74
-- | The category of this data collector.
75
dcCategory :: Maybe DCCategory
76
dcCategory = Just DCStorage
77

    
78
-- | The kind of this data collector.
79
dcKind :: DCKind
80
dcKind = DCKPerf
81

    
82
-- | The data exported by the data collector, taken from the default location.
83
dcReport :: IO DCReport
84
dcReport = buildDCReport Nothing
85

    
86
-- * Command line options
87

    
88
options :: IO [OptType]
89
options =
90
  return
91
    [ oInputFile
92
    ]
93

    
94
-- | The list of arguments supported by the program.
95
arguments :: [ArgCompletion]
96
arguments = [ArgCompletion OptComplFile 0 (Just 0)]
97

    
98
-- | Get information about logical volumes from file (if specified) or
99
-- by actually running the command to get it from a live cluster.
100
getLvInfo :: Maybe FilePath -> IO [LVInfo]
101
getLvInfo inputFile = do
102
  let cmd = lvCommand
103
      params = lvParams
104
      fromLvs =
105
        ((E.try $ readProcess cmd params "") :: IO (Either IOError String)) >>=
106
          exitIfBad "running command" . either (BT.Bad . show) BT.Ok
107
  contents <-
108
    maybe fromLvs (\fn -> ((E.try $ readFile fn) :: IO (Either IOError String))
109
      >>= exitIfBad "reading from file" . either (BT.Bad . show) BT.Ok)
110
      inputFile
111
  case A.parse lvParser $ pack contents of
112
    A.Fail unparsedText contexts errorMessage -> exitErr $
113
      show (Prelude.take defaultCharNum $ unpack unparsedText) ++ "\n"
114
        ++ show contexts ++ "\n" ++ errorMessage
115
    A.Done _ lvinfoD -> return lvinfoD
116

    
117
-- | This function computes the JSON representation of the LV status
118
buildJsonReport :: Maybe FilePath -> IO J.JSValue
119
buildJsonReport inputFile = do
120
  lvInfo <- getLvInfo inputFile
121
  return $ J.showJSON lvInfo
122

    
123
-- | This function computes the DCReport for the logical volumes.
124
buildDCReport :: Maybe FilePath -> IO DCReport
125
buildDCReport inputFile =
126
  buildJsonReport inputFile >>=
127
    buildReport dcName dcVersion dcFormatVersion dcCategory dcKind
128

    
129
-- | Main function.
130
main :: Options -> [String] -> IO ()
131
main opts args = do
132
  unless (null args) . exitErr $ "This program takes exactly zero" ++
133
                                 " arguments, got '" ++ unwords args ++ "'"
134
  report <- buildDCReport $ optInputFile opts
135

    
136
  putStrLn $ J.encode report