Statistics
| Branch: | Tag: | Revision:

root / src / Ganeti / OpCodes.hs @ 07e3c124

History | View | Annotate | Download (27 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, 2014 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
  , resolveDependencies
44
  , wrapOpCode
45
  , setOpComment
46
  , setOpPriority
47
  ) where
48

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

    
52
import Ganeti.THH
53

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

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

    
63
import qualified Ganeti.Constants as C
64

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

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

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

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

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

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

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

    
93
instance PyValue CVErrorCode where
94
  showValue = cVErrorCodeToRaw
95

    
96
instance PyValue VerifyOptionalChecks where
97
  showValue = verifyOptionalChecksToRaw
98

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

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

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

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

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

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

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

    
122
type QueryFieldsResponse = [QueryFieldDef]
123

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

    
914
-- | Returns the OP_ID for a given opcode value.
915
$(genOpID ''OpCode "opID")
916

    
917
-- | A list of all defined/supported opcode IDs.
918
$(genAllOpIDs ''OpCode "allOpIDs")
919

    
920
instance JSON OpCode where
921
  readJSON = loadOpCode
922
  showJSON = saveOpCode
923

    
924
-- | Generates the summary value for an opcode.
925
opSummaryVal :: OpCode -> Maybe String
926
opSummaryVal OpClusterVerifyGroup { opGroupName = s } = Just (fromNonEmpty s)
927
opSummaryVal OpGroupVerifyDisks { opGroupName = s } = Just (fromNonEmpty s)
928
opSummaryVal OpClusterRename { opName = s } = Just (fromNonEmpty s)
929
opSummaryVal OpQuery { opWhat = s } = Just (queryTypeOpToRaw s)
930
opSummaryVal OpQueryFields { opWhat = s } = Just (queryTypeOpToRaw s)
931
opSummaryVal OpNodeRemove { opNodeName = s } = Just (fromNonEmpty s)
932
opSummaryVal OpNodeAdd { opNodeName = s } = Just (fromNonEmpty s)
933
opSummaryVal OpNodeModifyStorage { opNodeName = s } = Just (fromNonEmpty s)
934
opSummaryVal OpRepairNodeStorage  { opNodeName = s } = Just (fromNonEmpty s)
935
opSummaryVal OpNodeSetParams { opNodeName = s } = Just (fromNonEmpty s)
936
opSummaryVal OpNodePowercycle { opNodeName = s } = Just (fromNonEmpty s)
937
opSummaryVal OpNodeMigrate { opNodeName = s } = Just (fromNonEmpty s)
938
opSummaryVal OpNodeEvacuate { opNodeName = s } = Just (fromNonEmpty s)
939
opSummaryVal OpInstanceCreate { opInstanceName = s } = Just s
940
opSummaryVal OpInstanceReinstall { opInstanceName = s } = Just s
941
opSummaryVal OpInstanceRemove { opInstanceName = s } = Just s
942
-- FIXME: instance rename should show both names; currently it shows none
943
-- opSummaryVal OpInstanceRename { opInstanceName = s } = Just s
944
opSummaryVal OpInstanceStartup { opInstanceName = s } = Just s
945
opSummaryVal OpInstanceShutdown { opInstanceName = s } = Just s
946
opSummaryVal OpInstanceReboot { opInstanceName = s } = Just s
947
opSummaryVal OpInstanceReplaceDisks { opInstanceName = s } = Just s
948
opSummaryVal OpInstanceFailover { opInstanceName = s } = Just s
949
opSummaryVal OpInstanceMigrate { opInstanceName = s } = Just s
950
opSummaryVal OpInstanceMove { opInstanceName = s } = Just s
951
opSummaryVal OpInstanceConsole { opInstanceName = s } = Just s
952
opSummaryVal OpInstanceActivateDisks { opInstanceName = s } = Just s
953
opSummaryVal OpInstanceDeactivateDisks { opInstanceName = s } = Just s
954
opSummaryVal OpInstanceRecreateDisks { opInstanceName = s } = Just s
955
opSummaryVal OpInstanceSetParams { opInstanceName = s } = Just s
956
opSummaryVal OpInstanceGrowDisk { opInstanceName = s } = Just s
957
opSummaryVal OpInstanceChangeGroup { opInstanceName = s } = Just s
958
opSummaryVal OpGroupAdd { opGroupName = s } = Just (fromNonEmpty s)
959
opSummaryVal OpGroupAssignNodes { opGroupName = s } = Just (fromNonEmpty s)
960
opSummaryVal OpGroupSetParams { opGroupName = s } = Just (fromNonEmpty s)
961
opSummaryVal OpGroupRemove { opGroupName = s } = Just (fromNonEmpty s)
962
opSummaryVal OpGroupEvacuate { opGroupName = s } = Just (fromNonEmpty s)
963
opSummaryVal OpBackupPrepare { opInstanceName = s } = Just s
964
opSummaryVal OpBackupExport { opInstanceName = s } = Just s
965
opSummaryVal OpBackupRemove { opInstanceName = s } = Just s
966
opSummaryVal OpTagsGet { opKind = s } = Just (show s)
967
opSummaryVal OpTagsSearch { opTagSearchPattern = s } = Just (fromNonEmpty s)
968
opSummaryVal OpTestDelay { opDelayDuration = d } = Just (show d)
969
opSummaryVal OpTestAllocator { opIallocator = s } =
970
  -- FIXME: Python doesn't handle None fields well, so we have behave the same
971
  Just $ maybe "None" fromNonEmpty s
972
opSummaryVal OpNetworkAdd { opNetworkName = s} = Just (fromNonEmpty s)
973
opSummaryVal OpNetworkRemove { opNetworkName = s} = Just (fromNonEmpty s)
974
opSummaryVal OpNetworkSetParams { opNetworkName = s} = Just (fromNonEmpty s)
975
opSummaryVal OpNetworkConnect { opNetworkName = s} = Just (fromNonEmpty s)
976
opSummaryVal OpNetworkDisconnect { opNetworkName = s} = Just (fromNonEmpty s)
977
opSummaryVal _ = Nothing
978

    
979
-- | Computes the summary of the opcode.
980
opSummary :: OpCode -> String
981
opSummary op =
982
  case opSummaryVal op of
983
    Nothing -> op_suffix
984
    Just s -> op_suffix ++ "(" ++ s ++ ")"
985
  where op_suffix = drop 3 $ opID op
986

    
987
-- | Generic\/common opcode parameters.
988
$(buildObject "CommonOpParams" "op"
989
  [ pDryRun
990
  , pDebugLevel
991
  , pOpPriority
992
  , pDependencies
993
  , pComment
994
  , pReason
995
  ])
996

    
997
-- | Default common parameter values.
998
defOpParams :: CommonOpParams
999
defOpParams =
1000
  CommonOpParams { opDryRun     = Nothing
1001
                 , opDebugLevel = Nothing
1002
                 , opPriority   = OpPrioNormal
1003
                 , opDepends    = Nothing
1004
                 , opComment    = Nothing
1005
                 , opReason     = []
1006
                 }
1007

    
1008
-- | Resolve relative dependencies to absolute ones, given the job ID.
1009
resolveDependsCommon :: (Monad m) => CommonOpParams -> JobId -> m CommonOpParams
1010
resolveDependsCommon p@(CommonOpParams { opDepends = Just deps}) jid = do
1011
  deps' <- mapM (`absoluteJobDependency` jid) deps
1012
  return p { opDepends = Just deps' }
1013
resolveDependsCommon p _ = return p
1014

    
1015
-- | The top-level opcode type.
1016
data MetaOpCode = MetaOpCode { metaParams :: CommonOpParams
1017
                             , metaOpCode :: OpCode
1018
                             } deriving (Show, Eq)
1019

    
1020
-- | Resolve relative dependencies to absolute ones, given the job Id.
1021
resolveDependencies :: (Monad m) => MetaOpCode -> JobId -> m MetaOpCode
1022
resolveDependencies mopc jid = do
1023
  mpar <- resolveDependsCommon (metaParams mopc) jid
1024
  return (mopc { metaParams = mpar })
1025

    
1026
-- | JSON serialisation for 'MetaOpCode'.
1027
showMeta :: MetaOpCode -> JSValue
1028
showMeta (MetaOpCode params op) =
1029
  let objparams = toDictCommonOpParams params
1030
      objop = toDictOpCode op
1031
  in makeObj (objparams ++ objop)
1032

    
1033
-- | JSON deserialisation for 'MetaOpCode'
1034
readMeta :: JSValue -> Text.JSON.Result MetaOpCode
1035
readMeta v = do
1036
  meta <- readJSON v
1037
  op <- readJSON v
1038
  return $ MetaOpCode meta op
1039

    
1040
instance JSON MetaOpCode where
1041
  showJSON = showMeta
1042
  readJSON = readMeta
1043

    
1044
-- | Wraps an 'OpCode' with the default parameters to build a
1045
-- 'MetaOpCode'.
1046
wrapOpCode :: OpCode -> MetaOpCode
1047
wrapOpCode = MetaOpCode defOpParams
1048

    
1049
-- | Sets the comment on a meta opcode.
1050
setOpComment :: String -> MetaOpCode -> MetaOpCode
1051
setOpComment comment (MetaOpCode common op) =
1052
  MetaOpCode (common { opComment = Just comment}) op
1053

    
1054
-- | Sets the priority on a meta opcode.
1055
setOpPriority :: OpSubmitPriority -> MetaOpCode -> MetaOpCode
1056
setOpPriority prio (MetaOpCode common op) =
1057
  MetaOpCode (common { opPriority = prio }) op