41a4371f426d9256e511c27e4722fd03e471eb22
[ganeti-local] / src / Ganeti / OpCodes.hs
1 {-# LANGUAGE TemplateHaskell #-}
2
3 {-| Implementation of the opcodes.
4
5 -}
6
7 {-
8
9 Copyright (C) 2009, 2010, 2011, 2012, 2013 Google Inc.
10
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.
15
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.
20
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
24 02110-1301, USA.
25
26 -}
27
28 module Ganeti.OpCodes
29   ( OpCode(..)
30   , TagObject(..)
31   , tagObjectFrom
32   , encodeTagObject
33   , decodeTagObject
34   , ReplaceDisksMode(..)
35   , DiskIndex
36   , mkDiskIndex
37   , unDiskIndex
38   , opID
39   , allOpIDs
40   , allOpFields
41   , opSummary
42   , CommonOpParams(..)
43   , defOpParams
44   , MetaOpCode(..)
45   , wrapOpCode
46   , setOpComment
47   , setOpPriority
48   ) where
49
50 import Data.Maybe (fromMaybe)
51 import Text.JSON (readJSON, JSON, JSValue, makeObj)
52 import qualified Text.JSON
53
54 import Ganeti.THH
55
56 import Ganeti.OpParams
57 import Ganeti.Types (OpSubmitPriority(..), fromNonEmpty)
58 import Ganeti.Query.Language (queryTypeOpToRaw)
59
60 -- | OpCode representation.
61 --
62 -- We only implement a subset of Ganeti opcodes: those which are actually used
63 -- in the htools codebase.
64 $(genOpCode "OpCode"
65   [ ("OpTestDelay",
66      [ pDelayDuration
67      , pDelayOnMaster
68      , pDelayOnNodes
69      , pDelayRepeat
70      ])
71   , ("OpInstanceReplaceDisks",
72      [ pInstanceName
73      , pEarlyRelease
74      , pIgnoreIpolicy
75      , pReplaceDisksMode
76      , pReplaceDisksList
77      , pRemoteNode
78      , pIallocator
79      ])
80   , ("OpInstanceFailover",
81      [ pInstanceName
82      , pShutdownTimeout
83      , pIgnoreConsistency
84      , pMigrationTargetNode
85      , pIgnoreIpolicy
86      , pIallocator
87      , pMigrationCleanup
88      ])
89   , ("OpInstanceMigrate",
90      [ pInstanceName
91      , pMigrationMode
92      , pMigrationLive
93      , pMigrationTargetNode
94      , pAllowRuntimeChgs
95      , pIgnoreIpolicy
96      , pMigrationCleanup
97      , pIallocator
98      , pAllowFailover
99      ])
100   , ("OpTagsGet",
101      [ pTagsObject
102      , pUseLocking
103      ])
104   , ("OpTagsSearch",
105      [ pTagSearchPattern ])
106   , ("OpTagsSet",
107      [ pTagsObject
108      , pTagsList
109      ])
110   , ("OpTagsDel",
111      [ pTagsObject
112      , pTagsList
113      ])
114   , ("OpClusterPostInit", [])
115   , ("OpClusterDestroy", [])
116   , ("OpClusterQuery", [])
117   , ("OpClusterVerify",
118      [ pDebugSimulateErrors
119      , pErrorCodes
120      , pSkipChecks
121      , pIgnoreErrors
122      , pVerbose
123      , pOptGroupName
124      ])
125   , ("OpClusterVerifyConfig",
126      [ pDebugSimulateErrors
127      , pErrorCodes
128      , pIgnoreErrors
129      , pVerbose
130      ])
131   , ("OpClusterVerifyGroup",
132      [ pGroupName
133      , pDebugSimulateErrors
134      , pErrorCodes
135      , pSkipChecks
136      , pIgnoreErrors
137      , pVerbose
138      ])
139   , ("OpClusterVerifyDisks", [])
140   , ("OpGroupVerifyDisks",
141      [ pGroupName
142      ])
143   , ("OpClusterRepairDiskSizes",
144      [ pInstances
145      ])
146   , ("OpClusterConfigQuery",
147      [ pOutputFields
148      ])
149   , ("OpClusterRename",
150      [ pName
151      ])
152   , ("OpClusterSetParams",
153      [ pForce
154      , pHvState
155      , pDiskState
156      , pVgName
157      , pEnabledHypervisors
158      , pClusterHvParams
159      , pClusterBeParams
160      , pOsHvp
161      , pClusterOsParams
162      , pDiskParams
163      , pCandidatePoolSize
164      , pUidPool
165      , pAddUids
166      , pRemoveUids
167      , pMaintainNodeHealth
168      , pPreallocWipeDisks
169      , pNicParams
170      , pNdParams
171      , pIpolicy
172      , pDrbdHelper
173      , pDefaultIAllocator
174      , pMasterNetdev
175      , pMasterNetmask
176      , pReservedLvs
177      , pHiddenOs
178      , pBlacklistedOs
179      , pUseExternalMipScript
180      , pEnabledDiskTemplates
181      , pModifyEtcHosts
182      ])
183   , ("OpClusterRedistConf", [])
184   , ("OpClusterActivateMasterIp", [])
185   , ("OpClusterDeactivateMasterIp", [])
186   , ("OpQuery",
187      [ pQueryWhat
188      , pUseLocking
189      , pQueryFields
190      , pQueryFilter
191      ])
192   , ("OpQueryFields",
193      [ pQueryWhat
194      , pQueryFields
195      ])
196   , ("OpOobCommand",
197      [ pNodeNames
198      , pOobCommand
199      , pOobTimeout
200      , pIgnoreStatus
201      , pPowerDelay
202      ])
203   , ("OpNodeRemove", [ pNodeName ])
204   , ("OpNodeAdd",
205      [ pNodeName
206      , pHvState
207      , pDiskState
208      , pPrimaryIp
209      , pSecondaryIp
210      , pReadd
211      , pNodeGroup
212      , pMasterCapable
213      , pVmCapable
214      , pNdParams
215     ])
216   , ("OpNodeQuery", dOldQuery)
217   , ("OpNodeQueryvols",
218      [ pOutputFields
219      , pNodes
220      ])
221   , ("OpNodeQueryStorage",
222      [ pOutputFields
223      , pStorageType
224      , pNodes
225      , pStorageName
226      ])
227   , ("OpNodeModifyStorage",
228      [ pNodeName
229      , pStorageType
230      , pStorageName
231      , pStorageChanges
232      ])
233   , ("OpRepairNodeStorage",
234      [ pNodeName
235      , pStorageType
236      , pStorageName
237      , pIgnoreConsistency
238      ])
239   , ("OpNodeSetParams",
240      [ pNodeName
241      , pForce
242      , pHvState
243      , pDiskState
244      , pMasterCandidate
245      , pOffline
246      , pDrained
247      , pAutoPromote
248      , pMasterCapable
249      , pVmCapable
250      , pSecondaryIp
251      , pNdParams
252      , pPowered
253      ])
254   , ("OpNodePowercycle",
255      [ pNodeName
256      , pForce
257      ])
258   , ("OpNodeMigrate",
259      [ pNodeName
260      , pMigrationMode
261      , pMigrationLive
262      , pMigrationTargetNode
263      , pAllowRuntimeChgs
264      , pIgnoreIpolicy
265      , pIallocator
266      ])
267   , ("OpNodeEvacuate",
268      [ pEarlyRelease
269      , pNodeName
270      , pRemoteNode
271      , pIallocator
272      , pEvacMode
273      ])
274   , ("OpInstanceCreate",
275      [ pInstanceName
276      , pForceVariant
277      , pWaitForSync
278      , pNameCheck
279      , pIgnoreIpolicy
280      , pInstBeParams
281      , pInstDisks
282      , pDiskTemplate
283      , pFileDriver
284      , pFileStorageDir
285      , pInstHvParams
286      , pHypervisor
287      , pIallocator
288      , pResetDefaults
289      , pIpCheck
290      , pIpConflictsCheck
291      , pInstCreateMode
292      , pInstNics
293      , pNoInstall
294      , pInstOsParams
295      , pInstOs
296      , pPrimaryNode
297      , pSecondaryNode
298      , pSourceHandshake
299      , pSourceInstance
300      , pSourceShutdownTimeout
301      , pSourceX509Ca
302      , pSrcNode
303      , pSrcPath
304      , pStartInstance
305      , pOpportunisticLocking
306      , pInstTags
307      ])
308   , ("OpInstanceMultiAlloc",
309      [ pIallocator
310      , pMultiAllocInstances
311      , pOpportunisticLocking
312      ])
313   , ("OpInstanceReinstall",
314      [ pInstanceName
315      , pForceVariant
316      , pInstOs
317      , pTempOsParams
318      ])
319   , ("OpInstanceSnapshot",
320      [ pInstanceName
321      , pInstSnaps
322      ])
323   , ("OpInstanceRemove",
324      [ pInstanceName
325      , pShutdownTimeout
326      , pIgnoreFailures
327      , pKeepDisks
328      ])
329   , ("OpInstanceRename",
330      [ pInstanceName
331      , pNewName
332      , pNameCheck
333      , pIpCheck
334      ])
335   , ("OpInstanceStartup",
336      [ pInstanceName
337      , pForce
338      , pIgnoreOfflineNodes
339      , pTempHvParams
340      , pTempBeParams
341      , pNoRemember
342      , pStartupPaused
343      ])
344   , ("OpInstanceShutdown",
345      [ pInstanceName
346      , pForce
347      , pIgnoreOfflineNodes
348      , pShutdownTimeout'
349      , pNoRemember
350      ])
351   , ("OpInstanceReboot",
352      [ pInstanceName
353      , pShutdownTimeout
354      , pIgnoreSecondaries
355      , pRebootType
356      ])
357   , ("OpInstanceMove",
358      [ pInstanceName
359      , pShutdownTimeout
360      , pIgnoreIpolicy
361      , pMoveTargetNode
362      , pIgnoreConsistency
363      ])
364   , ("OpInstanceConsole",
365      [ pInstanceName ])
366   , ("OpInstanceActivateDisks",
367      [ pInstanceName
368      , pIgnoreDiskSize
369      , pWaitForSyncFalse
370      ])
371   , ("OpInstanceDeactivateDisks",
372      [ pInstanceName
373      , pForce
374      ])
375   , ("OpInstanceRecreateDisks",
376      [ pInstanceName
377      , pRecreateDisksInfo
378      , pNodes
379      , pIallocator
380      ])
381   , ("OpInstanceQuery", dOldQuery)
382   , ("OpInstanceQueryData",
383      [ pUseLocking
384      , pInstances
385      , pStatic
386      ])
387   , ("OpInstanceSetParams",
388      [ pInstanceName
389      , pForce
390      , pForceVariant
391      , pIgnoreIpolicy
392      , pInstParamsNicChanges
393      , pInstParamsDiskChanges
394      , pInstBeParams
395      , pRuntimeMem
396      , pInstHvParams
397      , pOptDiskTemplate
398      , pPrimaryNode
399      , pRemoteNode
400      , pOsNameChange
401      , pInstOsParams
402      , pWaitForSync
403      , pOffline
404      , pIpConflictsCheck
405      , pHotplug
406      , pKeepDisks
407      ])
408   , ("OpInstanceGrowDisk",
409      [ pInstanceName
410      , pWaitForSync
411      , pDiskIndex
412      , pDiskChgAmount
413      , pDiskChgAbsolute
414      ])
415   , ("OpInstanceChangeGroup",
416      [ pInstanceName
417      , pEarlyRelease
418      , pIallocator
419      , pTargetGroups
420      ])
421   , ("OpGroupAdd",
422      [ pGroupName
423      , pNodeGroupAllocPolicy
424      , pGroupNodeParams
425      , pDiskParams
426      , pHvState
427      , pDiskState
428      , pIpolicy
429      ])
430   , ("OpGroupAssignNodes",
431      [ pGroupName
432      , pForce
433      , pRequiredNodes
434      ])
435   , ("OpGroupQuery", dOldQueryNoLocking)
436   , ("OpGroupSetParams",
437      [ pGroupName
438      , pNodeGroupAllocPolicy
439      , pGroupNodeParams
440      , pDiskParams
441      , pHvState
442      , pDiskState
443      , pIpolicy
444      ])
445   , ("OpGroupRemove",
446      [ pGroupName ])
447   , ("OpGroupRename",
448      [ pGroupName
449      , pNewName
450      ])
451   , ("OpGroupEvacuate",
452      [ pGroupName
453      , pEarlyRelease
454      , pIallocator
455      , pTargetGroups
456      ])
457   , ("OpOsDiagnose",
458      [ pOutputFields
459      , pNames ])
460   , ("OpExtStorageDiagnose",
461      [ pOutputFields
462      , pNames ])
463   , ("OpBackupQuery",
464      [ pUseLocking
465      , pNodes
466      ])
467   , ("OpBackupPrepare",
468      [ pInstanceName
469      , pExportMode
470      ])
471   , ("OpBackupExport",
472      [ pInstanceName
473      , pShutdownTimeout
474      , pExportTargetNode
475      , pShutdownInstance
476      , pRemoveInstance
477      , pIgnoreRemoveFailures
478      , pExportMode
479      , pX509KeyName
480      , pX509DestCA
481      ])
482   , ("OpBackupRemove",
483      [ pInstanceName ])
484   , ("OpTestAllocator",
485      [ pIAllocatorDirection
486      , pIAllocatorMode
487      , pIAllocatorReqName
488      , pIAllocatorNics
489      , pIAllocatorDisks
490      , pHypervisor
491      , pIallocator
492      , pInstTags
493      , pIAllocatorMemory
494      , pIAllocatorVCpus
495      , pIAllocatorOs
496      , pDiskTemplate
497      , pIAllocatorInstances
498      , pIAllocatorEvacMode
499      , pTargetGroups
500      , pIAllocatorSpindleUse
501      , pIAllocatorCount
502      ])
503   , ("OpTestJqueue",
504      [ pJQueueNotifyWaitLock
505      , pJQueueNotifyExec
506      , pJQueueLogMessages
507      , pJQueueFail
508      ])
509   , ("OpTestDummy",
510      [ pTestDummyResult
511      , pTestDummyMessages
512      , pTestDummyFail
513      , pTestDummySubmitJobs
514      ])
515   , ("OpNetworkAdd",
516      [ pNetworkName
517      , pNetworkAddress4
518      , pNetworkGateway4
519      , pNetworkAddress6
520      , pNetworkGateway6
521      , pNetworkMacPrefix
522      , pNetworkAddRsvdIps
523      , pIpConflictsCheck
524      , pInstTags
525      ])
526   , ("OpNetworkRemove",
527      [ pNetworkName
528      , pForce
529      ])
530   , ("OpNetworkSetParams",
531      [ pNetworkName
532      , pNetworkGateway4
533      , pNetworkAddress6
534      , pNetworkGateway6
535      , pNetworkMacPrefix
536      , pNetworkAddRsvdIps
537      , pNetworkRemoveRsvdIps
538      ])
539   , ("OpNetworkConnect",
540      [ pGroupName
541      , pNetworkName
542      , pNetworkMode
543      , pNetworkLink
544      , pIpConflictsCheck
545      ])
546   , ("OpNetworkDisconnect",
547      [ pGroupName
548      , pNetworkName
549      ])
550   , ("OpNetworkQuery", dOldQuery)
551   , ("OpRestrictedCommand",
552      [ pUseLocking
553      , pRequiredNodes
554      , pRestrictedCommand
555      ])
556   ])
557
558 -- | Returns the OP_ID for a given opcode value.
559 $(genOpID ''OpCode "opID")
560
561 -- | A list of all defined/supported opcode IDs.
562 $(genAllOpIDs ''OpCode "allOpIDs")
563
564 instance JSON OpCode where
565   readJSON = loadOpCode
566   showJSON = saveOpCode
567
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
624
625 -- | Computes the summary of the opcode.
626 opSummary :: OpCode -> String
627 opSummary op =
628   case opSummaryVal op of
629     Nothing -> op_suffix
630     Just s -> op_suffix ++ "(" ++ s ++ ")"
631   where op_suffix = drop 3 $ opID op
632
633 -- | Generic\/common opcode parameters.
634 $(buildObject "CommonOpParams" "op"
635   [ pDryRun
636   , pDebugLevel
637   , pOpPriority
638   , pDependencies
639   , pComment
640   , pReason
641   ])
642
643 -- | Default common parameter values.
644 defOpParams :: CommonOpParams
645 defOpParams =
646   CommonOpParams { opDryRun     = Nothing
647                  , opDebugLevel = Nothing
648                  , opPriority   = OpPrioNormal
649                  , opDepends    = Nothing
650                  , opComment    = Nothing
651                  , opReason     = []
652                  }
653
654 -- | The top-level opcode type.
655 data MetaOpCode = MetaOpCode { metaParams :: CommonOpParams
656                              , metaOpCode :: OpCode
657                              } deriving (Show, Eq)
658
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)
665
666 -- | JSON deserialisation for 'MetaOpCode'
667 readMeta :: JSValue -> Text.JSON.Result MetaOpCode
668 readMeta v = do
669   meta <- readJSON v
670   op <- readJSON v
671   return $ MetaOpCode meta op
672
673 instance JSON MetaOpCode where
674   showJSON = showMeta
675   readJSON = readMeta
676
677 -- | Wraps an 'OpCode' with the default parameters to build a
678 -- 'MetaOpCode'.
679 wrapOpCode :: OpCode -> MetaOpCode
680 wrapOpCode = MetaOpCode defOpParams
681
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
686
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