Statistics
| Branch: | Tag: | Revision:

root / src / Ganeti / OpCodes.hs @ 6bce7ba2

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
     , pInstOsParamsPrivate
442
     , pInstOsParamsSecret
443
     , pInstOs
444
     , pPrimaryNode
445
     , pPrimaryNodeUuid
446
     , pSecondaryNode
447
     , pSecondaryNodeUuid
448
     , pSourceHandshake
449
     , pSourceInstance
450
     , pSourceShutdownTimeout
451
     , pSourceX509Ca
452
     , pSrcNode
453
     , pSrcNodeUuid
454
     , pSrcPath
455
     , pBackupCompress
456
     , pStartInstance
457
     , pInstTags
458
     , pInstanceCommunication
459
     ],
460
     "instance_name")
461
  , ("OpInstanceMultiAlloc",
462
     [t| InstanceMultiAllocResponse |],
463
     OpDoc.opInstanceMultiAlloc,
464
     [ pOpportunisticLocking
465
     , pIallocator
466
     , pMultiAllocInstances
467
     ],
468
     [])
469
  , ("OpInstanceReinstall",
470
     [t| () |],
471
     OpDoc.opInstanceReinstall,
472
     [ pInstanceName
473
     , pInstanceUuid
474
     , pForceVariant
475
     , pInstOs
476
     , pTempOsParams
477
     ],
478
     "instance_name")
479
  , ("OpInstanceRemove",
480
     [t| () |],
481
     OpDoc.opInstanceRemove,
482
     [ pInstanceName
483
     , pInstanceUuid
484
     , pShutdownTimeout
485
     , pIgnoreFailures
486
     ],
487
     "instance_name")
488
  , ("OpInstanceRename",
489
     [t| NonEmptyString |],
490
     OpDoc.opInstanceRename,
491
     [ pInstanceName
492
     , pInstanceUuid
493
     , withDoc "New instance name" pNewName
494
     , pNameCheck
495
     , pIpCheck
496
     ],
497
     [])
498
  , ("OpInstanceStartup",
499
     [t| () |],
500
     OpDoc.opInstanceStartup,
501
     [ pInstanceName
502
     , pInstanceUuid
503
     , pForce
504
     , pIgnoreOfflineNodes
505
     , pTempHvParams
506
     , pTempBeParams
507
     , pNoRemember
508
     , pStartupPaused
509
     ],
510
     "instance_name")
511
  , ("OpInstanceShutdown",
512
     [t| () |],
513
     OpDoc.opInstanceShutdown,
514
     [ pInstanceName
515
     , pInstanceUuid
516
     , pForce
517
     , pIgnoreOfflineNodes
518
     , pShutdownTimeout'
519
     , pNoRemember
520
     ],
521
     "instance_name")
522
  , ("OpInstanceReboot",
523
     [t| () |],
524
     OpDoc.opInstanceReboot,
525
     [ pInstanceName
526
     , pInstanceUuid
527
     , pShutdownTimeout
528
     , pIgnoreSecondaries
529
     , pRebootType
530
     ],
531
     "instance_name")
532
  , ("OpInstanceReplaceDisks",
533
     [t| () |],
534
     OpDoc.opInstanceReplaceDisks,
535
     [ pInstanceName
536
     , pInstanceUuid
537
     , pEarlyRelease
538
     , pIgnoreIpolicy
539
     , pReplaceDisksMode
540
     , pReplaceDisksList
541
     , pRemoteNode
542
     , pRemoteNodeUuid
543
     , pIallocator
544
     ],
545
     "instance_name")
546
  , ("OpInstanceFailover",
547
     [t| () |],
548
     OpDoc.opInstanceFailover,
549
     [ pInstanceName
550
     , pInstanceUuid
551
     , pShutdownTimeout
552
     , pIgnoreConsistency
553
     , pMigrationTargetNode
554
     , pMigrationTargetNodeUuid
555
     , pIgnoreIpolicy
556
     , pMigrationCleanup
557
     , pIallocator
558
     ],
559
     "instance_name")
560
  , ("OpInstanceMigrate",
561
     [t| () |],
562
     OpDoc.opInstanceMigrate,
563
     [ pInstanceName
564
     , pInstanceUuid
565
     , pMigrationMode
566
     , pMigrationLive
567
     , pMigrationTargetNode
568
     , pMigrationTargetNodeUuid
569
     , pAllowRuntimeChgs
570
     , pIgnoreIpolicy
571
     , pMigrationCleanup
572
     , pIallocator
573
     , pAllowFailover
574
     ],
575
     "instance_name")
576
  , ("OpInstanceMove",
577
     [t| () |],
578
     OpDoc.opInstanceMove,
579
     [ pInstanceName
580
     , pInstanceUuid
581
     , pShutdownTimeout
582
     , pIgnoreIpolicy
583
     , pMoveTargetNode
584
     , pMoveTargetNodeUuid
585
     , pMoveCompress
586
     , pIgnoreConsistency
587
     ],
588
     "instance_name")
589
  , ("OpInstanceConsole",
590
     [t| JSObject JSValue |],
591
     OpDoc.opInstanceConsole,
592
     [ pInstanceName
593
     , pInstanceUuid
594
     ],
595
     "instance_name")
596
  , ("OpInstanceActivateDisks",
597
     [t| [(NonEmptyString, NonEmptyString, NonEmptyString)] |],
598
     OpDoc.opInstanceActivateDisks,
599
     [ pInstanceName
600
     , pInstanceUuid
601
     , pIgnoreDiskSize
602
     , pWaitForSyncFalse
603
     ],
604
     "instance_name")
605
  , ("OpInstanceDeactivateDisks",
606
     [t| () |],
607
     OpDoc.opInstanceDeactivateDisks,
608
     [ pInstanceName
609
     , pInstanceUuid
610
     , pForce
611
     ],
612
     "instance_name")
613
  , ("OpInstanceRecreateDisks",
614
     [t| () |],
615
     OpDoc.opInstanceRecreateDisks,
616
     [ pInstanceName
617
     , pInstanceUuid
618
     , pRecreateDisksInfo
619
     , withDoc "New instance nodes, if relocation is desired" pNodes
620
     , withDoc "New instance node UUIDs, if relocation is desired" pNodeUuids
621
     , pIallocator
622
     ],
623
     "instance_name")
624
  , ("OpInstanceQueryData",
625
     [t| JSObject (JSObject JSValue) |],
626
     OpDoc.opInstanceQueryData,
627
     [ pUseLocking
628
     , pInstances
629
     , pStatic
630
     ],
631
     [])
632
  , ("OpInstanceSetParams",
633
      [t| [(NonEmptyString, JSValue)] |],
634
      OpDoc.opInstanceSetParams,
635
     [ pInstanceName
636
     , pInstanceUuid
637
     , pForce
638
     , pForceVariant
639
     , pIgnoreIpolicy
640
     , pInstParamsNicChanges
641
     , pInstParamsDiskChanges
642
     , pInstBeParams
643
     , pRuntimeMem
644
     , pInstHvParams
645
     , pOptDiskTemplate
646
     , pPrimaryNode
647
     , pPrimaryNodeUuid
648
     , withDoc "Secondary node (used when changing disk template)" pRemoteNode
649
     , withDoc
650
       "Secondary node UUID (used when changing disk template)"
651
       pRemoteNodeUuid
652
     , pOsNameChange
653
     , pInstOsParams
654
     , pInstOsParamsPrivate
655
     , pWaitForSync
656
     , withDoc "Whether to mark the instance as offline" pOffline
657
     , pIpConflictsCheck
658
     , pHotplug
659
     , pHotplugIfPossible
660
     ],
661
     "instance_name")
662
  , ("OpInstanceGrowDisk",
663
     [t| () |],
664
     OpDoc.opInstanceGrowDisk,
665
     [ pInstanceName
666
     , pInstanceUuid
667
     , pWaitForSync
668
     , pDiskIndex
669
     , pDiskChgAmount
670
     , pDiskChgAbsolute
671
     ],
672
     "instance_name")
673
  , ("OpInstanceChangeGroup",
674
     [t| JobIdListOnly |],
675
     OpDoc.opInstanceChangeGroup,
676
     [ pInstanceName
677
     , pInstanceUuid
678
     , pEarlyRelease
679
     , pIallocator
680
     , pTargetGroups
681
     ],
682
     "instance_name")
683
  , ("OpGroupAdd",
684
     [t| () |],
685
     OpDoc.opGroupAdd,
686
     [ pGroupName
687
     , pNodeGroupAllocPolicy
688
     , pGroupNodeParams
689
     , pDiskParams
690
     , pHvState
691
     , pDiskState
692
     , withDoc "Group-wide ipolicy specs" pIpolicy
693
     ],
694
     "group_name")
695
  , ("OpGroupAssignNodes",
696
     [t| () |],
697
     OpDoc.opGroupAssignNodes,
698
     [ pGroupName
699
     , pForce
700
     , withDoc "List of nodes to assign" pRequiredNodes
701
     , withDoc "List of node UUIDs to assign" pRequiredNodeUuids
702
     ],
703
     "group_name")
704
  , ("OpGroupSetParams",
705
     [t| [(NonEmptyString, JSValue)] |],
706
     OpDoc.opGroupSetParams,
707
     [ pGroupName
708
     , pNodeGroupAllocPolicy
709
     , pGroupNodeParams
710
     , pDiskParams
711
     , pHvState
712
     , pDiskState
713
     , withDoc "Group-wide ipolicy specs" pIpolicy
714
     ],
715
     "group_name")
716
  , ("OpGroupRemove",
717
     [t| () |],
718
     OpDoc.opGroupRemove,
719
     [ pGroupName
720
     ],
721
     "group_name")
722
  , ("OpGroupRename",
723
     [t| NonEmptyString |],
724
     OpDoc.opGroupRename,
725
     [ pGroupName
726
     , withDoc "New group name" pNewName
727
     ],
728
     [])
729
  , ("OpGroupEvacuate",
730
     [t| JobIdListOnly |],
731
     OpDoc.opGroupEvacuate,
732
     [ pGroupName
733
     , pEarlyRelease
734
     , pIallocator
735
     , pTargetGroups
736
     ],
737
     "group_name")
738
  , ("OpOsDiagnose",
739
     [t| [[JSValue]] |],
740
     OpDoc.opOsDiagnose,
741
     [ pOutputFields
742
     , withDoc "Which operating systems to diagnose" pNames
743
     ],
744
     [])
745
  , ("OpExtStorageDiagnose",
746
     [t| [[JSValue]] |],
747
     OpDoc.opExtStorageDiagnose,
748
     [ pOutputFields
749
     , withDoc "Which ExtStorage Provider to diagnose" pNames
750
     ],
751
     [])
752
  , ("OpBackupPrepare",
753
     [t| Maybe (JSObject JSValue) |],
754
     OpDoc.opBackupPrepare,
755
     [ pInstanceName
756
     , pInstanceUuid
757
     , pExportMode
758
     ],
759
     "instance_name")
760
  , ("OpBackupExport",
761
     [t| (Bool, [Bool]) |],
762
     OpDoc.opBackupExport,
763
     [ pInstanceName
764
     , pInstanceUuid
765
     , pBackupCompress
766
     , pShutdownTimeout
767
     , pExportTargetNode
768
     , pExportTargetNodeUuid
769
     , pShutdownInstance
770
     , pRemoveInstance
771
     , pIgnoreRemoveFailures
772
     , defaultField [| ExportModeLocal |] pExportMode
773
     , pX509KeyName
774
     , pX509DestCA
775
     ],
776
     "instance_name")
777
  , ("OpBackupRemove",
778
     [t| () |],
779
     OpDoc.opBackupRemove,
780
     [ pInstanceName
781
     , pInstanceUuid
782
     ],
783
     "instance_name")
784
  , ("OpTagsGet",
785
     [t| [NonEmptyString] |],
786
     OpDoc.opTagsGet,
787
     [ pTagsObject
788
     , pUseLocking
789
     , withDoc "Name of object to retrieve tags from" pTagsName
790
     ],
791
     "name")
792
  , ("OpTagsSearch",
793
     [t| [(NonEmptyString, NonEmptyString)] |],
794
     OpDoc.opTagsSearch,
795
     [ pTagSearchPattern
796
     ],
797
     "pattern")
798
  , ("OpTagsSet",
799
     [t| () |],
800
     OpDoc.opTagsSet,
801
     [ pTagsObject
802
     , pTagsList
803
     , withDoc "Name of object where tag(s) should be added" pTagsName
804
     ],
805
     [])
806
  , ("OpTagsDel",
807
     [t| () |],
808
     OpDoc.opTagsDel,
809
     [ pTagsObject
810
     , pTagsList
811
     , withDoc "Name of object where tag(s) should be deleted" pTagsName
812
     ],
813
     [])
814
  , ("OpTestDelay",
815
     [t| () |],
816
     OpDoc.opTestDelay,
817
     [ pDelayDuration
818
     , pDelayOnMaster
819
     , pDelayOnNodes
820
     , pDelayOnNodeUuids
821
     , pDelayRepeat
822
     ],
823
     "duration")
824
  , ("OpTestAllocator",
825
     [t| String |],
826
     OpDoc.opTestAllocator,
827
     [ pIAllocatorDirection
828
     , pIAllocatorMode
829
     , pIAllocatorReqName
830
     , pIAllocatorNics
831
     , pIAllocatorDisks
832
     , pHypervisor
833
     , pIallocator
834
     , pInstTags
835
     , pIAllocatorMemory
836
     , pIAllocatorVCpus
837
     , pIAllocatorOs
838
     , pDiskTemplate
839
     , pIAllocatorInstances
840
     , pIAllocatorEvacMode
841
     , pTargetGroups
842
     , pIAllocatorSpindleUse
843
     , pIAllocatorCount
844
     ],
845
     "iallocator")
846
  , ("OpTestJqueue",
847
     [t| Bool |],
848
     OpDoc.opTestJqueue,
849
     [ pJQueueNotifyWaitLock
850
     , pJQueueNotifyExec
851
     , pJQueueLogMessages
852
     , pJQueueFail
853
     ],
854
     [])
855
  , ("OpTestDummy",
856
     [t| () |],
857
     OpDoc.opTestDummy,
858
     [ pTestDummyResult
859
     , pTestDummyMessages
860
     , pTestDummyFail
861
     , pTestDummySubmitJobs
862
     ],
863
     [])
864
  , ("OpNetworkAdd",
865
     [t| () |],
866
     OpDoc.opNetworkAdd,
867
     [ pNetworkName
868
     , pNetworkAddress4
869
     , pNetworkGateway4
870
     , pNetworkAddress6
871
     , pNetworkGateway6
872
     , pNetworkMacPrefix
873
     , pNetworkAddRsvdIps
874
     , pIpConflictsCheck
875
     , withDoc "Network tags" pInstTags
876
     ],
877
     "network_name")
878
  , ("OpNetworkRemove",
879
     [t| () |],
880
     OpDoc.opNetworkRemove,
881
     [ pNetworkName
882
     , pForce
883
     ],
884
     "network_name")
885
  , ("OpNetworkSetParams",
886
     [t| () |],
887
     OpDoc.opNetworkSetParams,
888
     [ pNetworkName
889
     , pNetworkGateway4
890
     , pNetworkAddress6
891
     , pNetworkGateway6
892
     , pNetworkMacPrefix
893
     , withDoc "Which external IP addresses to reserve" pNetworkAddRsvdIps
894
     , pNetworkRemoveRsvdIps
895
     ],
896
     "network_name")
897
  , ("OpNetworkConnect",
898
     [t| () |],
899
     OpDoc.opNetworkConnect,
900
     [ pGroupName
901
     , pNetworkName
902
     , pNetworkMode
903
     , pNetworkLink
904
     , pIpConflictsCheck
905
     ],
906
     "network_name")
907
  , ("OpNetworkDisconnect",
908
     [t| () |],
909
     OpDoc.opNetworkDisconnect,
910
     [ pGroupName
911
     , pNetworkName
912
     ],
913
     "network_name")
914
  ])
915

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

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

    
922
instance JSON OpCode where
923
  readJSON = loadOpCode
924
  showJSON = saveOpCode
925

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

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

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

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

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

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

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

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

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

    
1042
instance JSON MetaOpCode where
1043
  showJSON = showMeta
1044
  readJSON = readMeta
1045

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

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

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