module Ganeti.Storage.Lvm.LVParser (lvParser, lvCommand, lvParams) 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
lvsSeparator :: Char
lvsSeparator = ';'
skipSpaces :: Parser ()
skipSpaces = A.skipWhile A.isHorizontalSpace
bytesP :: Parser Int
bytesP = A.char lvsSeparator *> A.decimal <* A.char 'B'
intP :: Parser Int
intP = A.char lvsSeparator *> A.signed A.decimal
stringP :: Parser String
stringP =
A.char lvsSeparator *> fmap unpack (A.takeWhile (`notElem`
[ lvsSeparator
, '\n']
))
lvCommand :: String
lvCommand = "lvs"
lvParams :: [String]
lvParams =
[ "--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"
]
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
<*> return Nothing <* A.endOfLine
lvParser :: Parser [LVInfo]
lvParser = oneLvParser `AC.manyTill` A.endOfInput