Statistics
| Branch: | Tag: | Revision:

root / src / Ganeti / OpCodes.hs @ e713a686

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 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
  , opReasonSrcID
38
  , allOpIDs
39
  , allOpFields
40
  , opSummary
41
  , CommonOpParams(..)
42
  , defOpParams
43
  , MetaOpCode(..)
44
  , resolveDependencies
45
  , wrapOpCode
46
  , setOpComment
47
  , setOpPriority
48
  ) where
49

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

    
53
import Ganeti.THH
54

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

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

    
64
import qualified Ganeti.Constants as C
65

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

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

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

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

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

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

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

    
94
instance PyValue CVErrorCode where
95
  showValue = cVErrorCodeToRaw
96

    
97
instance PyValue VerifyOptionalChecks where
98
  showValue = verifyOptionalChecksToRaw
99

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

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

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

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

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

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

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

    
123
type QueryFieldsResponse = [QueryFieldDef]
124

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

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

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

    
918
-- | Convert the opcode name to lowercase with underscores and strip
919
-- the @Op@ prefix.
920
$(genOpLowerStrip (C.opcodeReasonSrcOpcode ++ ":") ''OpCode "opReasonSrcID")
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