Statistics
| Branch: | Tag: | Revision:

root / src / Ganeti / OpCodes.hs @ 2868f3f7

History | View | Annotate | Download (27.4 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
  , opReasonSrcID
38
  , allOpIDs
39
  , allOpFields
40
  , opSummary
41
  , CommonOpParams(..)
42
  , defOpParams
43
  , MetaOpCode(..)
44
  , resolveDependencies
45
  , wrapOpCode
46
  , setOpComment
47
  , setOpPriority
48
  ) where
49

    
50
import Data.List (intercalate)
51
import Data.Map (Map)
52
import qualified Text.JSON
53
import Text.JSON (readJSON, JSObject, JSON, JSValue(..), makeObj, fromJSObject)
54

    
55
import qualified Ganeti.Constants as C
56
import qualified Ganeti.Hs2Py.OpDoc as OpDoc
57
import Ganeti.JSON (DictObject(..))
58
import Ganeti.OpParams
59
import Ganeti.PyValue ()
60
import Ganeti.Query.Language (queryTypeOpToRaw)
61
import Ganeti.THH
62
import Ganeti.Types
63

    
64
instance PyValue DiskIndex where
65
  showValue = showValue . unDiskIndex
66

    
67
instance PyValue IDiskParams where
68
  showValue _ = error "OpCodes.showValue(IDiskParams): unhandled case"
69

    
70
instance PyValue RecreateDisksInfo where
71
  showValue RecreateDisksAll = "[]"
72
  showValue (RecreateDisksIndices is) = showValue is
73
  showValue (RecreateDisksParams is) = showValue is
74

    
75
instance PyValue a => PyValue (SetParamsMods a) where
76
  showValue SetParamsEmpty = "[]"
77
  showValue _ = error "OpCodes.showValue(SetParamsMods): unhandled case"
78

    
79
instance PyValue a => PyValue (NonNegative a) where
80
  showValue = showValue . fromNonNegative
81

    
82
instance PyValue a => PyValue (NonEmpty a) where
83
  showValue = showValue . fromNonEmpty
84

    
85
-- FIXME: should use the 'toRaw' function instead of being harcoded or
86
-- perhaps use something similar to the NonNegative type instead of
87
-- using the declareSADT
88
instance PyValue ExportMode where
89
  showValue ExportModeLocal = show C.exportModeLocal
90
  showValue ExportModeRemote = show C.exportModeLocal
91

    
92
instance PyValue CVErrorCode where
93
  showValue = cVErrorCodeToRaw
94

    
95
instance PyValue VerifyOptionalChecks where
96
  showValue = verifyOptionalChecksToRaw
97

    
98
instance PyValue INicParams where
99
  showValue = error "instance PyValue INicParams: not implemented"
100

    
101
instance PyValue a => PyValue (JSObject a) where
102
  showValue obj =
103
    "{" ++ intercalate ", " (map showPair (fromJSObject obj)) ++ "}"
104
    where showPair (k, v) = show k ++ ":" ++ showValue v
105

    
106
instance PyValue JSValue where
107
  showValue (JSObject obj) = showValue obj
108
  showValue x = show x
109

    
110
type JobIdListOnly = Map String [(Bool, Either String JobId)]
111

    
112
type InstanceMultiAllocResponse =
113
  ([(Bool, Either String JobId)], NonEmptyString)
114

    
115
type QueryFieldDef =
116
  (NonEmptyString, NonEmptyString, TagKind, NonEmptyString)
117

    
118
type QueryResponse =
119
  ([QueryFieldDef], [[(QueryResultCode, JSValue)]])
120

    
121
type QueryFieldsResponse = [QueryFieldDef]
122

    
123
-- | OpCode representation.
124
--
125
-- We only implement a subset of Ganeti opcodes: those which are actually used
126
-- in the htools codebase.
127
$(genOpCode "OpCode"
128
  [ ("OpClusterPostInit",
129
     [t| Bool |],
130
     OpDoc.opClusterPostInit,
131
     [],
132
     [])
133
  , ("OpClusterDestroy",
134
     [t| NonEmptyString |],
135
     OpDoc.opClusterDestroy,
136
     [],
137
     [])
138
  , ("OpClusterQuery",
139
     [t| JSObject JSValue |],
140
     OpDoc.opClusterQuery,
141
     [],
142
     [])
143
  , ("OpClusterVerify",
144
     [t| JobIdListOnly |],
145
     OpDoc.opClusterVerify,
146
     [ pDebugSimulateErrors
147
     , pErrorCodes
148
     , pSkipChecks
149
     , pIgnoreErrors
150
     , pVerbose
151
     , pOptGroupName
152
     ],
153
     [])
154
  , ("OpClusterVerifyConfig",
155
     [t| Bool |],
156
     OpDoc.opClusterVerifyConfig,
157
     [ pDebugSimulateErrors
158
     , pErrorCodes
159
     , pIgnoreErrors
160
     , pVerbose
161
     ],
162
     [])
163
  , ("OpClusterVerifyGroup",
164
     [t| Bool |],
165
     OpDoc.opClusterVerifyGroup,
166
     [ pGroupName
167
     , pDebugSimulateErrors
168
     , pErrorCodes
169
     , pSkipChecks
170
     , pIgnoreErrors
171
     , pVerbose
172
     ],
173
     "group_name")
174
  , ("OpClusterVerifyDisks",
175
     [t| JobIdListOnly |],
176
     OpDoc.opClusterVerifyDisks,
177
     [],
178
     [])
179
  , ("OpGroupVerifyDisks",
180
     [t| (Map String String, [String], Map String [[String]]) |],
181
     OpDoc.opGroupVerifyDisks,
182
     [ pGroupName
183
     ],
184
     "group_name")
185
  , ("OpClusterRepairDiskSizes",
186
     [t| [(NonEmptyString, NonNegative Int, NonEmptyString, NonNegative Int)]|],
187
     OpDoc.opClusterRepairDiskSizes,
188
     [ pInstances
189
     ],
190
     [])
191
  , ("OpClusterConfigQuery",
192
     [t| [JSValue] |],
193
     OpDoc.opClusterConfigQuery,
194
     [ pOutputFields
195
     ],
196
     [])
197
  , ("OpClusterRename",
198
      [t| NonEmptyString |],
199
      OpDoc.opClusterRename,
200
     [ pName
201
     ],
202
     "name")
203
  , ("OpClusterSetParams",
204
     [t| Either () JobIdListOnly |],
205
     OpDoc.opClusterSetParams,
206
     [ pForce
207
     , pHvState
208
     , pDiskState
209
     , pVgName
210
     , pEnabledHypervisors
211
     , pClusterHvParams
212
     , pClusterBeParams
213
     , pOsHvp
214
     , pClusterOsParams
215
     , pClusterOsParamsPrivate
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
     , pNetworkMacPrefix
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
     , pDelayInterruptible
827
     ],
828
     "duration")
829
  , ("OpTestAllocator",
830
     [t| String |],
831
     OpDoc.opTestAllocator,
832
     [ pIAllocatorDirection
833
     , pIAllocatorMode
834
     , pIAllocatorReqName
835
     , pIAllocatorNics
836
     , pIAllocatorDisks
837
     , pHypervisor
838
     , pIallocator
839
     , pInstTags
840
     , pIAllocatorMemory
841
     , pIAllocatorVCpus
842
     , pIAllocatorOs
843
     , pDiskTemplate
844
     , pIAllocatorInstances
845
     , pIAllocatorEvacMode
846
     , pTargetGroups
847
     , pIAllocatorSpindleUse
848
     , pIAllocatorCount
849
     ],
850
     "iallocator")
851
  , ("OpTestJqueue",
852
     [t| Bool |],
853
     OpDoc.opTestJqueue,
854
     [ pJQueueNotifyWaitLock
855
     , pJQueueNotifyExec
856
     , pJQueueLogMessages
857
     , pJQueueFail
858
     ],
859
     [])
860
  , ("OpTestDummy",
861
     [t| () |],
862
     OpDoc.opTestDummy,
863
     [ pTestDummyResult
864
     , pTestDummyMessages
865
     , pTestDummyFail
866
     , pTestDummySubmitJobs
867
     ],
868
     [])
869
  , ("OpNetworkAdd",
870
     [t| () |],
871
     OpDoc.opNetworkAdd,
872
     [ pNetworkName
873
     , pNetworkAddress4
874
     , pNetworkGateway4
875
     , pNetworkAddress6
876
     , pNetworkGateway6
877
     , pNetworkMacPrefix
878
     , pNetworkAddRsvdIps
879
     , pIpConflictsCheck
880
     , withDoc "Network tags" pInstTags
881
     ],
882
     "network_name")
883
  , ("OpNetworkRemove",
884
     [t| () |],
885
     OpDoc.opNetworkRemove,
886
     [ pNetworkName
887
     , pForce
888
     ],
889
     "network_name")
890
  , ("OpNetworkSetParams",
891
     [t| () |],
892
     OpDoc.opNetworkSetParams,
893
     [ pNetworkName
894
     , pNetworkGateway4
895
     , pNetworkAddress6
896
     , pNetworkGateway6
897
     , pNetworkMacPrefix
898
     , withDoc "Which external IP addresses to reserve" pNetworkAddRsvdIps
899
     , pNetworkRemoveRsvdIps
900
     ],
901
     "network_name")
902
  , ("OpNetworkConnect",
903
     [t| () |],
904
     OpDoc.opNetworkConnect,
905
     [ pGroupName
906
     , pNetworkName
907
     , pNetworkMode
908
     , pNetworkLink
909
     , pIpConflictsCheck
910
     ],
911
     "network_name")
912
  , ("OpNetworkDisconnect",
913
     [t| () |],
914
     OpDoc.opNetworkDisconnect,
915
     [ pGroupName
916
     , pNetworkName
917
     ],
918
     "network_name")
919
  ])
920

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

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

    
927
-- | Convert the opcode name to lowercase with underscores and strip
928
-- the @Op@ prefix.
929
$(genOpLowerStrip (C.opcodeReasonSrcOpcode ++ ":") ''OpCode "opReasonSrcID")
930

    
931
instance JSON OpCode where
932
  readJSON = loadOpCode
933
  showJSON = saveOpCode
934

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

    
990
-- | Computes the summary of the opcode.
991
opSummary :: OpCode -> String
992
opSummary op =
993
  case opSummaryVal op of
994
    Nothing -> op_suffix
995
    Just s -> op_suffix ++ "(" ++ s ++ ")"
996
  where op_suffix = drop 3 $ opID op
997

    
998
-- | Generic\/common opcode parameters.
999
$(buildObject "CommonOpParams" "op"
1000
  [ pDryRun
1001
  , pDebugLevel
1002
  , pOpPriority
1003
  , pDependencies
1004
  , pComment
1005
  , pReason
1006
  ])
1007

    
1008
-- | Default common parameter values.
1009
defOpParams :: CommonOpParams
1010
defOpParams =
1011
  CommonOpParams { opDryRun     = Nothing
1012
                 , opDebugLevel = Nothing
1013
                 , opPriority   = OpPrioNormal
1014
                 , opDepends    = Nothing
1015
                 , opComment    = Nothing
1016
                 , opReason     = []
1017
                 }
1018

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

    
1026
-- | The top-level opcode type.
1027
data MetaOpCode = MetaOpCode { metaParams :: CommonOpParams
1028
                             , metaOpCode :: OpCode
1029
                             } deriving (Show, Eq)
1030

    
1031
-- | Resolve relative dependencies to absolute ones, given the job Id.
1032
resolveDependencies :: (Monad m) => MetaOpCode -> JobId -> m MetaOpCode
1033
resolveDependencies mopc jid = do
1034
  mpar <- resolveDependsCommon (metaParams mopc) jid
1035
  return (mopc { metaParams = mpar })
1036

    
1037
-- | JSON serialisation for 'MetaOpCode'.
1038
showMeta :: MetaOpCode -> JSValue
1039
showMeta (MetaOpCode params op) =
1040
  let objparams = toDict params
1041
      objop = toDictOpCode op
1042
  in makeObj (objparams ++ objop)
1043

    
1044
-- | JSON deserialisation for 'MetaOpCode'
1045
readMeta :: JSValue -> Text.JSON.Result MetaOpCode
1046
readMeta v = do
1047
  meta <- readJSON v
1048
  op <- readJSON v
1049
  return $ MetaOpCode meta op
1050

    
1051
instance JSON MetaOpCode where
1052
  showJSON = showMeta
1053
  readJSON = readMeta
1054

    
1055
-- | Wraps an 'OpCode' with the default parameters to build a
1056
-- 'MetaOpCode'.
1057
wrapOpCode :: OpCode -> MetaOpCode
1058
wrapOpCode = MetaOpCode defOpParams
1059

    
1060
-- | Sets the comment on a meta opcode.
1061
setOpComment :: String -> MetaOpCode -> MetaOpCode
1062
setOpComment comment (MetaOpCode common op) =
1063
  MetaOpCode (common { opComment = Just comment}) op
1064

    
1065
-- | Sets the priority on a meta opcode.
1066
setOpPriority :: OpSubmitPriority -> MetaOpCode -> MetaOpCode
1067
setOpPriority prio (MetaOpCode common op) =
1068
  MetaOpCode (common { opPriority = prio }) op