Add LV parser
authorMichele Tartara <mtartara@google.com>
Fri, 7 Jun 2013 20:34:14 +0000 (20:34 +0000)
committerMichele Tartara <mtartara@google.com>
Mon, 1 Jul 2013 11:33:54 +0000 (11:33 +0000)
Add the parser for getting the information about the logical volumes in the
system.

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

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

index 91f3f37..7ff4cbc 100644 (file)
@@ -76,6 +76,7 @@ HS_DIRS = \
        src/Ganeti/Storage \
        src/Ganeti/Storage/Diskstats \
        src/Ganeti/Storage/Drbd \
+       src/Ganeti/Storage/Lvm \
        test/hs \
        test/hs/Test \
        test/hs/Test/Ganeti \
@@ -614,6 +615,8 @@ HS_LIB_SRCS = \
        src/Ganeti/Storage/Diskstats/Types.hs \
        src/Ganeti/Storage/Drbd/Parser.hs \
        src/Ganeti/Storage/Drbd/Types.hs \
+       src/Ganeti/Storage/Lvm/LVParser.hs \
+       src/Ganeti/Storage/Lvm/Types.hs \
        src/Ganeti/Storage/Utils.hs \
        src/Ganeti/THH.hs \
        src/Ganeti/Types.hs \
diff --git a/src/Ganeti/Storage/Lvm/LVParser.hs b/src/Ganeti/Storage/Lvm/LVParser.hs
new file mode 100644 (file)
index 0000000..c260c84
--- /dev/null
@@ -0,0 +1,116 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-| Logical Volumer information parser
+
+This module holds the definition of the parser that extracts status
+information about the logical volumes (LVs) of the system from the output of the
+@lvs@ command.
+
+-}
+{-
+
+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.Storage.Lvm.LVParser (lvParser, lvCommand) where
+
+import Control.Applicative ((<*>), (*>), (<*), (<$>), Applicative, )
+import qualified Data.Attoparsec.Text as A
+import qualified Data.Attoparsec.Combinator as AC
+import Data.Attoparsec.Text (Parser)
+import Data.Text (unpack)
+
+import Ganeti.Storage.Lvm.Types
+
+
+-- | The separator of the fields returned by @lvs@
+lvsSeparator :: Char
+lvsSeparator = ';'
+
+-- * Utility functions
+
+-- | Our own space-skipping function, because A.skipSpace also skips
+-- newline characters. It skips ZERO or more spaces, so it does not
+-- fail if there are no spaces.
+skipSpaces :: Parser ()
+skipSpaces = A.skipWhile A.isHorizontalSpace
+
+-- | A parser recognizing a number of bytes, represented as a number preceeded
+-- by a separator and followed by the "B" character.
+bytesP :: Parser Int
+bytesP = A.char lvsSeparator *> A.decimal <* A.char 'B'
+
+-- | A parser recognizing a number discarding the preceeding separator
+intP :: Parser Int
+intP = A.char lvsSeparator *> A.signed A.decimal
+
+-- | A parser recognizing a string starting with and closed by a separator (both
+-- are discarded)
+stringP :: Parser String
+stringP =
+  A.char lvsSeparator *> fmap unpack (A.takeWhile (`notElem`
+    [ lvsSeparator
+    , '\n']
+    ))
+
+-- * Parser implementation
+
+-- | The command providing the data, in the format the parser expects
+lvCommand :: [String]
+lvCommand =
+  [ "lvs"
+  , "--noheadings"
+  , "--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"
+  ]
+
+-- | The parser for one line of the diskstatus file.
+oneLvParser :: Parser LVInfo
+oneLvParser =
+  let uuidP = skipSpaces *> fmap unpack (A.takeWhile (/= lvsSeparator))
+      nameP = stringP
+      attrP = stringP
+      majorP = intP
+      minorP = intP
+      kernelMajorP = intP
+      kernelMinorP = intP
+      sizeP = bytesP
+      segCountP = intP
+      tagsP = stringP
+      modulesP = stringP
+      vgUuidP = stringP
+      vgNameP = stringP
+      segtypeP = stringP
+      segStartP = bytesP
+      segStartPeP = intP
+      segSizeP = bytesP
+      segTagsP = stringP
+      segPeRangesP = stringP
+      devicesP = stringP
+    in
+      LVInfo
+        <$> uuidP <*> nameP <*> attrP <*> majorP <*> minorP <*> kernelMajorP
+        <*> kernelMinorP <*> sizeP <*> segCountP <*> tagsP <*> modulesP
+        <*> vgUuidP <*> vgNameP <*> segtypeP <*> segStartP <*> segStartPeP
+        <*> segSizeP <*> segTagsP <*> segPeRangesP <*> devicesP <* A.endOfLine
+
+-- | The parser for a whole diskstatus file.
+lvParser :: Parser [LVInfo]
+lvParser = oneLvParser `AC.manyTill` A.endOfInput
diff --git a/src/Ganeti/Storage/Lvm/Types.hs b/src/Ganeti/Storage/Lvm/Types.hs
new file mode 100644 (file)
index 0000000..162e2be
--- /dev/null
@@ -0,0 +1,57 @@
+{-# LANGUAGE TemplateHaskell #-}
+{-| LVM data types
+
+This module holds the definition of the data types describing the status of the
+disks according to LVM (and particularly the lvs tool).
+
+-}
+{-
+
+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.Storage.Lvm.Types
+  ( LVInfo(..)
+  ) where
+
+import Ganeti.THH
+
+
+-- | This is the format of the report produced by each data collector.
+$(buildObject "LVInfo" "lvi"
+  [ simpleField "uuid"              [t| String |]
+  , simpleField "name"              [t| String |]
+  , simpleField "attr"              [t| String |]
+  , simpleField "major"             [t| Int |]
+  , simpleField "minor"             [t| Int |]
+  , simpleField "kernel_major"      [t| Int |]
+  , simpleField "kernel_minor"      [t| Int |]
+  , simpleField "size"              [t| Int |]
+  , simpleField "seg_count"         [t| Int |]
+  , simpleField "tags"              [t| String |]
+  , simpleField "modules"           [t| String |]
+  , simpleField "vg_uuid"           [t| String |]
+  , simpleField "vg_name"           [t| String |]
+  , simpleField "segtype"           [t| String |]
+  , simpleField "seg_start"         [t| Int |]
+  , simpleField "seg_start_pe"      [t| Int |]
+  , simpleField "seg_size"          [t| Int |]
+  , simpleField "seg_tags"          [t| String |]
+  , simpleField "seg_pe_ranges"     [t| String |]
+  , simpleField "devices"           [t| String |]
+  ])