1 {-# LANGUAGE TemplateHaskell #-}
3 {-| Implementation of the opcodes.
9 Copyright (C) 2009, 2010, 2011, 2012, 2013 Google Inc.
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
34 , ReplaceDisksMode(..)
50 import Data.Maybe (fromMaybe)
51 import Text.JSON (readJSON, JSON, JSValue, makeObj)
52 import qualified Text.JSON
56 import Ganeti.OpParams
57 import Ganeti.Types (OpSubmitPriority(..), fromNonEmpty)
58 import Ganeti.Query.Language (queryTypeOpToRaw)
60 -- | OpCode representation.
62 -- We only implement a subset of Ganeti opcodes: those which are actually used
63 -- in the htools codebase.
71 , ("OpInstanceReplaceDisks",
80 , ("OpInstanceFailover",
84 , pMigrationTargetNode
88 , ("OpInstanceMigrate",
92 , pMigrationTargetNode
104 [ pTagSearchPattern ])
113 , ("OpClusterPostInit", [])
114 , ("OpClusterDestroy", [])
115 , ("OpClusterQuery", [])
116 , ("OpClusterVerify",
117 [ pDebugSimulateErrors
124 , ("OpClusterVerifyConfig",
125 [ pDebugSimulateErrors
130 , ("OpClusterVerifyGroup",
132 , pDebugSimulateErrors
138 , ("OpClusterVerifyDisks", [])
139 , ("OpGroupVerifyDisks",
142 , ("OpClusterRepairDiskSizes",
145 , ("OpClusterConfigQuery",
148 , ("OpClusterRename",
151 , ("OpClusterSetParams",
156 , pEnabledHypervisors
166 , pMaintainNodeHealth
178 , pUseExternalMipScript
179 , pEnabledDiskTemplates
181 , ("OpClusterRedistConf", [])
182 , ("OpClusterActivateMasterIp", [])
183 , ("OpClusterDeactivateMasterIp", [])
201 , ("OpNodeRemove", [ pNodeName ])
214 , ("OpNodeQuery", dOldQuery)
215 , ("OpNodeQueryvols",
219 , ("OpNodeQueryStorage",
225 , ("OpNodeModifyStorage",
231 , ("OpRepairNodeStorage",
237 , ("OpNodeSetParams",
252 , ("OpNodePowercycle",
260 , pMigrationTargetNode
272 , ("OpInstanceCreate",
298 , pSourceShutdownTimeout
303 , pOpportunisticLocking
306 , ("OpInstanceMultiAlloc",
308 , pMultiAllocInstances
309 , pOpportunisticLocking
311 , ("OpInstanceReinstall",
317 , ("OpInstanceRemove",
322 , ("OpInstanceRename",
328 , ("OpInstanceStartup",
331 , pIgnoreOfflineNodes
337 , ("OpInstanceShutdown",
340 , pIgnoreOfflineNodes
344 , ("OpInstanceReboot",
357 , ("OpInstanceConsole",
359 , ("OpInstanceActivateDisks",
364 , ("OpInstanceDeactivateDisks",
368 , ("OpInstanceRecreateDisks",
374 , ("OpInstanceQuery", dOldQuery)
375 , ("OpInstanceQueryData",
380 , ("OpInstanceSetParams",
385 , pInstParamsNicChanges
386 , pInstParamsDiskChanges
399 , ("OpInstanceGrowDisk",
406 , ("OpInstanceChangeGroup",
414 , pNodeGroupAllocPolicy
421 , ("OpGroupAssignNodes",
426 , ("OpGroupQuery", dOldQueryNoLocking)
427 , ("OpGroupSetParams",
429 , pNodeGroupAllocPolicy
442 , ("OpGroupEvacuate",
451 , ("OpExtStorageDiagnose",
458 , ("OpBackupPrepare",
468 , pIgnoreRemoveFailures
475 , ("OpTestAllocator",
476 [ pIAllocatorDirection
488 , pIAllocatorInstances
489 , pIAllocatorEvacMode
491 , pIAllocatorSpindleUse
495 [ pJQueueNotifyWaitLock
504 , pTestDummySubmitJobs
517 , ("OpNetworkRemove",
521 , ("OpNetworkSetParams",
528 , pNetworkRemoveRsvdIps
530 , ("OpNetworkConnect",
537 , ("OpNetworkDisconnect",
541 , ("OpNetworkQuery", dOldQuery)
542 , ("OpRestrictedCommand",
549 -- | Returns the OP_ID for a given opcode value.
550 $(genOpID ''OpCode "opID")
552 -- | A list of all defined/supported opcode IDs.
553 $(genAllOpIDs ''OpCode "allOpIDs")
555 instance JSON OpCode where
556 readJSON = loadOpCode
557 showJSON = saveOpCode
559 -- | Generates the summary value for an opcode.
560 opSummaryVal :: OpCode -> Maybe String
561 opSummaryVal OpClusterVerifyGroup { opGroupName = s } = Just (fromNonEmpty s)
562 opSummaryVal OpGroupVerifyDisks { opGroupName = s } = Just (fromNonEmpty s)
563 opSummaryVal OpClusterRename { opName = s } = Just (fromNonEmpty s)
564 opSummaryVal OpQuery { opWhat = s } = Just (queryTypeOpToRaw s)
565 opSummaryVal OpQueryFields { opWhat = s } = Just (queryTypeOpToRaw s)
566 opSummaryVal OpNodeRemove { opNodeName = s } = Just (fromNonEmpty s)
567 opSummaryVal OpNodeAdd { opNodeName = s } = Just (fromNonEmpty s)
568 opSummaryVal OpNodeModifyStorage { opNodeName = s } = Just (fromNonEmpty s)
569 opSummaryVal OpRepairNodeStorage { opNodeName = s } = Just (fromNonEmpty s)
570 opSummaryVal OpNodeSetParams { opNodeName = s } = Just (fromNonEmpty s)
571 opSummaryVal OpNodePowercycle { opNodeName = s } = Just (fromNonEmpty s)
572 opSummaryVal OpNodeMigrate { opNodeName = s } = Just (fromNonEmpty s)
573 opSummaryVal OpNodeEvacuate { opNodeName = s } = Just (fromNonEmpty s)
574 opSummaryVal OpInstanceCreate { opInstanceName = s } = Just s
575 opSummaryVal OpInstanceReinstall { opInstanceName = s } = Just s
576 opSummaryVal OpInstanceRemove { opInstanceName = s } = Just s
577 -- FIXME: instance rename should show both names; currently it shows none
578 -- opSummaryVal OpInstanceRename { opInstanceName = s } = Just s
579 opSummaryVal OpInstanceStartup { opInstanceName = s } = Just s
580 opSummaryVal OpInstanceShutdown { opInstanceName = s } = Just s
581 opSummaryVal OpInstanceReboot { opInstanceName = s } = Just s
582 opSummaryVal OpInstanceReplaceDisks { opInstanceName = s } = Just s
583 opSummaryVal OpInstanceFailover { opInstanceName = s } = Just s
584 opSummaryVal OpInstanceMigrate { opInstanceName = s } = Just s
585 opSummaryVal OpInstanceMove { opInstanceName = s } = Just s
586 opSummaryVal OpInstanceConsole { opInstanceName = s } = Just s
587 opSummaryVal OpInstanceActivateDisks { opInstanceName = s } = Just s
588 opSummaryVal OpInstanceDeactivateDisks { opInstanceName = s } = Just s
589 opSummaryVal OpInstanceRecreateDisks { opInstanceName = s } = Just s
590 opSummaryVal OpInstanceSetParams { opInstanceName = s } = Just s
591 opSummaryVal OpInstanceGrowDisk { opInstanceName = s } = Just s
592 opSummaryVal OpInstanceChangeGroup { opInstanceName = s } = Just s
593 opSummaryVal OpGroupAdd { opGroupName = s } = Just (fromNonEmpty s)
594 opSummaryVal OpGroupAssignNodes { opGroupName = s } = Just (fromNonEmpty s)
595 opSummaryVal OpGroupSetParams { opGroupName = s } = Just (fromNonEmpty s)
596 opSummaryVal OpGroupRemove { opGroupName = s } = Just (fromNonEmpty s)
597 opSummaryVal OpGroupEvacuate { opGroupName = s } = Just (fromNonEmpty s)
598 opSummaryVal OpBackupPrepare { opInstanceName = s } = Just s
599 opSummaryVal OpBackupExport { opInstanceName = s } = Just s
600 opSummaryVal OpBackupRemove { opInstanceName = s } = Just s
601 opSummaryVal OpTagsGet { opKind = k } =
602 Just . fromMaybe "None" $ tagNameOf k
603 opSummaryVal OpTagsSearch { opTagSearchPattern = s } = Just (fromNonEmpty s)
604 opSummaryVal OpTestDelay { opDelayDuration = d } = Just (show d)
605 opSummaryVal OpTestAllocator { opIallocator = s } =
606 -- FIXME: Python doesn't handle None fields well, so we have behave the same
607 Just $ maybe "None" fromNonEmpty s
608 opSummaryVal OpNetworkAdd { opNetworkName = s} = Just (fromNonEmpty s)
609 opSummaryVal OpNetworkRemove { opNetworkName = s} = Just (fromNonEmpty s)
610 opSummaryVal OpNetworkSetParams { opNetworkName = s} = Just (fromNonEmpty s)
611 opSummaryVal OpNetworkConnect { opNetworkName = s} = Just (fromNonEmpty s)
612 opSummaryVal OpNetworkDisconnect { opNetworkName = s} = Just (fromNonEmpty s)
613 opSummaryVal _ = Nothing
615 -- | Computes the summary of the opcode.
616 opSummary :: OpCode -> String
618 case opSummaryVal op of
620 Just s -> op_suffix ++ "(" ++ s ++ ")"
621 where op_suffix = drop 3 $ opID op
623 -- | Generic\/common opcode parameters.
624 $(buildObject "CommonOpParams" "op"
633 -- | Default common parameter values.
634 defOpParams :: CommonOpParams
636 CommonOpParams { opDryRun = Nothing
637 , opDebugLevel = Nothing
638 , opPriority = OpPrioNormal
639 , opDepends = Nothing
640 , opComment = Nothing
644 -- | The top-level opcode type.
645 data MetaOpCode = MetaOpCode { metaParams :: CommonOpParams
646 , metaOpCode :: OpCode
647 } deriving (Show, Eq)
649 -- | JSON serialisation for 'MetaOpCode'.
650 showMeta :: MetaOpCode -> JSValue
651 showMeta (MetaOpCode params op) =
652 let objparams = toDictCommonOpParams params
653 objop = toDictOpCode op
654 in makeObj (objparams ++ objop)
656 -- | JSON deserialisation for 'MetaOpCode'
657 readMeta :: JSValue -> Text.JSON.Result MetaOpCode
661 return $ MetaOpCode meta op
663 instance JSON MetaOpCode where
667 -- | Wraps an 'OpCode' with the default parameters to build a
669 wrapOpCode :: OpCode -> MetaOpCode
670 wrapOpCode = MetaOpCode defOpParams
672 -- | Sets the comment on a meta opcode.
673 setOpComment :: String -> MetaOpCode -> MetaOpCode
674 setOpComment comment (MetaOpCode common op) =
675 MetaOpCode (common { opComment = Just comment}) op
677 -- | Sets the priority on a meta opcode.
678 setOpPriority :: OpSubmitPriority -> MetaOpCode -> MetaOpCode
679 setOpPriority prio (MetaOpCode common op) =
680 MetaOpCode (common { opPriority = prio }) op