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
89 , ("OpInstanceMigrate",
93 , pMigrationTargetNode
105 [ pTagSearchPattern ])
114 , ("OpClusterPostInit", [])
115 , ("OpClusterDestroy", [])
116 , ("OpClusterQuery", [])
117 , ("OpClusterVerify",
118 [ pDebugSimulateErrors
125 , ("OpClusterVerifyConfig",
126 [ pDebugSimulateErrors
131 , ("OpClusterVerifyGroup",
133 , pDebugSimulateErrors
139 , ("OpClusterVerifyDisks", [])
140 , ("OpGroupVerifyDisks",
143 , ("OpClusterRepairDiskSizes",
146 , ("OpClusterConfigQuery",
149 , ("OpClusterRename",
152 , ("OpClusterSetParams",
157 , pEnabledHypervisors
167 , pMaintainNodeHealth
179 , pUseExternalMipScript
180 , pEnabledDiskTemplates
183 , ("OpClusterRedistConf", [])
184 , ("OpClusterActivateMasterIp", [])
185 , ("OpClusterDeactivateMasterIp", [])
203 , ("OpNodeRemove", [ pNodeName ])
216 , ("OpNodeQuery", dOldQuery)
217 , ("OpNodeQueryvols",
221 , ("OpNodeQueryStorage",
227 , ("OpNodeModifyStorage",
233 , ("OpRepairNodeStorage",
239 , ("OpNodeSetParams",
254 , ("OpNodePowercycle",
262 , pMigrationTargetNode
274 , ("OpInstanceCreate",
300 , pSourceShutdownTimeout
305 , pOpportunisticLocking
308 , ("OpInstanceMultiAlloc",
310 , pMultiAllocInstances
311 , pOpportunisticLocking
313 , ("OpInstanceReinstall",
319 , ("OpInstanceSnapshot",
323 , ("OpInstanceRemove",
329 , ("OpInstanceRename",
335 , ("OpInstanceStartup",
338 , pIgnoreOfflineNodes
344 , ("OpInstanceShutdown",
347 , pIgnoreOfflineNodes
351 , ("OpInstanceReboot",
364 , ("OpInstanceConsole",
366 , ("OpInstanceActivateDisks",
371 , ("OpInstanceDeactivateDisks",
375 , ("OpInstanceRecreateDisks",
381 , ("OpInstanceQuery", dOldQuery)
382 , ("OpInstanceQueryData",
387 , ("OpInstanceSetParams",
392 , pInstParamsNicChanges
393 , pInstParamsDiskChanges
408 , ("OpInstanceGrowDisk",
415 , ("OpInstanceChangeGroup",
423 , pNodeGroupAllocPolicy
430 , ("OpGroupAssignNodes",
435 , ("OpGroupQuery", dOldQueryNoLocking)
436 , ("OpGroupSetParams",
438 , pNodeGroupAllocPolicy
451 , ("OpGroupEvacuate",
460 , ("OpExtStorageDiagnose",
467 , ("OpBackupPrepare",
477 , pIgnoreRemoveFailures
484 , ("OpTestAllocator",
485 [ pIAllocatorDirection
497 , pIAllocatorInstances
498 , pIAllocatorEvacMode
500 , pIAllocatorSpindleUse
504 [ pJQueueNotifyWaitLock
513 , pTestDummySubmitJobs
526 , ("OpNetworkRemove",
530 , ("OpNetworkSetParams",
537 , pNetworkRemoveRsvdIps
539 , ("OpNetworkConnect",
546 , ("OpNetworkDisconnect",
550 , ("OpNetworkQuery", dOldQuery)
551 , ("OpRestrictedCommand",
558 -- | Returns the OP_ID for a given opcode value.
559 $(genOpID ''OpCode "opID")
561 -- | A list of all defined/supported opcode IDs.
562 $(genAllOpIDs ''OpCode "allOpIDs")
564 instance JSON OpCode where
565 readJSON = loadOpCode
566 showJSON = saveOpCode
568 -- | Generates the summary value for an opcode.
569 opSummaryVal :: OpCode -> Maybe String
570 opSummaryVal OpClusterVerifyGroup { opGroupName = s } = Just (fromNonEmpty s)
571 opSummaryVal OpGroupVerifyDisks { opGroupName = s } = Just (fromNonEmpty s)
572 opSummaryVal OpClusterRename { opName = s } = Just (fromNonEmpty s)
573 opSummaryVal OpQuery { opWhat = s } = Just (queryTypeOpToRaw s)
574 opSummaryVal OpQueryFields { opWhat = s } = Just (queryTypeOpToRaw s)
575 opSummaryVal OpNodeRemove { opNodeName = s } = Just (fromNonEmpty s)
576 opSummaryVal OpNodeAdd { opNodeName = s } = Just (fromNonEmpty s)
577 opSummaryVal OpNodeModifyStorage { opNodeName = s } = Just (fromNonEmpty s)
578 opSummaryVal OpRepairNodeStorage { opNodeName = s } = Just (fromNonEmpty s)
579 opSummaryVal OpNodeSetParams { opNodeName = s } = Just (fromNonEmpty s)
580 opSummaryVal OpNodePowercycle { opNodeName = s } = Just (fromNonEmpty s)
581 opSummaryVal OpNodeMigrate { opNodeName = s } = Just (fromNonEmpty s)
582 opSummaryVal OpNodeEvacuate { opNodeName = s } = Just (fromNonEmpty s)
583 opSummaryVal OpInstanceCreate { opInstanceName = s } = Just s
584 opSummaryVal OpInstanceReinstall { opInstanceName = s } = Just s
585 opSummaryVal OpInstanceSnapshot { opInstanceName = s } = Just s
586 opSummaryVal OpInstanceRemove { opInstanceName = s } = Just s
587 -- FIXME: instance rename should show both names; currently it shows none
588 -- opSummaryVal OpInstanceRename { opInstanceName = s } = Just s
589 opSummaryVal OpInstanceStartup { opInstanceName = s } = Just s
590 opSummaryVal OpInstanceShutdown { opInstanceName = s } = Just s
591 opSummaryVal OpInstanceReboot { opInstanceName = s } = Just s
592 opSummaryVal OpInstanceReplaceDisks { opInstanceName = s } = Just s
593 opSummaryVal OpInstanceFailover { opInstanceName = s } = Just s
594 opSummaryVal OpInstanceMigrate { opInstanceName = s } = Just s
595 opSummaryVal OpInstanceMove { opInstanceName = s } = Just s
596 opSummaryVal OpInstanceConsole { opInstanceName = s } = Just s
597 opSummaryVal OpInstanceActivateDisks { opInstanceName = s } = Just s
598 opSummaryVal OpInstanceDeactivateDisks { opInstanceName = s } = Just s
599 opSummaryVal OpInstanceRecreateDisks { opInstanceName = s } = Just s
600 opSummaryVal OpInstanceSetParams { opInstanceName = s } = Just s
601 opSummaryVal OpInstanceGrowDisk { opInstanceName = s } = Just s
602 opSummaryVal OpInstanceChangeGroup { opInstanceName = s } = Just s
603 opSummaryVal OpGroupAdd { opGroupName = s } = Just (fromNonEmpty s)
604 opSummaryVal OpGroupAssignNodes { opGroupName = s } = Just (fromNonEmpty s)
605 opSummaryVal OpGroupSetParams { opGroupName = s } = Just (fromNonEmpty s)
606 opSummaryVal OpGroupRemove { opGroupName = s } = Just (fromNonEmpty s)
607 opSummaryVal OpGroupEvacuate { opGroupName = s } = Just (fromNonEmpty s)
608 opSummaryVal OpBackupPrepare { opInstanceName = s } = Just s
609 opSummaryVal OpBackupExport { opInstanceName = s } = Just s
610 opSummaryVal OpBackupRemove { opInstanceName = s } = Just s
611 opSummaryVal OpTagsGet { opKind = k } =
612 Just . fromMaybe "None" $ tagNameOf k
613 opSummaryVal OpTagsSearch { opTagSearchPattern = s } = Just (fromNonEmpty s)
614 opSummaryVal OpTestDelay { opDelayDuration = d } = Just (show d)
615 opSummaryVal OpTestAllocator { opIallocator = s } =
616 -- FIXME: Python doesn't handle None fields well, so we have behave the same
617 Just $ maybe "None" fromNonEmpty s
618 opSummaryVal OpNetworkAdd { opNetworkName = s} = Just (fromNonEmpty s)
619 opSummaryVal OpNetworkRemove { opNetworkName = s} = Just (fromNonEmpty s)
620 opSummaryVal OpNetworkSetParams { opNetworkName = s} = Just (fromNonEmpty s)
621 opSummaryVal OpNetworkConnect { opNetworkName = s} = Just (fromNonEmpty s)
622 opSummaryVal OpNetworkDisconnect { opNetworkName = s} = Just (fromNonEmpty s)
623 opSummaryVal _ = Nothing
625 -- | Computes the summary of the opcode.
626 opSummary :: OpCode -> String
628 case opSummaryVal op of
630 Just s -> op_suffix ++ "(" ++ s ++ ")"
631 where op_suffix = drop 3 $ opID op
633 -- | Generic\/common opcode parameters.
634 $(buildObject "CommonOpParams" "op"
643 -- | Default common parameter values.
644 defOpParams :: CommonOpParams
646 CommonOpParams { opDryRun = Nothing
647 , opDebugLevel = Nothing
648 , opPriority = OpPrioNormal
649 , opDepends = Nothing
650 , opComment = Nothing
654 -- | The top-level opcode type.
655 data MetaOpCode = MetaOpCode { metaParams :: CommonOpParams
656 , metaOpCode :: OpCode
657 } deriving (Show, Eq)
659 -- | JSON serialisation for 'MetaOpCode'.
660 showMeta :: MetaOpCode -> JSValue
661 showMeta (MetaOpCode params op) =
662 let objparams = toDictCommonOpParams params
663 objop = toDictOpCode op
664 in makeObj (objparams ++ objop)
666 -- | JSON deserialisation for 'MetaOpCode'
667 readMeta :: JSValue -> Text.JSON.Result MetaOpCode
671 return $ MetaOpCode meta op
673 instance JSON MetaOpCode where
677 -- | Wraps an 'OpCode' with the default parameters to build a
679 wrapOpCode :: OpCode -> MetaOpCode
680 wrapOpCode = MetaOpCode defOpParams
682 -- | Sets the comment on a meta opcode.
683 setOpComment :: String -> MetaOpCode -> MetaOpCode
684 setOpComment comment (MetaOpCode common op) =
685 MetaOpCode (common { opComment = Just comment}) op
687 -- | Sets the priority on a meta opcode.
688 setOpPriority :: OpSubmitPriority -> MetaOpCode -> MetaOpCode
689 setOpPriority prio (MetaOpCode common op) =
690 MetaOpCode (common { opPriority = prio }) op