Statistics
| Branch: | Tag: | Revision:

root / src / Ganeti / OpCodes.hs @ b3cc1646

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

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

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

    
916
instance JSON OpCode where
917
  readJSON = loadOpCode
918
  showJSON = saveOpCode
919

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

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

    
983
-- | Generic\/common opcode parameters.
984
$(buildObject "CommonOpParams" "op"
985
  [ pDryRun
986
  , pDebugLevel
987
  , pOpPriority
988
  , pDependencies
989
  , pComment
990
  , pReason
991
  ])
992

    
993
-- | Default common parameter values.
994
defOpParams :: CommonOpParams
995
defOpParams =
996
  CommonOpParams { opDryRun     = Nothing
997
                 , opDebugLevel = Nothing
998
                 , opPriority   = OpPrioNormal
999
                 , opDepends    = Nothing
1000
                 , opComment    = Nothing
1001
                 , opReason     = []
1002
                 }
1003

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

    
1011
-- | The top-level opcode type.
1012
data MetaOpCode = MetaOpCode { metaParams :: CommonOpParams
1013
                             , metaOpCode :: OpCode
1014
                             } deriving (Show, Eq)
1015

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

    
1022
-- | JSON serialisation for 'MetaOpCode'.
1023
showMeta :: MetaOpCode -> JSValue
1024
showMeta (MetaOpCode params op) =
1025
  let objparams = toDictCommonOpParams params
1026
      objop = toDictOpCode op
1027
  in makeObj (objparams ++ objop)
1028

    
1029
-- | JSON deserialisation for 'MetaOpCode'
1030
readMeta :: JSValue -> Text.JSON.Result MetaOpCode
1031
readMeta v = do
1032
  meta <- readJSON v
1033
  op <- readJSON v
1034
  return $ MetaOpCode meta op
1035

    
1036
instance JSON MetaOpCode where
1037
  showJSON = showMeta
1038
  readJSON = readMeta
1039

    
1040
-- | Wraps an 'OpCode' with the default parameters to build a
1041
-- 'MetaOpCode'.
1042
wrapOpCode :: OpCode -> MetaOpCode
1043
wrapOpCode = MetaOpCode defOpParams
1044

    
1045
-- | Sets the comment on a meta opcode.
1046
setOpComment :: String -> MetaOpCode -> MetaOpCode
1047
setOpComment comment (MetaOpCode common op) =
1048
  MetaOpCode (common { opComment = Just comment}) op
1049

    
1050
-- | Sets the priority on a meta opcode.
1051
setOpPriority :: OpSubmitPriority -> MetaOpCode -> MetaOpCode
1052
setOpPriority prio (MetaOpCode common op) =
1053
  MetaOpCode (common { opPriority = prio }) op