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