Statistics
| Branch: | Tag: | Revision:

root / src / Ganeti / OpCodes.hs @ 42fda604

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

    
919
-- | Returns the OP_ID for a given opcode value.
920
$(genOpID ''OpCode "opID")
921

    
922
-- | A list of all defined/supported opcode IDs.
923
$(genAllOpIDs ''OpCode "allOpIDs")
924

    
925
instance JSON OpCode where
926
  readJSON = loadOpCode
927
  showJSON = saveOpCode
928

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

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

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

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

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

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

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

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

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

    
1045
instance JSON MetaOpCode where
1046
  showJSON = showMeta
1047
  readJSON = readMeta
1048

    
1049
-- | Wraps an 'OpCode' with the default parameters to build a
1050
-- 'MetaOpCode'.
1051
wrapOpCode :: OpCode -> MetaOpCode
1052
wrapOpCode = MetaOpCode defOpParams
1053

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

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