Statistics
| Branch: | Tag: | Revision:

root / src / Ganeti / OpCodes.hs @ d3e6fd0e

History | View | Annotate | Download (26.7 kB)

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

    
4
{-| Implementation of the opcodes.
5

    
6
-}
7

    
8
{-
9

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

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

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

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

    
27
-}
28

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

    
904
-- | Returns the OP_ID for a given opcode value.
905
$(genOpID ''OpCode "opID")
906

    
907
-- | A list of all defined/supported opcode IDs.
908
$(genAllOpIDs ''OpCode "allOpIDs")
909

    
910
instance JSON OpCode where
911
  readJSON = loadOpCode
912
  showJSON = saveOpCode
913

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

    
969
-- | Computes the summary of the opcode.
970
opSummary :: OpCode -> String
971
opSummary op =
972
  case opSummaryVal op of
973
    Nothing -> op_suffix
974
    Just s -> op_suffix ++ "(" ++ s ++ ")"
975
  where op_suffix = drop 3 $ opID op
976

    
977
-- | Generic\/common opcode parameters.
978
$(buildObject "CommonOpParams" "op"
979
  [ pDryRun
980
  , pDebugLevel
981
  , pOpPriority
982
  , pDependencies
983
  , pComment
984
  , pReason
985
  ])
986

    
987
-- | Default common parameter values.
988
defOpParams :: CommonOpParams
989
defOpParams =
990
  CommonOpParams { opDryRun     = Nothing
991
                 , opDebugLevel = Nothing
992
                 , opPriority   = OpPrioNormal
993
                 , opDepends    = Nothing
994
                 , opComment    = Nothing
995
                 , opReason     = []
996
                 }
997

    
998
-- | Resolve relative dependencies to absolute ones, given the job ID.
999
resolveDependsCommon :: (Monad m) => CommonOpParams -> JobId -> m CommonOpParams
1000
resolveDependsCommon p@(CommonOpParams { opDepends = Just deps}) jid = do
1001
  deps' <- mapM (`absoluteJobDependency` jid) deps
1002
  return p { opDepends = Just deps' }
1003
resolveDependsCommon p _ = return p
1004

    
1005
-- | The top-level opcode type.
1006
data MetaOpCode = MetaOpCode { metaParams :: CommonOpParams
1007
                             , metaOpCode :: OpCode
1008
                             } deriving (Show, Eq)
1009

    
1010
-- | Resolve relative dependencies to absolute ones, given the job Id.
1011
resolveDependencies :: (Monad m) => MetaOpCode -> JobId -> m MetaOpCode
1012
resolveDependencies mopc jid = do
1013
  mpar <- resolveDependsCommon (metaParams mopc) jid
1014
  return (mopc { metaParams = mpar })
1015

    
1016
-- | JSON serialisation for 'MetaOpCode'.
1017
showMeta :: MetaOpCode -> JSValue
1018
showMeta (MetaOpCode params op) =
1019
  let objparams = toDictCommonOpParams params
1020
      objop = toDictOpCode op
1021
  in makeObj (objparams ++ objop)
1022

    
1023
-- | JSON deserialisation for 'MetaOpCode'
1024
readMeta :: JSValue -> Text.JSON.Result MetaOpCode
1025
readMeta v = do
1026
  meta <- readJSON v
1027
  op <- readJSON v
1028
  return $ MetaOpCode meta op
1029

    
1030
instance JSON MetaOpCode where
1031
  showJSON = showMeta
1032
  readJSON = readMeta
1033

    
1034
-- | Wraps an 'OpCode' with the default parameters to build a
1035
-- 'MetaOpCode'.
1036
wrapOpCode :: OpCode -> MetaOpCode
1037
wrapOpCode = MetaOpCode defOpParams
1038

    
1039
-- | Sets the comment on a meta opcode.
1040
setOpComment :: String -> MetaOpCode -> MetaOpCode
1041
setOpComment comment (MetaOpCode common op) =
1042
  MetaOpCode (common { opComment = Just comment}) op
1043

    
1044
-- | Sets the priority on a meta opcode.
1045
setOpPriority :: OpSubmitPriority -> MetaOpCode -> MetaOpCode
1046
setOpPriority prio (MetaOpCode common op) =
1047
  MetaOpCode (common { opPriority = prio }) op