Statistics
| Branch: | Tag: | Revision:

root / src / Ganeti / OpCodes.hs @ 803dafcd

History | View | Annotate | Download (27.1 kB)

1
{-# LANGUAGE ExistentialQuantification, TemplateHaskell #-}
2
{-# OPTIONS_GHC -fno-warn-orphans #-}
3

    
4
{-| Implementation of the opcodes.
5

    
6
-}
7

    
8
{-
9

    
10
Copyright (C) 2009, 2010, 2011, 2012, 2013 Google Inc.
11

    
12
This program is free software; you can redistribute it and/or modify
13
it under the terms of the GNU General Public License as published by
14
the Free Software Foundation; either version 2 of the License, or
15
(at your option) any later version.
16

    
17
This program is distributed in the hope that it will be useful, but
18
WITHOUT ANY WARRANTY; without even the implied warranty of
19
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20
General Public License for more details.
21

    
22
You should have received a copy of the GNU General Public License
23
along with this program; if not, write to the Free Software
24
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25
02110-1301, USA.
26

    
27
-}
28

    
29
module Ganeti.OpCodes
30
  ( pyClasses
31
  , OpCode(..)
32
  , ReplaceDisksMode(..)
33
  , DiskIndex
34
  , mkDiskIndex
35
  , unDiskIndex
36
  , opID
37
  , 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.OpParams
58
import Ganeti.PyValue ()
59
import Ganeti.Query.Language (queryTypeOpToRaw)
60
import Ganeti.THH
61
import Ganeti.Types
62

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

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

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

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

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

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

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

    
91
instance PyValue CVErrorCode where
92
  showValue = cVErrorCodeToRaw
93

    
94
instance PyValue VerifyOptionalChecks where
95
  showValue = verifyOptionalChecksToRaw
96

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

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

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

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

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

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

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

    
120
type QueryFieldsResponse = [QueryFieldDef]
121

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

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

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

    
915
-- | Convert the opcode name to lowercase with underscores and strip
916
-- the @Op@ prefix.
917
$(genOpLowerStrip (C.opcodeReasonSrcOpcode ++ ":") ''OpCode "opReasonSrcID")
918

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

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

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

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

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

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

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

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

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

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

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

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

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

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