Add cleanup parameter to instance failover
[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   , ("OpInstanceRemove",
320      [ pInstanceName
321      , pShutdownTimeout
322      , pIgnoreFailures
323      ])
324   , ("OpInstanceRename",
325      [ pInstanceName
326      , pNewName
327      , pNameCheck
328      , pIpCheck
329      ])
330   , ("OpInstanceStartup",
331      [ pInstanceName
332      , pForce
333      , pIgnoreOfflineNodes
334      , pTempHvParams
335      , pTempBeParams
336      , pNoRemember
337      , pStartupPaused
338      ])
339   , ("OpInstanceShutdown",
340      [ pInstanceName
341      , pForce
342      , pIgnoreOfflineNodes
343      , pShutdownTimeout'
344      , pNoRemember
345      ])
346   , ("OpInstanceReboot",
347      [ pInstanceName
348      , pShutdownTimeout
349      , pIgnoreSecondaries
350      , pRebootType
351      ])
352   , ("OpInstanceMove",
353      [ pInstanceName
354      , pShutdownTimeout
355      , pIgnoreIpolicy
356      , pMoveTargetNode
357      , pIgnoreConsistency
358      ])
359   , ("OpInstanceConsole",
360      [ pInstanceName ])
361   , ("OpInstanceActivateDisks",
362      [ pInstanceName
363      , pIgnoreDiskSize
364      , pWaitForSyncFalse
365      ])
366   , ("OpInstanceDeactivateDisks",
367      [ pInstanceName
368      , pForce
369      ])
370   , ("OpInstanceRecreateDisks",
371      [ pInstanceName
372      , pRecreateDisksInfo
373      , pNodes
374      , pIallocator
375      ])
376   , ("OpInstanceQuery", dOldQuery)
377   , ("OpInstanceQueryData",
378      [ pUseLocking
379      , pInstances
380      , pStatic
381      ])
382   , ("OpInstanceSetParams",
383      [ pInstanceName
384      , pForce
385      , pForceVariant
386      , pIgnoreIpolicy
387      , pInstParamsNicChanges
388      , pInstParamsDiskChanges
389      , pInstBeParams
390      , pRuntimeMem
391      , pInstHvParams
392      , pOptDiskTemplate
393      , pPrimaryNode
394      , pRemoteNode
395      , pOsNameChange
396      , pInstOsParams
397      , pWaitForSync
398      , pOffline
399      , pIpConflictsCheck
400      ])
401   , ("OpInstanceGrowDisk",
402      [ pInstanceName
403      , pWaitForSync
404      , pDiskIndex
405      , pDiskChgAmount
406      , pDiskChgAbsolute
407      ])
408   , ("OpInstanceChangeGroup",
409      [ pInstanceName
410      , pEarlyRelease
411      , pIallocator
412      , pTargetGroups
413      ])
414   , ("OpGroupAdd",
415      [ pGroupName
416      , pNodeGroupAllocPolicy
417      , pGroupNodeParams
418      , pDiskParams
419      , pHvState
420      , pDiskState
421      , pIpolicy
422      ])
423   , ("OpGroupAssignNodes",
424      [ pGroupName
425      , pForce
426      , pRequiredNodes
427      ])
428   , ("OpGroupQuery", dOldQueryNoLocking)
429   , ("OpGroupSetParams",
430      [ pGroupName
431      , pNodeGroupAllocPolicy
432      , pGroupNodeParams
433      , pDiskParams
434      , pHvState
435      , pDiskState
436      , pIpolicy
437      ])
438   , ("OpGroupRemove",
439      [ pGroupName ])
440   , ("OpGroupRename",
441      [ pGroupName
442      , pNewName
443      ])
444   , ("OpGroupEvacuate",
445      [ pGroupName
446      , pEarlyRelease
447      , pIallocator
448      , pTargetGroups
449      ])
450   , ("OpOsDiagnose",
451      [ pOutputFields
452      , pNames ])
453   , ("OpExtStorageDiagnose",
454      [ pOutputFields
455      , pNames ])
456   , ("OpBackupQuery",
457      [ pUseLocking
458      , pNodes
459      ])
460   , ("OpBackupPrepare",
461      [ pInstanceName
462      , pExportMode
463      ])
464   , ("OpBackupExport",
465      [ pInstanceName
466      , pShutdownTimeout
467      , pExportTargetNode
468      , pShutdownInstance
469      , pRemoveInstance
470      , pIgnoreRemoveFailures
471      , pExportMode
472      , pX509KeyName
473      , pX509DestCA
474      ])
475   , ("OpBackupRemove",
476      [ pInstanceName ])
477   , ("OpTestAllocator",
478      [ pIAllocatorDirection
479      , pIAllocatorMode
480      , pIAllocatorReqName
481      , pIAllocatorNics
482      , pIAllocatorDisks
483      , pHypervisor
484      , pIallocator
485      , pInstTags
486      , pIAllocatorMemory
487      , pIAllocatorVCpus
488      , pIAllocatorOs
489      , pDiskTemplate
490      , pIAllocatorInstances
491      , pIAllocatorEvacMode
492      , pTargetGroups
493      , pIAllocatorSpindleUse
494      , pIAllocatorCount
495      ])
496   , ("OpTestJqueue",
497      [ pJQueueNotifyWaitLock
498      , pJQueueNotifyExec
499      , pJQueueLogMessages
500      , pJQueueFail
501      ])
502   , ("OpTestDummy",
503      [ pTestDummyResult
504      , pTestDummyMessages
505      , pTestDummyFail
506      , pTestDummySubmitJobs
507      ])
508   , ("OpNetworkAdd",
509      [ pNetworkName
510      , pNetworkAddress4
511      , pNetworkGateway4
512      , pNetworkAddress6
513      , pNetworkGateway6
514      , pNetworkMacPrefix
515      , pNetworkAddRsvdIps
516      , pIpConflictsCheck
517      , pInstTags
518      ])
519   , ("OpNetworkRemove",
520      [ pNetworkName
521      , pForce
522      ])
523   , ("OpNetworkSetParams",
524      [ pNetworkName
525      , pNetworkGateway4
526      , pNetworkAddress6
527      , pNetworkGateway6
528      , pNetworkMacPrefix
529      , pNetworkAddRsvdIps
530      , pNetworkRemoveRsvdIps
531      ])
532   , ("OpNetworkConnect",
533      [ pGroupName
534      , pNetworkName
535      , pNetworkMode
536      , pNetworkLink
537      , pIpConflictsCheck
538      ])
539   , ("OpNetworkDisconnect",
540      [ pGroupName
541      , pNetworkName
542      ])
543   , ("OpNetworkQuery", dOldQuery)
544   , ("OpRestrictedCommand",
545      [ pUseLocking
546      , pRequiredNodes
547      , pRestrictedCommand
548      ])
549   ])
550
551 -- | Returns the OP_ID for a given opcode value.
552 $(genOpID ''OpCode "opID")
553
554 -- | A list of all defined/supported opcode IDs.
555 $(genAllOpIDs ''OpCode "allOpIDs")
556
557 instance JSON OpCode where
558   readJSON = loadOpCode
559   showJSON = saveOpCode
560
561 -- | Generates the summary value for an opcode.
562 opSummaryVal :: OpCode -> Maybe String
563 opSummaryVal OpClusterVerifyGroup { opGroupName = s } = Just (fromNonEmpty s)
564 opSummaryVal OpGroupVerifyDisks { opGroupName = s } = Just (fromNonEmpty s)
565 opSummaryVal OpClusterRename { opName = s } = Just (fromNonEmpty s)
566 opSummaryVal OpQuery { opWhat = s } = Just (queryTypeOpToRaw s)
567 opSummaryVal OpQueryFields { opWhat = s } = Just (queryTypeOpToRaw s)
568 opSummaryVal OpNodeRemove { opNodeName = s } = Just (fromNonEmpty s)
569 opSummaryVal OpNodeAdd { opNodeName = s } = Just (fromNonEmpty s)
570 opSummaryVal OpNodeModifyStorage { opNodeName = s } = Just (fromNonEmpty s)
571 opSummaryVal OpRepairNodeStorage  { opNodeName = s } = Just (fromNonEmpty s)
572 opSummaryVal OpNodeSetParams { opNodeName = s } = Just (fromNonEmpty s)
573 opSummaryVal OpNodePowercycle { opNodeName = s } = Just (fromNonEmpty s)
574 opSummaryVal OpNodeMigrate { opNodeName = s } = Just (fromNonEmpty s)
575 opSummaryVal OpNodeEvacuate { opNodeName = s } = Just (fromNonEmpty s)
576 opSummaryVal OpInstanceCreate { opInstanceName = s } = Just s
577 opSummaryVal OpInstanceReinstall { opInstanceName = s } = Just s
578 opSummaryVal OpInstanceRemove { opInstanceName = s } = Just s
579 -- FIXME: instance rename should show both names; currently it shows none
580 -- opSummaryVal OpInstanceRename { opInstanceName = s } = Just s
581 opSummaryVal OpInstanceStartup { opInstanceName = s } = Just s
582 opSummaryVal OpInstanceShutdown { opInstanceName = s } = Just s
583 opSummaryVal OpInstanceReboot { opInstanceName = s } = Just s
584 opSummaryVal OpInstanceReplaceDisks { opInstanceName = s } = Just s
585 opSummaryVal OpInstanceFailover { opInstanceName = s } = Just s
586 opSummaryVal OpInstanceMigrate { opInstanceName = s } = Just s
587 opSummaryVal OpInstanceMove { opInstanceName = s } = Just s
588 opSummaryVal OpInstanceConsole { opInstanceName = s } = Just s
589 opSummaryVal OpInstanceActivateDisks { opInstanceName = s } = Just s
590 opSummaryVal OpInstanceDeactivateDisks { opInstanceName = s } = Just s
591 opSummaryVal OpInstanceRecreateDisks { opInstanceName = s } = Just s
592 opSummaryVal OpInstanceSetParams { opInstanceName = s } = Just s
593 opSummaryVal OpInstanceGrowDisk { opInstanceName = s } = Just s
594 opSummaryVal OpInstanceChangeGroup { opInstanceName = s } = Just s
595 opSummaryVal OpGroupAdd { opGroupName = s } = Just (fromNonEmpty s)
596 opSummaryVal OpGroupAssignNodes { opGroupName = s } = Just (fromNonEmpty s)
597 opSummaryVal OpGroupSetParams { opGroupName = s } = Just (fromNonEmpty s)
598 opSummaryVal OpGroupRemove { opGroupName = s } = Just (fromNonEmpty s)
599 opSummaryVal OpGroupEvacuate { opGroupName = s } = Just (fromNonEmpty s)
600 opSummaryVal OpBackupPrepare { opInstanceName = s } = Just s
601 opSummaryVal OpBackupExport { opInstanceName = s } = Just s
602 opSummaryVal OpBackupRemove { opInstanceName = s } = Just s
603 opSummaryVal OpTagsGet { opKind = k } =
604   Just . fromMaybe "None" $ tagNameOf k
605 opSummaryVal OpTagsSearch { opTagSearchPattern = s } = Just (fromNonEmpty s)
606 opSummaryVal OpTestDelay { opDelayDuration = d } = Just (show d)
607 opSummaryVal OpTestAllocator { opIallocator = s } =
608   -- FIXME: Python doesn't handle None fields well, so we have behave the same
609   Just $ maybe "None" fromNonEmpty s
610 opSummaryVal OpNetworkAdd { opNetworkName = s} = Just (fromNonEmpty s)
611 opSummaryVal OpNetworkRemove { opNetworkName = s} = Just (fromNonEmpty s)
612 opSummaryVal OpNetworkSetParams { opNetworkName = s} = Just (fromNonEmpty s)
613 opSummaryVal OpNetworkConnect { opNetworkName = s} = Just (fromNonEmpty s)
614 opSummaryVal OpNetworkDisconnect { opNetworkName = s} = Just (fromNonEmpty s)
615 opSummaryVal _ = Nothing
616
617 -- | Computes the summary of the opcode.
618 opSummary :: OpCode -> String
619 opSummary op =
620   case opSummaryVal op of
621     Nothing -> op_suffix
622     Just s -> op_suffix ++ "(" ++ s ++ ")"
623   where op_suffix = drop 3 $ opID op
624
625 -- | Generic\/common opcode parameters.
626 $(buildObject "CommonOpParams" "op"
627   [ pDryRun
628   , pDebugLevel
629   , pOpPriority
630   , pDependencies
631   , pComment
632   , pReason
633   ])
634
635 -- | Default common parameter values.
636 defOpParams :: CommonOpParams
637 defOpParams =
638   CommonOpParams { opDryRun     = Nothing
639                  , opDebugLevel = Nothing
640                  , opPriority   = OpPrioNormal
641                  , opDepends    = Nothing
642                  , opComment    = Nothing
643                  , opReason     = []
644                  }
645
646 -- | The top-level opcode type.
647 data MetaOpCode = MetaOpCode { metaParams :: CommonOpParams
648                              , metaOpCode :: OpCode
649                              } deriving (Show, Eq)
650
651 -- | JSON serialisation for 'MetaOpCode'.
652 showMeta :: MetaOpCode -> JSValue
653 showMeta (MetaOpCode params op) =
654   let objparams = toDictCommonOpParams params
655       objop = toDictOpCode op
656   in makeObj (objparams ++ objop)
657
658 -- | JSON deserialisation for 'MetaOpCode'
659 readMeta :: JSValue -> Text.JSON.Result MetaOpCode
660 readMeta v = do
661   meta <- readJSON v
662   op <- readJSON v
663   return $ MetaOpCode meta op
664
665 instance JSON MetaOpCode where
666   showJSON = showMeta
667   readJSON = readMeta
668
669 -- | Wraps an 'OpCode' with the default parameters to build a
670 -- 'MetaOpCode'.
671 wrapOpCode :: OpCode -> MetaOpCode
672 wrapOpCode = MetaOpCode defOpParams
673
674 -- | Sets the comment on a meta opcode.
675 setOpComment :: String -> MetaOpCode -> MetaOpCode
676 setOpComment comment (MetaOpCode common op) =
677   MetaOpCode (common { opComment = Just comment}) op
678
679 -- | Sets the priority on a meta opcode.
680 setOpPriority :: OpSubmitPriority -> MetaOpCode -> MetaOpCode
681 setOpPriority prio (MetaOpCode common op) =
682   MetaOpCode (common { opPriority = prio }) op