Statistics
| Branch: | Tag: | Revision:

root / src / Ganeti / OpCodes.hs @ 08fcaf55

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

    
920
-- | Returns the OP_ID for a given opcode value.
921
$(genOpID ''OpCode "opID")
922

    
923
-- | A list of all defined/supported opcode IDs.
924
$(genAllOpIDs ''OpCode "allOpIDs")
925

    
926
instance JSON OpCode where
927
  readJSON = loadOpCode
928
  showJSON = saveOpCode
929

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

    
985
-- | Computes the summary of the opcode.
986
opSummary :: OpCode -> String
987
opSummary op =
988
  case opSummaryVal op of
989
    Nothing -> op_suffix
990
    Just s -> op_suffix ++ "(" ++ s ++ ")"
991
  where op_suffix = drop 3 $ opID op
992

    
993
-- | Generic\/common opcode parameters.
994
$(buildObject "CommonOpParams" "op"
995
  [ pDryRun
996
  , pDebugLevel
997
  , pOpPriority
998
  , pDependencies
999
  , pComment
1000
  , pReason
1001
  ])
1002

    
1003
-- | Default common parameter values.
1004
defOpParams :: CommonOpParams
1005
defOpParams =
1006
  CommonOpParams { opDryRun     = Nothing
1007
                 , opDebugLevel = Nothing
1008
                 , opPriority   = OpPrioNormal
1009
                 , opDepends    = Nothing
1010
                 , opComment    = Nothing
1011
                 , opReason     = []
1012
                 }
1013

    
1014
-- | Resolve relative dependencies to absolute ones, given the job ID.
1015
resolveDependsCommon :: (Monad m) => CommonOpParams -> JobId -> m CommonOpParams
1016
resolveDependsCommon p@(CommonOpParams { opDepends = Just deps}) jid = do
1017
  deps' <- mapM (`absoluteJobDependency` jid) deps
1018
  return p { opDepends = Just deps' }
1019
resolveDependsCommon p _ = return p
1020

    
1021
-- | The top-level opcode type.
1022
data MetaOpCode = MetaOpCode { metaParams :: CommonOpParams
1023
                             , metaOpCode :: OpCode
1024
                             } deriving (Show, Eq)
1025

    
1026
-- | Resolve relative dependencies to absolute ones, given the job Id.
1027
resolveDependencies :: (Monad m) => MetaOpCode -> JobId -> m MetaOpCode
1028
resolveDependencies mopc jid = do
1029
  mpar <- resolveDependsCommon (metaParams mopc) jid
1030
  return (mopc { metaParams = mpar })
1031

    
1032
-- | JSON serialisation for 'MetaOpCode'.
1033
showMeta :: MetaOpCode -> JSValue
1034
showMeta (MetaOpCode params op) =
1035
  let objparams = toDictCommonOpParams params
1036
      objop = toDictOpCode op
1037
  in makeObj (objparams ++ objop)
1038

    
1039
-- | JSON deserialisation for 'MetaOpCode'
1040
readMeta :: JSValue -> Text.JSON.Result MetaOpCode
1041
readMeta v = do
1042
  meta <- readJSON v
1043
  op <- readJSON v
1044
  return $ MetaOpCode meta op
1045

    
1046
instance JSON MetaOpCode where
1047
  showJSON = showMeta
1048
  readJSON = readMeta
1049

    
1050
-- | Wraps an 'OpCode' with the default parameters to build a
1051
-- 'MetaOpCode'.
1052
wrapOpCode :: OpCode -> MetaOpCode
1053
wrapOpCode = MetaOpCode defOpParams
1054

    
1055
-- | Sets the comment on a meta opcode.
1056
setOpComment :: String -> MetaOpCode -> MetaOpCode
1057
setOpComment comment (MetaOpCode common op) =
1058
  MetaOpCode (common { opComment = Just comment}) op
1059

    
1060
-- | Sets the priority on a meta opcode.
1061
setOpPriority :: OpSubmitPriority -> MetaOpCode -> MetaOpCode
1062
setOpPriority prio (MetaOpCode common op) =
1063
  MetaOpCode (common { opPriority = prio }) op