Statistics
| Branch: | Tag: | Revision:

root / src / Ganeti / OpCodes.hs @ a82a94e1

History | View | Annotate | Download (16.9 kB)

1
{-# LANGUAGE TemplateHaskell #-}
2

    
3
{-| Implementation of the opcodes.
4

    
5
-}
6

    
7
{-
8

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

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

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

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

    
26
-}
27

    
28
module Ganeti.OpCodes
29
  ( OpCode(..)
30
  , TagObject(..)
31
  , tagObjectFrom
32
  , encodeTagObject
33
  , decodeTagObject
34
  , ReplaceDisksMode(..)
35
  , DiskIndex
36
  , mkDiskIndex
37
  , unDiskIndex
38
  , opID
39
  , allOpIDs
40
  , allOpFields
41
  , opSummary
42
  , CommonOpParams(..)
43
  , defOpParams
44
  , MetaOpCode(..)
45
  , wrapOpCode
46
  , setOpComment
47
  , setOpPriority
48
  ) where
49

    
50
import Data.Maybe (fromMaybe)
51
import Text.JSON (readJSON, JSON, JSValue, makeObj)
52
import qualified Text.JSON
53

    
54
import Ganeti.THH
55

    
56
import Ganeti.OpParams
57
import Ganeti.Types (OpSubmitPriority(..), fromNonEmpty)
58
import Ganeti.Query.Language (queryTypeOpToRaw)
59

    
60
-- | OpCode representation.
61
--
62
-- We only implement a subset of Ganeti opcodes: those which are actually used
63
-- in the htools codebase.
64
$(genOpCode "OpCode"
65
  [ ("OpTestDelay",
66
     [ pDelayDuration
67
     , pDelayOnMaster
68
     , pDelayOnNodes
69
     , pDelayRepeat
70
     ])
71
  , ("OpInstanceReplaceDisks",
72
     [ pInstanceName
73
     , pEarlyRelease
74
     , pIgnoreIpolicy
75
     , pReplaceDisksMode
76
     , pReplaceDisksList
77
     , pRemoteNode
78
     , pIallocator
79
     ])
80
  , ("OpInstanceFailover",
81
     [ pInstanceName
82
     , pShutdownTimeout
83
     , pIgnoreConsistency
84
     , pMigrationTargetNode
85
     , pIgnoreIpolicy
86
     , pIallocator
87
     , pMigrationCleanup
88
     ])
89
  , ("OpInstanceMigrate",
90
     [ pInstanceName
91
     , pMigrationMode
92
     , pMigrationLive
93
     , pMigrationTargetNode
94
     , pAllowRuntimeChgs
95
     , pIgnoreIpolicy
96
     , pMigrationCleanup
97
     , pIallocator
98
     , pAllowFailover
99
     ])
100
  , ("OpTagsGet",
101
     [ pTagsObject
102
     , pUseLocking
103
     ])
104
  , ("OpTagsSearch",
105
     [ pTagSearchPattern ])
106
  , ("OpTagsSet",
107
     [ pTagsObject
108
     , pTagsList
109
     ])
110
  , ("OpTagsDel",
111
     [ pTagsObject
112
     , pTagsList
113
     ])
114
  , ("OpClusterPostInit", [])
115
  , ("OpClusterDestroy", [])
116
  , ("OpClusterQuery", [])
117
  , ("OpClusterVerify",
118
     [ pDebugSimulateErrors
119
     , pErrorCodes
120
     , pSkipChecks
121
     , pIgnoreErrors
122
     , pVerbose
123
     , pOptGroupName
124
     ])
125
  , ("OpClusterVerifyConfig",
126
     [ pDebugSimulateErrors
127
     , pErrorCodes
128
     , pIgnoreErrors
129
     , pVerbose
130
     ])
131
  , ("OpClusterVerifyGroup",
132
     [ pGroupName
133
     , pDebugSimulateErrors
134
     , pErrorCodes
135
     , pSkipChecks
136
     , pIgnoreErrors
137
     , pVerbose
138
     ])
139
  , ("OpClusterVerifyDisks", [])
140
  , ("OpGroupVerifyDisks",
141
     [ pGroupName
142
     ])
143
  , ("OpClusterRepairDiskSizes",
144
     [ pInstances
145
     ])
146
  , ("OpClusterConfigQuery",
147
     [ pOutputFields
148
     ])
149
  , ("OpClusterRename",
150
     [ pName
151
     ])
152
  , ("OpClusterSetParams",
153
     [ pForce
154
     , pHvState
155
     , pDiskState
156
     , pVgName
157
     , pEnabledHypervisors
158
     , pClusterHvParams
159
     , pClusterBeParams
160
     , pOsHvp
161
     , pClusterOsParams
162
     , pDiskParams
163
     , pCandidatePoolSize
164
     , pUidPool
165
     , pAddUids
166
     , pRemoveUids
167
     , pMaintainNodeHealth
168
     , pPreallocWipeDisks
169
     , pNicParams
170
     , pNdParams
171
     , pIpolicy
172
     , pDrbdHelper
173
     , pDefaultIAllocator
174
     , pMasterNetdev
175
     , pMasterNetmask
176
     , pReservedLvs
177
     , pHiddenOs
178
     , pBlacklistedOs
179
     , pUseExternalMipScript
180
     , pEnabledDiskTemplates
181
     , pModifyEtcHosts
182
     ])
183
  , ("OpClusterRedistConf", [])
184
  , ("OpClusterActivateMasterIp", [])
185
  , ("OpClusterDeactivateMasterIp", [])
186
  , ("OpQuery",
187
     [ pQueryWhat
188
     , pUseLocking
189
     , pQueryFields
190
     , pQueryFilter
191
     ])
192
  , ("OpQueryFields",
193
     [ pQueryWhat
194
     , pQueryFields
195
     ])
196
  , ("OpOobCommand",
197
     [ pNodeNames
198
     , pOobCommand
199
     , pOobTimeout
200
     , pIgnoreStatus
201
     , pPowerDelay
202
     ])
203
  , ("OpNodeRemove", [ pNodeName ])
204
  , ("OpNodeAdd",
205
     [ pNodeName
206
     , pHvState
207
     , pDiskState
208
     , pPrimaryIp
209
     , pSecondaryIp
210
     , pReadd
211
     , pNodeGroup
212
     , pMasterCapable
213
     , pVmCapable
214
     , pNdParams
215
    ])
216
  , ("OpNodeQuery", dOldQuery)
217
  , ("OpNodeQueryvols",
218
     [ pOutputFields
219
     , pNodes
220
     ])
221
  , ("OpNodeQueryStorage",
222
     [ pOutputFields
223
     , pStorageType
224
     , pNodes
225
     , pStorageName
226
     ])
227
  , ("OpNodeModifyStorage",
228
     [ pNodeName
229
     , pStorageType
230
     , pStorageName
231
     , pStorageChanges
232
     ])
233
  , ("OpRepairNodeStorage",
234
     [ pNodeName
235
     , pStorageType
236
     , pStorageName
237
     , pIgnoreConsistency
238
     ])
239
  , ("OpNodeSetParams",
240
     [ pNodeName
241
     , pForce
242
     , pHvState
243
     , pDiskState
244
     , pMasterCandidate
245
     , pOffline
246
     , pDrained
247
     , pAutoPromote
248
     , pMasterCapable
249
     , pVmCapable
250
     , pSecondaryIp
251
     , pNdParams
252
     , pPowered
253
     ])
254
  , ("OpNodePowercycle",
255
     [ pNodeName
256
     , pForce
257
     ])
258
  , ("OpNodeMigrate",
259
     [ pNodeName
260
     , pMigrationMode
261
     , pMigrationLive
262
     , pMigrationTargetNode
263
     , pAllowRuntimeChgs
264
     , pIgnoreIpolicy
265
     , pIallocator
266
     ])
267
  , ("OpNodeEvacuate",
268
     [ pEarlyRelease
269
     , pNodeName
270
     , pRemoteNode
271
     , pIallocator
272
     , pEvacMode
273
     ])
274
  , ("OpInstanceCreate",
275
     [ pInstanceName
276
     , pForceVariant
277
     , pWaitForSync
278
     , pNameCheck
279
     , pIgnoreIpolicy
280
     , pInstBeParams
281
     , pInstDisks
282
     , pDiskTemplate
283
     , pFileDriver
284
     , pFileStorageDir
285
     , pInstHvParams
286
     , pHypervisor
287
     , pIallocator
288
     , pResetDefaults
289
     , pIpCheck
290
     , pIpConflictsCheck
291
     , pInstCreateMode
292
     , pInstNics
293
     , pNoInstall
294
     , pInstOsParams
295
     , pInstOs
296
     , pPrimaryNode
297
     , pSecondaryNode
298
     , pSourceHandshake
299
     , pSourceInstance
300
     , pSourceShutdownTimeout
301
     , pSourceX509Ca
302
     , pSrcNode
303
     , pSrcPath
304
     , pStartInstance
305
     , pOpportunisticLocking
306
     , pInstTags
307
     ])
308
  , ("OpInstanceMultiAlloc",
309
     [ pIallocator
310
     , pMultiAllocInstances
311
     , pOpportunisticLocking
312
     ])
313
  , ("OpInstanceReinstall",
314
     [ pInstanceName
315
     , pForceVariant
316
     , pInstOs
317
     , pTempOsParams
318
     ])
319
  , ("OpInstanceSnapshot",
320
     [ pInstanceName
321
     , pInstSnaps
322
     ])
323
  , ("OpInstanceRemove",
324
     [ pInstanceName
325
     , pShutdownTimeout
326
     , pIgnoreFailures
327
     , pKeepDisks
328
     ])
329
  , ("OpInstanceRename",
330
     [ pInstanceName
331
     , pNewName
332
     , pNameCheck
333
     , pIpCheck
334
     ])
335
  , ("OpInstanceStartup",
336
     [ pInstanceName
337
     , pForce
338
     , pIgnoreOfflineNodes
339
     , pTempHvParams
340
     , pTempBeParams
341
     , pNoRemember
342
     , pStartupPaused
343
     ])
344
  , ("OpInstanceShutdown",
345
     [ pInstanceName
346
     , pForce
347
     , pIgnoreOfflineNodes
348
     , pShutdownTimeout'
349
     , pNoRemember
350
     ])
351
  , ("OpInstanceReboot",
352
     [ pInstanceName
353
     , pShutdownTimeout
354
     , pIgnoreSecondaries
355
     , pRebootType
356
     ])
357
  , ("OpInstanceMove",
358
     [ pInstanceName
359
     , pShutdownTimeout
360
     , pIgnoreIpolicy
361
     , pMoveTargetNode
362
     , pIgnoreConsistency
363
     ])
364
  , ("OpInstanceConsole",
365
     [ pInstanceName ])
366
  , ("OpInstanceActivateDisks",
367
     [ pInstanceName
368
     , pIgnoreDiskSize
369
     , pWaitForSyncFalse
370
     ])
371
  , ("OpInstanceDeactivateDisks",
372
     [ pInstanceName
373
     , pForce
374
     ])
375
  , ("OpInstanceRecreateDisks",
376
     [ pInstanceName
377
     , pRecreateDisksInfo
378
     , pNodes
379
     , pIallocator
380
     ])
381
  , ("OpInstanceQuery", dOldQuery)
382
  , ("OpInstanceQueryData",
383
     [ pUseLocking
384
     , pInstances
385
     , pStatic
386
     ])
387
  , ("OpInstanceSetParams",
388
     [ pInstanceName
389
     , pForce
390
     , pForceVariant
391
     , pIgnoreIpolicy
392
     , pInstParamsNicChanges
393
     , pInstParamsDiskChanges
394
     , pInstBeParams
395
     , pRuntimeMem
396
     , pInstHvParams
397
     , pOptDiskTemplate
398
     , pPrimaryNode
399
     , pRemoteNode
400
     , pOsNameChange
401
     , pInstOsParams
402
     , pWaitForSync
403
     , pOffline
404
     , pIpConflictsCheck
405
     , pHotplug
406
     , pHotplugIfPossible
407
     , pKeepDisks
408
     ])
409
  , ("OpInstanceGrowDisk",
410
     [ pInstanceName
411
     , pWaitForSync
412
     , pDiskIndex
413
     , pDiskChgAmount
414
     , pDiskChgAbsolute
415
     ])
416
  , ("OpInstanceChangeGroup",
417
     [ pInstanceName
418
     , pEarlyRelease
419
     , pIallocator
420
     , pTargetGroups
421
     ])
422
  , ("OpGroupAdd",
423
     [ pGroupName
424
     , pNodeGroupAllocPolicy
425
     , pGroupNodeParams
426
     , pDiskParams
427
     , pHvState
428
     , pDiskState
429
     , pIpolicy
430
     ])
431
  , ("OpGroupAssignNodes",
432
     [ pGroupName
433
     , pForce
434
     , pRequiredNodes
435
     ])
436
  , ("OpGroupQuery", dOldQueryNoLocking)
437
  , ("OpGroupSetParams",
438
     [ pGroupName
439
     , pNodeGroupAllocPolicy
440
     , pGroupNodeParams
441
     , pDiskParams
442
     , pHvState
443
     , pDiskState
444
     , pIpolicy
445
     ])
446
  , ("OpGroupRemove",
447
     [ pGroupName ])
448
  , ("OpGroupRename",
449
     [ pGroupName
450
     , pNewName
451
     ])
452
  , ("OpGroupEvacuate",
453
     [ pGroupName
454
     , pEarlyRelease
455
     , pIallocator
456
     , pTargetGroups
457
     ])
458
  , ("OpOsDiagnose",
459
     [ pOutputFields
460
     , pNames ])
461
  , ("OpExtStorageDiagnose",
462
     [ pOutputFields
463
     , pNames ])
464
  , ("OpBackupQuery",
465
     [ pUseLocking
466
     , pNodes
467
     ])
468
  , ("OpBackupPrepare",
469
     [ pInstanceName
470
     , pExportMode
471
     ])
472
  , ("OpBackupExport",
473
     [ pInstanceName
474
     , pShutdownTimeout
475
     , pExportTargetNode
476
     , pShutdownInstance
477
     , pRemoveInstance
478
     , pIgnoreRemoveFailures
479
     , pExportMode
480
     , pX509KeyName
481
     , pX509DestCA
482
     ])
483
  , ("OpBackupRemove",
484
     [ pInstanceName ])
485
  , ("OpTestAllocator",
486
     [ pIAllocatorDirection
487
     , pIAllocatorMode
488
     , pIAllocatorReqName
489
     , pIAllocatorNics
490
     , pIAllocatorDisks
491
     , pHypervisor
492
     , pIallocator
493
     , pInstTags
494
     , pIAllocatorMemory
495
     , pIAllocatorVCpus
496
     , pIAllocatorOs
497
     , pDiskTemplate
498
     , pIAllocatorInstances
499
     , pIAllocatorEvacMode
500
     , pTargetGroups
501
     , pIAllocatorSpindleUse
502
     , pIAllocatorCount
503
     ])
504
  , ("OpTestJqueue",
505
     [ pJQueueNotifyWaitLock
506
     , pJQueueNotifyExec
507
     , pJQueueLogMessages
508
     , pJQueueFail
509
     ])
510
  , ("OpTestDummy",
511
     [ pTestDummyResult
512
     , pTestDummyMessages
513
     , pTestDummyFail
514
     , pTestDummySubmitJobs
515
     ])
516
  , ("OpNetworkAdd",
517
     [ pNetworkName
518
     , pNetworkAddress4
519
     , pNetworkGateway4
520
     , pNetworkAddress6
521
     , pNetworkGateway6
522
     , pNetworkMacPrefix
523
     , pNetworkAddRsvdIps
524
     , pIpConflictsCheck
525
     , pInstTags
526
     ])
527
  , ("OpNetworkRemove",
528
     [ pNetworkName
529
     , pForce
530
     ])
531
  , ("OpNetworkSetParams",
532
     [ pNetworkName
533
     , pNetworkGateway4
534
     , pNetworkAddress6
535
     , pNetworkGateway6
536
     , pNetworkMacPrefix
537
     , pNetworkAddRsvdIps
538
     , pNetworkRemoveRsvdIps
539
     ])
540
  , ("OpNetworkConnect",
541
     [ pGroupName
542
     , pNetworkName
543
     , pNetworkMode
544
     , pNetworkLink
545
     , pIpConflictsCheck
546
     ])
547
  , ("OpNetworkDisconnect",
548
     [ pGroupName
549
     , pNetworkName
550
     ])
551
  , ("OpNetworkQuery", dOldQuery)
552
  , ("OpRestrictedCommand",
553
     [ pUseLocking
554
     , pRequiredNodes
555
     , pRestrictedCommand
556
     ])
557
  ])
558

    
559
-- | Returns the OP_ID for a given opcode value.
560
$(genOpID ''OpCode "opID")
561

    
562
-- | A list of all defined/supported opcode IDs.
563
$(genAllOpIDs ''OpCode "allOpIDs")
564

    
565
instance JSON OpCode where
566
  readJSON = loadOpCode
567
  showJSON = saveOpCode
568

    
569
-- | Generates the summary value for an opcode.
570
opSummaryVal :: OpCode -> Maybe String
571
opSummaryVal OpClusterVerifyGroup { opGroupName = s } = Just (fromNonEmpty s)
572
opSummaryVal OpGroupVerifyDisks { opGroupName = s } = Just (fromNonEmpty s)
573
opSummaryVal OpClusterRename { opName = s } = Just (fromNonEmpty s)
574
opSummaryVal OpQuery { opWhat = s } = Just (queryTypeOpToRaw s)
575
opSummaryVal OpQueryFields { opWhat = s } = Just (queryTypeOpToRaw s)
576
opSummaryVal OpNodeRemove { opNodeName = s } = Just (fromNonEmpty s)
577
opSummaryVal OpNodeAdd { opNodeName = s } = Just (fromNonEmpty s)
578
opSummaryVal OpNodeModifyStorage { opNodeName = s } = Just (fromNonEmpty s)
579
opSummaryVal OpRepairNodeStorage  { opNodeName = s } = Just (fromNonEmpty s)
580
opSummaryVal OpNodeSetParams { opNodeName = s } = Just (fromNonEmpty s)
581
opSummaryVal OpNodePowercycle { opNodeName = s } = Just (fromNonEmpty s)
582
opSummaryVal OpNodeMigrate { opNodeName = s } = Just (fromNonEmpty s)
583
opSummaryVal OpNodeEvacuate { opNodeName = s } = Just (fromNonEmpty s)
584
opSummaryVal OpInstanceCreate { opInstanceName = s } = Just s
585
opSummaryVal OpInstanceReinstall { opInstanceName = s } = Just s
586
opSummaryVal OpInstanceSnapshot { opInstanceName = s } = Just s
587
opSummaryVal OpInstanceRemove { opInstanceName = s } = Just s
588
-- FIXME: instance rename should show both names; currently it shows none
589
-- opSummaryVal OpInstanceRename { opInstanceName = s } = Just s
590
opSummaryVal OpInstanceStartup { opInstanceName = s } = Just s
591
opSummaryVal OpInstanceShutdown { opInstanceName = s } = Just s
592
opSummaryVal OpInstanceReboot { opInstanceName = s } = Just s
593
opSummaryVal OpInstanceReplaceDisks { opInstanceName = s } = Just s
594
opSummaryVal OpInstanceFailover { opInstanceName = s } = Just s
595
opSummaryVal OpInstanceMigrate { opInstanceName = s } = Just s
596
opSummaryVal OpInstanceMove { opInstanceName = s } = Just s
597
opSummaryVal OpInstanceConsole { opInstanceName = s } = Just s
598
opSummaryVal OpInstanceActivateDisks { opInstanceName = s } = Just s
599
opSummaryVal OpInstanceDeactivateDisks { opInstanceName = s } = Just s
600
opSummaryVal OpInstanceRecreateDisks { opInstanceName = s } = Just s
601
opSummaryVal OpInstanceSetParams { opInstanceName = s } = Just s
602
opSummaryVal OpInstanceGrowDisk { opInstanceName = s } = Just s
603
opSummaryVal OpInstanceChangeGroup { opInstanceName = s } = Just s
604
opSummaryVal OpGroupAdd { opGroupName = s } = Just (fromNonEmpty s)
605
opSummaryVal OpGroupAssignNodes { opGroupName = s } = Just (fromNonEmpty s)
606
opSummaryVal OpGroupSetParams { opGroupName = s } = Just (fromNonEmpty s)
607
opSummaryVal OpGroupRemove { opGroupName = s } = Just (fromNonEmpty s)
608
opSummaryVal OpGroupEvacuate { opGroupName = s } = Just (fromNonEmpty s)
609
opSummaryVal OpBackupPrepare { opInstanceName = s } = Just s
610
opSummaryVal OpBackupExport { opInstanceName = s } = Just s
611
opSummaryVal OpBackupRemove { opInstanceName = s } = Just s
612
opSummaryVal OpTagsGet { opKind = k } =
613
  Just . fromMaybe "None" $ tagNameOf k
614
opSummaryVal OpTagsSearch { opTagSearchPattern = s } = Just (fromNonEmpty s)
615
opSummaryVal OpTestDelay { opDelayDuration = d } = Just (show d)
616
opSummaryVal OpTestAllocator { opIallocator = s } =
617
  -- FIXME: Python doesn't handle None fields well, so we have behave the same
618
  Just $ maybe "None" fromNonEmpty s
619
opSummaryVal OpNetworkAdd { opNetworkName = s} = Just (fromNonEmpty s)
620
opSummaryVal OpNetworkRemove { opNetworkName = s} = Just (fromNonEmpty s)
621
opSummaryVal OpNetworkSetParams { opNetworkName = s} = Just (fromNonEmpty s)
622
opSummaryVal OpNetworkConnect { opNetworkName = s} = Just (fromNonEmpty s)
623
opSummaryVal OpNetworkDisconnect { opNetworkName = s} = Just (fromNonEmpty s)
624
opSummaryVal _ = Nothing
625

    
626
-- | Computes the summary of the opcode.
627
opSummary :: OpCode -> String
628
opSummary op =
629
  case opSummaryVal op of
630
    Nothing -> op_suffix
631
    Just s -> op_suffix ++ "(" ++ s ++ ")"
632
  where op_suffix = drop 3 $ opID op
633

    
634
-- | Generic\/common opcode parameters.
635
$(buildObject "CommonOpParams" "op"
636
  [ pDryRun
637
  , pDebugLevel
638
  , pOpPriority
639
  , pDependencies
640
  , pComment
641
  , pReason
642
  ])
643

    
644
-- | Default common parameter values.
645
defOpParams :: CommonOpParams
646
defOpParams =
647
  CommonOpParams { opDryRun     = Nothing
648
                 , opDebugLevel = Nothing
649
                 , opPriority   = OpPrioNormal
650
                 , opDepends    = Nothing
651
                 , opComment    = Nothing
652
                 , opReason     = []
653
                 }
654

    
655
-- | The top-level opcode type.
656
data MetaOpCode = MetaOpCode { metaParams :: CommonOpParams
657
                             , metaOpCode :: OpCode
658
                             } deriving (Show, Eq)
659

    
660
-- | JSON serialisation for 'MetaOpCode'.
661
showMeta :: MetaOpCode -> JSValue
662
showMeta (MetaOpCode params op) =
663
  let objparams = toDictCommonOpParams params
664
      objop = toDictOpCode op
665
  in makeObj (objparams ++ objop)
666

    
667
-- | JSON deserialisation for 'MetaOpCode'
668
readMeta :: JSValue -> Text.JSON.Result MetaOpCode
669
readMeta v = do
670
  meta <- readJSON v
671
  op <- readJSON v
672
  return $ MetaOpCode meta op
673

    
674
instance JSON MetaOpCode where
675
  showJSON = showMeta
676
  readJSON = readMeta
677

    
678
-- | Wraps an 'OpCode' with the default parameters to build a
679
-- 'MetaOpCode'.
680
wrapOpCode :: OpCode -> MetaOpCode
681
wrapOpCode = MetaOpCode defOpParams
682

    
683
-- | Sets the comment on a meta opcode.
684
setOpComment :: String -> MetaOpCode -> MetaOpCode
685
setOpComment comment (MetaOpCode common op) =
686
  MetaOpCode (common { opComment = Just comment}) op
687

    
688
-- | Sets the priority on a meta opcode.
689
setOpPriority :: OpSubmitPriority -> MetaOpCode -> MetaOpCode
690
setOpPriority prio (MetaOpCode common op) =
691
  MetaOpCode (common { opPriority = prio }) op