module Ganeti.HTools.Types
( Idx
, Ndx
, Gdx
, NameAssoc
, Score
, Weight
, GroupID
, defaultGroupID
, AllocPolicy(..)
, allocPolicyFromRaw
, allocPolicyToRaw
, NetworkID
, 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
, Element(..)
, FailMode(..)
, FailStats
, OpResult
, opToResult
, EvacMode(..)
, ISpec(..)
, MinMaxISpecs(..)
, IPolicy(..)
, defIPolicy
, rspecFromISpec
, AutoRepairType(..)
, autoRepairTypeToRaw
, autoRepairTypeFromRaw
, AutoRepairResult(..)
, autoRepairResultToRaw
, autoRepairResultFromRaw
, AutoRepairPolicy(..)
, AutoRepairSuspendTime(..)
, AutoRepairData(..)
, AutoRepairStatus(..)
) where
import qualified Data.Map as M
import System.Time (ClockTime)
import qualified Ganeti.Constants as C
import qualified Ganeti.THH as THH
import Ganeti.BasicTypes
import Ganeti.Types
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"
data MirrorType = MirrorNone
| MirrorInternal
| MirrorExternal
deriving (Eq, Show)
templateMirrorType :: DiskTemplate -> MirrorType
templateMirrorType DTDiskless = MirrorExternal
templateMirrorType DTFile = MirrorNone
templateMirrorType DTSharedFile = MirrorExternal
templateMirrorType DTPlain = MirrorNone
templateMirrorType DTBlock = MirrorExternal
templateMirrorType DTDrbd8 = MirrorInternal
templateMirrorType DTRbd = MirrorExternal
templateMirrorType DTExt = MirrorExternal
data RSpec = RSpec
{ rspecCpu :: Int
, rspecMem :: Int
, rspecDsk :: Int
} deriving (Show, Eq)
data AllocInfo = AllocInfo
{ allocInfoVCpus :: Int
, allocInfoNCpus :: Double
, allocInfoMem :: Int
, allocInfoDisk :: Int
} deriving (Show, Eq)
type AllocStats = (AllocInfo, AllocInfo, AllocInfo)
type NetworkID = String
$(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.ispecsMinmaxDefaultsMinMemorySize
, iSpecCpuCount = C.ispecsMinmaxDefaultsMinCpuCount
, iSpecDiskSize = C.ispecsMinmaxDefaultsMinDiskSize
, iSpecDiskCount = C.ispecsMinmaxDefaultsMinDiskCount
, iSpecNicCount = C.ispecsMinmaxDefaultsMinNicCount
, iSpecSpindleUse = C.ispecsMinmaxDefaultsMinSpindleUse
}
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.ispecsMinmaxDefaultsMaxMemorySize
, iSpecCpuCount = C.ispecsMinmaxDefaultsMaxCpuCount
, iSpecDiskSize = C.ispecsMinmaxDefaultsMaxDiskSize
, iSpecDiskCount = C.ispecsMinmaxDefaultsMaxDiskCount
, iSpecNicCount = C.ispecsMinmaxDefaultsMaxNicCount
, iSpecSpindleUse = C.ispecsMinmaxDefaultsMaxSpindleUse
}
$(THH.buildObject "MinMaxISpecs" "minMaxISpecs"
[ THH.renameField "MinSpec" $ THH.simpleField "min" [t| ISpec |]
, THH.renameField "MaxSpec" $ THH.simpleField "max" [t| ISpec |]
])
defMinMaxISpecs :: [MinMaxISpecs]
defMinMaxISpecs = [MinMaxISpecs { minMaxISpecsMinSpec = defMinISpec
, minMaxISpecsMaxSpec = defMaxISpec
}]
$(THH.buildObject "IPolicy" "iPolicy"
[ THH.renameField "MinMaxISpecs" $
THH.simpleField C.ispecsMinmax [t| [MinMaxISpecs] |]
, THH.renameField "StdSpec" $ THH.simpleField C.ispecsStd [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 { iPolicyMinMaxISpecs = defMinMaxISpecs
, iPolicyStdSpec = defStdISpec
, iPolicyDiskTemplates = [minBound..maxBound]
, iPolicyVcpuRatio = C.ipolicyDefaultsVcpuRatio
, iPolicySpindleRatio = C.ipolicyDefaultsSpindleRatio
}
data DynUtil = DynUtil
{ cpuWeight :: Weight
, memWeight :: Weight
, dskWeight :: Weight
, netWeight :: Weight
} deriving (Show, 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)
type MoveJob = ([Ndx], Idx, IMove, [String])
unknownField :: String
unknownField = "<unknown field>"
type JobSet = [MoveJob]
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)
type FailStats = [(FailMode, Int)]
type OpResult = GenericResult FailMode
instance FromString FailMode where
mkFromString v = error $ "Programming error: OpResult used as generic monad"
++ v
opToResult :: OpResult a -> Result a
opToResult (Bad f) = Bad $ show f
opToResult (Ok 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)
$(THH.declareSADT "AutoRepairType"
[ ("ArFixStorage", 'C.autoRepairFixStorage)
, ("ArMigrate", 'C.autoRepairMigrate)
, ("ArFailover", 'C.autoRepairFailover)
, ("ArReinstall", 'C.autoRepairReinstall)
])
$(THH.declareSADT "AutoRepairResult"
[ ("ArEnoperm", 'C.autoRepairEnoperm)
, ("ArSuccess", 'C.autoRepairSuccess)
, ("ArFailure", 'C.autoRepairFailure)
])
data AutoRepairPolicy
= ArEnabled AutoRepairType
| ArSuspended AutoRepairSuspendTime
| ArNotEnabled
deriving (Eq, Show)
data AutoRepairSuspendTime = Forever
| Until ClockTime
deriving (Eq, Show)
data AutoRepairStatus
= ArHealthy (Maybe AutoRepairData)
| ArNeedsRepair AutoRepairData
| ArPendingRepair AutoRepairData
| ArFailedRepair AutoRepairData
deriving (Eq, Show)
data AutoRepairData = AutoRepairData { arType :: AutoRepairType
, arUuid :: String
, arTime :: ClockTime
, arJobs :: [JobId]
, arResult :: Maybe AutoRepairResult
, arTag :: String
}
deriving (Eq, Show)