Statistics
| Branch: | Tag: | Revision:

root / src / Ganeti / OpCodes.hs @ 64981f25

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

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

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

    
918
instance JSON OpCode where
919
  readJSON = loadOpCode
920
  showJSON = saveOpCode
921

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

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

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

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

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

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

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

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

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

    
1038
instance JSON MetaOpCode where
1039
  showJSON = showMeta
1040
  readJSON = readMeta
1041

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

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

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