Statistics
| Branch: | Tag: | Revision:

root / src / Ganeti / OpCodes.hs @ 26e32dee

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
     ],
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
-- | Convert the opcode name to lowercase with underscores and strip
927
-- the @Op@ prefix.
928
$(genOpLowerStrip (C.opcodeReasonSrcOpcode ++ ":") ''OpCode "opReasonSrcID")
929

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

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

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

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

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

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

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

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

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

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

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

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

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

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