Add LV data collector
authorMichele Tartara <mtartara@google.com>
Tue, 25 Jun 2013 13:10:23 +0000 (13:10 +0000)
committerMichele Tartara <mtartara@google.com>
Mon, 1 Jul 2013 11:35:12 +0000 (11:35 +0000)
This commit adds the LV data collector.

Also, the lvCommand function was not providing the correct value as expected by
the readProcess function, so it was fixed.

Signed-off-by: Michele Tartara <mtartara@google.com>
Reviewed-by: Helga Velroyen <helgav@google.com>

Makefile.am
src/Ganeti/DataCollectors/Lv.hs [new file with mode: 0644]
src/Ganeti/DataCollectors/Program.hs
src/Ganeti/Storage/Lvm/LVParser.hs

index 1a85084..9c3c5f7 100644 (file)
@@ -553,6 +553,7 @@ HS_LIB_SRCS = \
        src/Ganeti/DataCollectors/Drbd.hs \
        src/Ganeti/DataCollectors/InstStatus.hs \
        src/Ganeti/DataCollectors/InstStatusTypes.hs \
+       src/Ganeti/DataCollectors/Lv.hs \
        src/Ganeti/DataCollectors/Program.hs \
        src/Ganeti/DataCollectors/Types.hs \
        src/Ganeti/Errors.hs \
diff --git a/src/Ganeti/DataCollectors/Lv.hs b/src/Ganeti/DataCollectors/Lv.hs
new file mode 100644 (file)
index 0000000..8c34c34
--- /dev/null
@@ -0,0 +1,129 @@
+{-| Logical Volumes data collector.
+
+-}
+
+{-
+
+Copyright (C) 2013 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
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.
+
+-}
+
+module Ganeti.DataCollectors.Lv
+  ( main
+  , options
+  , arguments
+  , dcName
+  , dcVersion
+  , dcFormatVersion
+  , dcCategory
+  , dcKind
+  , dcReport
+  ) where
+
+
+import qualified Control.Exception as E
+import Control.Monad
+import Data.Attoparsec.Text.Lazy as A
+import Data.Text.Lazy (pack, unpack)
+import System.Process
+import qualified Text.JSON as J
+
+import qualified Ganeti.BasicTypes as BT
+import Ganeti.Common
+import Ganeti.DataCollectors.CLI
+import Ganeti.DataCollectors.Types
+import Ganeti.Storage.Lvm.LVParser
+import Ganeti.Utils
+
+
+-- | The default setting for the maximum amount of not parsed character to
+-- print in case of error.
+-- It is set to use most of the screen estate on a standard 80x25 terminal.
+-- TODO: add the possibility to set this with a command line parameter.
+defaultCharNum :: Int
+defaultCharNum = 80*20
+
+-- | The name of this data collector.
+dcName :: String
+dcName = "lv"
+
+-- | The version of this data collector.
+dcVersion :: DCVersion
+dcVersion = DCVerBuiltin
+
+-- | The version number for the data format of this data collector.
+dcFormatVersion :: Int
+dcFormatVersion = 1
+
+-- | The category of this data collector.
+dcCategory :: Maybe DCCategory
+dcCategory = Just DCStorage
+
+-- | The kind of this data collector.
+dcKind :: DCKind
+dcKind = DCKPerf
+
+-- | The data exported by the data collector, taken from the default location.
+dcReport :: IO DCReport
+dcReport = buildDCReport Nothing
+
+-- * Command line options
+
+options :: IO [OptType]
+options =
+  return
+    [ oInputFile
+    ]
+
+-- | The list of arguments supported by the program.
+arguments :: [ArgCompletion]
+arguments = [ArgCompletion OptComplFile 0 (Just 0)]
+
+-- | This function computes the JSON representation of the LV status
+buildJsonReport :: Maybe FilePath -> IO J.JSValue
+buildJsonReport inputFile = do
+  let (cmd:params) = lvCommand
+      fromLvs =
+        ((E.try $ readProcess cmd params "") :: IO (Either IOError String)) >>=
+          exitIfBad "running command" . either (BT.Bad . show) BT.Ok
+  contents <-
+    maybe fromLvs (\fn -> ((E.try $ readFile fn) :: IO (Either IOError String))
+      >>= exitIfBad "reading from file" . either (BT.Bad . show) BT.Ok)
+      inputFile
+  lvInfo <-
+    case A.parse lvParser $ pack contents of
+      A.Fail unparsedText contexts errorMessage -> exitErr $
+        show (Prelude.take defaultCharNum $ unpack unparsedText) ++ "\n"
+          ++ show contexts ++ "\n" ++ errorMessage
+      A.Done _ lvinfoD -> return lvinfoD
+  return $ J.showJSON lvInfo
+
+-- | This function computes the DCReport for the logical volumes.
+buildDCReport :: Maybe FilePath -> IO DCReport
+buildDCReport inputFile =
+  buildJsonReport inputFile >>=
+    buildReport dcName dcVersion dcFormatVersion dcCategory dcKind
+
+-- | Main function.
+main :: Options -> [String] -> IO ()
+main opts args = do
+  unless (null args) . exitErr $ "This program takes exactly zero" ++
+                                 " arguments, got '" ++ unwords args ++ "'"
+  report <- buildDCReport $ optInputFile opts
+
+  putStrLn $ J.encode report
index 6d95dd8..7005535 100644 (file)
@@ -31,6 +31,7 @@ import Ganeti.DataCollectors.CLI (Options)
 import qualified Ganeti.DataCollectors.Diskstats as Diskstats
 import qualified Ganeti.DataCollectors.Drbd as Drbd
 import qualified Ganeti.DataCollectors.InstStatus as InstStatus
+import qualified Ganeti.DataCollectors.Lv as Lv
 
 -- | Supported binaries.
 personalities :: PersonalityList Options
@@ -45,4 +46,6 @@ personalities = [ (Drbd.dcName, (Drbd.main, Drbd.options, Drbd.arguments,
                                       Diskstats.arguments,
                                       "gathers and displays the disk usage\
                                       \ statistics in JSON format"))
+                , (Lv.dcName, (Lv.main, Lv.options, Lv.arguments, "gathers and\
+                               \ displays info about logical volumes"))
                 ]
index c260c84..b51aa86 100644 (file)
@@ -74,9 +74,9 @@ lvCommand :: [String]
 lvCommand =
   [ "lvs"
   , "--noheadings"
-  , "--units B"
-  , "-- separator ;"
-  , "-o lv_uuid,lv_name,lv_attr,lv_major,lv_minor,lv_kernel_major\
+  , "--units", "B"
+  , "--separator", ";"
+  , "-o", "lv_uuid,lv_name,lv_attr,lv_major,lv_minor,lv_kernel_major\
     \,lv_kernel_minor,lv_size,seg_count,lv_tags,modules,vg_uuid,vg_name,segtype\
     \,seg_start,seg_start_pe,seg_size,seg_tags,seg_pe_ranges,devices"
   ]