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
94 , ("OpInstanceMigrate",
99 , pMigrationTargetNode
100 , pMigrationTargetNodeUuid
112 [ pTagSearchPattern ])
121 , ("OpClusterPostInit", [])
122 , ("OpClusterDestroy", [])
123 , ("OpClusterQuery", [])
124 , ("OpClusterVerify",
125 [ pDebugSimulateErrors
132 , ("OpClusterVerifyConfig",
133 [ pDebugSimulateErrors
138 , ("OpClusterVerifyGroup",
140 , pDebugSimulateErrors
146 , ("OpClusterVerifyDisks", [])
147 , ("OpGroupVerifyDisks",
150 , ("OpClusterRepairDiskSizes",
153 , ("OpClusterConfigQuery",
156 , ("OpClusterRename",
159 , ("OpClusterSetParams",
164 , pEnabledHypervisors
174 , pMaintainNodeHealth
186 , pUseExternalMipScript
187 , pEnabledDiskTemplates
189 , pGlobalFileStorageDir
190 , pGlobalSharedFileStorageDir
192 , ("OpClusterRedistConf", [])
193 , ("OpClusterActivateMasterIp", [])
194 , ("OpClusterDeactivateMasterIp", [])
229 , ("OpNodeQuery", dOldQuery)
230 , ("OpNodeQueryvols",
234 , ("OpNodeQueryStorage",
240 , ("OpNodeModifyStorage",
247 , ("OpRepairNodeStorage",
254 , ("OpNodeSetParams",
270 , ("OpNodePowercycle",
280 , pMigrationTargetNode
281 , pMigrationTargetNodeUuid
295 , ("OpInstanceCreate",
323 , pSourceShutdownTimeout
329 , pOpportunisticLocking
332 , ("OpInstanceMultiAlloc",
334 , pMultiAllocInstances
335 , pOpportunisticLocking
337 , ("OpInstanceReinstall",
344 , ("OpInstanceRemove",
350 , ("OpInstanceRename",
357 , ("OpInstanceStartup",
361 , pIgnoreOfflineNodes
367 , ("OpInstanceShutdown",
371 , pIgnoreOfflineNodes
375 , ("OpInstanceReboot",
388 , pMoveTargetNodeUuid
391 , ("OpInstanceConsole",
395 , ("OpInstanceActivateDisks",
401 , ("OpInstanceDeactivateDisks",
406 , ("OpInstanceRecreateDisks",
414 , ("OpInstanceQuery", dOldQuery)
415 , ("OpInstanceQueryData",
420 , ("OpInstanceSetParams",
426 , pInstParamsNicChanges
427 , pInstParamsDiskChanges
442 , ("OpInstanceGrowDisk",
450 , ("OpInstanceChangeGroup",
459 , pNodeGroupAllocPolicy
466 , ("OpGroupAssignNodes",
472 , ("OpGroupQuery", dOldQueryNoLocking)
473 , ("OpGroupSetParams",
475 , pNodeGroupAllocPolicy
488 , ("OpGroupEvacuate",
497 , ("OpExtStorageDiagnose",
504 , ("OpBackupPrepare",
514 , pExportTargetNodeUuid
517 , pIgnoreRemoveFailures
526 , ("OpTestAllocator",
527 [ pIAllocatorDirection
539 , pIAllocatorInstances
540 , pIAllocatorEvacMode
542 , pIAllocatorSpindleUse
546 [ pJQueueNotifyWaitLock
555 , pTestDummySubmitJobs
568 , ("OpNetworkRemove",
572 , ("OpNetworkSetParams",
579 , pNetworkRemoveRsvdIps
581 , ("OpNetworkConnect",
588 , ("OpNetworkDisconnect",
592 , ("OpNetworkQuery", dOldQuery)
593 , ("OpRestrictedCommand",
601 -- | Returns the OP_ID for a given opcode value.
602 $(genOpID ''OpCode "opID")
604 -- | A list of all defined/supported opcode IDs.
605 $(genAllOpIDs ''OpCode "allOpIDs")
607 instance JSON OpCode where
608 readJSON = loadOpCode
609 showJSON = saveOpCode
611 -- | Generates the summary value for an opcode.
612 opSummaryVal :: OpCode -> Maybe String
613 opSummaryVal OpClusterVerifyGroup { opGroupName = s } = Just (fromNonEmpty s)
614 opSummaryVal OpGroupVerifyDisks { opGroupName = s } = Just (fromNonEmpty s)
615 opSummaryVal OpClusterRename { opName = s } = Just (fromNonEmpty s)
616 opSummaryVal OpQuery { opWhat = s } = Just (queryTypeOpToRaw s)
617 opSummaryVal OpQueryFields { opWhat = s } = Just (queryTypeOpToRaw s)
618 opSummaryVal OpNodeRemove { opNodeName = s } = Just (fromNonEmpty s)
619 opSummaryVal OpNodeAdd { opNodeName = s } = Just (fromNonEmpty s)
620 opSummaryVal OpNodeModifyStorage { opNodeName = s } = Just (fromNonEmpty s)
621 opSummaryVal OpRepairNodeStorage { opNodeName = s } = Just (fromNonEmpty s)
622 opSummaryVal OpNodeSetParams { opNodeName = s } = Just (fromNonEmpty s)
623 opSummaryVal OpNodePowercycle { opNodeName = s } = Just (fromNonEmpty s)
624 opSummaryVal OpNodeMigrate { opNodeName = s } = Just (fromNonEmpty s)
625 opSummaryVal OpNodeEvacuate { opNodeName = s } = Just (fromNonEmpty s)
626 opSummaryVal OpInstanceCreate { opInstanceName = s } = Just s
627 opSummaryVal OpInstanceReinstall { opInstanceName = s } = Just s
628 opSummaryVal OpInstanceRemove { opInstanceName = s } = Just s
629 -- FIXME: instance rename should show both names; currently it shows none
630 -- opSummaryVal OpInstanceRename { opInstanceName = s } = Just s
631 opSummaryVal OpInstanceStartup { opInstanceName = s } = Just s
632 opSummaryVal OpInstanceShutdown { opInstanceName = s } = Just s
633 opSummaryVal OpInstanceReboot { opInstanceName = s } = Just s
634 opSummaryVal OpInstanceReplaceDisks { opInstanceName = s } = Just s
635 opSummaryVal OpInstanceFailover { opInstanceName = s } = Just s
636 opSummaryVal OpInstanceMigrate { opInstanceName = s } = Just s
637 opSummaryVal OpInstanceMove { opInstanceName = s } = Just s
638 opSummaryVal OpInstanceConsole { opInstanceName = s } = Just s
639 opSummaryVal OpInstanceActivateDisks { opInstanceName = s } = Just s
640 opSummaryVal OpInstanceDeactivateDisks { opInstanceName = s } = Just s
641 opSummaryVal OpInstanceRecreateDisks { opInstanceName = s } = Just s
642 opSummaryVal OpInstanceSetParams { opInstanceName = s } = Just s
643 opSummaryVal OpInstanceGrowDisk { opInstanceName = s } = Just s
644 opSummaryVal OpInstanceChangeGroup { opInstanceName = s } = Just s
645 opSummaryVal OpGroupAdd { opGroupName = s } = Just (fromNonEmpty s)
646 opSummaryVal OpGroupAssignNodes { opGroupName = s } = Just (fromNonEmpty s)
647 opSummaryVal OpGroupSetParams { opGroupName = s } = Just (fromNonEmpty s)
648 opSummaryVal OpGroupRemove { opGroupName = s } = Just (fromNonEmpty s)
649 opSummaryVal OpGroupEvacuate { opGroupName = s } = Just (fromNonEmpty s)
650 opSummaryVal OpBackupPrepare { opInstanceName = s } = Just s
651 opSummaryVal OpBackupExport { opInstanceName = s } = Just s
652 opSummaryVal OpBackupRemove { opInstanceName = s } = Just s
653 opSummaryVal OpTagsGet { opKind = k } =
654 Just . fromMaybe "None" $ tagNameOf k
655 opSummaryVal OpTagsSearch { opTagSearchPattern = s } = Just (fromNonEmpty s)
656 opSummaryVal OpTestDelay { opDelayDuration = d } = Just (show d)
657 opSummaryVal OpTestAllocator { opIallocator = s } =
658 -- FIXME: Python doesn't handle None fields well, so we have behave the same
659 Just $ maybe "None" fromNonEmpty s
660 opSummaryVal OpNetworkAdd { opNetworkName = s} = Just (fromNonEmpty s)
661 opSummaryVal OpNetworkRemove { opNetworkName = s} = Just (fromNonEmpty s)
662 opSummaryVal OpNetworkSetParams { opNetworkName = s} = Just (fromNonEmpty s)
663 opSummaryVal OpNetworkConnect { opNetworkName = s} = Just (fromNonEmpty s)
664 opSummaryVal OpNetworkDisconnect { opNetworkName = s} = Just (fromNonEmpty s)
665 opSummaryVal _ = Nothing
667 -- | Computes the summary of the opcode.
668 opSummary :: OpCode -> String
670 case opSummaryVal op of
672 Just s -> op_suffix ++ "(" ++ s ++ ")"
673 where op_suffix = drop 3 $ opID op
675 -- | Generic\/common opcode parameters.
676 $(buildObject "CommonOpParams" "op"
685 -- | Default common parameter values.
686 defOpParams :: CommonOpParams
688 CommonOpParams { opDryRun = Nothing
689 , opDebugLevel = Nothing
690 , opPriority = OpPrioNormal
691 , opDepends = Nothing
692 , opComment = Nothing
696 -- | The top-level opcode type.
697 data MetaOpCode = MetaOpCode { metaParams :: CommonOpParams
698 , metaOpCode :: OpCode
699 } deriving (Show, Eq)
701 -- | JSON serialisation for 'MetaOpCode'.
702 showMeta :: MetaOpCode -> JSValue
703 showMeta (MetaOpCode params op) =
704 let objparams = toDictCommonOpParams params
705 objop = toDictOpCode op
706 in makeObj (objparams ++ objop)
708 -- | JSON deserialisation for 'MetaOpCode'
709 readMeta :: JSValue -> Text.JSON.Result MetaOpCode
713 return $ MetaOpCode meta op
715 instance JSON MetaOpCode where
719 -- | Wraps an 'OpCode' with the default parameters to build a
721 wrapOpCode :: OpCode -> MetaOpCode
722 wrapOpCode = MetaOpCode defOpParams
724 -- | Sets the comment on a meta opcode.
725 setOpComment :: String -> MetaOpCode -> MetaOpCode
726 setOpComment comment (MetaOpCode common op) =
727 MetaOpCode (common { opComment = Just comment}) op
729 -- | Sets the priority on a meta opcode.
730 setOpPriority :: OpSubmitPriority -> MetaOpCode -> MetaOpCode
731 setOpPriority prio (MetaOpCode common op) =
732 MetaOpCode (common { opPriority = prio }) op