module Ganeti.Storage.Drbd.Types
( DRBDStatus(..)
, VersionInfo(..)
, DeviceInfo(..)
, ConnState(..)
, LocalRemote(..)
, Role(..)
, DiskState(..)
, PerfIndicators(..)
, SyncStatus(..)
, SizeUnit(..)
, Time(..)
, TimeUnit(..)
, AdditionalInfo(..)
, DrbdInstMinor(..)
) where
import Control.Monad
import Text.JSON
import Text.Printf
import Ganeti.JSON
data DRBDStatus =
DRBDStatus
{ versionInfo :: VersionInfo
, deviceInfos :: [DeviceInfo]
} deriving (Eq, Show)
instance JSON DRBDStatus where
showJSON d = makeObj
[ ("versionInfo", showJSON $ versionInfo d)
, ("deviceInfos", showJSONs $ deviceInfos d)
]
readJSON = error "JSON read instance not implemented for type DRBDStatus"
data VersionInfo =
VersionInfo
{ version :: Maybe String
, api :: Maybe String
, proto :: Maybe String
, srcversion :: Maybe String
, gitHash :: Maybe String
, buildBy :: Maybe String
} deriving (Eq, Show)
instance JSON VersionInfo where
showJSON (VersionInfo versionF apiF protoF srcversionF gitHashF buildByF) =
optFieldsToObj
[ optionalJSField "version" versionF
, optionalJSField "api" apiF
, optionalJSField "proto" protoF
, optionalJSField "srcversion" srcversionF
, optionalJSField "gitHash" gitHashF
, optionalJSField "buildBy" buildByF
]
readJSON = error "JSON read instance not implemented for type VersionInfo"
data DeviceInfo =
UnconfiguredDevice Int
|
DeviceInfo
{ minorNumber :: Int
, connectionState :: ConnState
, resourceRoles :: LocalRemote Role
, diskStates :: LocalRemote DiskState
, replicationProtocol :: Char
, ioFlags :: String
, perfIndicators :: PerfIndicators
, syncStatus :: Maybe SyncStatus
, resync :: Maybe AdditionalInfo
, actLog :: Maybe AdditionalInfo
, instName :: Maybe String
} deriving (Eq, Show)
instance JSON DeviceInfo where
showJSON (UnconfiguredDevice num) = makeObj
[ ("minor", showJSON num)
, ("connectionState", showJSON Unconfigured)
]
showJSON (DeviceInfo minorNumberF connectionStateF (LocalRemote
localRole remoteRole) (LocalRemote localState remoteState)
replicProtocolF ioFlagsF perfIndicatorsF syncStatusF _ _ instNameF) =
optFieldsToObj
[ Just ("minor", showJSON minorNumberF)
, Just ("connectionState", showJSON connectionStateF)
, Just ("localRole", showJSON localRole)
, Just ("remoteRole", showJSON remoteRole)
, Just ("localState", showJSON localState)
, Just ("remoteState", showJSON remoteState)
, Just ("replicationProtocol", showJSON replicProtocolF)
, Just ("ioFlags", showJSON ioFlagsF)
, Just ("perfIndicators", showJSON perfIndicatorsF)
, optionalJSField "syncStatus" syncStatusF
, Just ("instance", maybe JSNull showJSON instNameF)
]
readJSON = error "JSON read instance not implemented for type DeviceInfo"
data ConnState
= StandAlone
| Disconnecting
| Unconnected
| Timeout
| BrokenPipe
| NetworkFailure
| ProtocolError
| TearDown
| WFConnection
| WFReportParams
| Connected
| StartingSyncS
| StartingSyncT
| WFBitMapS
| WFBitMapT
| WFSyncUUID
| SyncSource
| SyncTarget
| PausedSyncS
| PausedSyncT
| VerifyS
| VerifyT
| Unconfigured
deriving (Show, Eq)
instance JSON ConnState where
showJSON = showJSON . show
readJSON = error "JSON read instance not implemented for type ConnState"
data LocalRemote a =
LocalRemote
{ local :: a
, remote :: a
} deriving (Eq, Show)
data Role = Primary
| Secondary
| Unknown
deriving (Eq, Show)
instance JSON Role where
showJSON = showJSON . show
readJSON = error "JSON read instance not implemented for type Role"
data DiskState
= Diskless
| Attaching
| Failed
| Negotiating
| Inconsistent
| Outdated
| DUnknown
| Consistent
| UpToDate
deriving (Eq, Show)
instance JSON DiskState where
showJSON = showJSON . show
readJSON = error "JSON read instance not implemented for type DiskState"
data PerfIndicators = PerfIndicators
{ networkSend :: Int
, networkReceive :: Int
, diskWrite :: Int
, diskRead :: Int
, activityLog :: Int
, bitMap :: Int
, localCount :: Int
, pending :: Int
, unacknowledged :: Int
, applicationPending :: Int
, epochs :: Maybe Int
, writeOrder :: Maybe Char
, outOfSync :: Maybe Int
} deriving (Eq, Show)
instance JSON PerfIndicators where
showJSON p = optFieldsToObj
[ Just ("networkSend", showJSON $ networkSend p)
, Just ("networkReceive", showJSON $ networkReceive p)
, Just ("diskWrite", showJSON $ diskWrite p)
, Just ("diskRead", showJSON $ diskRead p)
, Just ("activityLog", showJSON $ activityLog p)
, Just ("bitMap", showJSON $ bitMap p)
, Just ("localCount", showJSON $ localCount p)
, Just ("pending", showJSON $ pending p)
, Just ("unacknowledged", showJSON $ unacknowledged p)
, Just ("applicationPending", showJSON $ applicationPending p)
, optionalJSField "epochs" $ epochs p
, optionalJSField "writeOrder" $ writeOrder p
, optionalJSField "outOfSync" $ outOfSync p
]
readJSON = error "JSON read instance not implemented for type PerfIndicators"
data SyncStatus =
SyncStatus
{ percentage :: Double
, partialSyncSize :: Int
, totalSyncSize :: Int
, syncUnit :: SizeUnit
, timeToFinish :: Time
, speed :: Int
, want :: Maybe Int
, speedSizeUnit :: SizeUnit
, speedTimeUnit :: TimeUnit
} deriving (Eq, Show)
instance JSON SyncStatus where
showJSON s = optFieldsToObj
[ Just ("percentage", showJSON $ percentage s)
, Just ("progress", showJSON $ show (partialSyncSize s) ++ "/" ++
show (totalSyncSize s))
, Just ("progressUnit", showJSON $ syncUnit s)
, Just ("timeToFinish", showJSON $ timeToFinish s)
, Just ("speed", showJSON $ speed s)
, optionalJSField "want" $ want s
, Just ("speedUnit", showJSON $ show (speedSizeUnit s) ++ "/" ++
show (speedTimeUnit s))
]
readJSON = error "JSON read instance not implemented for type SyncStatus"
data SizeUnit = KiloByte | MegaByte deriving (Eq, Show)
instance JSON SizeUnit where
showJSON = showJSON . show
readJSON = error "JSON read instance not implemented for type SizeUnit"
data Time = Time
{ hour :: Int
, min :: Int
, sec :: Int
} deriving (Eq, Show)
instance JSON Time where
showJSON (Time h m s) = showJSON (printf "%02d:%02d:%02d" h m s :: String)
readJSON = error "JSON read instance not implemented for type Time"
data TimeUnit = Second deriving (Eq, Show)
instance JSON TimeUnit where
showJSON Second = showJSON "Second"
readJSON = error "JSON read instance not implemented for type TimeUnit"
data AdditionalInfo = AdditionalInfo
{ partialUsed :: Int
, totalUsed :: Int
, hits :: Int
, misses :: Int
, starving :: Int
, dirty :: Int
, changed :: Int
} deriving (Eq, Show)
data DrbdInstMinor = DrbdInstMinor
{ dimNode :: String
, dimMinor :: Int
, dimInstName :: String
, dimDiskIdx :: String
, dimRole :: String
, dimPeer :: String
} deriving (Show)
instance JSON DrbdInstMinor where
showJSON (DrbdInstMinor a b c d e f) =
JSArray
[ showJSON a
, showJSON b
, showJSON c
, showJSON d
, showJSON e
, showJSON f
]
readJSON (JSArray [a, b, c, d, e, f]) =
DrbdInstMinor
`fmap` readJSON a
`ap` readJSON b
`ap` readJSON c
`ap` readJSON d
`ap` readJSON e
`ap` readJSON f
readJSON _ = fail "Unable to read a DrbdInstMinor"