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.
72 , ("OpInstanceReplaceDisks",
83 , ("OpInstanceFailover",
88 , pMigrationTargetNode
89 , pMigrationTargetNodeUuid
93 , ("OpInstanceMigrate",
98 , pMigrationTargetNode
99 , pMigrationTargetNodeUuid
111 [ pTagSearchPattern ])
120 , ("OpClusterPostInit", [])
121 , ("OpClusterDestroy", [])
122 , ("OpClusterQuery", [])
123 , ("OpClusterVerify",
124 [ pDebugSimulateErrors
131 , ("OpClusterVerifyConfig",
132 [ pDebugSimulateErrors
137 , ("OpClusterVerifyGroup",
139 , pDebugSimulateErrors
145 , ("OpClusterVerifyDisks", [])
146 , ("OpGroupVerifyDisks",
149 , ("OpClusterRepairDiskSizes",
152 , ("OpClusterConfigQuery",
155 , ("OpClusterRename",
158 , ("OpClusterSetParams",
163 , pEnabledHypervisors
173 , pMaintainNodeHealth
185 , pUseExternalMipScript
186 , pEnabledDiskTemplates
188 , pGlobalFileStorageDir
189 , pGlobalSharedFileStorageDir
191 , ("OpClusterRedistConf", [])
192 , ("OpClusterActivateMasterIp", [])
193 , ("OpClusterDeactivateMasterIp", [])
228 , ("OpNodeQuery", dOldQuery)
229 , ("OpNodeQueryvols",
233 , ("OpNodeQueryStorage",
239 , ("OpNodeModifyStorage",
246 , ("OpRepairNodeStorage",
253 , ("OpNodeSetParams",
269 , ("OpNodePowercycle",
279 , pMigrationTargetNode
280 , pMigrationTargetNodeUuid
294 , ("OpInstanceCreate",
322 , pSourceShutdownTimeout
328 , pOpportunisticLocking
331 , ("OpInstanceMultiAlloc",
333 , pMultiAllocInstances
334 , pOpportunisticLocking
336 , ("OpInstanceReinstall",
343 , ("OpInstanceRemove",
349 , ("OpInstanceRename",
356 , ("OpInstanceStartup",
360 , pIgnoreOfflineNodes
366 , ("OpInstanceShutdown",
370 , pIgnoreOfflineNodes
374 , ("OpInstanceReboot",
387 , pMoveTargetNodeUuid
390 , ("OpInstanceConsole",
394 , ("OpInstanceActivateDisks",
400 , ("OpInstanceDeactivateDisks",
405 , ("OpInstanceRecreateDisks",
413 , ("OpInstanceQuery", dOldQuery)
414 , ("OpInstanceQueryData",
419 , ("OpInstanceSetParams",
425 , pInstParamsNicChanges
426 , pInstParamsDiskChanges
441 , ("OpInstanceGrowDisk",
449 , ("OpInstanceChangeGroup",
458 , pNodeGroupAllocPolicy
465 , ("OpGroupAssignNodes",
471 , ("OpGroupQuery", dOldQueryNoLocking)
472 , ("OpGroupSetParams",
474 , pNodeGroupAllocPolicy
487 , ("OpGroupEvacuate",
496 , ("OpExtStorageDiagnose",
503 , ("OpBackupPrepare",
513 , pExportTargetNodeUuid
516 , pIgnoreRemoveFailures
525 , ("OpTestAllocator",
526 [ pIAllocatorDirection
538 , pIAllocatorInstances
539 , pIAllocatorEvacMode
541 , pIAllocatorSpindleUse
545 [ pJQueueNotifyWaitLock
554 , pTestDummySubmitJobs
567 , ("OpNetworkRemove",
571 , ("OpNetworkSetParams",
578 , pNetworkRemoveRsvdIps
580 , ("OpNetworkConnect",
587 , ("OpNetworkDisconnect",
591 , ("OpNetworkQuery", dOldQuery)
592 , ("OpRestrictedCommand",
600 -- | Returns the OP_ID for a given opcode value.
601 $(genOpID ''OpCode "opID")
603 -- | A list of all defined/supported opcode IDs.
604 $(genAllOpIDs ''OpCode "allOpIDs")
606 instance JSON OpCode where
607 readJSON = loadOpCode
608 showJSON = saveOpCode
610 -- | Generates the summary value for an opcode.
611 opSummaryVal :: OpCode -> Maybe String
612 opSummaryVal OpClusterVerifyGroup { opGroupName = s } = Just (fromNonEmpty s)
613 opSummaryVal OpGroupVerifyDisks { opGroupName = s } = Just (fromNonEmpty s)
614 opSummaryVal OpClusterRename { opName = s } = Just (fromNonEmpty s)
615 opSummaryVal OpQuery { opWhat = s } = Just (queryTypeOpToRaw s)
616 opSummaryVal OpQueryFields { opWhat = s } = Just (queryTypeOpToRaw s)
617 opSummaryVal OpNodeRemove { opNodeName = s } = Just (fromNonEmpty s)
618 opSummaryVal OpNodeAdd { opNodeName = s } = Just (fromNonEmpty s)
619 opSummaryVal OpNodeModifyStorage { opNodeName = s } = Just (fromNonEmpty s)
620 opSummaryVal OpRepairNodeStorage { opNodeName = s } = Just (fromNonEmpty s)
621 opSummaryVal OpNodeSetParams { opNodeName = s } = Just (fromNonEmpty s)
622 opSummaryVal OpNodePowercycle { opNodeName = s } = Just (fromNonEmpty s)
623 opSummaryVal OpNodeMigrate { opNodeName = s } = Just (fromNonEmpty s)
624 opSummaryVal OpNodeEvacuate { opNodeName = s } = Just (fromNonEmpty s)
625 opSummaryVal OpInstanceCreate { opInstanceName = s } = Just s
626 opSummaryVal OpInstanceReinstall { opInstanceName = s } = Just s
627 opSummaryVal OpInstanceRemove { opInstanceName = s } = Just s
628 -- FIXME: instance rename should show both names; currently it shows none
629 -- opSummaryVal OpInstanceRename { opInstanceName = s } = Just s
630 opSummaryVal OpInstanceStartup { opInstanceName = s } = Just s
631 opSummaryVal OpInstanceShutdown { opInstanceName = s } = Just s
632 opSummaryVal OpInstanceReboot { opInstanceName = s } = Just s
633 opSummaryVal OpInstanceReplaceDisks { opInstanceName = s } = Just s
634 opSummaryVal OpInstanceFailover { opInstanceName = s } = Just s
635 opSummaryVal OpInstanceMigrate { opInstanceName = s } = Just s
636 opSummaryVal OpInstanceMove { opInstanceName = s } = Just s
637 opSummaryVal OpInstanceConsole { opInstanceName = s } = Just s
638 opSummaryVal OpInstanceActivateDisks { opInstanceName = s } = Just s
639 opSummaryVal OpInstanceDeactivateDisks { opInstanceName = s } = Just s
640 opSummaryVal OpInstanceRecreateDisks { opInstanceName = s } = Just s
641 opSummaryVal OpInstanceSetParams { opInstanceName = s } = Just s
642 opSummaryVal OpInstanceGrowDisk { opInstanceName = s } = Just s
643 opSummaryVal OpInstanceChangeGroup { opInstanceName = s } = Just s
644 opSummaryVal OpGroupAdd { opGroupName = s } = Just (fromNonEmpty s)
645 opSummaryVal OpGroupAssignNodes { opGroupName = s } = Just (fromNonEmpty s)
646 opSummaryVal OpGroupSetParams { opGroupName = s } = Just (fromNonEmpty s)
647 opSummaryVal OpGroupRemove { opGroupName = s } = Just (fromNonEmpty s)
648 opSummaryVal OpGroupEvacuate { opGroupName = s } = Just (fromNonEmpty s)
649 opSummaryVal OpBackupPrepare { opInstanceName = s } = Just s
650 opSummaryVal OpBackupExport { opInstanceName = s } = Just s
651 opSummaryVal OpBackupRemove { opInstanceName = s } = Just s
652 opSummaryVal OpTagsGet { opKind = k } =
653 Just . fromMaybe "None" $ tagNameOf k
654 opSummaryVal OpTagsSearch { opTagSearchPattern = s } = Just (fromNonEmpty s)
655 opSummaryVal OpTestDelay { opDelayDuration = d } = Just (show d)
656 opSummaryVal OpTestAllocator { opIallocator = s } =
657 -- FIXME: Python doesn't handle None fields well, so we have behave the same
658 Just $ maybe "None" fromNonEmpty s
659 opSummaryVal OpNetworkAdd { opNetworkName = s} = Just (fromNonEmpty s)
660 opSummaryVal OpNetworkRemove { opNetworkName = s} = Just (fromNonEmpty s)
661 opSummaryVal OpNetworkSetParams { opNetworkName = s} = Just (fromNonEmpty s)
662 opSummaryVal OpNetworkConnect { opNetworkName = s} = Just (fromNonEmpty s)
663 opSummaryVal OpNetworkDisconnect { opNetworkName = s} = Just (fromNonEmpty s)
664 opSummaryVal _ = Nothing
666 -- | Computes the summary of the opcode.
667 opSummary :: OpCode -> String
669 case opSummaryVal op of
671 Just s -> op_suffix ++ "(" ++ s ++ ")"
672 where op_suffix = drop 3 $ opID op
674 -- | Generic\/common opcode parameters.
675 $(buildObject "CommonOpParams" "op"
684 -- | Default common parameter values.
685 defOpParams :: CommonOpParams
687 CommonOpParams { opDryRun = Nothing
688 , opDebugLevel = Nothing
689 , opPriority = OpPrioNormal
690 , opDepends = Nothing
691 , opComment = Nothing
695 -- | The top-level opcode type.
696 data MetaOpCode = MetaOpCode { metaParams :: CommonOpParams
697 , metaOpCode :: OpCode
698 } deriving (Show, Eq)
700 -- | JSON serialisation for 'MetaOpCode'.
701 showMeta :: MetaOpCode -> JSValue
702 showMeta (MetaOpCode params op) =
703 let objparams = toDictCommonOpParams params
704 objop = toDictOpCode op
705 in makeObj (objparams ++ objop)
707 -- | JSON deserialisation for 'MetaOpCode'
708 readMeta :: JSValue -> Text.JSON.Result MetaOpCode
712 return $ MetaOpCode meta op
714 instance JSON MetaOpCode where
718 -- | Wraps an 'OpCode' with the default parameters to build a
720 wrapOpCode :: OpCode -> MetaOpCode
721 wrapOpCode = MetaOpCode defOpParams
723 -- | Sets the comment on a meta opcode.
724 setOpComment :: String -> MetaOpCode -> MetaOpCode
725 setOpComment comment (MetaOpCode common op) =
726 MetaOpCode (common { opComment = Just comment}) op
728 -- | Sets the priority on a meta opcode.
729 setOpPriority :: OpSubmitPriority -> MetaOpCode -> MetaOpCode
730 setOpPriority prio (MetaOpCode common op) =
731 MetaOpCode (common { opPriority = prio }) op