module Ganeti.HTools.Types
( Idx
, Ndx
, Gdx
, NameAssoc
, Score
, Weight
, GroupID
, defaultGroupID
, AllocPolicy(..)
, allocPolicyFromRaw
, allocPolicyToRaw
, InstanceStatus(..)
, instanceStatusFromRaw
, instanceStatusToRaw
, RSpec(..)
, AllocInfo(..)
, AllocStats
, DynUtil(..)
, zeroUtil
, baseUtil
, addUtil
, subUtil
, defReservedDiskRatio
, unitMem
, unitCpu
, unitDsk
, unknownField
, Placement
, IMove(..)
, DiskTemplate(..)
, diskTemplateToRaw
, diskTemplateFromRaw
, MirrorType(..)
, templateMirrorType
, MoveJob
, JobSet
, Result(..)
, isOk
, isBad
, eitherToResult
, annotateResult
, Element(..)
, FailMode(..)
, FailStats
, OpResult(..)
, opToResult
, connTimeout
, queryTimeout
, EvacMode(..)
, ISpec(..)
, IPolicy(..)
, defIPolicy
, rspecFromISpec
) where
import qualified Data.Map as M
import Text.JSON (makeObj, readJSON, showJSON)
import qualified Ganeti.Constants as C
import qualified Ganeti.THH as THH
import Ganeti.BasicTypes
import Ganeti.HTools.JSON
type Idx = Int
type Ndx = Int
type Gdx = Int
type NameAssoc = M.Map String Int
type Score = Double
type Weight = Double
type GroupID = String
defaultGroupID :: GroupID
defaultGroupID = "00000000-0000-0000-0000-000000000000"
$(THH.declareSADT "DiskTemplate"
[ ("DTDiskless", 'C.dtDiskless)
, ("DTFile", 'C.dtFile)
, ("DTSharedFile", 'C.dtSharedFile)
, ("DTPlain", 'C.dtPlain)
, ("DTBlock", 'C.dtBlock)
, ("DTDrbd8", 'C.dtDrbd8)
, ("DTRbd", 'C.dtRbd)
])
$(THH.makeJSONInstance ''DiskTemplate)
data MirrorType = MirrorNone
| MirrorInternal
| MirrorExternal
deriving (Eq, Show, Read)
templateMirrorType :: DiskTemplate -> MirrorType
templateMirrorType DTDiskless = MirrorExternal
templateMirrorType DTFile = MirrorNone
templateMirrorType DTSharedFile = MirrorExternal
templateMirrorType DTPlain = MirrorNone
templateMirrorType DTBlock = MirrorExternal
templateMirrorType DTDrbd8 = MirrorInternal
templateMirrorType DTRbd = MirrorExternal
$(THH.declareSADT "AllocPolicy"
[ ("AllocPreferred", 'C.allocPolicyPreferred)
, ("AllocLastResort", 'C.allocPolicyLastResort)
, ("AllocUnallocable", 'C.allocPolicyUnallocable)
])
$(THH.makeJSONInstance ''AllocPolicy)
$(THH.declareSADT "InstanceStatus"
[ ("AdminDown", 'C.inststAdmindown)
, ("AdminOffline", 'C.inststAdminoffline)
, ("ErrorDown", 'C.inststErrordown)
, ("ErrorUp", 'C.inststErrorup)
, ("NodeDown", 'C.inststNodedown)
, ("NodeOffline", 'C.inststNodeoffline)
, ("Running", 'C.inststRunning)
, ("WrongNode", 'C.inststWrongnode)
])
$(THH.makeJSONInstance ''InstanceStatus)
data RSpec = RSpec
{ rspecCpu :: Int
, rspecMem :: Int
, rspecDsk :: Int
} deriving (Show, Read, Eq)
data AllocInfo = AllocInfo
{ allocInfoVCpus :: Int
, allocInfoNCpus :: Double
, allocInfoMem :: Int
, allocInfoDisk :: Int
} deriving (Show, Read, Eq)
type AllocStats = (AllocInfo, AllocInfo, AllocInfo)
$(THH.buildObject "ISpec" "iSpec"
[ THH.renameField "MemorySize" $ THH.simpleField C.ispecMemSize [t| Int |]
, THH.renameField "CpuCount" $ THH.simpleField C.ispecCpuCount [t| Int |]
, THH.renameField "DiskSize" $ THH.simpleField C.ispecDiskSize [t| Int |]
, THH.renameField "DiskCount" $ THH.simpleField C.ispecDiskCount [t| Int |]
, THH.renameField "NicCount" $ THH.simpleField C.ispecNicCount [t| Int |]
, THH.renameField "SpindleUse" $ THH.simpleField C.ispecSpindleUse [t| Int |]
])
defMinISpec :: ISpec
defMinISpec = ISpec { iSpecMemorySize = C.ipolicyDefaultsMinMemorySize
, iSpecCpuCount = C.ipolicyDefaultsMinCpuCount
, iSpecDiskSize = C.ipolicyDefaultsMinDiskSize
, iSpecDiskCount = C.ipolicyDefaultsMinDiskCount
, iSpecNicCount = C.ipolicyDefaultsMinNicCount
, iSpecSpindleUse = C.ipolicyDefaultsMinSpindleUse
}
defStdISpec :: ISpec
defStdISpec = ISpec { iSpecMemorySize = C.ipolicyDefaultsStdMemorySize
, iSpecCpuCount = C.ipolicyDefaultsStdCpuCount
, iSpecDiskSize = C.ipolicyDefaultsStdDiskSize
, iSpecDiskCount = C.ipolicyDefaultsStdDiskCount
, iSpecNicCount = C.ipolicyDefaultsStdNicCount
, iSpecSpindleUse = C.ipolicyDefaultsStdSpindleUse
}
defMaxISpec :: ISpec
defMaxISpec = ISpec { iSpecMemorySize = C.ipolicyDefaultsMaxMemorySize
, iSpecCpuCount = C.ipolicyDefaultsMaxCpuCount
, iSpecDiskSize = C.ipolicyDefaultsMaxDiskSize
, iSpecDiskCount = C.ipolicyDefaultsMaxDiskCount
, iSpecNicCount = C.ipolicyDefaultsMaxNicCount
, iSpecSpindleUse = C.ipolicyDefaultsMaxSpindleUse
}
$(THH.buildObject "IPolicy" "iPolicy"
[ THH.renameField "StdSpec" $ THH.simpleField C.ispecsStd [t| ISpec |]
, THH.renameField "MinSpec" $ THH.simpleField C.ispecsMin [t| ISpec |]
, THH.renameField "MaxSpec" $ THH.simpleField C.ispecsMax [t| ISpec |]
, THH.renameField "DiskTemplates" $
THH.simpleField C.ipolicyDts [t| [DiskTemplate] |]
, THH.renameField "VcpuRatio" $
THH.simpleField C.ipolicyVcpuRatio [t| Double |]
, THH.renameField "SpindleRatio" $
THH.simpleField C.ipolicySpindleRatio [t| Double |]
])
rspecFromISpec :: ISpec -> RSpec
rspecFromISpec ispec = RSpec { rspecCpu = iSpecCpuCount ispec
, rspecMem = iSpecMemorySize ispec
, rspecDsk = iSpecDiskSize ispec
}
defIPolicy :: IPolicy
defIPolicy = IPolicy { iPolicyStdSpec = defStdISpec
, iPolicyMinSpec = defMinISpec
, iPolicyMaxSpec = defMaxISpec
, iPolicyDiskTemplates = [minBound..maxBound]
, iPolicyVcpuRatio = C.ipolicyDefaultsVcpuRatio
, iPolicySpindleRatio = C.ipolicyDefaultsSpindleRatio
}
data DynUtil = DynUtil
{ cpuWeight :: Weight
, memWeight :: Weight
, dskWeight :: Weight
, netWeight :: Weight
} deriving (Show, Read, Eq)
zeroUtil :: DynUtil
zeroUtil = DynUtil { cpuWeight = 0, memWeight = 0
, dskWeight = 0, netWeight = 0 }
baseUtil :: DynUtil
baseUtil = DynUtil { cpuWeight = 1, memWeight = 1
, dskWeight = 1, netWeight = 1 }
addUtil :: DynUtil -> DynUtil -> DynUtil
addUtil (DynUtil a1 a2 a3 a4) (DynUtil b1 b2 b3 b4) =
DynUtil (a1+b1) (a2+b2) (a3+b3) (a4+b4)
subUtil :: DynUtil -> DynUtil -> DynUtil
subUtil (DynUtil a1 a2 a3 a4) (DynUtil b1 b2 b3 b4) =
DynUtil (a1b1) (a2b2) (a3b3) (a4b4)
type Placement = (Idx, Ndx, Ndx, IMove, Score)
data IMove = Failover
| FailoverToAny Ndx
| ReplacePrimary Ndx
| ReplaceSecondary Ndx
| ReplaceAndFailover Ndx
| FailoverAndReplace Ndx
deriving (Show, Read)
type MoveJob = ([Ndx], Idx, IMove, [String])
unknownField :: String
unknownField = "<unknown field>"
type JobSet = [MoveJob]
connTimeout :: Int
connTimeout = 15
queryTimeout :: Int
queryTimeout = 60
defReservedDiskRatio :: Double
defReservedDiskRatio = 0
unitMem :: Int
unitMem = 64
unitDsk :: Int
unitDsk = 256
unitCpu :: Int
unitCpu = 1
data FailMode = FailMem
| FailDisk
| FailCPU
| FailN1
| FailTags
deriving (Eq, Enum, Bounded, Show, Read)
type FailStats = [(FailMode, Int)]
data OpResult a = OpFail FailMode
| OpGood a
deriving (Show, Read)
instance Monad OpResult where
(OpGood x) >>= fn = fn x
(OpFail y) >>= _ = OpFail y
return = OpGood
opToResult :: OpResult a -> Result a
opToResult (OpFail f) = Bad $ show f
opToResult (OpGood v) = Ok v
class Element a where
nameOf :: a -> String
allNames :: a -> [String]
idxOf :: a -> Int
setAlias :: a -> String -> a
computeAlias :: String -> a -> a
computeAlias dom e = setAlias e alias
where alias = take (length name length dom) name
name = nameOf e
setIdx :: a -> Int -> a
$(THH.declareSADT "EvacMode"
[ ("ChangePrimary", 'C.iallocatorNevacPri)
, ("ChangeSecondary", 'C.iallocatorNevacSec)
, ("ChangeAll", 'C.iallocatorNevacAll)
])
$(THH.makeJSONInstance ''EvacMode)