root / src / Ganeti / Block / Drbd / Parser.hs @ 3add7574
History | View | Annotate | Download (12.6 kB)
1 | 3c1915df | Michele Tartara | {-# LANGUAGE OverloadedStrings #-} |
---|---|---|---|
2 | 3c1915df | Michele Tartara | {-| DRBD proc file parser |
3 | 3c1915df | Michele Tartara | |
4 | 3c1915df | Michele Tartara | This module holds the definition of the parser that extracts status |
5 | 3c1915df | Michele Tartara | information from the DRBD proc file. |
6 | 3c1915df | Michele Tartara | |
7 | 3c1915df | Michele Tartara | -} |
8 | 3c1915df | Michele Tartara | {- |
9 | 3c1915df | Michele Tartara | |
10 | 3c1915df | Michele Tartara | Copyright (C) 2012 Google Inc. |
11 | 3c1915df | Michele Tartara | |
12 | 3c1915df | Michele Tartara | This program is free software; you can redistribute it and/or modify |
13 | 3c1915df | Michele Tartara | it under the terms of the GNU General Public License as published by |
14 | 3c1915df | Michele Tartara | the Free Software Foundation; either version 2 of the License, or |
15 | 3c1915df | Michele Tartara | (at your option) any later version. |
16 | 3c1915df | Michele Tartara | |
17 | 3c1915df | Michele Tartara | This program is distributed in the hope that it will be useful, but |
18 | 3c1915df | Michele Tartara | WITHOUT ANY WARRANTY; without even the implied warranty of |
19 | 3c1915df | Michele Tartara | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
20 | 3c1915df | Michele Tartara | General Public License for more details. |
21 | 3c1915df | Michele Tartara | |
22 | 3c1915df | Michele Tartara | You should have received a copy of the GNU General Public License |
23 | 3c1915df | Michele Tartara | along with this program; if not, write to the Free Software |
24 | 3c1915df | Michele Tartara | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
25 | 3c1915df | Michele Tartara | 02110-1301, USA. |
26 | 3c1915df | Michele Tartara | |
27 | 3c1915df | Michele Tartara | -} |
28 | 3c1915df | Michele Tartara | module Ganeti.Block.Drbd.Parser (drbdStatusParser, commaIntParser) where |
29 | 3c1915df | Michele Tartara | |
30 | 3c1915df | Michele Tartara | import Control.Applicative ((<*>), (*>), (<*), (<$>), (<|>), pure) |
31 | 3c1915df | Michele Tartara | import qualified Data.Attoparsec.Text as A |
32 | 3c1915df | Michele Tartara | import qualified Data.Attoparsec.Combinator as AC |
33 | 3c1915df | Michele Tartara | import Data.Attoparsec.Text (Parser) |
34 | cefd4a4a | Michele Tartara | import Data.Maybe |
35 | 3c1915df | Michele Tartara | import Data.Text (Text, unpack) |
36 | 3c1915df | Michele Tartara | |
37 | 3c1915df | Michele Tartara | import Ganeti.Block.Drbd.Types |
38 | 3c1915df | Michele Tartara | |
39 | 3c1915df | Michele Tartara | -- | Our own space-skipping function, because A.skipSpace also skips |
40 | 3c1915df | Michele Tartara | -- newline characters. It skips ZERO or more spaces, so it does not |
41 | 3c1915df | Michele Tartara | -- fail if there are no spaces. |
42 | 3c1915df | Michele Tartara | skipSpaces :: Parser () |
43 | 3c1915df | Michele Tartara | skipSpaces = A.skipWhile A.isHorizontalSpace |
44 | 3c1915df | Michele Tartara | |
45 | 3c1915df | Michele Tartara | -- | Skips spaces and the given string, then executes a parser and |
46 | 3c1915df | Michele Tartara | -- returns its result. |
47 | 3c1915df | Michele Tartara | skipSpacesAndString :: Text -> Parser a -> Parser a |
48 | 3c1915df | Michele Tartara | skipSpacesAndString s parser = |
49 | 3c1915df | Michele Tartara | skipSpaces |
50 | 3c1915df | Michele Tartara | *> A.string s |
51 | 3c1915df | Michele Tartara | *> parser |
52 | 3c1915df | Michele Tartara | |
53 | 3c1915df | Michele Tartara | -- | Predicate verifying (potentially bad) end of lines |
54 | 3c1915df | Michele Tartara | isBadEndOfLine :: Char -> Bool |
55 | 3c1915df | Michele Tartara | isBadEndOfLine c = (c == '\0') || A.isEndOfLine c |
56 | 3c1915df | Michele Tartara | |
57 | 3c1915df | Michele Tartara | -- | Takes a parser and returns it with the content wrapped in a Maybe |
58 | 3c1915df | Michele Tartara | -- object. The resulting parser never fails, but contains Nothing if |
59 | 3c1915df | Michele Tartara | -- it couldn't properly parse the string. |
60 | 3c1915df | Michele Tartara | optional :: Parser a -> Parser (Maybe a) |
61 | 3c1915df | Michele Tartara | optional parser = (Just <$> parser) <|> pure Nothing |
62 | 3c1915df | Michele Tartara | |
63 | 3c1915df | Michele Tartara | -- | The parser for a whole DRBD status file. |
64 | 3c1915df | Michele Tartara | drbdStatusParser :: Parser DRBDStatus |
65 | 3c1915df | Michele Tartara | drbdStatusParser = |
66 | 3c1915df | Michele Tartara | DRBDStatus <$> versionInfoParser |
67 | 3c1915df | Michele Tartara | <*> deviceParser `AC.manyTill` A.endOfInput |
68 | fd80be11 | Michele Tartara | <* A.endOfInput |
69 | 3c1915df | Michele Tartara | |
70 | 3c1915df | Michele Tartara | -- | The parser for the version information lines. |
71 | 3c1915df | Michele Tartara | versionInfoParser :: Parser VersionInfo |
72 | cefd4a4a | Michele Tartara | versionInfoParser = do |
73 | cefd4a4a | Michele Tartara | versionF <- optional versionP |
74 | cefd4a4a | Michele Tartara | apiF <- optional apiP |
75 | cefd4a4a | Michele Tartara | protoF <- optional protoP |
76 | cefd4a4a | Michele Tartara | srcVersionF <- optional srcVersion |
77 | cefd4a4a | Michele Tartara | ghF <- fmap unpack <$> optional gh |
78 | cefd4a4a | Michele Tartara | builderF <- fmap unpack <$> optional builder |
79 | cefd4a4a | Michele Tartara | if isNothing versionF |
80 | cefd4a4a | Michele Tartara | && isNothing apiF |
81 | cefd4a4a | Michele Tartara | && isNothing protoF |
82 | cefd4a4a | Michele Tartara | && isNothing srcVersionF |
83 | cefd4a4a | Michele Tartara | && isNothing ghF |
84 | cefd4a4a | Michele Tartara | && isNothing builderF |
85 | cefd4a4a | Michele Tartara | then fail "versionInfo" |
86 | cefd4a4a | Michele Tartara | else pure $ VersionInfo versionF apiF protoF srcVersionF ghF builderF |
87 | cefd4a4a | Michele Tartara | |
88 | 3c1915df | Michele Tartara | where versionP = |
89 | 3c1915df | Michele Tartara | A.string "version:" |
90 | 3c1915df | Michele Tartara | *> skipSpaces |
91 | 3c1915df | Michele Tartara | *> fmap unpack (A.takeWhile $ not . A.isHorizontalSpace) |
92 | 3c1915df | Michele Tartara | apiP = |
93 | 3c1915df | Michele Tartara | skipSpacesAndString "(api:" . fmap unpack $ A.takeWhile (/= '/') |
94 | 3c1915df | Michele Tartara | protoP = |
95 | 3c1915df | Michele Tartara | A.string "/proto:" |
96 | 3c1915df | Michele Tartara | *> fmap Data.Text.unpack (A.takeWhile (/= ')')) |
97 | 3c1915df | Michele Tartara | <* A.takeTill A.isEndOfLine <* A.endOfLine |
98 | 3c1915df | Michele Tartara | srcVersion = |
99 | 3c1915df | Michele Tartara | A.string "srcversion:" |
100 | 3c1915df | Michele Tartara | *> AC.skipMany1 A.space |
101 | 3c1915df | Michele Tartara | *> fmap unpack (A.takeTill A.isEndOfLine) |
102 | 3c1915df | Michele Tartara | <* A.endOfLine |
103 | 3c1915df | Michele Tartara | gh = |
104 | 3c1915df | Michele Tartara | A.string "GIT-hash:" |
105 | 3c1915df | Michele Tartara | *> skipSpaces |
106 | 3c1915df | Michele Tartara | *> A.takeWhile (not . A.isHorizontalSpace) |
107 | 3c1915df | Michele Tartara | builder = |
108 | 3c1915df | Michele Tartara | skipSpacesAndString "build by" $ |
109 | 3c1915df | Michele Tartara | skipSpaces |
110 | 3c1915df | Michele Tartara | *> A.takeTill A.isEndOfLine |
111 | 3c1915df | Michele Tartara | <* A.endOfLine |
112 | 3c1915df | Michele Tartara | |
113 | 3c1915df | Michele Tartara | -- | The parser for a (multi-line) string representing a device. |
114 | 3c1915df | Michele Tartara | deviceParser :: Parser DeviceInfo |
115 | 3c1915df | Michele Tartara | deviceParser = do |
116 | 3c1915df | Michele Tartara | deviceNum <- skipSpaces *> A.decimal <* A.char ':' |
117 | 2188740e | Michele Tartara | cs <- skipSpacesAndString "cs:" connStateParser |
118 | 3c1915df | Michele Tartara | if cs == Unconfigured |
119 | 3c1915df | Michele Tartara | then do |
120 | 3c1915df | Michele Tartara | _ <- additionalEOL |
121 | 3c1915df | Michele Tartara | return $ UnconfiguredDevice deviceNum |
122 | 3c1915df | Michele Tartara | else do |
123 | 3c1915df | Michele Tartara | ro <- skipSpaces *> skipRoleString *> localRemoteParser roleParser |
124 | 3c1915df | Michele Tartara | ds <- skipSpacesAndString "ds:" $ localRemoteParser diskStateParser |
125 | 3c1915df | Michele Tartara | replicProtocol <- A.space *> A.anyChar |
126 | 3c1915df | Michele Tartara | io <- skipSpaces *> ioFlagsParser <* A.skipWhile isBadEndOfLine |
127 | 2188740e | Michele Tartara | pIndicators <- perfIndicatorsParser |
128 | 3c1915df | Michele Tartara | syncS <- conditionalSyncStatusParser cs |
129 | 3c1915df | Michele Tartara | reS <- optional resyncParser |
130 | 3c1915df | Michele Tartara | act <- optional actLogParser |
131 | 3c1915df | Michele Tartara | _ <- additionalEOL |
132 | 2188740e | Michele Tartara | return $ DeviceInfo deviceNum cs ro ds replicProtocol io pIndicators |
133 | 3c1915df | Michele Tartara | syncS reS act |
134 | 3c1915df | Michele Tartara | |
135 | 3c1915df | Michele Tartara | where conditionalSyncStatusParser SyncSource = Just <$> syncStatusParser |
136 | 3c1915df | Michele Tartara | conditionalSyncStatusParser SyncTarget = Just <$> syncStatusParser |
137 | 3c1915df | Michele Tartara | conditionalSyncStatusParser _ = pure Nothing |
138 | 3c1915df | Michele Tartara | skipRoleString = A.string "ro:" <|> A.string "st:" |
139 | 3c1915df | Michele Tartara | resyncParser = skipSpacesAndString "resync:" additionalInfoParser |
140 | 3c1915df | Michele Tartara | actLogParser = skipSpacesAndString "act_log:" additionalInfoParser |
141 | 3c1915df | Michele Tartara | additionalEOL = A.skipWhile A.isEndOfLine |
142 | 3c1915df | Michele Tartara | |
143 | 3c1915df | Michele Tartara | -- | The parser for the connection state. |
144 | 2188740e | Michele Tartara | connStateParser :: Parser ConnState |
145 | 2188740e | Michele Tartara | connStateParser = |
146 | 3c1915df | Michele Tartara | standAlone |
147 | 3c1915df | Michele Tartara | <|> disconnecting |
148 | 3c1915df | Michele Tartara | <|> unconnected |
149 | 3c1915df | Michele Tartara | <|> timeout |
150 | 3c1915df | Michele Tartara | <|> brokenPipe |
151 | 3c1915df | Michele Tartara | <|> networkFailure |
152 | 3c1915df | Michele Tartara | <|> protocolError |
153 | 3c1915df | Michele Tartara | <|> tearDown |
154 | 3c1915df | Michele Tartara | <|> wfConnection |
155 | 3c1915df | Michele Tartara | <|> wfReportParams |
156 | 3c1915df | Michele Tartara | <|> connected |
157 | 3c1915df | Michele Tartara | <|> startingSyncS |
158 | 3c1915df | Michele Tartara | <|> startingSyncT |
159 | 3c1915df | Michele Tartara | <|> wfBitMapS |
160 | 3c1915df | Michele Tartara | <|> wfBitMapT |
161 | 3c1915df | Michele Tartara | <|> wfSyncUUID |
162 | 3c1915df | Michele Tartara | <|> syncSource |
163 | 3c1915df | Michele Tartara | <|> syncTarget |
164 | 3c1915df | Michele Tartara | <|> pausedSyncS |
165 | 3c1915df | Michele Tartara | <|> pausedSyncT |
166 | 3c1915df | Michele Tartara | <|> verifyS |
167 | 3c1915df | Michele Tartara | <|> verifyT |
168 | 3c1915df | Michele Tartara | <|> unconfigured |
169 | 3c1915df | Michele Tartara | where standAlone = A.string "StandAlone" *> pure StandAlone |
170 | 3c1915df | Michele Tartara | disconnecting = A.string "Disconnectiog" *> pure Disconnecting |
171 | 3c1915df | Michele Tartara | unconnected = A.string "Unconnected" *> pure Unconnected |
172 | 3c1915df | Michele Tartara | timeout = A.string "Timeout" *> pure Timeout |
173 | 3c1915df | Michele Tartara | brokenPipe = A.string "BrokenPipe" *> pure BrokenPipe |
174 | 3c1915df | Michele Tartara | networkFailure = A.string "NetworkFailure" *> pure NetworkFailure |
175 | 3c1915df | Michele Tartara | protocolError = A.string "ProtocolError" *> pure ProtocolError |
176 | 3c1915df | Michele Tartara | tearDown = A.string "TearDown" *> pure TearDown |
177 | 3c1915df | Michele Tartara | wfConnection = A.string "WFConnection" *> pure WFConnection |
178 | 3c1915df | Michele Tartara | wfReportParams = A.string "WFReportParams" *> pure WFReportParams |
179 | 3c1915df | Michele Tartara | connected = A.string "Connected" *> pure Connected |
180 | 3c1915df | Michele Tartara | startingSyncS = A.string "StartingSyncS" *> pure StartingSyncS |
181 | 3c1915df | Michele Tartara | startingSyncT = A.string "StartingSyncT" *> pure StartingSyncT |
182 | 3c1915df | Michele Tartara | wfBitMapS = A.string "WFBitMapS" *> pure WFBitMapS |
183 | 3c1915df | Michele Tartara | wfBitMapT = A.string "WFBitMapT" *> pure WFBitMapT |
184 | 3c1915df | Michele Tartara | wfSyncUUID = A.string "WFSyncUUID" *> pure WFSyncUUID |
185 | 3c1915df | Michele Tartara | syncSource = A.string "SyncSource" *> pure SyncSource |
186 | 3c1915df | Michele Tartara | syncTarget = A.string "SyncTarget" *> pure SyncTarget |
187 | 3c1915df | Michele Tartara | pausedSyncS = A.string "PausedSyncS" *> pure PausedSyncS |
188 | 3c1915df | Michele Tartara | pausedSyncT = A.string "PausedSyncT" *> pure PausedSyncT |
189 | 3c1915df | Michele Tartara | verifyS = A.string "VerifyS" *> pure VerifyS |
190 | 3c1915df | Michele Tartara | verifyT = A.string "VerifyT" *> pure VerifyT |
191 | 3c1915df | Michele Tartara | unconfigured = A.string "Unconfigured" *> pure Unconfigured |
192 | 3c1915df | Michele Tartara | |
193 | 3c1915df | Michele Tartara | -- | Parser for recognizing strings describing two elements of the |
194 | 3c1915df | Michele Tartara | -- same type separated by a '/'. The first one is considered local, |
195 | 3c1915df | Michele Tartara | -- the second remote. |
196 | 3c1915df | Michele Tartara | localRemoteParser :: Parser a -> Parser (LocalRemote a) |
197 | 3c1915df | Michele Tartara | localRemoteParser parser = LocalRemote <$> parser <*> (A.char '/' *> parser) |
198 | 3c1915df | Michele Tartara | |
199 | 3c1915df | Michele Tartara | -- | The parser for resource roles. |
200 | 3c1915df | Michele Tartara | roleParser :: Parser Role |
201 | 3c1915df | Michele Tartara | roleParser = |
202 | 3c1915df | Michele Tartara | primary |
203 | 3c1915df | Michele Tartara | <|> secondary |
204 | 3c1915df | Michele Tartara | <|> unknown |
205 | 3c1915df | Michele Tartara | where primary = A.string "Primary" *> pure Primary |
206 | 3c1915df | Michele Tartara | secondary = A.string "Secondary" *> pure Secondary |
207 | 3c1915df | Michele Tartara | unknown = A.string "Unknown" *> pure Unknown |
208 | 3c1915df | Michele Tartara | |
209 | 3c1915df | Michele Tartara | -- | The parser for disk states. |
210 | 3c1915df | Michele Tartara | diskStateParser :: Parser DiskState |
211 | 3c1915df | Michele Tartara | diskStateParser = |
212 | 3c1915df | Michele Tartara | diskless |
213 | 3c1915df | Michele Tartara | <|> attaching |
214 | 3c1915df | Michele Tartara | <|> failed |
215 | 3c1915df | Michele Tartara | <|> negotiating |
216 | 3c1915df | Michele Tartara | <|> inconsistent |
217 | 3c1915df | Michele Tartara | <|> outdated |
218 | 3c1915df | Michele Tartara | <|> dUnknown |
219 | 3c1915df | Michele Tartara | <|> consistent |
220 | 3c1915df | Michele Tartara | <|> upToDate |
221 | 3c1915df | Michele Tartara | where diskless = A.string "Diskless" *> pure Diskless |
222 | 3c1915df | Michele Tartara | attaching = A.string "Attaching" *> pure Attaching |
223 | 3c1915df | Michele Tartara | failed = A.string "Failed" *> pure Failed |
224 | 3c1915df | Michele Tartara | negotiating = A.string "Negotiating" *> pure Negotiating |
225 | 3c1915df | Michele Tartara | inconsistent = A.string "Inconsistent" *> pure Inconsistent |
226 | 3c1915df | Michele Tartara | outdated = A.string "Outdated" *> pure Outdated |
227 | 3c1915df | Michele Tartara | dUnknown = A.string "DUnknown" *> pure DUnknown |
228 | 3c1915df | Michele Tartara | consistent = A.string "Consistent" *> pure Consistent |
229 | 3c1915df | Michele Tartara | upToDate = A.string "UpToDate" *> pure UpToDate |
230 | 3c1915df | Michele Tartara | |
231 | 3c1915df | Michele Tartara | -- | The parser for I/O flags. |
232 | 3c1915df | Michele Tartara | ioFlagsParser :: Parser String |
233 | 3c1915df | Michele Tartara | ioFlagsParser = fmap unpack . A.takeWhile $ not . isBadEndOfLine |
234 | 3c1915df | Michele Tartara | |
235 | 3c1915df | Michele Tartara | -- | The parser for performance indicators. |
236 | 2188740e | Michele Tartara | perfIndicatorsParser :: Parser PerfIndicators |
237 | 2188740e | Michele Tartara | perfIndicatorsParser = |
238 | 2188740e | Michele Tartara | PerfIndicators |
239 | 3c1915df | Michele Tartara | <$> skipSpacesAndString "ns:" A.decimal |
240 | 3c1915df | Michele Tartara | <*> skipSpacesAndString "nr:" A.decimal |
241 | 3c1915df | Michele Tartara | <*> skipSpacesAndString "dw:" A.decimal |
242 | 3c1915df | Michele Tartara | <*> skipSpacesAndString "dr:" A.decimal |
243 | 3c1915df | Michele Tartara | <*> skipSpacesAndString "al:" A.decimal |
244 | 3c1915df | Michele Tartara | <*> skipSpacesAndString "bm:" A.decimal |
245 | 3c1915df | Michele Tartara | <*> skipSpacesAndString "lo:" A.decimal |
246 | 3c1915df | Michele Tartara | <*> skipSpacesAndString "pe:" A.decimal |
247 | 3c1915df | Michele Tartara | <*> skipSpacesAndString "ua:" A.decimal |
248 | 3c1915df | Michele Tartara | <*> skipSpacesAndString "ap:" A.decimal |
249 | 3c1915df | Michele Tartara | <*> optional (skipSpacesAndString "ep:" A.decimal) |
250 | 3c1915df | Michele Tartara | <*> optional (skipSpacesAndString "wo:" A.anyChar) |
251 | 3c1915df | Michele Tartara | <*> optional (skipSpacesAndString "oos:" A.decimal) |
252 | 3c1915df | Michele Tartara | <* skipSpaces <* A.endOfLine |
253 | 3c1915df | Michele Tartara | |
254 | 3c1915df | Michele Tartara | -- | The parser for the syncronization status. |
255 | 3c1915df | Michele Tartara | syncStatusParser :: Parser SyncStatus |
256 | 3c1915df | Michele Tartara | syncStatusParser = do |
257 | 3c1915df | Michele Tartara | _ <- statusBarParser |
258 | 3c1915df | Michele Tartara | percent <- |
259 | 3c1915df | Michele Tartara | skipSpacesAndString "sync'ed:" $ skipSpaces *> A.double <* A.char '%' |
260 | 3c1915df | Michele Tartara | partSyncSize <- skipSpaces *> A.char '(' *> A.decimal |
261 | 3c1915df | Michele Tartara | totSyncSize <- A.char '/' *> A.decimal <* A.char ')' |
262 | 3c1915df | Michele Tartara | sizeUnit <- sizeUnitParser <* optional A.endOfLine |
263 | 3c1915df | Michele Tartara | timeToEnd <- skipSpacesAndString "finish:" $ skipSpaces *> timeParser |
264 | 3c1915df | Michele Tartara | sp <- |
265 | 3c1915df | Michele Tartara | skipSpacesAndString "speed:" $ |
266 | 3c1915df | Michele Tartara | skipSpaces |
267 | 3c1915df | Michele Tartara | *> commaIntParser |
268 | 3c1915df | Michele Tartara | <* skipSpaces |
269 | 3c1915df | Michele Tartara | <* A.char '(' |
270 | 3c1915df | Michele Tartara | <* commaIntParser |
271 | 3c1915df | Michele Tartara | <* A.char ')' |
272 | 3c1915df | Michele Tartara | w <- skipSpacesAndString "want:" ( |
273 | 3c1915df | Michele Tartara | skipSpaces |
274 | 3c1915df | Michele Tartara | *> (Just <$> commaIntParser) |
275 | 3c1915df | Michele Tartara | ) |
276 | 3c1915df | Michele Tartara | <|> pure Nothing |
277 | 3c1915df | Michele Tartara | sSizeUnit <- skipSpaces *> sizeUnitParser |
278 | 3c1915df | Michele Tartara | sTimeUnit <- A.char '/' *> timeUnitParser |
279 | 3c1915df | Michele Tartara | _ <- A.endOfLine |
280 | 3c1915df | Michele Tartara | return $ |
281 | 3c1915df | Michele Tartara | SyncStatus percent partSyncSize totSyncSize sizeUnit timeToEnd sp w |
282 | 3c1915df | Michele Tartara | sSizeUnit sTimeUnit |
283 | 3c1915df | Michele Tartara | |
284 | 3c1915df | Michele Tartara | -- | The parser for recognizing (and discarding) the sync status bar. |
285 | 3c1915df | Michele Tartara | statusBarParser :: Parser () |
286 | 3c1915df | Michele Tartara | statusBarParser = |
287 | 3c1915df | Michele Tartara | skipSpaces |
288 | 3c1915df | Michele Tartara | *> A.char '[' |
289 | 3c1915df | Michele Tartara | *> A.skipWhile (== '=') |
290 | 3c1915df | Michele Tartara | *> A.skipWhile (== '>') |
291 | 3c1915df | Michele Tartara | *> A.skipWhile (== '.') |
292 | 3c1915df | Michele Tartara | *> A.char ']' |
293 | 3c1915df | Michele Tartara | *> pure () |
294 | 3c1915df | Michele Tartara | |
295 | 3c1915df | Michele Tartara | -- | The parser for recognizing data size units (only the ones |
296 | 3c1915df | Michele Tartara | -- actually found in DRBD files are implemented). |
297 | 3c1915df | Michele Tartara | sizeUnitParser :: Parser SizeUnit |
298 | 3c1915df | Michele Tartara | sizeUnitParser = |
299 | 3c1915df | Michele Tartara | kilobyte |
300 | 3c1915df | Michele Tartara | <|> megabyte |
301 | 3c1915df | Michele Tartara | where kilobyte = A.string "K" *> pure KiloByte |
302 | 3c1915df | Michele Tartara | megabyte = A.string "M" *> pure MegaByte |
303 | 3c1915df | Michele Tartara | |
304 | 3c1915df | Michele Tartara | -- | The parser for recognizing time (hh:mm:ss). |
305 | 3c1915df | Michele Tartara | timeParser :: Parser Time |
306 | 3c1915df | Michele Tartara | timeParser = Time <$> h <*> m <*> s |
307 | 2188740e | Michele Tartara | where h = A.decimal :: Parser Int |
308 | 2188740e | Michele Tartara | m = A.char ':' *> A.decimal :: Parser Int |
309 | 2188740e | Michele Tartara | s = A.char ':' *> A.decimal :: Parser Int |
310 | 3c1915df | Michele Tartara | |
311 | 3c1915df | Michele Tartara | -- | The parser for recognizing time units (only the ones actually |
312 | 3c1915df | Michele Tartara | -- found in DRBD files are implemented). |
313 | 3c1915df | Michele Tartara | timeUnitParser :: Parser TimeUnit |
314 | 3c1915df | Michele Tartara | timeUnitParser = second |
315 | 3c1915df | Michele Tartara | where second = A.string "sec" *> pure Second |
316 | 3c1915df | Michele Tartara | |
317 | b22b93dc | Michele Tartara | -- | Haskell does not recognise ',' as the thousands separator every 3 |
318 | b22b93dc | Michele Tartara | -- digits but DRBD uses it, so we need an ah-hoc parser. |
319 | b22b93dc | Michele Tartara | -- If a number beginning with more than 3 digits without a comma is |
320 | b22b93dc | Michele Tartara | -- parsed, only the first 3 digits are considered to be valid, the rest |
321 | b22b93dc | Michele Tartara | -- is not consumed, and left for further parsing. |
322 | 3c1915df | Michele Tartara | commaIntParser :: Parser Int |
323 | 3c1915df | Michele Tartara | commaIntParser = do |
324 | b22b93dc | Michele Tartara | first <- |
325 | b22b93dc | Michele Tartara | AC.count 3 A.digit <|> AC.count 2 A.digit <|> AC.count 1 A.digit |
326 | b22b93dc | Michele Tartara | allDigits <- commaIntHelper (read first) |
327 | 3c1915df | Michele Tartara | pure allDigits |
328 | 3c1915df | Michele Tartara | |
329 | 3c1915df | Michele Tartara | -- | Helper (triplet parser) for the commaIntParser |
330 | 3c1915df | Michele Tartara | commaIntHelper :: Int -> Parser Int |
331 | 3c1915df | Michele Tartara | commaIntHelper acc = nextTriplet <|> end |
332 | 3c1915df | Michele Tartara | where nextTriplet = do |
333 | 3c1915df | Michele Tartara | _ <- A.char ',' |
334 | 3c1915df | Michele Tartara | triplet <- AC.count 3 A.digit |
335 | 3c1915df | Michele Tartara | commaIntHelper $ acc * 1000 + (read triplet :: Int) |
336 | 3c1915df | Michele Tartara | end = pure acc :: Parser Int |
337 | 3c1915df | Michele Tartara | |
338 | 3c1915df | Michele Tartara | -- | Parser for the additional information provided by DRBD <= 8.0. |
339 | 3c1915df | Michele Tartara | additionalInfoParser::Parser AdditionalInfo |
340 | 3c1915df | Michele Tartara | additionalInfoParser = AdditionalInfo |
341 | 3c1915df | Michele Tartara | <$> skipSpacesAndString "used:" A.decimal |
342 | 3c1915df | Michele Tartara | <*> (A.char '/' *> A.decimal) |
343 | 3c1915df | Michele Tartara | <*> skipSpacesAndString "hits:" A.decimal |
344 | 3c1915df | Michele Tartara | <*> skipSpacesAndString "misses:" A.decimal |
345 | 3c1915df | Michele Tartara | <*> skipSpacesAndString "starving:" A.decimal |
346 | 3c1915df | Michele Tartara | <*> skipSpacesAndString "dirty:" A.decimal |
347 | 3c1915df | Michele Tartara | <*> skipSpacesAndString "changed:" A.decimal |
348 | 3c1915df | Michele Tartara | <* A.endOfLine |