Revision eb62691c
b/src/Ganeti/Block/Drbd/Parser.hs | ||
---|---|---|
31 | 31 |
import qualified Data.Attoparsec.Text as A |
32 | 32 |
import qualified Data.Attoparsec.Combinator as AC |
33 | 33 |
import Data.Attoparsec.Text (Parser) |
34 |
import Data.List |
|
34 | 35 |
import Data.Maybe |
35 | 36 |
import Data.Text (Text, unpack) |
36 | 37 |
|
... | ... | |
61 | 62 |
optional parser = (Just <$> parser) <|> pure Nothing |
62 | 63 |
|
63 | 64 |
-- | The parser for a whole DRBD status file. |
64 |
drbdStatusParser :: Parser DRBDStatus |
|
65 |
drbdStatusParser = |
|
65 |
drbdStatusParser :: [DrbdInstMinor] -> Parser DRBDStatus
|
|
66 |
drbdStatusParser instMinor =
|
|
66 | 67 |
DRBDStatus <$> versionInfoParser |
67 |
<*> deviceParser `AC.manyTill` A.endOfInput |
|
68 |
<*> deviceParser instMinor `AC.manyTill` A.endOfInput
|
|
68 | 69 |
<* A.endOfInput |
69 | 70 |
|
70 | 71 |
-- | The parser for the version information lines. |
... | ... | |
111 | 112 |
<* A.endOfLine |
112 | 113 |
|
113 | 114 |
-- | The parser for a (multi-line) string representing a device. |
114 |
deviceParser :: Parser DeviceInfo |
|
115 |
deviceParser = do |
|
115 |
deviceParser :: [DrbdInstMinor] -> Parser DeviceInfo
|
|
116 |
deviceParser instMinor = do
|
|
116 | 117 |
deviceNum <- skipSpaces *> A.decimal <* A.char ':' |
117 | 118 |
cs <- skipSpacesAndString "cs:" connStateParser |
118 | 119 |
if cs == Unconfigured |
... | ... | |
129 | 130 |
reS <- optional resyncParser |
130 | 131 |
act <- optional actLogParser |
131 | 132 |
_ <- additionalEOL |
133 |
let inst = find ((deviceNum ==) . dimMinor) instMinor |
|
134 |
iName = fmap dimInstName inst |
|
132 | 135 |
return $ DeviceInfo deviceNum cs ro ds replicProtocol io pIndicators |
133 |
syncS reS act |
|
136 |
syncS reS act iName
|
|
134 | 137 |
|
135 | 138 |
where conditionalSyncStatusParser SyncSource = Just <$> syncStatusParser |
136 | 139 |
conditionalSyncStatusParser SyncTarget = Just <$> syncStatusParser |
b/src/Ganeti/Block/Drbd/Types.hs | ||
---|---|---|
38 | 38 |
, Time(..) |
39 | 39 |
, TimeUnit(..) |
40 | 40 |
, AdditionalInfo(..) |
41 |
, DrbdInstMinor(..) |
|
41 | 42 |
) where |
42 | 43 |
|
44 |
import Control.Monad |
|
43 | 45 |
import Text.JSON |
44 | 46 |
import Text.Printf |
45 | 47 |
|
... | ... | |
93 | 95 |
UnconfiguredDevice Int -- ^ An DRBD minor marked as unconfigured |
94 | 96 |
| -- | A configured DRBD minor |
95 | 97 |
DeviceInfo |
96 |
{ minorNumber :: Int -- ^ The minor index of the device |
|
97 |
, connectionState :: ConnState -- ^ State of the connection |
|
98 |
, resourceRoles :: LocalRemote Role -- ^ Roles of the resources |
|
98 |
{ minorNumber :: Int -- ^ The minor index of the device
|
|
99 |
, connectionState :: ConnState -- ^ State of the connection
|
|
100 |
, resourceRoles :: LocalRemote Role -- ^ Roles of the resources
|
|
99 | 101 |
, diskStates :: LocalRemote DiskState -- ^ Status of the disks |
100 |
, replicationProtocol :: Char -- ^ The replication protocol being used |
|
101 |
, ioFlags :: String -- ^ The input/output flags |
|
102 |
, perfIndicators |
|
103 |
:: PerfIndicators -- ^ Performance indicators |
|
104 |
, syncStatus :: Maybe SyncStatus -- ^ The status of the syncronization of |
|
105 |
-- the disk (only if it is happening) |
|
106 |
, resync :: Maybe AdditionalInfo -- ^ Additional info by DRBD 8.0 |
|
107 |
, actLog :: Maybe AdditionalInfo -- ^ Additional info by DRBD 8.0 |
|
102 |
, replicationProtocol :: Char -- ^ The replication protocol |
|
103 |
-- being used |
|
104 |
, ioFlags :: String -- ^ The input/output flags |
|
105 |
, perfIndicators :: PerfIndicators -- ^ Performance indicators |
|
106 |
, syncStatus :: Maybe SyncStatus -- ^ The status of the |
|
107 |
-- syncronization of the disk |
|
108 |
-- (only if it is happening) |
|
109 |
, resync :: Maybe AdditionalInfo -- ^ Additional info by DRBD 8.0 |
|
110 |
, actLog :: Maybe AdditionalInfo -- ^ Additional info by DRBD 8.0 |
|
111 |
, instName :: Maybe String -- ^ The name of the associated |
|
112 |
-- instance |
|
108 | 113 |
} deriving (Eq, Show) |
109 | 114 |
|
110 | 115 |
-- | The DeviceInfo instance of JSON. |
... | ... | |
115 | 120 |
] |
116 | 121 |
showJSON (DeviceInfo minorNumberF connectionStateF (LocalRemote |
117 | 122 |
localRole remoteRole) (LocalRemote localState remoteState) |
118 |
replicProtocolF ioFlagsF perfIndicatorsF syncStatusF _ _) = |
|
123 |
replicProtocolF ioFlagsF perfIndicatorsF syncStatusF _ _ instNameF) =
|
|
119 | 124 |
optFieldsToObj |
120 | 125 |
[ Just ("minor", showJSON minorNumberF) |
121 | 126 |
, Just ("connectionState", showJSON connectionStateF) |
... | ... | |
127 | 132 |
, Just ("ioFlags", showJSON ioFlagsF) |
128 | 133 |
, Just ("perfIndicators", showJSON perfIndicatorsF) |
129 | 134 |
, optionalJSField "syncStatus" syncStatusF |
135 |
, Just ("instance", maybe JSNull showJSON instNameF) |
|
130 | 136 |
] |
131 | 137 |
|
132 | 138 |
readJSON = error "JSON read instance not implemented for type DeviceInfo" |
... | ... | |
321 | 327 |
, dirty :: Int |
322 | 328 |
, changed :: Int |
323 | 329 |
} deriving (Eq, Show) |
330 |
|
|
331 |
-- | Data type representing the pairing of a DRBD minor with an instance. |
|
332 |
data DrbdInstMinor = DrbdInstMinor |
|
333 |
{ dimNode :: String |
|
334 |
, dimMinor :: Int |
|
335 |
, dimInstName :: String |
|
336 |
, dimDiskIdx :: String |
|
337 |
, dimRole :: String |
|
338 |
, dimPeer :: String |
|
339 |
} deriving (Show) |
|
340 |
|
|
341 |
-- | The DrbdInstMinor instance of JSON. |
|
342 |
instance JSON DrbdInstMinor where |
|
343 |
showJSON (DrbdInstMinor a b c d e f) = |
|
344 |
JSArray |
|
345 |
[ showJSON a |
|
346 |
, showJSON b |
|
347 |
, showJSON c |
|
348 |
, showJSON d |
|
349 |
, showJSON e |
|
350 |
, showJSON f |
|
351 |
] |
|
352 |
readJSON (JSArray [a, b, c, d, e, f]) = |
|
353 |
DrbdInstMinor |
|
354 |
`fmap` readJSON a |
|
355 |
`ap` readJSON b |
|
356 |
`ap` readJSON c |
|
357 |
`ap` readJSON d |
|
358 |
`ap` readJSON e |
|
359 |
`ap` readJSON f |
|
360 |
readJSON _ = fail "Unable to read a DrbdInstMinor" |
b/src/Ganeti/DataCollectors/Drbd.hs | ||
---|---|---|
76 | 76 |
((E.try $ readFile proc_drbd) :: IO (Either IOError String)) >>= |
77 | 77 |
exitIfBad "reading from file" . either (BT.Bad . show) BT.Ok |
78 | 78 |
output <- |
79 |
case A.parse drbdStatusParser $ pack contents of
|
|
79 |
case A.parse (drbdStatusParser []) $ pack contents of
|
|
80 | 80 |
A.Fail unparsedText contexts errorMessage -> exitErr $ |
81 | 81 |
show (Prelude.take defaultCharNum $ unpack unparsedText) ++ "\n" |
82 | 82 |
++ show contexts ++ "\n" ++ errorMessage |
b/test/hs/Test/Ganeti/Block/Drbd/Parser.hs | ||
---|---|---|
44 | 44 |
testFile :: String -> DRBDStatus -> Assertion |
45 | 45 |
testFile fileName expectedContent = do |
46 | 46 |
fileContent <- readTestData fileName |
47 |
case A.parseOnly drbdStatusParser $ pack fileContent of
|
|
47 |
case A.parseOnly (drbdStatusParser []) $ pack fileContent of
|
|
48 | 48 |
Left msg -> assertFailure $ "Parsing failed: " ++ msg |
49 | 49 |
Right obtained -> assertEqual fileName expectedContent obtained |
50 | 50 |
|
... | ... | |
62 | 62 |
Nothing Nothing Nothing) |
63 | 63 |
Nothing |
64 | 64 |
(Just $ AdditionalInfo 0 61 65657 135 0 0 135) |
65 |
(Just $ AdditionalInfo 0 257 11378843 254 0 0 254), |
|
65 |
(Just $ AdditionalInfo 0 257 11378843 254 0 0 254) |
|
66 |
Nothing, |
|
66 | 67 |
UnconfiguredDevice 1, |
67 | 68 |
UnconfiguredDevice 2, |
68 | 69 |
UnconfiguredDevice 5, |
... | ... | |
83 | 84 |
(Just 'b') (Just 0)) |
84 | 85 |
Nothing |
85 | 86 |
Nothing |
87 |
Nothing |
|
86 | 88 |
Nothing, |
87 | 89 |
DeviceInfo 1 Connected (LocalRemote Secondary Primary) |
88 | 90 |
(LocalRemote UpToDate UpToDate) 'C' "r---" |
... | ... | |
90 | 92 |
(Just 0)) |
91 | 93 |
Nothing |
92 | 94 |
Nothing |
95 |
Nothing |
|
93 | 96 |
Nothing, |
94 | 97 |
UnconfiguredDevice 2, |
95 | 98 |
DeviceInfo 3 SyncSource (LocalRemote Primary Secondary) |
... | ... | |
99 | 102 |
(Just $ SyncStatus 2.4 14996 15360 MegaByte (Time 0 4 8) 61736 Nothing |
100 | 103 |
KiloByte Second) |
101 | 104 |
Nothing |
105 |
Nothing |
|
102 | 106 |
Nothing, |
103 | 107 |
DeviceInfo 4 WFConnection (LocalRemote Primary Unknown) |
104 | 108 |
(LocalRemote UpToDate DUnknown) 'C' "r----" |
... | ... | |
107 | 111 |
Nothing |
108 | 112 |
Nothing |
109 | 113 |
Nothing |
114 |
Nothing |
|
110 | 115 |
] |
111 | 116 |
|
112 | 117 |
-- | Test a DRBD 8.3 file with an ongoing synchronization. |
... | ... | |
123 | 128 |
(Just 'b') (Just 0)) |
124 | 129 |
Nothing |
125 | 130 |
Nothing |
131 |
Nothing |
|
126 | 132 |
Nothing, |
127 | 133 |
DeviceInfo 1 Connected (LocalRemote Secondary Primary) |
128 | 134 |
(LocalRemote UpToDate UpToDate) 'C' "r---" |
... | ... | |
130 | 136 |
(Just 0)) |
131 | 137 |
Nothing |
132 | 138 |
Nothing |
139 |
Nothing |
|
133 | 140 |
Nothing, |
134 | 141 |
UnconfiguredDevice 2, |
135 | 142 |
DeviceInfo 3 SyncTarget (LocalRemote Primary Secondary) |
... | ... | |
139 | 146 |
(Just $ SyncStatus 34.9 346112 524288 MegaByte (Time 0 0 5) 59392 |
140 | 147 |
Nothing KiloByte Second) |
141 | 148 |
Nothing |
149 |
Nothing |
|
142 | 150 |
Nothing, |
143 | 151 |
DeviceInfo 4 WFConnection (LocalRemote Primary Unknown) |
144 | 152 |
(LocalRemote UpToDate DUnknown) 'C' "r----" |
... | ... | |
147 | 155 |
Nothing |
148 | 156 |
Nothing |
149 | 157 |
Nothing |
158 |
Nothing |
|
150 | 159 |
] |
151 | 160 |
|
152 | 161 |
-- | Test a DRBD 8.3 file not from git sources, with an ongoing synchronization |
... | ... | |
165 | 174 |
(Just $ SyncStatus 44.4 588416 1048576 KiloByte (Time 0 0 8) 65736 |
166 | 175 |
(Just 61440) KiloByte Second) |
167 | 176 |
Nothing |
177 |
Nothing |
|
168 | 178 |
Nothing, |
169 | 179 |
UnconfiguredDevice 1, |
170 | 180 |
UnconfiguredDevice 2, |
... | ... | |
186 | 196 |
(Just 'b') (Just 0)) |
187 | 197 |
Nothing |
188 | 198 |
Nothing |
199 |
Nothing |
|
189 | 200 |
Nothing, |
190 | 201 |
DeviceInfo 1 Connected (LocalRemote Secondary Primary) |
191 | 202 |
(LocalRemote UpToDate UpToDate) 'C' "r---" |
... | ... | |
193 | 204 |
(Just 0)) |
194 | 205 |
Nothing |
195 | 206 |
Nothing |
207 |
Nothing |
|
196 | 208 |
Nothing, |
197 | 209 |
UnconfiguredDevice 2, |
198 | 210 |
DeviceInfo 4 WFConnection (LocalRemote Primary Unknown) |
... | ... | |
201 | 213 |
(Just 'b') (Just 0)) |
202 | 214 |
Nothing |
203 | 215 |
Nothing |
216 |
Nothing |
|
204 | 217 |
Nothing, |
205 | 218 |
DeviceInfo 5 Connected (LocalRemote Primary Secondary) |
206 | 219 |
(LocalRemote UpToDate Diskless) 'C' "r----" |
... | ... | |
208 | 221 |
(Just 'b') (Just 0)) |
209 | 222 |
Nothing |
210 | 223 |
Nothing |
224 |
Nothing |
|
211 | 225 |
Nothing, |
212 | 226 |
DeviceInfo 6 Connected (LocalRemote Secondary Primary) |
213 | 227 |
(LocalRemote Diskless UpToDate) 'C' "r---" |
... | ... | |
215 | 229 |
(Just 0)) |
216 | 230 |
Nothing |
217 | 231 |
Nothing |
232 |
Nothing |
|
218 | 233 |
Nothing, |
219 | 234 |
DeviceInfo 7 WFConnection (LocalRemote Secondary Unknown) |
220 | 235 |
(LocalRemote UpToDate DUnknown) 'C' "r---" |
... | ... | |
222 | 237 |
(Just 0)) |
223 | 238 |
Nothing |
224 | 239 |
Nothing |
240 |
Nothing |
|
225 | 241 |
Nothing, |
226 | 242 |
DeviceInfo 8 StandAlone (LocalRemote Secondary Unknown) |
227 | 243 |
(LocalRemote UpToDate DUnknown) ' ' "r---" |
... | ... | |
230 | 246 |
Nothing |
231 | 247 |
Nothing |
232 | 248 |
Nothing |
249 |
Nothing |
|
233 | 250 |
] |
234 | 251 |
|
235 | 252 |
-- | Test a DRBD 8.0 file with a missing device. |
... | ... | |
246 | 263 |
Nothing Nothing) |
247 | 264 |
Nothing |
248 | 265 |
(Just $ AdditionalInfo 0 61 0 0 0 0 0) |
249 |
(Just $ AdditionalInfo 0 257 793749 1067 0 0 1067), |
|
266 |
(Just $ AdditionalInfo 0 257 793749 1067 0 0 1067) |
|
267 |
Nothing, |
|
250 | 268 |
DeviceInfo 1 Connected (LocalRemote Secondary Primary) |
251 | 269 |
(LocalRemote UpToDate UpToDate) 'C' "r---" |
252 | 270 |
(PerfIndicators 738320 0 738320 554400 67 0 0 0 0 0 Nothing |
253 | 271 |
Nothing Nothing) |
254 | 272 |
Nothing |
255 | 273 |
(Just $ AdditionalInfo 0 61 0 0 0 0 0) |
256 |
(Just $ AdditionalInfo 0 257 92464 67 0 0 67), |
|
274 |
(Just $ AdditionalInfo 0 257 92464 67 0 0 67) |
|
275 |
Nothing, |
|
257 | 276 |
UnconfiguredDevice 2, |
258 | 277 |
DeviceInfo 4 WFConnection (LocalRemote Primary Unknown) |
259 | 278 |
(LocalRemote UpToDate DUnknown) 'C' "r---" |
... | ... | |
261 | 280 |
Nothing Nothing) |
262 | 281 |
Nothing |
263 | 282 |
(Just $ AdditionalInfo 0 61 0 0 0 0 0) |
264 |
(Just $ AdditionalInfo 0 257 92464 67 0 0 67), |
|
283 |
(Just $ AdditionalInfo 0 257 92464 67 0 0 67) |
|
284 |
Nothing, |
|
265 | 285 |
DeviceInfo 5 Connected (LocalRemote Primary Secondary) |
266 | 286 |
(LocalRemote UpToDate Diskless) 'C' "r---" |
267 | 287 |
(PerfIndicators 4375581 0 4446283 674 1069 69 0 0 0 0 Nothing |
268 | 288 |
Nothing Nothing) |
269 | 289 |
Nothing |
270 | 290 |
(Just $ AdditionalInfo 0 61 0 0 0 0 0) |
271 |
(Just $ AdditionalInfo 0 257 793750 1069 0 0 1069), |
|
291 |
(Just $ AdditionalInfo 0 257 793750 1069 0 0 1069) |
|
292 |
Nothing, |
|
272 | 293 |
DeviceInfo 6 Connected (LocalRemote Secondary Primary) |
273 | 294 |
(LocalRemote Diskless UpToDate) 'C' "r---" |
274 | 295 |
(PerfIndicators 0 4375581 5186925 327 75 214 0 0 0 0 Nothing |
275 | 296 |
Nothing Nothing) |
276 | 297 |
Nothing |
277 | 298 |
Nothing |
299 |
Nothing |
|
278 | 300 |
Nothing, |
279 | 301 |
DeviceInfo 7 WFConnection (LocalRemote Secondary Unknown) |
280 | 302 |
(LocalRemote UpToDate DUnknown) 'C' "r---" |
281 | 303 |
(PerfIndicators 0 0 0 0 0 0 0 0 0 0 Nothing Nothing Nothing) |
282 | 304 |
Nothing |
283 | 305 |
(Just $ AdditionalInfo 0 61 0 0 0 0 0) |
284 |
(Just $ AdditionalInfo 0 257 0 0 0 0 0), |
|
306 |
(Just $ AdditionalInfo 0 257 0 0 0 0 0) |
|
307 |
Nothing, |
|
285 | 308 |
DeviceInfo 8 StandAlone (LocalRemote Secondary Unknown) |
286 | 309 |
(LocalRemote UpToDate DUnknown) ' ' "r---" |
287 | 310 |
(PerfIndicators 0 0 0 0 0 0 0 0 0 0 Nothing Nothing Nothing) |
288 | 311 |
Nothing |
289 | 312 |
(Just $ AdditionalInfo 0 61 0 0 0 0 0) |
290 | 313 |
(Just $ AdditionalInfo 0 257 0 0 0 0 0) |
314 |
Nothing |
|
291 | 315 |
] |
292 | 316 |
|
293 | 317 |
-- | Function for splitting a list in chunks of a given size. |
b/test/hs/Test/Ganeti/Block/Drbd/Types.hs | ||
---|---|---|
84 | 84 |
ep <- genMaybe natural |
85 | 85 |
wo <- genMaybe wOrderFlag |
86 | 86 |
oos <- genMaybe natural |
87 |
inst <- genMaybe arbitrary |
|
87 | 88 |
let obtained = |
88 | 89 |
showJSON $ |
89 | 90 |
DeviceInfo minor state (LocalRemote locRole remRole) |
... | ... | |
91 | 92 |
Nothing |
92 | 93 |
Nothing |
93 | 94 |
Nothing |
95 |
inst |
|
94 | 96 |
perfInd = |
95 | 97 |
PerfIndicators ns nr dw dr al bm lc pe ua ap ep wo oos |
96 | 98 |
expected = |
... | ... | |
104 | 106 |
, ("replicationProtocol", showJSON alg) |
105 | 107 |
, ("ioFlags", showJSON "r----") |
106 | 108 |
, ("perfIndicators", showJSON perfInd) |
109 |
, ("instance", maybe JSNull showJSON inst) |
|
107 | 110 |
] |
108 | 111 |
obtained ==? expected |
109 | 112 |
|
Also available in: Unified diff