Revision 65e183af lib/opcodes.py

b/lib/opcodes.py
33 33
# few public methods:
34 34
# pylint: disable-msg=R0903
35 35

  
36
from ganeti import constants
37
from ganeti import errors
38
from ganeti import ht
39

  
40

  
41
# Common opcode attributes
42

  
43
#: output fields for a query operation
44
_POutputFields = ("output_fields", ht.NoDefault, ht.TListOf(ht.TNonEmptyString))
45

  
46
#: the shutdown timeout
47
_PShutdownTimeout = ("shutdown_timeout", constants.DEFAULT_SHUTDOWN_TIMEOUT,
48
                     ht.TPositiveInt)
49

  
50
#: the force parameter
51
_PForce = ("force", False, ht.TBool)
52

  
53
#: a required instance name (for single-instance LUs)
54
_PInstanceName = ("instance_name", ht.NoDefault, ht.TNonEmptyString)
55

  
56
#: Whether to ignore offline nodes
57
_PIgnoreOfflineNodes = ("ignore_offline_nodes", False, ht.TBool)
58

  
59
#: a required node name (for single-node LUs)
60
_PNodeName = ("node_name", ht.NoDefault, ht.TNonEmptyString)
61

  
62
#: a required node group name (for single-group LUs)
63
_PGroupName = ("group_name", ht.NoDefault, ht.TNonEmptyString)
64

  
65
#: Migration type (live/non-live)
66
_PMigrationMode = ("mode", None,
67
                   ht.TOr(ht.TNone, ht.TElemOf(constants.HT_MIGRATION_MODES)))
68

  
69
#: Obsolete 'live' migration mode (boolean)
70
_PMigrationLive = ("live", None, ht.TMaybeBool)
71

  
72
#: Tag type
73
_PTagKind = ("kind", ht.NoDefault, ht.TElemOf(constants.VALID_TAG_TYPES))
74

  
75
#: List of tag strings
76
_PTags = ("tags", ht.NoDefault, ht.TListOf(ht.TNonEmptyString))
77

  
78

  
79
def RequireFileStorage():
80
  """Checks that file storage is enabled.
81

  
82
  While it doesn't really fit into this module, L{utils} was deemed too large
83
  of a dependency to be imported for just one or two functions.
84

  
85
  @raise errors.OpPrereqError: when file storage is disabled
86

  
87
  """
88
  if not constants.ENABLE_FILE_STORAGE:
89
    raise errors.OpPrereqError("File storage disabled at configure time",
90
                               errors.ECODE_INVAL)
91

  
92

  
93
def _CheckDiskTemplate(template):
94
  """Ensure a given disk template is valid.
95

  
96
  """
97
  if template not in constants.DISK_TEMPLATES:
98
    # Using str.join directly to avoid importing utils for CommaJoin
99
    msg = ("Invalid disk template name '%s', valid templates are: %s" %
100
           (template, ", ".join(constants.DISK_TEMPLATES)))
101
    raise errors.OpPrereqError(msg, errors.ECODE_INVAL)
102
  if template == constants.DT_FILE:
103
    RequireFileStorage()
104
  return True
105

  
106

  
107
def _CheckStorageType(storage_type):
108
  """Ensure a given storage type is valid.
109

  
110
  """
111
  if storage_type not in constants.VALID_STORAGE_TYPES:
112
    raise errors.OpPrereqError("Unknown storage type: %s" % storage_type,
113
                               errors.ECODE_INVAL)
114
  if storage_type == constants.ST_FILE:
115
    RequireFileStorage()
116
  return True
117

  
118

  
119
#: Storage type parameter
120
_PStorageType = ("storage_type", ht.NoDefault, _CheckStorageType)
121

  
122

  
123
class _AutoOpParamSlots(type):
124
  """Meta class for opcode definitions.
125

  
126
  """
127
  def __new__(mcs, name, bases, attrs):
128
    """Called when a class should be created.
129

  
130
    @param mcs: The meta class
131
    @param name: Name of created class
132
    @param bases: Base classes
133
    @type attrs: dict
134
    @param attrs: Class attributes
135

  
136
    """
137
    assert "__slots__" not in attrs, \
138
      "Class '%s' defines __slots__ when it should use OP_PARAMS" % name
139
    assert "OP_ID" in attrs, "Class '%s' is missing OP_ID attribute" % name
140

  
141
    # Always set OP_PARAMS to avoid duplicates in BaseOpCode.GetAllParams
142
    params = attrs.setdefault("OP_PARAMS", [])
143

  
144
    # Use parameter names as slots
145
    slots = [pname for (pname, _, _) in params]
146

  
147
    assert "OP_DSC_FIELD" not in attrs or attrs["OP_DSC_FIELD"] in slots, \
148
      "Class '%s' uses unknown field in OP_DSC_FIELD" % name
149

  
150
    attrs["__slots__"] = slots
151

  
152
    return type.__new__(mcs, name, bases, attrs)
153

  
36 154

  
37 155
class BaseOpCode(object):
38 156
  """A simple serializable object.
......
41 159
  field handling.
42 160

  
43 161
  """
44
  __slots__ = []
162
  __metaclass__ = _AutoOpParamSlots
163

  
164
  OP_ID = None
45 165

  
46 166
  def __init__(self, **kwargs):
47 167
    """Constructor for BaseOpCode.
......
106 226
      slots.extend(getattr(parent, "__slots__", []))
107 227
    return slots
108 228

  
229
  @classmethod
230
  def GetAllParams(cls):
231
    """Compute list of all parameters for an opcode.
232

  
233
    """
234
    slots = []
235
    for parent in cls.__mro__:
236
      slots.extend(getattr(parent, "OP_PARAMS", []))
237
    return slots
238

  
109 239

  
110 240
class OpCode(BaseOpCode):
111 241
  """Abstract OpCode.
......
118 248
  @cvar OP_DSC_FIELD: The name of a field whose value will be included in the
119 249
                      string returned by Summary(); see the docstring of that
120 250
                      method for details).
251
  @cvar OP_PARAMS: List of opcode attributes, the default values they should
252
                   get if not already defined, and types they must match.
121 253
  @ivar dry_run: Whether the LU should be run in dry-run mode, i.e. just
122 254
                 the check steps
123 255
  @ivar priority: Opcode priority for queue
124 256

  
125 257
  """
126 258
  OP_ID = "OP_ABSTRACT"
127
  __slots__ = ["dry_run", "debug_level", "priority"]
259
  OP_PARAMS = [
260
    ("dry_run", None, ht.TMaybeBool),
261
    ("debug_level", None, ht.TOr(ht.TNone, ht.TPositiveInt)),
262
    ("priority", constants.OP_PRIO_DEFAULT,
263
     ht.TElemOf(constants.OP_PRIO_SUBMIT_VALID)),
264
    ]
128 265

  
129 266
  def __getstate__(self):
130 267
    """Specialized getstate for opcodes.
......
200 337

  
201 338
  """
202 339
  OP_ID = "OP_CLUSTER_POST_INIT"
203
  __slots__ = []
204 340

  
205 341

  
206 342
class OpDestroyCluster(OpCode):
......
211 347

  
212 348
  """
213 349
  OP_ID = "OP_CLUSTER_DESTROY"
214
  __slots__ = []
215 350

  
216 351

  
217 352
class OpQueryClusterInfo(OpCode):
218 353
  """Query cluster information."""
219 354
  OP_ID = "OP_CLUSTER_QUERY"
220
  __slots__ = []
221 355

  
222 356

  
223 357
class OpVerifyCluster(OpCode):
......
231 365

  
232 366
  """
233 367
  OP_ID = "OP_CLUSTER_VERIFY"
234
  __slots__ = ["skip_checks", "verbose", "error_codes",
235
               "debug_simulate_errors"]
368
  OP_PARAMS = [
369
    ("skip_checks", ht.EmptyList,
370
     ht.TListOf(ht.TElemOf(constants.VERIFY_OPTIONAL_CHECKS))),
371
    ("verbose", False, ht.TBool),
372
    ("error_codes", False, ht.TBool),
373
    ("debug_simulate_errors", False, ht.TBool),
374
    ]
236 375

  
237 376

  
238 377
class OpVerifyDisks(OpCode):
......
257 396

  
258 397
  """
259 398
  OP_ID = "OP_CLUSTER_VERIFY_DISKS"
260
  __slots__ = []
261 399

  
262 400

  
263 401
class OpRepairDiskSizes(OpCode):
......
277 415

  
278 416
  """
279 417
  OP_ID = "OP_CLUSTER_REPAIR_DISK_SIZES"
280
  __slots__ = ["instances"]
418
  OP_PARAMS = [
419
    ("instances", ht.EmptyList, ht.TListOf(ht.TNonEmptyString)),
420
    ]
281 421

  
282 422

  
283 423
class OpQueryConfigValues(OpCode):
284 424
  """Query cluster configuration values."""
285 425
  OP_ID = "OP_CLUSTER_CONFIG_QUERY"
286
  __slots__ = ["output_fields"]
426
  OP_PARAMS = [
427
    _POutputFields
428
    ]
287 429

  
288 430

  
289 431
class OpRenameCluster(OpCode):
......
297 439
  """
298 440
  OP_ID = "OP_CLUSTER_RENAME"
299 441
  OP_DSC_FIELD = "name"
300
  __slots__ = ["name"]
442
  OP_PARAMS = [
443
    ("name", ht.NoDefault, ht.TNonEmptyString),
444
    ]
301 445

  
302 446

  
303 447
class OpSetClusterParams(OpCode):
......
308 452

  
309 453
  """
310 454
  OP_ID = "OP_CLUSTER_SET_PARAMS"
311
  __slots__ = [
312
    "vg_name",
313
    "drbd_helper",
314
    "enabled_hypervisors",
315
    "hvparams",
316
    "os_hvp",
317
    "beparams",
318
    "osparams",
319
    "nicparams",
320
    "ndparams",
321
    "candidate_pool_size",
322
    "maintain_node_health",
323
    "uid_pool",
324
    "add_uids",
325
    "remove_uids",
326
    "default_iallocator",
327
    "reserved_lvs",
328
    "hidden_os",
329
    "blacklisted_os",
330
    "prealloc_wipe_disks",
331
    "master_netdev",
455
  OP_PARAMS = [
456
    ("vg_name", None, ht.TMaybeString),
457
    ("enabled_hypervisors", None,
458
     ht.TOr(ht.TAnd(ht.TListOf(ht.TElemOf(constants.HYPER_TYPES)), ht.TTrue),
459
            ht.TNone)),
460
    ("hvparams", None, ht.TOr(ht.TDictOf(ht.TNonEmptyString, ht.TDict),
461
                              ht.TNone)),
462
    ("beparams", None, ht.TOr(ht.TDict, ht.TNone)),
463
    ("os_hvp", None, ht.TOr(ht.TDictOf(ht.TNonEmptyString, ht.TDict),
464
                            ht.TNone)),
465
    ("osparams", None, ht.TOr(ht.TDictOf(ht.TNonEmptyString, ht.TDict),
466
                              ht.TNone)),
467
    ("candidate_pool_size", None, ht.TOr(ht.TStrictPositiveInt, ht.TNone)),
468
    ("uid_pool", None, ht.NoType),
469
    ("add_uids", None, ht.NoType),
470
    ("remove_uids", None, ht.NoType),
471
    ("maintain_node_health", None, ht.TMaybeBool),
472
    ("prealloc_wipe_disks", None, ht.TMaybeBool),
473
    ("nicparams", None, ht.TOr(ht.TDict, ht.TNone)),
474
    ("ndparams", None, ht.TOr(ht.TDict, ht.TNone)),
475
    ("drbd_helper", None, ht.TOr(ht.TString, ht.TNone)),
476
    ("default_iallocator", None, ht.TOr(ht.TString, ht.TNone)),
477
    ("master_netdev", None, ht.TOr(ht.TString, ht.TNone)),
478
    ("reserved_lvs", None, ht.TOr(ht.TListOf(ht.TNonEmptyString), ht.TNone)),
479
    ("hidden_os", None, ht.TOr(ht.TListOf(
480
          ht.TAnd(ht.TList,
481
                ht.TIsLength(2),
482
                ht.TMap(lambda v: v[0], ht.TElemOf(constants.DDMS_VALUES)))),
483
          ht.TNone)),
484
    ("blacklisted_os", None, ht.TOr(ht.TListOf(
485
          ht.TAnd(ht.TList,
486
                ht.TIsLength(2),
487
                ht.TMap(lambda v: v[0], ht.TElemOf(constants.DDMS_VALUES)))),
488
          ht.TNone)),
332 489
    ]
333 490

  
334 491

  
......
337 494

  
338 495
  """
339 496
  OP_ID = "OP_CLUSTER_REDIST_CONF"
340
  __slots__ = []
341 497

  
342 498

  
343 499
class OpQuery(OpCode):
......
349 505

  
350 506
  """
351 507
  OP_ID = "OP_QUERY"
352
  __slots__ = [
353
    "what",
354
    "fields",
355
    "filter",
508
  OP_PARAMS = [
509
    ("what", ht.NoDefault, ht.TElemOf(constants.QR_OP_QUERY)),
510
    ("fields", ht.NoDefault, ht.TListOf(ht.TNonEmptyString)),
511
    ("filter", None, ht.TOr(ht.TNone,
512
                            ht.TListOf(ht.TOr(ht.TNonEmptyString, ht.TList)))),
356 513
    ]
357 514

  
358 515

  
......
364 521

  
365 522
  """
366 523
  OP_ID = "OP_QUERY_FIELDS"
367
  __slots__ = [
368
    "what",
369
    "fields",
524
  OP_PARAMS = [
525
    ("what", ht.NoDefault, ht.TElemOf(constants.QR_OP_QUERY)),
526
    ("fields", None, ht.TOr(ht.TNone, ht.TListOf(ht.TNonEmptyString))),
370 527
    ]
371 528

  
372 529

  
373 530
class OpOobCommand(OpCode):
374 531
  """Interact with OOB."""
375 532
  OP_ID = "OP_OOB_COMMAND"
376
  __slots__ = [
377
    "node_name",
378
    "command",
379
    "timeout",
533
  OP_PARAMS = [
534
    _PNodeName,
535
    ("command", None, ht.TElemOf(constants.OOB_COMMANDS)),
536
    ("timeout", constants.OOB_TIMEOUT, ht.TInt),
380 537
    ]
381 538

  
382 539

  
......
392 549
  """
393 550
  OP_ID = "OP_NODE_REMOVE"
394 551
  OP_DSC_FIELD = "node_name"
395
  __slots__ = ["node_name"]
552
  OP_PARAMS = [
553
    _PNodeName,
554
    ]
396 555

  
397 556

  
398 557
class OpAddNode(OpCode):
......
425 584
  """
426 585
  OP_ID = "OP_NODE_ADD"
427 586
  OP_DSC_FIELD = "node_name"
428
  __slots__ = ["node_name", "primary_ip", "secondary_ip", "readd", "group",
429
               "vm_capable", "master_capable", "ndparams"]
587
  OP_PARAMS = [
588
    _PNodeName,
589
    ("primary_ip", None, ht.NoType),
590
    ("secondary_ip", None, ht.TMaybeString),
591
    ("readd", False, ht.TBool),
592
    ("group", None, ht.TMaybeString),
593
    ("master_capable", None, ht.TMaybeBool),
594
    ("vm_capable", None, ht.TMaybeBool),
595
    ("ndparams", None, ht.TOr(ht.TDict, ht.TNone)),
596
    ]
430 597

  
431 598

  
432 599
class OpQueryNodes(OpCode):
433 600
  """Compute the list of nodes."""
434 601
  OP_ID = "OP_NODE_QUERY"
435
  __slots__ = ["output_fields", "names", "use_locking"]
602
  OP_PARAMS = [
603
    _POutputFields,
604
    ("names", ht.EmptyList, ht.TListOf(ht.TNonEmptyString)),
605
    ("use_locking", False, ht.TBool),
606
    ]
436 607

  
437 608

  
438 609
class OpQueryNodeVolumes(OpCode):
439 610
  """Get list of volumes on node."""
440 611
  OP_ID = "OP_NODE_QUERYVOLS"
441
  __slots__ = ["nodes", "output_fields"]
612
  OP_PARAMS = [
613
    _POutputFields,
614
    ("nodes", ht.EmptyList, ht.TListOf(ht.TNonEmptyString)),
615
    ]
442 616

  
443 617

  
444 618
class OpQueryNodeStorage(OpCode):
445 619
  """Get information on storage for node(s)."""
446 620
  OP_ID = "OP_NODE_QUERY_STORAGE"
447
  __slots__ = [
448
    "nodes",
449
    "storage_type",
450
    "name",
451
    "output_fields",
621
  OP_PARAMS = [
622
    _POutputFields,
623
    _PStorageType,
624
    ("nodes", ht.EmptyList, ht.TListOf(ht.TNonEmptyString)),
625
    ("name", None, ht.TMaybeString),
452 626
    ]
453 627

  
454 628

  
455 629
class OpModifyNodeStorage(OpCode):
456 630
  """Modifies the properies of a storage unit"""
457 631
  OP_ID = "OP_NODE_MODIFY_STORAGE"
458
  __slots__ = [
459
    "node_name",
460
    "storage_type",
461
    "name",
462
    "changes",
632
  OP_PARAMS = [
633
    _PNodeName,
634
    _PStorageType,
635
    ("name", ht.NoDefault, ht.TNonEmptyString),
636
    ("changes", ht.NoDefault, ht.TDict),
463 637
    ]
464 638

  
465 639

  
......
467 641
  """Repairs the volume group on a node."""
468 642
  OP_ID = "OP_REPAIR_NODE_STORAGE"
469 643
  OP_DSC_FIELD = "node_name"
470
  __slots__ = [
471
    "node_name",
472
    "storage_type",
473
    "name",
474
    "ignore_consistency",
644
  OP_PARAMS = [
645
    _PNodeName,
646
    _PStorageType,
647
    ("name", ht.NoDefault, ht.TNonEmptyString),
648
    ("ignore_consistency", False, ht.TBool),
475 649
    ]
476 650

  
477 651

  
......
479 653
  """Change the parameters of a node."""
480 654
  OP_ID = "OP_NODE_SET_PARAMS"
481 655
  OP_DSC_FIELD = "node_name"
482
  __slots__ = [
483
    "node_name",
484
    "force",
485
    "master_candidate",
486
    "offline",
487
    "drained",
488
    "auto_promote",
489
    "master_capable",
490
    "vm_capable",
491
    "secondary_ip",
492
    "ndparams",
493
    "powered",
656
  OP_PARAMS = [
657
    _PNodeName,
658
    _PForce,
659
    ("master_candidate", None, ht.TMaybeBool),
660
    ("offline", None, ht.TMaybeBool),
661
    ("drained", None, ht.TMaybeBool),
662
    ("auto_promote", False, ht.TBool),
663
    ("master_capable", None, ht.TMaybeBool),
664
    ("vm_capable", None, ht.TMaybeBool),
665
    ("secondary_ip", None, ht.TMaybeString),
666
    ("ndparams", None, ht.TOr(ht.TDict, ht.TNone)),
667
    ("powered", None, ht.TMaybeBool),
494 668
    ]
495 669

  
496 670

  
......
498 672
  """Tries to powercycle a node."""
499 673
  OP_ID = "OP_NODE_POWERCYCLE"
500 674
  OP_DSC_FIELD = "node_name"
501
  __slots__ = [
502
    "node_name",
503
    "force",
675
  OP_PARAMS = [
676
    _PNodeName,
677
    _PForce,
504 678
    ]
505 679

  
506 680

  
......
508 682
  """Migrate all instances from a node."""
509 683
  OP_ID = "OP_NODE_MIGRATE"
510 684
  OP_DSC_FIELD = "node_name"
511
  __slots__ = [
512
    "node_name",
513
    "mode",
514
    "live",
685
  OP_PARAMS = [
686
    _PNodeName,
687
    _PMigrationMode,
688
    _PMigrationLive,
515 689
    ]
516 690

  
517 691

  
......
519 693
  """Compute the evacuation strategy for a list of nodes."""
520 694
  OP_ID = "OP_NODE_EVAC_STRATEGY"
521 695
  OP_DSC_FIELD = "nodes"
522
  __slots__ = ["nodes", "iallocator", "remote_node"]
696
  OP_PARAMS = [
697
    ("nodes", ht.NoDefault, ht.TListOf(ht.TNonEmptyString)),
698
    ("remote_node", None, ht.TMaybeString),
699
    ("iallocator", None, ht.TMaybeString),
700
    ]
523 701

  
524 702

  
525 703
# instance opcodes
......
538 716
  """
539 717
  OP_ID = "OP_INSTANCE_CREATE"
540 718
  OP_DSC_FIELD = "instance_name"
541
  __slots__ = [
542
    "instance_name",
543
    "os_type", "force_variant", "no_install",
544
    "pnode", "disk_template", "snode", "mode",
545
    "disks", "nics",
546
    "src_node", "src_path", "start", "identify_defaults",
547
    "wait_for_sync", "ip_check", "name_check",
548
    "file_storage_dir", "file_driver",
549
    "iallocator",
550
    "hypervisor", "hvparams", "beparams", "osparams",
551
    "source_handshake",
552
    "source_x509_ca",
553
    "source_instance_name",
554
    "source_shutdown_timeout",
719
  OP_PARAMS = [
720
    _PInstanceName,
721
    ("beparams", ht.EmptyDict, ht.TDict),
722
    ("disks", ht.NoDefault, ht.TListOf(ht.TDict)),
723
    ("disk_template", ht.NoDefault, _CheckDiskTemplate),
724
    ("file_driver", None, ht.TOr(ht.TNone, ht.TElemOf(constants.FILE_DRIVER))),
725
    ("file_storage_dir", None, ht.TMaybeString),
726
    ("force_variant", False, ht.TBool),
727
    ("hvparams", ht.EmptyDict, ht.TDict),
728
    ("hypervisor", None, ht.TMaybeString),
729
    ("iallocator", None, ht.TMaybeString),
730
    ("identify_defaults", False, ht.TBool),
731
    ("ip_check", True, ht.TBool),
732
    ("mode", ht.NoDefault, ht.TElemOf(constants.INSTANCE_CREATE_MODES)),
733
    ("name_check", True, ht.TBool),
734
    ("nics", ht.NoDefault, ht.TListOf(ht.TDict)),
735
    ("no_install", None, ht.TMaybeBool),
736
    ("osparams", ht.EmptyDict, ht.TDict),
737
    ("os_type", None, ht.TMaybeString),
738
    ("pnode", None, ht.TMaybeString),
739
    ("snode", None, ht.TMaybeString),
740
    ("source_handshake", None, ht.TOr(ht.TList, ht.TNone)),
741
    ("source_instance_name", None, ht.TMaybeString),
742
    ("source_shutdown_timeout", constants.DEFAULT_SHUTDOWN_TIMEOUT,
743
     ht.TPositiveInt),
744
    ("source_x509_ca", None, ht.TMaybeString),
745
    ("src_node", None, ht.TMaybeString),
746
    ("src_path", None, ht.TMaybeString),
747
    ("start", True, ht.TBool),
748
    ("wait_for_sync", True, ht.TBool),
555 749
    ]
556 750

  
557 751

  
......
559 753
  """Reinstall an instance's OS."""
560 754
  OP_ID = "OP_INSTANCE_REINSTALL"
561 755
  OP_DSC_FIELD = "instance_name"
562
  __slots__ = ["instance_name", "os_type", "force_variant", "osparams"]
756
  OP_PARAMS = [
757
    _PInstanceName,
758
    ("os_type", None, ht.TMaybeString),
759
    ("force_variant", False, ht.TBool),
760
    ("osparams", None, ht.TOr(ht.TDict, ht.TNone)),
761
    ]
563 762

  
564 763

  
565 764
class OpRemoveInstance(OpCode):
566 765
  """Remove an instance."""
567 766
  OP_ID = "OP_INSTANCE_REMOVE"
568 767
  OP_DSC_FIELD = "instance_name"
569
  __slots__ = [
570
    "instance_name",
571
    "ignore_failures",
572
    "shutdown_timeout",
768
  OP_PARAMS = [
769
    _PInstanceName,
770
    _PShutdownTimeout,
771
    ("ignore_failures", False, ht.TBool),
573 772
    ]
574 773

  
575 774

  
576 775
class OpRenameInstance(OpCode):
577 776
  """Rename an instance."""
578 777
  OP_ID = "OP_INSTANCE_RENAME"
579
  __slots__ = [
580
    "instance_name", "ip_check", "new_name", "name_check",
778
  OP_PARAMS = [
779
    _PInstanceName,
780
    ("new_name", ht.NoDefault, ht.TNonEmptyString),
781
    ("ip_check", False, ht.TBool),
782
    ("name_check", True, ht.TBool),
581 783
    ]
582 784

  
583 785

  
......
585 787
  """Startup an instance."""
586 788
  OP_ID = "OP_INSTANCE_STARTUP"
587 789
  OP_DSC_FIELD = "instance_name"
588
  __slots__ = [
589
    "instance_name", "force", "hvparams", "beparams", "ignore_offline_nodes",
790
  OP_PARAMS = [
791
    _PInstanceName,
792
    _PForce,
793
    _PIgnoreOfflineNodes,
794
    ("hvparams", ht.EmptyDict, ht.TDict),
795
    ("beparams", ht.EmptyDict, ht.TDict),
590 796
    ]
591 797

  
592 798

  
......
594 800
  """Shutdown an instance."""
595 801
  OP_ID = "OP_INSTANCE_SHUTDOWN"
596 802
  OP_DSC_FIELD = "instance_name"
597
  __slots__ = [
598
    "instance_name", "timeout", "ignore_offline_nodes",
803
  OP_PARAMS = [
804
    _PInstanceName,
805
    _PIgnoreOfflineNodes,
806
    ("timeout", constants.DEFAULT_SHUTDOWN_TIMEOUT, ht.TPositiveInt),
599 807
    ]
600 808

  
601 809

  
......
603 811
  """Reboot an instance."""
604 812
  OP_ID = "OP_INSTANCE_REBOOT"
605 813
  OP_DSC_FIELD = "instance_name"
606
  __slots__ = [
607
    "instance_name", "reboot_type", "ignore_secondaries", "shutdown_timeout",
814
  OP_PARAMS = [
815
    _PInstanceName,
816
    _PShutdownTimeout,
817
    ("ignore_secondaries", False, ht.TBool),
818
    ("reboot_type", ht.NoDefault, ht.TElemOf(constants.REBOOT_TYPES)),
608 819
    ]
609 820

  
610 821

  
......
612 823
  """Replace the disks of an instance."""
613 824
  OP_ID = "OP_INSTANCE_REPLACE_DISKS"
614 825
  OP_DSC_FIELD = "instance_name"
615
  __slots__ = [
616
    "instance_name", "remote_node", "mode", "disks", "iallocator",
617
    "early_release",
826
  OP_PARAMS = [
827
    _PInstanceName,
828
    ("mode", ht.NoDefault, ht.TElemOf(constants.REPLACE_MODES)),
829
    ("disks", ht.EmptyList, ht.TListOf(ht.TPositiveInt)),
830
    ("remote_node", None, ht.TMaybeString),
831
    ("iallocator", None, ht.TMaybeString),
832
    ("early_release", False, ht.TBool),
618 833
    ]
619 834

  
620 835

  
......
622 837
  """Failover an instance."""
623 838
  OP_ID = "OP_INSTANCE_FAILOVER"
624 839
  OP_DSC_FIELD = "instance_name"
625
  __slots__ = [
626
    "instance_name", "ignore_consistency", "shutdown_timeout",
840
  OP_PARAMS = [
841
    _PInstanceName,
842
    _PShutdownTimeout,
843
    ("ignore_consistency", False, ht.TBool),
627 844
    ]
628 845

  
629 846

  
......
639 856
  """
640 857
  OP_ID = "OP_INSTANCE_MIGRATE"
641 858
  OP_DSC_FIELD = "instance_name"
642
  __slots__ = ["instance_name", "mode", "cleanup", "live"]
859
  OP_PARAMS = [
860
    _PInstanceName,
861
    _PMigrationMode,
862
    _PMigrationLive,
863
    ("cleanup", False, ht.TBool),
864
    ]
643 865

  
644 866

  
645 867
class OpMoveInstance(OpCode):
......
654 876
  """
655 877
  OP_ID = "OP_INSTANCE_MOVE"
656 878
  OP_DSC_FIELD = "instance_name"
657
  __slots__ = [
658
    "instance_name", "target_node", "shutdown_timeout",
879
  OP_PARAMS = [
880
    _PInstanceName,
881
    _PShutdownTimeout,
882
    ("target_node", ht.NoDefault, ht.TNonEmptyString),
659 883
    ]
660 884

  
661 885

  
......
663 887
  """Connect to an instance's console."""
664 888
  OP_ID = "OP_INSTANCE_CONSOLE"
665 889
  OP_DSC_FIELD = "instance_name"
666
  __slots__ = ["instance_name"]
890
  OP_PARAMS = [
891
    _PInstanceName
892
    ]
667 893

  
668 894

  
669 895
class OpActivateInstanceDisks(OpCode):
670 896
  """Activate an instance's disks."""
671 897
  OP_ID = "OP_INSTANCE_ACTIVATE_DISKS"
672 898
  OP_DSC_FIELD = "instance_name"
673
  __slots__ = ["instance_name", "ignore_size"]
899
  OP_PARAMS = [
900
    _PInstanceName,
901
    ("ignore_size", False, ht.TBool),
902
    ]
674 903

  
675 904

  
676 905
class OpDeactivateInstanceDisks(OpCode):
677 906
  """Deactivate an instance's disks."""
678 907
  OP_ID = "OP_INSTANCE_DEACTIVATE_DISKS"
679 908
  OP_DSC_FIELD = "instance_name"
680
  __slots__ = ["instance_name"]
909
  OP_PARAMS = [
910
    _PInstanceName
911
    ]
681 912

  
682 913

  
683 914
class OpRecreateInstanceDisks(OpCode):
684 915
  """Deactivate an instance's disks."""
685 916
  OP_ID = "OP_INSTANCE_RECREATE_DISKS"
686 917
  OP_DSC_FIELD = "instance_name"
687
  __slots__ = ["instance_name", "disks"]
918
  OP_PARAMS = [
919
    _PInstanceName,
920
    ("disks", ht.EmptyList, ht.TListOf(ht.TPositiveInt)),
921
    ]
688 922

  
689 923

  
690 924
class OpQueryInstances(OpCode):
691 925
  """Compute the list of instances."""
692 926
  OP_ID = "OP_INSTANCE_QUERY"
693
  __slots__ = ["output_fields", "names", "use_locking"]
927
  OP_PARAMS = [
928
    _POutputFields,
929
    ("names", ht.EmptyList, ht.TListOf(ht.TNonEmptyString)),
930
    ("use_locking", False, ht.TBool),
931
    ]
694 932

  
695 933

  
696 934
class OpQueryInstanceData(OpCode):
697 935
  """Compute the run-time status of instances."""
698 936
  OP_ID = "OP_INSTANCE_QUERY_DATA"
699
  __slots__ = ["instances", "static"]
937
  OP_PARAMS = [
938
    ("instances", ht.EmptyList, ht.TListOf(ht.TNonEmptyString)),
939
    ("static", False, ht.TBool),
940
    ]
700 941

  
701 942

  
702 943
class OpSetInstanceParams(OpCode):
703 944
  """Change the parameters of an instance."""
704 945
  OP_ID = "OP_INSTANCE_SET_PARAMS"
705 946
  OP_DSC_FIELD = "instance_name"
706
  __slots__ = [
707
    "instance_name",
708
    "hvparams", "beparams", "osparams", "force",
709
    "nics", "disks", "disk_template",
710
    "remote_node", "os_name", "force_variant",
947
  OP_PARAMS = [
948
    _PInstanceName,
949
    _PForce,
950
    ("nics", ht.EmptyList, ht.TList),
951
    ("disks", ht.EmptyList, ht.TList),
952
    ("beparams", ht.EmptyDict, ht.TDict),
953
    ("hvparams", ht.EmptyDict, ht.TDict),
954
    ("disk_template", None, _CheckDiskTemplate),
955
    ("remote_node", None, ht.TMaybeString),
956
    ("os_name", None, ht.TMaybeString),
957
    ("force_variant", False, ht.TBool),
958
    ("osparams", None, ht.TOr(ht.TDict, ht.TNone)),
711 959
    ]
712 960

  
713 961

  
......
715 963
  """Grow a disk of an instance."""
716 964
  OP_ID = "OP_INSTANCE_GROW_DISK"
717 965
  OP_DSC_FIELD = "instance_name"
718
  __slots__ = [
719
    "instance_name", "disk", "amount", "wait_for_sync",
966
  OP_PARAMS = [
967
    _PInstanceName,
968
    ("disk", ht.NoDefault, ht.TInt),
969
    ("amount", ht.NoDefault, ht.TInt),
970
    ("wait_for_sync", True, ht.TBool),
720 971
    ]
721 972

  
722 973

  
......
726 977
  """Add a node group to the cluster."""
727 978
  OP_ID = "OP_GROUP_ADD"
728 979
  OP_DSC_FIELD = "group_name"
729
  __slots__ = [
730
    "group_name",
731
    "ndparams",
732
    "alloc_policy",
980
  OP_PARAMS = [
981
    _PGroupName,
982
    ("ndparams", None, ht.TOr(ht.TDict, ht.TNone)),
983
    ("alloc_policy", None,
984
     ht.TOr(ht.TNone, ht.TElemOf(constants.VALID_ALLOC_POLICIES))),
733 985
    ]
734 986

  
735 987

  
736 988
class OpQueryGroups(OpCode):
737 989
  """Compute the list of node groups."""
738 990
  OP_ID = "OP_GROUP_QUERY"
739
  __slots__ = ["output_fields", "names"]
991
  OP_PARAMS = [
992
    _POutputFields,
993
    ("names", ht.EmptyList, ht.TListOf(ht.TNonEmptyString)),
994
    ]
740 995

  
741 996

  
742 997
class OpSetGroupParams(OpCode):
743 998
  """Change the parameters of a node group."""
744 999
  OP_ID = "OP_GROUP_SET_PARAMS"
745 1000
  OP_DSC_FIELD = "group_name"
746
  __slots__ = [
747
    "group_name",
748
    "ndparams",
749
    "alloc_policy",
1001
  OP_PARAMS = [
1002
    _PGroupName,
1003
    ("ndparams", None, ht.TOr(ht.TDict, ht.TNone)),
1004
    ("alloc_policy", None, ht.TOr(ht.TNone,
1005
                                  ht.TElemOf(constants.VALID_ALLOC_POLICIES))),
750 1006
    ]
751 1007

  
752 1008

  
......
754 1010
  """Remove a node group from the cluster."""
755 1011
  OP_ID = "OP_GROUP_REMOVE"
756 1012
  OP_DSC_FIELD = "group_name"
757
  __slots__ = ["group_name"]
1013
  OP_PARAMS = [
1014
    _PGroupName,
1015
    ]
758 1016

  
759 1017

  
760 1018
class OpRenameGroup(OpCode):
761 1019
  """Rename a node group in the cluster."""
762 1020
  OP_ID = "OP_GROUP_RENAME"
763 1021
  OP_DSC_FIELD = "old_name"
764
  __slots__ = ["old_name", "new_name"]
1022
  OP_PARAMS = [
1023
    ("old_name", ht.NoDefault, ht.TNonEmptyString),
1024
    ("new_name", ht.NoDefault, ht.TNonEmptyString),
1025
    ]
765 1026

  
766 1027

  
767 1028
# OS opcodes
768 1029
class OpDiagnoseOS(OpCode):
769 1030
  """Compute the list of guest operating systems."""
770 1031
  OP_ID = "OP_OS_DIAGNOSE"
771
  __slots__ = ["output_fields", "names"]
1032
  OP_PARAMS = [
1033
    _POutputFields,
1034
    ("names", ht.EmptyList, ht.TListOf(ht.TNonEmptyString)),
1035
    ]
772 1036

  
773 1037

  
774 1038
# Exports opcodes
775 1039
class OpQueryExports(OpCode):
776 1040
  """Compute the list of exported images."""
777 1041
  OP_ID = "OP_BACKUP_QUERY"
778
  __slots__ = ["nodes", "use_locking"]
1042
  OP_PARAMS = [
1043
    ("nodes", ht.EmptyList, ht.TListOf(ht.TNonEmptyString)),
1044
    ("use_locking", False, ht.TBool),
1045
    ]
779 1046

  
780 1047

  
781 1048
class OpPrepareExport(OpCode):
......
787 1054
  """
788 1055
  OP_ID = "OP_BACKUP_PREPARE"
789 1056
  OP_DSC_FIELD = "instance_name"
790
  __slots__ = [
791
    "instance_name", "mode",
1057
  OP_PARAMS = [
1058
    _PInstanceName,
1059
    ("mode", ht.NoDefault, ht.TElemOf(constants.EXPORT_MODES)),
792 1060
    ]
793 1061

  
794 1062

  
......
810 1078
  """
811 1079
  OP_ID = "OP_BACKUP_EXPORT"
812 1080
  OP_DSC_FIELD = "instance_name"
813
  __slots__ = [
1081
  OP_PARAMS = [
1082
    _PInstanceName,
1083
    _PShutdownTimeout,
814 1084
    # TODO: Rename target_node as it changes meaning for different export modes
815 1085
    # (e.g. "destination")
816
    "instance_name", "target_node", "shutdown", "shutdown_timeout",
817
    "remove_instance",
818
    "ignore_remove_failures",
819
    "mode",
820
    "x509_key_name",
821
    "destination_x509_ca",
1086
    ("target_node", ht.NoDefault, ht.TOr(ht.TNonEmptyString, ht.TList)),
1087
    ("shutdown", True, ht.TBool),
1088
    ("remove_instance", False, ht.TBool),
1089
    ("ignore_remove_failures", False, ht.TBool),
1090
    ("mode", constants.EXPORT_MODE_LOCAL, ht.TElemOf(constants.EXPORT_MODES)),
1091
    ("x509_key_name", None, ht.TOr(ht.TList, ht.TNone)),
1092
    ("destination_x509_ca", None, ht.TMaybeString),
822 1093
    ]
823 1094

  
824 1095

  
......
826 1097
  """Remove an instance's export."""
827 1098
  OP_ID = "OP_BACKUP_REMOVE"
828 1099
  OP_DSC_FIELD = "instance_name"
829
  __slots__ = ["instance_name"]
1100
  OP_PARAMS = [
1101
    _PInstanceName,
1102
    ]
830 1103

  
831 1104

  
832 1105
# Tags opcodes
......
834 1107
  """Returns the tags of the given object."""
835 1108
  OP_ID = "OP_TAGS_GET"
836 1109
  OP_DSC_FIELD = "name"
837
  __slots__ = ["kind", "name"]
1110
  OP_PARAMS = [
1111
    _PTagKind,
1112
    # Name is only meaningful for nodes and instances
1113
    ("name", ht.NoDefault, ht.TMaybeString),
1114
    ]
838 1115

  
839 1116

  
840 1117
class OpSearchTags(OpCode):
841 1118
  """Searches the tags in the cluster for a given pattern."""
842 1119
  OP_ID = "OP_TAGS_SEARCH"
843 1120
  OP_DSC_FIELD = "pattern"
844
  __slots__ = ["pattern"]
1121
  OP_PARAMS = [
1122
    ("pattern", ht.NoDefault, ht.TNonEmptyString),
1123
    ]
845 1124

  
846 1125

  
847 1126
class OpAddTags(OpCode):
848 1127
  """Add a list of tags on a given object."""
849 1128
  OP_ID = "OP_TAGS_SET"
850
  __slots__ = ["kind", "name", "tags"]
1129
  OP_PARAMS = [
1130
    _PTagKind,
1131
    _PTags,
1132
    # Name is only meaningful for nodes and instances
1133
    ("name", ht.NoDefault, ht.TMaybeString),
1134
    ]
851 1135

  
852 1136

  
853 1137
class OpDelTags(OpCode):
854 1138
  """Remove a list of tags from a given object."""
855 1139
  OP_ID = "OP_TAGS_DEL"
856
  __slots__ = ["kind", "name", "tags"]
857

  
1140
  OP_PARAMS = [
1141
    _PTagKind,
1142
    _PTags,
1143
    # Name is only meaningful for nodes and instances
1144
    ("name", ht.NoDefault, ht.TMaybeString),
1145
    ]
858 1146

  
859 1147
# Test opcodes
860 1148
class OpTestDelay(OpCode):
......
880 1168
  """
881 1169
  OP_ID = "OP_TEST_DELAY"
882 1170
  OP_DSC_FIELD = "duration"
883
  __slots__ = ["duration", "on_master", "on_nodes", "repeat"]
1171
  OP_PARAMS = [
1172
    ("duration", ht.NoDefault, ht.TFloat),
1173
    ("on_master", True, ht.TBool),
1174
    ("on_nodes", ht.EmptyList, ht.TListOf(ht.TNonEmptyString)),
1175
    ("repeat", 0, ht.TPositiveInt)
1176
    ]
884 1177

  
885 1178

  
886 1179
class OpTestAllocator(OpCode):
......
896 1189
  """
897 1190
  OP_ID = "OP_TEST_ALLOCATOR"
898 1191
  OP_DSC_FIELD = "allocator"
899
  __slots__ = [
900
    "direction", "mode", "allocator", "name",
901
    "mem_size", "disks", "disk_template",
902
    "os", "tags", "nics", "vcpus", "hypervisor",
903
    "evac_nodes",
1192
  OP_PARAMS = [
1193
    ("direction", ht.NoDefault,
1194
     ht.TElemOf(constants.VALID_IALLOCATOR_DIRECTIONS)),
1195
    ("mode", ht.NoDefault, ht.TElemOf(constants.VALID_IALLOCATOR_MODES)),
1196
    ("name", ht.NoDefault, ht.TNonEmptyString),
1197
    ("nics", ht.NoDefault, ht.TOr(ht.TNone, ht.TListOf(
1198
      ht.TDictOf(ht.TElemOf(["mac", "ip", "bridge"]),
1199
               ht.TOr(ht.TNone, ht.TNonEmptyString))))),
1200
    ("disks", ht.NoDefault, ht.TOr(ht.TNone, ht.TList)),
1201
    ("hypervisor", None, ht.TMaybeString),
1202
    ("allocator", None, ht.TMaybeString),
1203
    ("tags", ht.EmptyList, ht.TListOf(ht.TNonEmptyString)),
1204
    ("mem_size", None, ht.TOr(ht.TNone, ht.TPositiveInt)),
1205
    ("vcpus", None, ht.TOr(ht.TNone, ht.TPositiveInt)),
1206
    ("os", None, ht.TMaybeString),
1207
    ("disk_template", None, ht.TMaybeString),
1208
    ("evac_nodes", None, ht.TOr(ht.TNone, ht.TListOf(ht.TNonEmptyString))),
904 1209
    ]
905 1210

  
906 1211

  
......
909 1214

  
910 1215
  """
911 1216
  OP_ID = "OP_TEST_JQUEUE"
912
  __slots__ = [
913
    "notify_waitlock",
914
    "notify_exec",
915
    "log_messages",
916
    "fail",
1217
  OP_PARAMS = [
1218
    ("notify_waitlock", False, ht.TBool),
1219
    ("notify_exec", False, ht.TBool),
1220
    ("log_messages", ht.EmptyList, ht.TListOf(ht.TString)),
1221
    ("fail", False, ht.TBool),
917 1222
    ]
918 1223

  
919 1224

  
......
922 1227

  
923 1228
  """
924 1229
  OP_ID = "OP_TEST_DUMMY"
925
  __slots__ = [
926
    "result",
927
    "messages",
928
    "fail",
1230
  OP_PARAMS = [
1231
    ("result", ht.NoDefault, ht.NoType),
1232
    ("messages", ht.NoDefault, ht.NoType),
1233
    ("fail", ht.NoDefault, ht.NoType),
929 1234
    ]
930 1235

  
931 1236

  

Also available in: Unified diff