1 {-# LANGUAGE TemplateHaskell #-}
3 {-| Some common Ganeti types.
5 This holds types common to both core work, and to htools. Types that
6 are very core specific (e.g. configuration objects) should go in
7 'Ganeti.Objects', while types that are specific to htools in-memory
8 representation should go into 'Ganeti.HTools.Types'.
14 Copyright (C) 2012, 2013 Google Inc.
16 This program is free software; you can redistribute it and/or modify
17 it under the terms of the GNU General Public License as published by
18 the Free Software Foundation; either version 2 of the License, or
19 (at your option) any later version.
21 This program is distributed in the hope that it will be useful, but
22 WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 General Public License for more details.
26 You should have received a copy of the GNU General Public License
27 along with this program; if not, write to the Free Software
28 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
38 , instanceStatusFromRaw
70 , VerifyOptionalChecks(..)
71 , verifyOptionalChecksToRaw
95 , IAllocatorTestDir(..)
96 , iAllocatorTestDirToRaw
104 , FinalizedJobStatus(..)
105 , finalizedJobStatusToRaw
113 , OpSubmitPriority(..)
114 , opSubmitPriorityToRaw
115 , parseSubmitPriority
127 , addParamsToStorageUnit
128 , diskTemplateToStorageType
145 , diskAccessModeToRaw
146 , ReplaceDisksMode(..)
147 , replaceDisksModeToRaw
150 import Control.Monad (liftM)
151 import qualified Text.JSON as JSON
152 import Text.JSON (JSON, readJSON, showJSON)
153 import Data.Ratio (numerator, denominator)
155 import qualified Ganeti.ConstantUtils as ConstantUtils
157 import qualified Ganeti.THH as THH
162 -- | Type that holds a non-negative value.
163 newtype NonNegative a = NonNegative { fromNonNegative :: a }
166 -- | Smart constructor for 'NonNegative'.
167 mkNonNegative :: (Monad m, Num a, Ord a, Show a) => a -> m (NonNegative a)
168 mkNonNegative i | i >= 0 = return (NonNegative i)
169 | otherwise = fail $ "Invalid value for non-negative type '" ++
172 instance (JSON.JSON a, Num a, Ord a, Show a) => JSON.JSON (NonNegative a) where
173 showJSON = JSON.showJSON . fromNonNegative
174 readJSON v = JSON.readJSON v >>= mkNonNegative
176 -- | Type that holds a positive value.
177 newtype Positive a = Positive { fromPositive :: a }
180 -- | Smart constructor for 'Positive'.
181 mkPositive :: (Monad m, Num a, Ord a, Show a) => a -> m (Positive a)
182 mkPositive i | i > 0 = return (Positive i)
183 | otherwise = fail $ "Invalid value for positive type '" ++
186 instance (JSON.JSON a, Num a, Ord a, Show a) => JSON.JSON (Positive a) where
187 showJSON = JSON.showJSON . fromPositive
188 readJSON v = JSON.readJSON v >>= mkPositive
190 -- | Type that holds a negative value.
191 newtype Negative a = Negative { fromNegative :: a }
194 -- | Smart constructor for 'Negative'.
195 mkNegative :: (Monad m, Num a, Ord a, Show a) => a -> m (Negative a)
196 mkNegative i | i < 0 = return (Negative i)
197 | otherwise = fail $ "Invalid value for negative type '" ++
200 instance (JSON.JSON a, Num a, Ord a, Show a) => JSON.JSON (Negative a) where
201 showJSON = JSON.showJSON . fromNegative
202 readJSON v = JSON.readJSON v >>= mkNegative
204 -- | Type that holds a non-null list.
205 newtype NonEmpty a = NonEmpty { fromNonEmpty :: [a] }
208 -- | Smart constructor for 'NonEmpty'.
209 mkNonEmpty :: (Monad m) => [a] -> m (NonEmpty a)
210 mkNonEmpty [] = fail "Received empty value for non-empty list"
211 mkNonEmpty xs = return (NonEmpty xs)
213 instance (Eq a, Ord a) => Ord (NonEmpty a) where
214 NonEmpty { fromNonEmpty = x1 } `compare` NonEmpty { fromNonEmpty = x2 } =
217 instance (JSON.JSON a) => JSON.JSON (NonEmpty a) where
218 showJSON = JSON.showJSON . fromNonEmpty
219 readJSON v = JSON.readJSON v >>= mkNonEmpty
221 -- | A simple type alias for non-empty strings.
222 type NonEmptyString = NonEmpty Char
224 type QueryResultCode = Int
226 newtype IPv4Address = IPv4Address { fromIPv4Address :: String }
229 -- FIXME: this should check that 'address' is a valid ip
230 mkIPv4Address :: Monad m => String -> m IPv4Address
231 mkIPv4Address address =
232 return IPv4Address { fromIPv4Address = address }
234 instance JSON.JSON IPv4Address where
235 showJSON = JSON.showJSON . fromIPv4Address
236 readJSON v = JSON.readJSON v >>= mkIPv4Address
238 newtype IPv4Network = IPv4Network { fromIPv4Network :: String }
241 -- FIXME: this should check that 'address' is a valid ip
242 mkIPv4Network :: Monad m => String -> m IPv4Network
243 mkIPv4Network address =
244 return IPv4Network { fromIPv4Network = address }
246 instance JSON.JSON IPv4Network where
247 showJSON = JSON.showJSON . fromIPv4Network
248 readJSON v = JSON.readJSON v >>= mkIPv4Network
250 newtype IPv6Address = IPv6Address { fromIPv6Address :: String }
253 -- FIXME: this should check that 'address' is a valid ip
254 mkIPv6Address :: Monad m => String -> m IPv6Address
255 mkIPv6Address address =
256 return IPv6Address { fromIPv6Address = address }
258 instance JSON.JSON IPv6Address where
259 showJSON = JSON.showJSON . fromIPv6Address
260 readJSON v = JSON.readJSON v >>= mkIPv6Address
262 newtype IPv6Network = IPv6Network { fromIPv6Network :: String }
265 -- FIXME: this should check that 'address' is a valid ip
266 mkIPv6Network :: Monad m => String -> m IPv6Network
267 mkIPv6Network address =
268 return IPv6Network { fromIPv6Network = address }
270 instance JSON.JSON IPv6Network where
271 showJSON = JSON.showJSON . fromIPv6Network
272 readJSON v = JSON.readJSON v >>= mkIPv6Network
276 -- | Instance disk template type.
277 $(THH.declareLADT ''String "DiskTemplate"
278 [ ("DTDiskless", "diskless")
280 , ("DTSharedFile", "sharedfile")
281 , ("DTPlain", "plain")
282 , ("DTBlock", "blockdev")
283 , ("DTDrbd8", "drbd")
287 $(THH.makeJSONInstance ''DiskTemplate)
289 instance THH.PyValue DiskTemplate where
290 showValue = show . diskTemplateToRaw
292 instance HasStringRepr DiskTemplate where
293 fromStringRepr = diskTemplateFromRaw
294 toStringRepr = diskTemplateToRaw
296 -- | Data type representing what items the tag operations apply to.
297 $(THH.declareLADT ''String "TagKind"
298 [ ("TagKindInstance", "instance")
299 , ("TagKindNode", "node")
300 , ("TagKindGroup", "nodegroup")
301 , ("TagKindCluster", "cluster")
302 , ("TagKindNetwork", "network")
304 $(THH.makeJSONInstance ''TagKind)
306 -- | The Group allocation policy type.
308 -- Note that the order of constructors is important as the automatic
309 -- Ord instance will order them in the order they are defined, so when
310 -- changing this data type be careful about the interaction with the
311 -- desired sorting order.
312 $(THH.declareLADT ''String "AllocPolicy"
313 [ ("AllocPreferred", "preferred")
314 , ("AllocLastResort", "last_resort")
315 , ("AllocUnallocable", "unallocable")
317 $(THH.makeJSONInstance ''AllocPolicy)
319 -- | The Instance real state type. FIXME: this could be improved to
320 -- just wrap a /NormalState AdminStatus | ErrorState ErrorCondition/.
321 $(THH.declareLADT ''String "InstanceStatus"
322 [ ("StatusDown", "ADMIN_down")
323 , ("StatusOffline", "ADMIN_offline")
324 , ("ErrorDown", "ERROR_down")
325 , ("ErrorUp", "ERROR_up")
326 , ("NodeDown", "ERROR_nodedown")
327 , ("NodeOffline", "ERROR_nodeoffline")
328 , ("Running", "running")
329 , ("WrongNode", "ERROR_wrongnode")
331 $(THH.makeJSONInstance ''InstanceStatus)
334 $(THH.declareLADT ''String "MigrationMode"
335 [ ("MigrationLive", "live")
336 , ("MigrationNonLive", "non-live")
338 $(THH.makeJSONInstance ''MigrationMode)
340 -- | Verify optional checks.
341 $(THH.declareLADT ''String "VerifyOptionalChecks"
342 [ ("VerifyNPlusOneMem", "nplusone_mem")
344 $(THH.makeJSONInstance ''VerifyOptionalChecks)
346 -- | Cluster verify error codes.
347 $(THH.declareLADT ''String "CVErrorCode"
348 [ ("CvECLUSTERCFG", "ECLUSTERCFG")
349 , ("CvECLUSTERCERT", "ECLUSTERCERT")
350 , ("CvECLUSTERFILECHECK", "ECLUSTERFILECHECK")
351 , ("CvECLUSTERDANGLINGNODES", "ECLUSTERDANGLINGNODES")
352 , ("CvECLUSTERDANGLINGINST", "ECLUSTERDANGLINGINST")
353 , ("CvEINSTANCEBADNODE", "EINSTANCEBADNODE")
354 , ("CvEINSTANCEDOWN", "EINSTANCEDOWN")
355 , ("CvEINSTANCELAYOUT", "EINSTANCELAYOUT")
356 , ("CvEINSTANCEMISSINGDISK", "EINSTANCEMISSINGDISK")
357 , ("CvEINSTANCEFAULTYDISK", "EINSTANCEFAULTYDISK")
358 , ("CvEINSTANCEWRONGNODE", "EINSTANCEWRONGNODE")
359 , ("CvEINSTANCESPLITGROUPS", "EINSTANCESPLITGROUPS")
360 , ("CvEINSTANCEPOLICY", "EINSTANCEPOLICY")
361 , ("CvEINSTANCEUNSUITABLENODE", "EINSTANCEUNSUITABLENODE")
362 , ("CvEINSTANCEMISSINGCFGPARAMETER", "EINSTANCEMISSINGCFGPARAMETER")
363 , ("CvENODEDRBD", "ENODEDRBD")
364 , ("CvENODEDRBDVERSION", "ENODEDRBDVERSION")
365 , ("CvENODEDRBDHELPER", "ENODEDRBDHELPER")
366 , ("CvENODEFILECHECK", "ENODEFILECHECK")
367 , ("CvENODEHOOKS", "ENODEHOOKS")
368 , ("CvENODEHV", "ENODEHV")
369 , ("CvENODELVM", "ENODELVM")
370 , ("CvENODEN1", "ENODEN1")
371 , ("CvENODENET", "ENODENET")
372 , ("CvENODEOS", "ENODEOS")
373 , ("CvENODEORPHANINSTANCE", "ENODEORPHANINSTANCE")
374 , ("CvENODEORPHANLV", "ENODEORPHANLV")
375 , ("CvENODERPC", "ENODERPC")
376 , ("CvENODESSH", "ENODESSH")
377 , ("CvENODEVERSION", "ENODEVERSION")
378 , ("CvENODESETUP", "ENODESETUP")
379 , ("CvENODETIME", "ENODETIME")
380 , ("CvENODEOOBPATH", "ENODEOOBPATH")
381 , ("CvENODEUSERSCRIPTS", "ENODEUSERSCRIPTS")
382 , ("CvENODEFILESTORAGEPATHS", "ENODEFILESTORAGEPATHS")
383 , ("CvENODEFILESTORAGEPATHUNUSABLE", "ENODEFILESTORAGEPATHUNUSABLE")
384 , ("CvENODESHAREDFILESTORAGEPATHUNUSABLE",
385 "ENODESHAREDFILESTORAGEPATHUNUSABLE")
386 , ("CvEGROUPDIFFERENTPVSIZE", "EGROUPDIFFERENTPVSIZE")
388 $(THH.makeJSONInstance ''CVErrorCode)
390 -- | Dynamic device modification, just add\/remove version.
391 $(THH.declareLADT ''String "DdmSimple"
392 [ ("DdmSimpleAdd", "add")
393 , ("DdmSimpleRemove", "remove")
395 $(THH.makeJSONInstance ''DdmSimple)
397 -- | Dynamic device modification, all operations version.
398 $(THH.declareLADT ''String "DdmFull"
399 [ ("DdmFullAdd", "add")
400 , ("DdmFullRemove", "remove")
401 , ("DdmFullModify", "modify")
403 $(THH.makeJSONInstance ''DdmFull)
405 -- | Hypervisor type definitions.
406 $(THH.declareLADT ''String "Hypervisor"
408 , ("XenPvm", "xen-pvm")
409 , ("Chroot", "chroot")
410 , ("XenHvm", "xen-hvm")
414 $(THH.makeJSONInstance ''Hypervisor)
416 instance THH.PyValue Hypervisor where
417 showValue = show . hypervisorToRaw
419 -- | Oob command type.
420 $(THH.declareLADT ''String "OobCommand"
421 [ ("OobHealth", "health")
422 , ("OobPowerCycle", "power-cycle")
423 , ("OobPowerOff", "power-off")
424 , ("OobPowerOn", "power-on")
425 , ("OobPowerStatus", "power-status")
427 $(THH.makeJSONInstance ''OobCommand)
429 -- | Oob command status
430 $(THH.declareLADT ''String "OobStatus"
431 [ ("OobStatusCritical", "CRITICAL")
432 , ("OobStatusOk", "OK")
433 , ("OobStatusUnknown", "UNKNOWN")
434 , ("OobStatusWarning", "WARNING")
436 $(THH.makeJSONInstance ''OobStatus)
439 $(THH.declareLADT ''String "StorageType"
440 [ ("StorageFile", "file")
441 , ("StorageLvmPv", "lvm-pv")
442 , ("StorageLvmVg", "lvm-vg")
443 , ("StorageDiskless", "diskless")
444 , ("StorageBlock", "blockdev")
445 , ("StorageRados", "rados")
446 , ("StorageExt", "ext")
448 $(THH.makeJSONInstance ''StorageType)
450 -- | Storage keys are identifiers for storage units. Their content varies
451 -- depending on the storage type, for example a storage key for LVM storage
452 -- is the volume group name.
453 type StorageKey = String
455 -- | Storage parameters
456 type SPExclusiveStorage = Bool
458 -- | Storage units without storage-type-specific parameters
459 data StorageUnitRaw = SURaw StorageType StorageKey
461 -- | Full storage unit with storage-type-specific parameters
462 data StorageUnit = SUFile StorageKey
463 | SULvmPv StorageKey SPExclusiveStorage
464 | SULvmVg StorageKey SPExclusiveStorage
465 | SUDiskless StorageKey
471 instance Show StorageUnit where
472 show (SUFile key) = showSUSimple StorageFile key
473 show (SULvmPv key es) = showSULvm StorageLvmPv key es
474 show (SULvmVg key es) = showSULvm StorageLvmVg key es
475 show (SUDiskless key) = showSUSimple StorageDiskless key
476 show (SUBlock key) = showSUSimple StorageBlock key
477 show (SURados key) = showSUSimple StorageRados key
478 show (SUExt key) = showSUSimple StorageExt key
480 instance JSON StorageUnit where
481 showJSON (SUFile key) = showJSON (StorageFile, key, []::[String])
482 showJSON (SULvmPv key es) = showJSON (StorageLvmPv, key, [es])
483 showJSON (SULvmVg key es) = showJSON (StorageLvmVg, key, [es])
484 showJSON (SUDiskless key) = showJSON (StorageDiskless, key, []::[String])
485 showJSON (SUBlock key) = showJSON (StorageBlock, key, []::[String])
486 showJSON (SURados key) = showJSON (StorageRados, key, []::[String])
487 showJSON (SUExt key) = showJSON (StorageExt, key, []::[String])
488 -- FIXME: add readJSON implementation
489 readJSON = fail "Not implemented"
491 -- | Composes a string representation of storage types without
492 -- storage parameters
493 showSUSimple :: StorageType -> StorageKey -> String
494 showSUSimple st sk = show (storageTypeToRaw st, sk, []::[String])
496 -- | Composes a string representation of the LVM storage types
497 showSULvm :: StorageType -> StorageKey -> SPExclusiveStorage -> String
498 showSULvm st sk es = show (storageTypeToRaw st, sk, [es])
500 -- | Mapping from disk templates to storage types
501 -- FIXME: This is semantically the same as the constant
502 -- C.diskTemplatesStorageType, remove this when python constants
503 -- are generated from haskell constants
504 diskTemplateToStorageType :: DiskTemplate -> StorageType
505 diskTemplateToStorageType DTExt = StorageExt
506 diskTemplateToStorageType DTFile = StorageFile
507 diskTemplateToStorageType DTSharedFile = StorageFile
508 diskTemplateToStorageType DTDrbd8 = StorageLvmVg
509 diskTemplateToStorageType DTPlain = StorageLvmVg
510 diskTemplateToStorageType DTRbd = StorageRados
511 diskTemplateToStorageType DTDiskless = StorageDiskless
512 diskTemplateToStorageType DTBlock = StorageBlock
514 -- | Equips a raw storage unit with its parameters
515 addParamsToStorageUnit :: SPExclusiveStorage -> StorageUnitRaw -> StorageUnit
516 addParamsToStorageUnit _ (SURaw StorageBlock key) = SUBlock key
517 addParamsToStorageUnit _ (SURaw StorageDiskless key) = SUDiskless key
518 addParamsToStorageUnit _ (SURaw StorageExt key) = SUExt key
519 addParamsToStorageUnit _ (SURaw StorageFile key) = SUFile key
520 addParamsToStorageUnit es (SURaw StorageLvmPv key) = SULvmPv key es
521 addParamsToStorageUnit es (SURaw StorageLvmVg key) = SULvmVg key es
522 addParamsToStorageUnit _ (SURaw StorageRados key) = SURados key
524 -- | Node evac modes.
526 -- This is part of the 'IAllocator' interface and it is used, for
527 -- example, in 'Ganeti.HTools.Loader.RqType'. However, it must reside
528 -- in this module, and not in 'Ganeti.HTools.Types', because it is
529 -- also used by 'Ganeti.HsConstants'.
530 $(THH.declareLADT ''String "EvacMode"
531 [ ("ChangePrimary", "primary-only")
532 , ("ChangeSecondary", "secondary-only")
533 , ("ChangeAll", "all")
535 $(THH.makeJSONInstance ''EvacMode)
537 -- | The file driver type.
538 $(THH.declareLADT ''String "FileDriver"
539 [ ("FileLoop", "loop")
540 , ("FileBlktap", "blktap")
542 $(THH.makeJSONInstance ''FileDriver)
544 -- | The instance create mode.
545 $(THH.declareLADT ''String "InstCreateMode"
546 [ ("InstCreate", "create")
547 , ("InstImport", "import")
548 , ("InstRemoteImport", "remote-import")
550 $(THH.makeJSONInstance ''InstCreateMode)
553 $(THH.declareLADT ''String "RebootType"
554 [ ("RebootSoft", "soft")
555 , ("RebootHard", "hard")
556 , ("RebootFull", "full")
558 $(THH.makeJSONInstance ''RebootType)
561 $(THH.declareLADT ''String "ExportMode"
562 [ ("ExportModeLocal", "local")
563 , ("ExportModeRemote", "remote")
565 $(THH.makeJSONInstance ''ExportMode)
567 -- | IAllocator run types (OpTestIAllocator).
568 $(THH.declareLADT ''String "IAllocatorTestDir"
569 [ ("IAllocatorDirIn", "in")
570 , ("IAllocatorDirOut", "out")
572 $(THH.makeJSONInstance ''IAllocatorTestDir)
574 -- | IAllocator mode. FIXME: use this in "HTools.Backend.IAlloc".
575 $(THH.declareLADT ''String "IAllocatorMode"
576 [ ("IAllocatorAlloc", "allocate")
577 , ("IAllocatorMultiAlloc", "multi-allocate")
578 , ("IAllocatorReloc", "relocate")
579 , ("IAllocatorNodeEvac", "node-evacuate")
580 , ("IAllocatorChangeGroup", "change-group")
582 $(THH.makeJSONInstance ''IAllocatorMode)
585 $(THH.declareLADT ''String "NICMode"
586 [ ("NMBridged", "bridged")
587 , ("NMRouted", "routed")
588 , ("NMOvs", "openvswitch")
591 $(THH.makeJSONInstance ''NICMode)
593 -- | The JobStatus data type. Note that this is ordered especially
594 -- such that greater\/lesser comparison on values of this type makes
596 $(THH.declareLADT ''String "JobStatus"
597 [ ("JOB_STATUS_QUEUED", "queued")
598 , ("JOB_STATUS_WAITING", "waiting")
599 , ("JOB_STATUS_CANCELING", "canceling")
600 , ("JOB_STATUS_RUNNING", "running")
601 , ("JOB_STATUS_CANCELED", "canceled")
602 , ("JOB_STATUS_SUCCESS", "success")
603 , ("JOB_STATUS_ERROR", "error")
605 $(THH.makeJSONInstance ''JobStatus)
607 -- | Finalized job status.
608 $(THH.declareLADT ''String "FinalizedJobStatus"
609 [ ("JobStatusCanceled", "canceled")
610 , ("JobStatusSuccessful", "success")
611 , ("JobStatusFailed", "error")
613 $(THH.makeJSONInstance ''FinalizedJobStatus)
615 -- | The Ganeti job type.
616 newtype JobId = JobId { fromJobId :: Int }
619 -- | Builds a job ID.
620 makeJobId :: (Monad m) => Int -> m JobId
621 makeJobId i | i >= 0 = return $ JobId i
622 | otherwise = fail $ "Invalid value for job ID ' " ++ show i ++ "'"
624 -- | Builds a job ID from a string.
625 makeJobIdS :: (Monad m) => String -> m JobId
626 makeJobIdS s = tryRead "parsing job id" s >>= makeJobId
628 -- | Parses a job ID.
629 parseJobId :: (Monad m) => JSON.JSValue -> m JobId
630 parseJobId (JSON.JSString x) = makeJobIdS $ JSON.fromJSString x
631 parseJobId (JSON.JSRational _ x) =
632 if denominator x /= 1
633 then fail $ "Got fractional job ID from master daemon?! Value:" ++ show x
634 -- FIXME: potential integer overflow here on 32-bit platforms
635 else makeJobId . fromIntegral . numerator $ x
636 parseJobId x = fail $ "Wrong type/value for job id: " ++ show x
638 instance JSON.JSON JobId where
639 showJSON = JSON.showJSON . fromJobId
640 readJSON = parseJobId
642 -- | Relative job ID type alias.
643 type RelativeJobId = Negative Int
645 -- | Job ID dependency.
646 data JobIdDep = JobDepRelative RelativeJobId
647 | JobDepAbsolute JobId
650 instance JSON.JSON JobIdDep where
651 showJSON (JobDepRelative i) = showJSON i
652 showJSON (JobDepAbsolute i) = showJSON i
654 case JSON.readJSON v::JSON.Result (Negative Int) of
655 -- first try relative dependency, usually most common
656 JSON.Ok r -> return $ JobDepRelative r
657 JSON.Error _ -> liftM JobDepAbsolute (parseJobId v)
659 -- | Job Dependency type.
660 data JobDependency = JobDependency JobIdDep [FinalizedJobStatus]
663 instance JSON JobDependency where
664 showJSON (JobDependency dep status) = showJSON (dep, status)
665 readJSON = liftM (uncurry JobDependency) . readJSON
667 -- | Valid opcode priorities for submit.
668 $(THH.declareIADT "OpSubmitPriority"
669 [ ("OpPrioLow", 'ConstantUtils.priorityLow)
670 , ("OpPrioNormal", 'ConstantUtils.priorityNormal)
671 , ("OpPrioHigh", 'ConstantUtils.priorityHigh)
673 $(THH.makeJSONInstance ''OpSubmitPriority)
675 -- | Parse submit priorities from a string.
676 parseSubmitPriority :: (Monad m) => String -> m OpSubmitPriority
677 parseSubmitPriority "low" = return OpPrioLow
678 parseSubmitPriority "normal" = return OpPrioNormal
679 parseSubmitPriority "high" = return OpPrioHigh
680 parseSubmitPriority str = fail $ "Unknown priority '" ++ str ++ "'"
682 -- | Format a submit priority as string.
683 fmtSubmitPriority :: OpSubmitPriority -> String
684 fmtSubmitPriority OpPrioLow = "low"
685 fmtSubmitPriority OpPrioNormal = "normal"
686 fmtSubmitPriority OpPrioHigh = "high"
688 -- | Our ADT for the OpCode status at runtime (while in a job).
689 $(THH.declareLADT ''String "OpStatus"
690 [ ("OP_STATUS_QUEUED", "queued")
691 , ("OP_STATUS_WAITING", "waiting")
692 , ("OP_STATUS_CANCELING", "canceling")
693 , ("OP_STATUS_RUNNING", "running")
694 , ("OP_STATUS_CANCELED", "canceled")
695 , ("OP_STATUS_SUCCESS", "success")
696 , ("OP_STATUS_ERROR", "error")
698 $(THH.makeJSONInstance ''OpStatus)
700 -- | Type for the job message type.
701 $(THH.declareLADT ''String "ELogType"
702 [ ("ELogMessage", "message")
703 , ("ELogRemoteImport", "remote-import")
704 , ("ELogJqueueTest", "jqueue-test")
706 $(THH.makeJSONInstance ''ELogType)
708 -- | Type of one element of a reason trail.
709 type ReasonElem = (String, String, Integer)
711 -- | Type representing a reason trail.
712 type ReasonTrail = [ReasonElem]
714 -- | The VTYPES, a mini-type system in Python.
715 $(THH.declareLADT ''String "VType"
716 [ ("VTypeString", "string")
717 , ("VTypeMaybeString", "maybe-string")
718 , ("VTypeBool", "bool")
719 , ("VTypeSize", "size")
720 , ("VTypeInt", "int")
722 $(THH.makeJSONInstance ''VType)
726 $(THH.declareLADT ''String "NodeRole"
730 , ("NRCandidate", "C")
733 $(THH.makeJSONInstance ''NodeRole)
735 -- | The description of the node role.
736 roleDescription :: NodeRole -> String
737 roleDescription NROffline = "offline"
738 roleDescription NRDrained = "drained"
739 roleDescription NRRegular = "regular"
740 roleDescription NRCandidate = "master candidate"
741 roleDescription NRMaster = "master"
745 $(THH.declareLADT ''String "DiskMode"
746 [ ("DiskRdOnly", "ro")
749 $(THH.makeJSONInstance ''DiskMode)
751 -- | The persistent block driver type. Currently only one type is allowed.
752 $(THH.declareLADT ''String "BlockDriver"
753 [ ("BlockDrvManual", "manual")
755 $(THH.makeJSONInstance ''BlockDriver)
759 $(THH.declareLADT ''String "AdminState"
760 [ ("AdminOffline", "offline")
761 , ("AdminDown", "down")
764 $(THH.makeJSONInstance ''AdminState)
766 -- * Storage field type
768 $(THH.declareLADT ''String "StorageField"
769 [ ( "SFUsed", "used")
770 , ( "SFName", "name")
771 , ( "SFAllocatable", "allocatable")
772 , ( "SFFree", "free")
773 , ( "SFSize", "size")
775 $(THH.makeJSONInstance ''StorageField)
777 -- * Disk access protocol
779 $(THH.declareLADT ''String "DiskAccessMode"
780 [ ( "DiskUserspace", "userspace")
781 , ( "DiskKernelspace", "kernelspace")
783 $(THH.makeJSONInstance ''DiskAccessMode)
785 -- | Replace disks type.
786 $(THH.declareLADT ''String "ReplaceDisksMode"
787 [ -- Replace disks on primary
788 ("ReplaceOnPrimary", "replace_on_primary")
789 -- Replace disks on secondary
790 , ("ReplaceOnSecondary", "replace_on_secondary")
791 -- Change secondary node
792 , ("ReplaceNewSecondary", "replace_new_secondary")
793 , ("ReplaceAuto", "replace_auto")
795 $(THH.makeJSONInstance ''ReplaceDisksMode)