Statistics
| Branch: | Tag: | Revision:

root / src / Ganeti / OpCodes.hs @ ad756c77

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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