Statistics
| Branch: | Tag: | Revision:

root / src / Ganeti / OpCodes.hs @ f665d9de

History | View | Annotate | Download (27.4 kB)

1
{-# LANGUAGE ExistentialQuantification, TemplateHaskell #-}
2
{-# OPTIONS_GHC -fno-warn-orphans #-}
3

    
4
{-| Implementation of the opcodes.
5

    
6
-}
7

    
8
{-
9

    
10
Copyright (C) 2009, 2010, 2011, 2012, 2013 Google Inc.
11

    
12
This program is free software; you can redistribute it and/or modify
13
it under the terms of the GNU General Public License as published by
14
the Free Software Foundation; either version 2 of the License, or
15
(at your option) any later version.
16

    
17
This program is distributed in the hope that it will be useful, but
18
WITHOUT ANY WARRANTY; without even the implied warranty of
19
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20
General Public License for more details.
21

    
22
You should have received a copy of the GNU General Public License
23
along with this program; if not, write to the Free Software
24
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25
02110-1301, USA.
26

    
27
-}
28

    
29
module Ganeti.OpCodes
30
  ( pyClasses
31
  , OpCode(..)
32
  , ReplaceDisksMode(..)
33
  , DiskIndex
34
  , mkDiskIndex
35
  , unDiskIndex
36
  , opID
37
  , allOpIDs
38
  , allOpFields
39
  , opSummary
40
  , CommonOpParams(..)
41
  , defOpParams
42
  , MetaOpCode(..)
43
  , wrapOpCode
44
  , setOpComment
45
  , setOpPriority
46
  ) where
47

    
48
import Text.JSON (readJSON, JSObject, JSON, JSValue(..), makeObj, fromJSObject)
49
import qualified Text.JSON
50

    
51
import Ganeti.THH
52

    
53
import qualified Ganeti.Hs2Py.OpDoc as OpDoc
54
import Ganeti.OpParams
55
import Ganeti.PyValueInstances ()
56
import Ganeti.Types
57
import Ganeti.Query.Language (queryTypeOpToRaw)
58

    
59
import Data.List (intercalate)
60
import Data.Map (Map)
61

    
62
import qualified Ganeti.Constants as C
63

    
64
instance PyValue DiskIndex where
65
  showValue = showValue . unDiskIndex
66

    
67
instance PyValue IDiskParams where
68
  showValue _ = error "OpCodes.showValue(IDiskParams): unhandled case"
69

    
70
instance PyValue RecreateDisksInfo where
71
  showValue RecreateDisksAll = "[]"
72
  showValue (RecreateDisksIndices is) = showValue is
73
  showValue (RecreateDisksParams is) = showValue is
74

    
75
instance PyValue a => PyValue (SetParamsMods a) where
76
  showValue SetParamsEmpty = "[]"
77
  showValue _ = error "OpCodes.showValue(SetParamsMods): unhandled case"
78

    
79
instance PyValue a => PyValue (NonNegative a) where
80
  showValue = showValue . fromNonNegative
81

    
82
instance PyValue a => PyValue (NonEmpty a) where
83
  showValue = showValue . fromNonEmpty
84

    
85
-- FIXME: should use the 'toRaw' function instead of being harcoded or
86
-- perhaps use something similar to the NonNegative type instead of
87
-- using the declareSADT
88
instance PyValue ExportMode where
89
  showValue ExportModeLocal = show C.exportModeLocal
90
  showValue ExportModeRemote = show C.exportModeLocal
91

    
92
instance PyValue CVErrorCode where
93
  showValue = cVErrorCodeToRaw
94

    
95
instance PyValue VerifyOptionalChecks where
96
  showValue = verifyOptionalChecksToRaw
97

    
98
instance PyValue INicParams where
99
  showValue = error "instance PyValue INicParams: not implemented"
100

    
101
instance PyValue a => PyValue (JSObject a) where
102
  showValue obj =
103
    "{" ++ intercalate ", " (map showPair (fromJSObject obj)) ++ "}"
104
    where showPair (k, v) = show k ++ ":" ++ showValue v
105

    
106
instance PyValue JSValue where
107
  showValue (JSObject obj) = showValue obj
108
  showValue x = show x
109

    
110
type JobIdListOnly = Map String [(Bool, Either String JobId)]
111

    
112
type InstanceMultiAllocResponse =
113
  ([(Bool, Either String JobId)], NonEmptyString)
114

    
115
type QueryFieldDef =
116
  (NonEmptyString, NonEmptyString, TagKind, NonEmptyString)
117

    
118
type QueryResponse =
119
  ([QueryFieldDef], [[(QueryResultCode, JSValue)]])
120

    
121
type QueryFieldsResponse = [QueryFieldDef]
122

    
123
-- | OpCode representation.
124
--
125
-- We only implement a subset of Ganeti opcodes: those which are actually used
126
-- in the htools codebase.
127
$(genOpCode "OpCode"
128
  [ ("OpClusterPostInit",
129
     [t| Bool |],
130
     OpDoc.opClusterPostInit,
131
     [],
132
     [])
133
  , ("OpClusterDestroy",
134
     [t| NonEmptyString |],
135
     OpDoc.opClusterDestroy,
136
     [],
137
     [])
138
  , ("OpClusterQuery",
139
     [t| JSObject JSValue |],
140
     OpDoc.opClusterQuery,
141
     [],
142
     [])
143
  , ("OpClusterVerify",
144
     [t| JobIdListOnly |],
145
     OpDoc.opClusterVerify,
146
     [ pDebugSimulateErrors
147
     , pErrorCodes
148
     , pSkipChecks
149
     , pIgnoreErrors
150
     , pVerbose
151
     , pOptGroupName
152
     ],
153
     [])
154
  , ("OpClusterVerifyConfig",
155
     [t| Bool |],
156
     OpDoc.opClusterVerifyConfig,
157
     [ pDebugSimulateErrors
158
     , pErrorCodes
159
     , pIgnoreErrors
160
     , pVerbose
161
     ],
162
     [])
163
  , ("OpClusterVerifyGroup",
164
     [t| Bool |],
165
     OpDoc.opClusterVerifyGroup,
166
     [ pGroupName
167
     , pDebugSimulateErrors
168
     , pErrorCodes
169
     , pSkipChecks
170
     , pIgnoreErrors
171
     , pVerbose
172
     ],
173
     "group_name")
174
  , ("OpClusterVerifyDisks",
175
     [t| JobIdListOnly |],
176
     OpDoc.opClusterVerifyDisks,
177
     [],
178
     [])
179
  , ("OpGroupVerifyDisks",
180
     [t| (Map String String, [String], Map String [[String]]) |],
181
     OpDoc.opGroupVerifyDisks,
182
     [ pGroupName
183
     ],
184
     "group_name")
185
  , ("OpClusterRepairDiskSizes",
186
     [t| [(NonEmptyString, NonNegative Int, NonEmptyString, NonNegative Int)]|],
187
     OpDoc.opClusterRepairDiskSizes,
188
     [ pInstances
189
     ],
190
     [])
191
  , ("OpClusterConfigQuery",
192
     [t| [JSValue] |],
193
     OpDoc.opClusterConfigQuery,
194
     [ pOutputFields
195
     ],
196
     [])
197
  , ("OpClusterRename",
198
      [t| NonEmptyString |],
199
      OpDoc.opClusterRename,
200
     [ pName
201
     ],
202
     "name")
203
  , ("OpClusterSetParams",
204
     [t| () |],
205
     OpDoc.opClusterSetParams,
206
     [ pForce
207
     , pHvState
208
     , pDiskState
209
     , pVgName
210
     , pEnabledHypervisors
211
     , pClusterHvParams
212
     , pClusterBeParams
213
     , pOsHvp
214
     , pClusterOsParams
215
     , pGroupDiskParams
216
     , pCandidatePoolSize
217
     , pUidPool
218
     , pAddUids
219
     , pRemoveUids
220
     , pMaintainNodeHealth
221
     , pPreallocWipeDisks
222
     , pNicParams
223
     , withDoc "Cluster-wide node parameter defaults" pNdParams
224
     , withDoc "Cluster-wide ipolicy specs" pIpolicy
225
     , pDrbdHelper
226
     , pDefaultIAllocator
227
     , pMasterNetdev
228
     , pMasterNetmask
229
     , pReservedLvs
230
     , pHiddenOs
231
     , pBlacklistedOs
232
     , pUseExternalMipScript
233
     , pEnabledDiskTemplates
234
     , pModifyEtcHosts
235
     , pClusterFileStorageDir
236
     , pClusterSharedFileStorageDir
237
     ],
238
     [])
239
  , ("OpClusterRedistConf",
240
     [t| () |],
241
     OpDoc.opClusterRedistConf,
242
     [],
243
     [])
244
  , ("OpClusterActivateMasterIp",
245
     [t| () |],
246
     OpDoc.opClusterActivateMasterIp,
247
     [],
248
     [])
249
  , ("OpClusterDeactivateMasterIp",
250
     [t| () |],
251
     OpDoc.opClusterDeactivateMasterIp,
252
     [],
253
     [])
254
  , ("OpQuery",
255
     [t| QueryResponse |],
256
     OpDoc.opQuery,
257
     [ pQueryWhat
258
     , pUseLocking
259
     , pQueryFields
260
     , pQueryFilter
261
     ],
262
     "what")
263
  , ("OpQueryFields",
264
     [t| QueryFieldsResponse |],
265
     OpDoc.opQueryFields,
266
     [ pQueryWhat
267
     , pQueryFieldsFields
268
     ],
269
     "what")
270
  , ("OpOobCommand",
271
     [t| [[(QueryResultCode, JSValue)]] |],
272
     OpDoc.opOobCommand,
273
     [ pNodeNames
274
     , withDoc "List of node UUIDs to run the OOB command against" pNodeUuids
275
     , pOobCommand
276
     , pOobTimeout
277
     , pIgnoreStatus
278
     , pPowerDelay
279
     ],
280
     [])
281
  , ("OpRestrictedCommand",
282
     [t| [(Bool, String)] |],
283
     OpDoc.opRestrictedCommand,
284
     [ pUseLocking
285
     , withDoc
286
       "Nodes on which the command should be run (at least one)"
287
       pRequiredNodes
288
     , withDoc
289
       "Node UUIDs on which the command should be run (at least one)"
290
       pRequiredNodeUuids
291
     , pRestrictedCommand
292
     ],
293
     [])
294
  , ("OpNodeRemove",
295
     [t| () |],
296
      OpDoc.opNodeRemove,
297
     [ pNodeName
298
     , pNodeUuid
299
     ],
300
     "node_name")
301
  , ("OpNodeAdd",
302
     [t| () |],
303
      OpDoc.opNodeAdd,
304
     [ pNodeName
305
     , pHvState
306
     , pDiskState
307
     , pPrimaryIp
308
     , pSecondaryIp
309
     , pReadd
310
     , pNodeGroup
311
     , pMasterCapable
312
     , pVmCapable
313
     , pNdParams
314
     ],
315
     "node_name")
316
  , ("OpNodeQuery",
317
     [t| [[JSValue]] |],
318
     OpDoc.opNodeQuery,
319
     [ pOutputFields
320
     , withDoc "Empty list to query all nodes, node names otherwise" pNames
321
     , pUseLocking
322
     ],
323
     [])
324
  , ("OpNodeQueryvols",
325
     [t| [JSValue] |],
326
     OpDoc.opNodeQueryvols,
327
     [ pOutputFields
328
     , withDoc "Empty list to query all nodes, node names otherwise" pNodes
329
     ],
330
     [])
331
  , ("OpNodeQueryStorage",
332
     [t| [[JSValue]] |],
333
     OpDoc.opNodeQueryStorage,
334
     [ pOutputFields
335
     , pStorageTypeOptional
336
     , withDoc
337
       "Empty list to query all, list of names to query otherwise"
338
       pNodes
339
     , pStorageName
340
     ],
341
     [])
342
  , ("OpNodeModifyStorage",
343
     [t| () |],
344
     OpDoc.opNodeModifyStorage,
345
     [ pNodeName
346
     , pNodeUuid
347
     , pStorageType
348
     , pStorageName
349
     , pStorageChanges
350
     ],
351
     "node_name")
352
  , ("OpRepairNodeStorage",
353
      [t| () |],
354
      OpDoc.opRepairNodeStorage,
355
     [ pNodeName
356
     , pNodeUuid
357
     , pStorageType
358
     , pStorageName
359
     , pIgnoreConsistency
360
     ],
361
     "node_name")
362
  , ("OpNodeSetParams",
363
     [t| [(NonEmptyString, JSValue)] |],
364
     OpDoc.opNodeSetParams,
365
     [ pNodeName
366
     , pNodeUuid
367
     , pForce
368
     , pHvState
369
     , pDiskState
370
     , pMasterCandidate
371
     , withDoc "Whether to mark the node offline" pOffline
372
     , pDrained
373
     , pAutoPromote
374
     , pMasterCapable
375
     , pVmCapable
376
     , pSecondaryIp
377
     , pNdParams
378
     , pPowered
379
     ],
380
     "node_name")
381
  , ("OpNodePowercycle",
382
     [t| Maybe NonEmptyString |],
383
     OpDoc.opNodePowercycle,
384
     [ pNodeName
385
     , pNodeUuid
386
     , pForce
387
     ],
388
     "node_name")
389
  , ("OpNodeMigrate",
390
     [t| JobIdListOnly |],
391
     OpDoc.opNodeMigrate,
392
     [ pNodeName
393
     , pNodeUuid
394
     , pMigrationMode
395
     , pMigrationLive
396
     , pMigrationTargetNode
397
     , pMigrationTargetNodeUuid
398
     , pAllowRuntimeChgs
399
     , pIgnoreIpolicy
400
     , pIallocator
401
     ],
402
     "node_name")
403
  , ("OpNodeEvacuate",
404
     [t| JobIdListOnly |],
405
     OpDoc.opNodeEvacuate,
406
     [ pEarlyRelease
407
     , pNodeName
408
     , pNodeUuid
409
     , pRemoteNode
410
     , pRemoteNodeUuid
411
     , pIallocator
412
     , pEvacMode
413
     ],
414
     "node_name")
415
  , ("OpInstanceCreate",
416
     [t| [NonEmptyString] |],
417
     OpDoc.opInstanceCreate,
418
     [ pInstanceName
419
     , pForceVariant
420
     , pWaitForSync
421
     , pNameCheck
422
     , pIgnoreIpolicy
423
     , pOpportunisticLocking
424
     , pInstBeParams
425
     , pInstDisks
426
     , pOptDiskTemplate
427
     , pFileDriver
428
     , pFileStorageDir
429
     , pInstHvParams
430
     , pHypervisor
431
     , pIallocator
432
     , pResetDefaults
433
     , pIpCheck
434
     , pIpConflictsCheck
435
     , pInstCreateMode
436
     , pInstNics
437
     , pNoInstall
438
     , pInstOsParams
439
     , pInstOs
440
     , pPrimaryNode
441
     , pPrimaryNodeUuid
442
     , pSecondaryNode
443
     , pSecondaryNodeUuid
444
     , pSourceHandshake
445
     , pSourceInstance
446
     , pSourceShutdownTimeout
447
     , pSourceX509Ca
448
     , pSrcNode
449
     , pSrcNodeUuid
450
     , pSrcPath
451
     , pStartInstance
452
     , pInstTags
453
     ],
454
     "instance_name")
455
  , ("OpInstanceMultiAlloc",
456
     [t| InstanceMultiAllocResponse |],
457
     OpDoc.opInstanceMultiAlloc,
458
     [ pOpportunisticLocking
459
     , pIallocator
460
     , pMultiAllocInstances
461
     ],
462
     [])
463
  , ("OpInstanceReinstall",
464
     [t| () |],
465
     OpDoc.opInstanceReinstall,
466
     [ pInstanceName
467
     , pInstanceUuid
468
     , pForceVariant
469
     , pInstOs
470
     , pTempOsParams
471
     ],
472
     "instance_name")
473
  , ("OpInstanceSnapshot",
474
     [t| () |],
475
     OpDoc.opInstanceSnapshot,
476
     [ pInstanceName
477
     , pInstSnaps
478
     ],
479
     "instance_name")
480
  , ("OpInstanceRemove",
481
     [t| () |],
482
     OpDoc.opInstanceRemove,
483
     [ pInstanceName
484
     , pInstanceUuid
485
     , pShutdownTimeout
486
     , pIgnoreFailures
487
     , pKeepDisks
488
     ],
489
     "instance_name")
490
  , ("OpInstanceRename",
491
     [t| NonEmptyString |],
492
     OpDoc.opInstanceRename,
493
     [ pInstanceName
494
     , pInstanceUuid
495
     , withDoc "New instance name" pNewName
496
     , pNameCheck
497
     , pIpCheck
498
     ],
499
     [])
500
  , ("OpInstanceStartup",
501
     [t| () |],
502
     OpDoc.opInstanceStartup,
503
     [ pInstanceName
504
     , pInstanceUuid
505
     , pForce
506
     , pIgnoreOfflineNodes
507
     , pTempHvParams
508
     , pTempBeParams
509
     , pNoRemember
510
     , pStartupPaused
511
     ],
512
     "instance_name")
513
  , ("OpInstanceShutdown",
514
     [t| () |],
515
     OpDoc.opInstanceShutdown,
516
     [ pInstanceName
517
     , pInstanceUuid
518
     , pForce
519
     , pIgnoreOfflineNodes
520
     , pShutdownTimeout'
521
     , pNoRemember
522
     ],
523
     "instance_name")
524
  , ("OpInstanceReboot",
525
     [t| () |],
526
     OpDoc.opInstanceReboot,
527
     [ pInstanceName
528
     , pInstanceUuid
529
     , pShutdownTimeout
530
     , pIgnoreSecondaries
531
     , pRebootType
532
     ],
533
     "instance_name")
534
  , ("OpInstanceReplaceDisks",
535
     [t| () |],
536
     OpDoc.opInstanceReplaceDisks,
537
     [ pInstanceName
538
     , pInstanceUuid
539
     , pEarlyRelease
540
     , pIgnoreIpolicy
541
     , pReplaceDisksMode
542
     , pReplaceDisksList
543
     , pRemoteNode
544
     , pRemoteNodeUuid
545
     , pIallocator
546
     ],
547
     "instance_name")
548
  , ("OpInstanceFailover",
549
     [t| () |],
550
     OpDoc.opInstanceFailover,
551
     [ pInstanceName
552
     , pInstanceUuid
553
     , pShutdownTimeout
554
     , pIgnoreConsistency
555
     , pMigrationTargetNode
556
     , pMigrationTargetNodeUuid
557
     , pIgnoreIpolicy
558
     , pMigrationCleanup
559
     , pIallocator
560
     ],
561
     "instance_name")
562
  , ("OpInstanceMigrate",
563
     [t| () |],
564
     OpDoc.opInstanceMigrate,
565
     [ pInstanceName
566
     , pInstanceUuid
567
     , pMigrationMode
568
     , pMigrationLive
569
     , pMigrationTargetNode
570
     , pMigrationTargetNodeUuid
571
     , pAllowRuntimeChgs
572
     , pIgnoreIpolicy
573
     , pMigrationCleanup
574
     , pIallocator
575
     , pAllowFailover
576
     ],
577
     "instance_name")
578
  , ("OpInstanceMove",
579
     [t| () |],
580
     OpDoc.opInstanceMove,
581
     [ pInstanceName
582
     , pInstanceUuid
583
     , pShutdownTimeout
584
     , pIgnoreIpolicy
585
     , pMoveTargetNode
586
     , pMoveTargetNodeUuid
587
     , pIgnoreConsistency
588
     ],
589
     "instance_name")
590
  , ("OpInstanceConsole",
591
     [t| JSObject JSValue |],
592
     OpDoc.opInstanceConsole,
593
     [ pInstanceName
594
     , pInstanceUuid
595
     ],
596
     "instance_name")
597
  , ("OpInstanceActivateDisks",
598
     [t| [(NonEmptyString, NonEmptyString, NonEmptyString)] |],
599
     OpDoc.opInstanceActivateDisks,
600
     [ pInstanceName
601
     , pInstanceUuid
602
     , pIgnoreDiskSize
603
     , pWaitForSyncFalse
604
     ],
605
     "instance_name")
606
  , ("OpInstanceDeactivateDisks",
607
     [t| () |],
608
     OpDoc.opInstanceDeactivateDisks,
609
     [ pInstanceName
610
     , pInstanceUuid
611
     , pForce
612
     ],
613
     "instance_name")
614
  , ("OpInstanceRecreateDisks",
615
     [t| () |],
616
     OpDoc.opInstanceRecreateDisks,
617
     [ pInstanceName
618
     , pInstanceUuid
619
     , pRecreateDisksInfo
620
     , withDoc "New instance nodes, if relocation is desired" pNodes
621
     , withDoc "New instance node UUIDs, if relocation is desired" pNodeUuids
622
     , pIallocator
623
     ],
624
     "instance_name")
625
  , ("OpInstanceQuery",
626
     [t| [[JSValue]] |],
627
     OpDoc.opInstanceQuery,
628
     [ pOutputFields
629
     , pUseLocking
630
     , withDoc
631
       "Empty list to query all instances, instance names otherwise"
632
       pNames
633
     ],
634
     [])
635
  , ("OpInstanceQueryData",
636
     [t| JSObject (JSObject JSValue) |],
637
     OpDoc.opInstanceQueryData,
638
     [ pUseLocking
639
     , pInstances
640
     , pStatic
641
     ],
642
     [])
643
  , ("OpInstanceSetParams",
644
      [t| [(NonEmptyString, JSValue)] |],
645
      OpDoc.opInstanceSetParams,
646
     [ pInstanceName
647
     , pInstanceUuid
648
     , pForce
649
     , pForceVariant
650
     , pIgnoreIpolicy
651
     , pInstParamsNicChanges
652
     , pInstParamsDiskChanges
653
     , pInstBeParams
654
     , pRuntimeMem
655
     , pInstHvParams
656
     , pOptDiskTemplate
657
     , pPrimaryNode
658
     , pPrimaryNodeUuid
659
     , withDoc "Secondary node (used when changing disk template)" pRemoteNode
660
     , withDoc
661
       "Secondary node UUID (used when changing disk template)"
662
       pRemoteNodeUuid
663
     , pOsNameChange
664
     , pInstOsParams
665
     , pWaitForSync
666
     , withDoc "Whether to mark the instance as offline" pOffline
667
     , pIpConflictsCheck
668
     , pHotplug
669
     , pHotplugIfPossible
670
     , pKeepDisks
671
     ],
672
     "instance_name")
673
  , ("OpInstanceGrowDisk",
674
     [t| () |],
675
     OpDoc.opInstanceGrowDisk,
676
     [ pInstanceName
677
     , pInstanceUuid
678
     , pWaitForSync
679
     , pDiskIndex
680
     , pDiskChgAmount
681
     , pDiskChgAbsolute
682
     ],
683
     "instance_name")
684
  , ("OpInstanceChangeGroup",
685
     [t| JobIdListOnly |],
686
     OpDoc.opInstanceChangeGroup,
687
     [ pInstanceName
688
     , pInstanceUuid
689
     , pEarlyRelease
690
     , pIallocator
691
     , pTargetGroups
692
     ],
693
     "instance_name")
694
  , ("OpGroupAdd",
695
     [t| () |],
696
     OpDoc.opGroupAdd,
697
     [ pGroupName
698
     , pNodeGroupAllocPolicy
699
     , pGroupNodeParams
700
     , pGroupDiskParams
701
     , pHvState
702
     , pDiskState
703
     , withDoc "Group-wide ipolicy specs" pIpolicy
704
     ],
705
     "group_name")
706
  , ("OpGroupAssignNodes",
707
     [t| () |],
708
     OpDoc.opGroupAssignNodes,
709
     [ pGroupName
710
     , pForce
711
     , withDoc "List of nodes to assign" pRequiredNodes
712
     , withDoc "List of node UUIDs to assign" pRequiredNodeUuids
713
     ],
714
     "group_name")
715
  , ("OpGroupQuery",
716
     [t| [[JSValue]] |],
717
     OpDoc.opGroupQuery,
718
     [ pOutputFields
719
     , withDoc "Empty list to query all groups, group names otherwise" pNames
720
     ],
721
     [])
722
  , ("OpGroupSetParams",
723
     [t| [(NonEmptyString, JSValue)] |],
724
     OpDoc.opGroupSetParams,
725
     [ pGroupName
726
     , pNodeGroupAllocPolicy
727
     , pGroupNodeParams
728
     , pGroupDiskParams
729
     , pHvState
730
     , pDiskState
731
     , withDoc "Group-wide ipolicy specs" pIpolicy
732
     ],
733
     "group_name")
734
  , ("OpGroupRemove",
735
     [t| () |],
736
     OpDoc.opGroupRemove,
737
     [ pGroupName
738
     ],
739
     "group_name")
740
  , ("OpGroupRename",
741
     [t| NonEmptyString |],
742
     OpDoc.opGroupRename,
743
     [ pGroupName
744
     , withDoc "New group name" pNewName
745
     ],
746
     [])
747
  , ("OpGroupEvacuate",
748
     [t| JobIdListOnly |],
749
     OpDoc.opGroupEvacuate,
750
     [ pGroupName
751
     , pEarlyRelease
752
     , pIallocator
753
     , pTargetGroups
754
     , pSequential
755
     , pForceFailover
756
     ],
757
     "group_name")
758
  , ("OpOsDiagnose",
759
     [t| [[JSValue]] |],
760
     OpDoc.opOsDiagnose,
761
     [ pOutputFields
762
     , withDoc "Which operating systems to diagnose" pNames
763
     ],
764
     [])
765
  , ("OpExtStorageDiagnose",
766
     [t| [[JSValue]] |],
767
     OpDoc.opExtStorageDiagnose,
768
     [ pOutputFields
769
     , withDoc "Which ExtStorage Provider to diagnose" pNames
770
     ],
771
     [])
772
  , ("OpBackupQuery",
773
     [t| JSObject (Either Bool [NonEmptyString]) |],
774
     OpDoc.opBackupQuery,
775
     [ pUseLocking
776
     , withDoc "Empty list to query all nodes, node names otherwise" pNodes
777
     ],
778
     [])
779
  , ("OpBackupPrepare",
780
     [t| Maybe (JSObject JSValue) |],
781
     OpDoc.opBackupPrepare,
782
     [ pInstanceName
783
     , pInstanceUuid
784
     , pExportMode
785
     ],
786
     "instance_name")
787
  , ("OpBackupExport",
788
     [t| (Bool, [Bool]) |],
789
     OpDoc.opBackupExport,
790
     [ pInstanceName
791
     , pInstanceUuid
792
     , pShutdownTimeout
793
     , pExportTargetNode
794
     , pExportTargetNodeUuid
795
     , pShutdownInstance
796
     , pRemoveInstance
797
     , pIgnoreRemoveFailures
798
     , defaultField [| ExportModeLocal |] pExportMode
799
     , pX509KeyName
800
     , pX509DestCA
801
     ],
802
     "instance_name")
803
  , ("OpBackupRemove",
804
     [t| () |],
805
     OpDoc.opBackupRemove,
806
     [ pInstanceName
807
     , pInstanceUuid
808
     ],
809
     "instance_name")
810
  , ("OpTagsGet",
811
     [t| [NonEmptyString] |],
812
     OpDoc.opTagsGet,
813
     [ pTagsObject
814
     , pUseLocking
815
     , withDoc "Name of object to retrieve tags from" pTagsName
816
     ],
817
     "name")
818
  , ("OpTagsSearch",
819
     [t| [(NonEmptyString, NonEmptyString)] |],
820
     OpDoc.opTagsSearch,
821
     [ pTagSearchPattern
822
     ],
823
     "pattern")
824
  , ("OpTagsSet",
825
     [t| () |],
826
     OpDoc.opTagsSet,
827
     [ pTagsObject
828
     , pTagsList
829
     , withDoc "Name of object where tag(s) should be added" pTagsName
830
     ],
831
     [])
832
  , ("OpTagsDel",
833
     [t| () |],
834
     OpDoc.opTagsDel,
835
     [ pTagsObject
836
     , pTagsList
837
     , withDoc "Name of object where tag(s) should be deleted" pTagsName
838
     ],
839
     [])
840
  , ("OpTestDelay",
841
     [t| () |],
842
     OpDoc.opTestDelay,
843
     [ pDelayDuration
844
     , pDelayOnMaster
845
     , pDelayOnNodes
846
     , pDelayOnNodeUuids
847
     , pDelayRepeat
848
     , pDelayNoLocks
849
     ],
850
     "duration")
851
  , ("OpTestAllocator",
852
     [t| String |],
853
     OpDoc.opTestAllocator,
854
     [ pIAllocatorDirection
855
     , pIAllocatorMode
856
     , pIAllocatorReqName
857
     , pIAllocatorNics
858
     , pIAllocatorDisks
859
     , pHypervisor
860
     , pIallocator
861
     , pInstTags
862
     , pIAllocatorMemory
863
     , pIAllocatorVCpus
864
     , pIAllocatorOs
865
     , pDiskTemplate
866
     , pIAllocatorInstances
867
     , pIAllocatorEvacMode
868
     , pTargetGroups
869
     , pIAllocatorSpindleUse
870
     , pIAllocatorCount
871
     ],
872
     "iallocator")
873
  , ("OpTestJqueue",
874
     [t| Bool |],
875
     OpDoc.opTestJqueue,
876
     [ pJQueueNotifyWaitLock
877
     , pJQueueNotifyExec
878
     , pJQueueLogMessages
879
     , pJQueueFail
880
     ],
881
     [])
882
  , ("OpTestDummy",
883
     [t| () |],
884
     OpDoc.opTestDummy,
885
     [ pTestDummyResult
886
     , pTestDummyMessages
887
     , pTestDummyFail
888
     , pTestDummySubmitJobs
889
     ],
890
     [])
891
  , ("OpNetworkAdd",
892
     [t| () |],
893
     OpDoc.opNetworkAdd,
894
     [ pNetworkName
895
     , pNetworkAddress4
896
     , pNetworkGateway4
897
     , pNetworkAddress6
898
     , pNetworkGateway6
899
     , pNetworkMacPrefix
900
     , pNetworkAddRsvdIps
901
     , pIpConflictsCheck
902
     , withDoc "Network tags" pInstTags
903
     ],
904
     "network_name")
905
  , ("OpNetworkRemove",
906
     [t| () |],
907
     OpDoc.opNetworkRemove,
908
     [ pNetworkName
909
     , pForce
910
     ],
911
     "network_name")
912
  , ("OpNetworkSetParams",
913
     [t| () |],
914
     OpDoc.opNetworkSetParams,
915
     [ pNetworkName
916
     , pNetworkGateway4
917
     , pNetworkAddress6
918
     , pNetworkGateway6
919
     , pNetworkMacPrefix
920
     , withDoc "Which external IP addresses to reserve" pNetworkAddRsvdIps
921
     , pNetworkRemoveRsvdIps
922
     ],
923
     "network_name")
924
  , ("OpNetworkConnect",
925
     [t| () |],
926
     OpDoc.opNetworkConnect,
927
     [ pGroupName
928
     , pNetworkName
929
     , pNetworkMode
930
     , pNetworkLink
931
     , pIpConflictsCheck
932
     ],
933
     "network_name")
934
  , ("OpNetworkDisconnect",
935
     [t| () |],
936
     OpDoc.opNetworkDisconnect,
937
     [ pGroupName
938
     , pNetworkName
939
     ],
940
     "network_name")
941
  , ("OpNetworkQuery",
942
     [t| [[JSValue]] |],
943
     OpDoc.opNetworkQuery,
944
     [ pOutputFields
945
     , pUseLocking
946
     , withDoc "Empty list to query all groups, group names otherwise" pNames
947
     ],
948
     [])
949
  ])
950

    
951
-- | Returns the OP_ID for a given opcode value.
952
$(genOpID ''OpCode "opID")
953

    
954
-- | A list of all defined/supported opcode IDs.
955
$(genAllOpIDs ''OpCode "allOpIDs")
956

    
957
instance JSON OpCode where
958
  readJSON = loadOpCode
959
  showJSON = saveOpCode
960

    
961
-- | Generates the summary value for an opcode.
962
opSummaryVal :: OpCode -> Maybe String
963
opSummaryVal OpClusterVerifyGroup { opGroupName = s } = Just (fromNonEmpty s)
964
opSummaryVal OpGroupVerifyDisks { opGroupName = s } = Just (fromNonEmpty s)
965
opSummaryVal OpClusterRename { opName = s } = Just (fromNonEmpty s)
966
opSummaryVal OpQuery { opWhat = s } = Just (queryTypeOpToRaw s)
967
opSummaryVal OpQueryFields { opWhat = s } = Just (queryTypeOpToRaw s)
968
opSummaryVal OpNodeRemove { opNodeName = s } = Just (fromNonEmpty s)
969
opSummaryVal OpNodeAdd { opNodeName = s } = Just (fromNonEmpty s)
970
opSummaryVal OpNodeModifyStorage { opNodeName = s } = Just (fromNonEmpty s)
971
opSummaryVal OpRepairNodeStorage  { opNodeName = s } = Just (fromNonEmpty s)
972
opSummaryVal OpNodeSetParams { opNodeName = s } = Just (fromNonEmpty s)
973
opSummaryVal OpNodePowercycle { opNodeName = s } = Just (fromNonEmpty s)
974
opSummaryVal OpNodeMigrate { opNodeName = s } = Just (fromNonEmpty s)
975
opSummaryVal OpNodeEvacuate { opNodeName = s } = Just (fromNonEmpty s)
976
opSummaryVal OpInstanceCreate { opInstanceName = s } = Just s
977
opSummaryVal OpInstanceReinstall { opInstanceName = s } = Just s
978
opSummaryVal OpInstanceSnapshot { opInstanceName = s } = Just s
979
opSummaryVal OpInstanceRemove { opInstanceName = s } = Just s
980
-- FIXME: instance rename should show both names; currently it shows none
981
-- opSummaryVal OpInstanceRename { opInstanceName = s } = Just s
982
opSummaryVal OpInstanceStartup { opInstanceName = s } = Just s
983
opSummaryVal OpInstanceShutdown { opInstanceName = s } = Just s
984
opSummaryVal OpInstanceReboot { opInstanceName = s } = Just s
985
opSummaryVal OpInstanceReplaceDisks { opInstanceName = s } = Just s
986
opSummaryVal OpInstanceFailover { opInstanceName = s } = Just s
987
opSummaryVal OpInstanceMigrate { opInstanceName = s } = Just s
988
opSummaryVal OpInstanceMove { opInstanceName = s } = Just s
989
opSummaryVal OpInstanceConsole { opInstanceName = s } = Just s
990
opSummaryVal OpInstanceActivateDisks { opInstanceName = s } = Just s
991
opSummaryVal OpInstanceDeactivateDisks { opInstanceName = s } = Just s
992
opSummaryVal OpInstanceRecreateDisks { opInstanceName = s } = Just s
993
opSummaryVal OpInstanceSetParams { opInstanceName = s } = Just s
994
opSummaryVal OpInstanceGrowDisk { opInstanceName = s } = Just s
995
opSummaryVal OpInstanceChangeGroup { opInstanceName = s } = Just s
996
opSummaryVal OpGroupAdd { opGroupName = s } = Just (fromNonEmpty s)
997
opSummaryVal OpGroupAssignNodes { opGroupName = s } = Just (fromNonEmpty s)
998
opSummaryVal OpGroupSetParams { opGroupName = s } = Just (fromNonEmpty s)
999
opSummaryVal OpGroupRemove { opGroupName = s } = Just (fromNonEmpty s)
1000
opSummaryVal OpGroupEvacuate { opGroupName = s } = Just (fromNonEmpty s)
1001
opSummaryVal OpBackupPrepare { opInstanceName = s } = Just s
1002
opSummaryVal OpBackupExport { opInstanceName = s } = Just s
1003
opSummaryVal OpBackupRemove { opInstanceName = s } = Just s
1004
opSummaryVal OpTagsGet { opKind = s } = Just (show s)
1005
opSummaryVal OpTagsSearch { opTagSearchPattern = s } = Just (fromNonEmpty s)
1006
opSummaryVal OpTestDelay { opDelayDuration = d } = Just (show d)
1007
opSummaryVal OpTestAllocator { opIallocator = s } =
1008
  -- FIXME: Python doesn't handle None fields well, so we have behave the same
1009
  Just $ maybe "None" fromNonEmpty s
1010
opSummaryVal OpNetworkAdd { opNetworkName = s} = Just (fromNonEmpty s)
1011
opSummaryVal OpNetworkRemove { opNetworkName = s} = Just (fromNonEmpty s)
1012
opSummaryVal OpNetworkSetParams { opNetworkName = s} = Just (fromNonEmpty s)
1013
opSummaryVal OpNetworkConnect { opNetworkName = s} = Just (fromNonEmpty s)
1014
opSummaryVal OpNetworkDisconnect { opNetworkName = s} = Just (fromNonEmpty s)
1015
opSummaryVal _ = Nothing
1016

    
1017
-- | Computes the summary of the opcode.
1018
opSummary :: OpCode -> String
1019
opSummary op =
1020
  case opSummaryVal op of
1021
    Nothing -> op_suffix
1022
    Just s -> op_suffix ++ "(" ++ s ++ ")"
1023
  where op_suffix = drop 3 $ opID op
1024

    
1025
-- | Generic\/common opcode parameters.
1026
$(buildObject "CommonOpParams" "op"
1027
  [ pDryRun
1028
  , pDebugLevel
1029
  , pOpPriority
1030
  , pDependencies
1031
  , pComment
1032
  , pReason
1033
  ])
1034

    
1035
-- | Default common parameter values.
1036
defOpParams :: CommonOpParams
1037
defOpParams =
1038
  CommonOpParams { opDryRun     = Nothing
1039
                 , opDebugLevel = Nothing
1040
                 , opPriority   = OpPrioNormal
1041
                 , opDepends    = Nothing
1042
                 , opComment    = Nothing
1043
                 , opReason     = []
1044
                 }
1045

    
1046
-- | The top-level opcode type.
1047
data MetaOpCode = MetaOpCode { metaParams :: CommonOpParams
1048
                             , metaOpCode :: OpCode
1049
                             } deriving (Show, Eq)
1050

    
1051
-- | JSON serialisation for 'MetaOpCode'.
1052
showMeta :: MetaOpCode -> JSValue
1053
showMeta (MetaOpCode params op) =
1054
  let objparams = toDictCommonOpParams params
1055
      objop = toDictOpCode op
1056
  in makeObj (objparams ++ objop)
1057

    
1058
-- | JSON deserialisation for 'MetaOpCode'
1059
readMeta :: JSValue -> Text.JSON.Result MetaOpCode
1060
readMeta v = do
1061
  meta <- readJSON v
1062
  op <- readJSON v
1063
  return $ MetaOpCode meta op
1064

    
1065
instance JSON MetaOpCode where
1066
  showJSON = showMeta
1067
  readJSON = readMeta
1068

    
1069
-- | Wraps an 'OpCode' with the default parameters to build a
1070
-- 'MetaOpCode'.
1071
wrapOpCode :: OpCode -> MetaOpCode
1072
wrapOpCode = MetaOpCode defOpParams
1073

    
1074
-- | Sets the comment on a meta opcode.
1075
setOpComment :: String -> MetaOpCode -> MetaOpCode
1076
setOpComment comment (MetaOpCode common op) =
1077
  MetaOpCode (common { opComment = Just comment}) op
1078

    
1079
-- | Sets the priority on a meta opcode.
1080
setOpPriority :: OpSubmitPriority -> MetaOpCode -> MetaOpCode
1081
setOpPriority prio (MetaOpCode common op) =
1082
  MetaOpCode (common { opPriority = prio }) op