Statistics
| Branch: | Tag: | Revision:

root / src / Ganeti / OpCodes.hs @ 48e4da5c

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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