Revision a8005e17

b/lib/cli.py
46 46
           "SubmitOpCode", "GetClient",
47 47
           "cli_option",
48 48
           "GenerateTable", "AskUser",
49
           "ARGS_NONE", "ARGS_FIXED", "ARGS_ATLEAST", "ARGS_ANY", "ARGS_ONE",
50 49
           "USEUNITS_OPT", "FIELDS_OPT", "FORCE_OPT", "SUBMIT_OPT",
51 50
           "ListTags", "AddTags", "RemoveTags", "TAG_SRC_OPT",
52 51
           "FormatError", "SplitNodeOption", "SubmitOrSend",
......
279 278
                          " check steps and verify it it could be executed")
280 279

  
281 280

  
282
def ARGS_FIXED(val):
283
  """Macro-like function denoting a fixed number of arguments"""
284
  return -val
285

  
286

  
287
def ARGS_ATLEAST(val):
288
  """Macro-like function denoting a minimum number of arguments"""
289
  return val
290

  
291

  
292
ARGS_NONE = None
293
ARGS_ONE = ARGS_FIXED(1)
294
ARGS_ANY = ARGS_ATLEAST(0)
295

  
296

  
297 281
def check_unit(option, opt, value):
298 282
  """OptParsers custom converter for units.
299 283

  
......
464 448

  
465 449
    cmd = aliases[cmd]
466 450

  
467
  func, nargs, parser_opts, usage, description = commands[cmd]
451
  func, args_def, parser_opts, usage, description = commands[cmd]
468 452
  parser = OptionParser(option_list=parser_opts + [_DRY_RUN_OPT],
469 453
                        description=description,
470 454
                        formatter=TitledHelpFormatter(),
471 455
                        usage="%%prog %s %s" % (cmd, usage))
472 456
  parser.disable_interspersed_args()
473 457
  options, args = parser.parse_args()
474
  if nargs is None:
475
    if len(args) != 0:
476
      ToStderr("Error: Command %s expects no arguments", cmd)
477
      return None, None, None
478
  elif nargs < 0 and len(args) != -nargs:
479
    ToStderr("Error: Command %s expects %d argument(s)", cmd, -nargs)
480
    return None, None, None
481
  elif nargs >= 0 and len(args) < nargs:
482
    ToStderr("Error: Command %s expects at least %d argument(s)", cmd, nargs)
458

  
459
  if not _CheckArguments(cmd, args_def, args):
483 460
    return None, None, None
484 461

  
485 462
  return func, options, args
486 463

  
487 464

  
465
def _CheckArguments(cmd, args_def, args):
466
  """Verifies the arguments using the argument definition.
467

  
468
  Algorithm:
469

  
470
    1. Abort with error if values specified by user but none expected.
471

  
472
    1. For each argument in definition
473

  
474
      1. Keep running count of minimum number of values (min_count)
475
      1. Keep running count of maximum number of values (max_count)
476
      1. If it has an unlimited number of values
477

  
478
        1. Abort with error if it's not the last argument in the definition
479

  
480
    1. If last argument has limited number of values
481

  
482
      1. Abort with error if number of values doesn't match or is too large
483

  
484
    1. Abort with error if user didn't pass enough values (min_count)
485

  
486
  """
487
  if args and not args_def:
488
    ToStderr("Error: Command %s expects no arguments", cmd)
489
    return False
490

  
491
  min_count = None
492
  max_count = None
493
  check_max = None
494

  
495
  last_idx = len(args_def) - 1
496

  
497
  for idx, arg in enumerate(args_def):
498
    if min_count is None:
499
      min_count = arg.min
500
    elif arg.min is not None:
501
      min_count += arg.min
502

  
503
    if max_count is None:
504
      max_count = arg.max
505
    elif arg.max is not None:
506
      max_count += arg.max
507

  
508
    if idx == last_idx:
509
      check_max = (arg.max is not None)
510

  
511
    elif arg.max is None:
512
      raise errors.ProgrammerError("Only the last argument can have max=None")
513

  
514
  if check_max:
515
    # Command with exact number of arguments
516
    if (min_count is not None and max_count is not None and
517
        min_count == max_count and len(args) != min_count):
518
      ToStderr("Error: Command %s expects %d argument(s)", cmd, min_count)
519
      return False
520

  
521
    # Command with limited number of arguments
522
    if max_count is not None and len(args) > max_count:
523
      ToStderr("Error: Command %s expects only %d argument(s)",
524
               cmd, max_count)
525
      return False
526

  
527
  # Command with some required arguments
528
  if min_count is not None and len(args) < min_count:
529
    ToStderr("Error: Command %s expects at least %d argument(s)",
530
             cmd, min_count)
531
    return False
532

  
533
  return True
534

  
535

  
488 536
def SplitNodeOption(value):
489 537
  """Splits the value of a --node option.
490 538

  
b/scripts/gnt-backup
35 35

  
36 36
_VALUE_TRUE = "true"
37 37

  
38

  
38 39
def PrintExportList(opts, args):
39 40
  """Prints a list of all the exported system images.
40 41

  
......
259 260
  ]
260 261

  
261 262
commands = {
262
  'list': (PrintExportList, ARGS_NONE,
263
  'list': (PrintExportList, [],
263 264
           [DEBUG_OPT,
264 265
            make_option("--node", dest="nodes", default=[], action="append",
265 266
                        help="List only backups stored on this node"
266 267
                             " (can be used multiple times)"),
267 268
            ],
268 269
           "", "Lists instance exports available in the ganeti cluster"),
269
  'export': (ExportInstance, ARGS_ONE,
270
  'export': (ExportInstance, [ArgInstance(min=1, max=1)],
270 271
             [DEBUG_OPT, FORCE_OPT,
271 272
              make_option("-n", "--node", dest="node", help="Target node",
272 273
                          metavar="<node>"),
......
275 276
                          help="Don't shutdown the instance (unsafe)"), ],
276 277
             "-n <target_node> [opts...] <name>",
277 278
             "Exports an instance to an image"),
278
  'import': (ImportInstance, ARGS_ONE, import_opts,
279
  'import': (ImportInstance, [ArgInstance(min=1, max=1)], import_opts,
279 280
             ("[...] -t disk-type -n node[:secondary-node]"
280 281
              " <name>"),
281 282
             "Imports an instance from an exported image"),
282
  'remove': (RemoveExport, ARGS_ONE,
283
  'remove': (RemoveExport, [ArgUnknown(min=1, max=1)],
283 284
             [DEBUG_OPT],
284 285
             "<name>",
285 286
             "Remove exports of named instance from the filesystem."),
286 287
  }
287 288

  
289

  
288 290
if __name__ == '__main__':
289 291
  sys.exit(GenericMain(commands))
b/scripts/gnt-cluster
542 542
                          metavar="<node>", default=[])
543 543

  
544 544
commands = {
545
  'init': (InitCluster, ARGS_ONE,
545
  'init': (InitCluster, [ArgUnknown(min=1, max=1)],
546 546
           [DEBUG_OPT,
547 547
            make_option("-s", "--secondary-ip", dest="secondary_ip",
548 548
                        help="Specify the secondary ip for this node;"
......
603 603
            ],
604 604
           "[opts...] <cluster_name>",
605 605
           "Initialises a new cluster configuration"),
606
  'destroy': (DestroyCluster, ARGS_NONE,
606
  'destroy': (DestroyCluster, [],
607 607
              [DEBUG_OPT,
608 608
               make_option("--yes-do-it", dest="yes_do_it",
609 609
                           help="Destroy cluster",
610 610
                           action="store_true"),
611 611
              ],
612 612
              "", "Destroy cluster"),
613
  'rename': (RenameCluster, ARGS_ONE, [DEBUG_OPT, FORCE_OPT],
614
               "<new_name>",
615
               "Renames the cluster"),
616
  'redist-conf': (RedistributeConfig, ARGS_NONE, [DEBUG_OPT, SUBMIT_OPT],
613
  'rename': (RenameCluster, [ArgUnknown(min=1, max=1)],
614
             [DEBUG_OPT, FORCE_OPT],
615
             "<new_name>",
616
             "Renames the cluster"),
617
  'redist-conf': (RedistributeConfig, [], [DEBUG_OPT, SUBMIT_OPT],
617 618
                  "",
618 619
                  "Forces a push of the configuration file and ssconf files"
619 620
                  " to the nodes in the cluster"),
620
  'verify': (VerifyCluster, ARGS_NONE, [DEBUG_OPT,
621
  'verify': (VerifyCluster, [], [DEBUG_OPT,
621 622
             make_option("--no-nplus1-mem", dest="skip_nplusone_mem",
622 623
                         help="Skip N+1 memory redundancy tests",
623 624
                         action="store_true",
624 625
                         default=False,),
625 626
             ],
626 627
             "", "Does a check on the cluster configuration"),
627
  'verify-disks': (VerifyDisks, ARGS_NONE, [DEBUG_OPT],
628
  'verify-disks': (VerifyDisks, [], [DEBUG_OPT],
628 629
                   "", "Does a check on the cluster disk status"),
629
  'repair-disk-sizes': (RepairDiskSizes, ARGS_ANY, [DEBUG_OPT],
630
  'repair-disk-sizes': (RepairDiskSizes, [ArgInstance()], [DEBUG_OPT],
630 631
                   "", "Updates mismatches in recorded disk sizes"),
631
  'masterfailover': (MasterFailover, ARGS_NONE, [DEBUG_OPT,
632
  'masterfailover': (MasterFailover, [], [DEBUG_OPT,
632 633
                     make_option("--no-voting", dest="no_voting",
633 634
                                 help="Skip node agreement check (dangerous)",
634 635
                                 action="store_true",
635 636
                                 default=False,),
636 637
                     ],
637 638
                     "", "Makes the current node the master"),
638
  'version': (ShowClusterVersion, ARGS_NONE, [DEBUG_OPT],
639
  'version': (ShowClusterVersion, [], [DEBUG_OPT],
639 640
              "", "Shows the cluster version"),
640
  'getmaster': (ShowClusterMaster, ARGS_NONE, [DEBUG_OPT],
641
  'getmaster': (ShowClusterMaster, [], [DEBUG_OPT],
641 642
                "", "Shows the cluster master"),
642
  'copyfile': (ClusterCopyFile, ARGS_ONE, [DEBUG_OPT, node_option],
643
  'copyfile': (ClusterCopyFile, [ArgFile(min=1, max=1)],
644
               [DEBUG_OPT, node_option],
643 645
               "[-n node...] <filename>",
644 646
               "Copies a file to all (or only some) nodes"),
645
  'command': (RunClusterCommand, ARGS_ATLEAST(1), [DEBUG_OPT, node_option],
647
  'command': (RunClusterCommand, [ArgCommand(min=1)], [DEBUG_OPT, node_option],
646 648
              "[-n node...] <command>",
647 649
              "Runs a command on all (or only some) nodes"),
648
  'info': (ShowClusterConfig, ARGS_NONE, [DEBUG_OPT],
649
                 "", "Show cluster configuration"),
650
  'list-tags': (ListTags, ARGS_NONE,
650
  'info': (ShowClusterConfig, [], [DEBUG_OPT],
651
           "", "Show cluster configuration"),
652
  'list-tags': (ListTags, [],
651 653
                [DEBUG_OPT], "", "List the tags of the cluster"),
652
  'add-tags': (AddTags, ARGS_ANY, [DEBUG_OPT, TAG_SRC_OPT],
654
  'add-tags': (AddTags, [ArgUnknown()], [DEBUG_OPT, TAG_SRC_OPT],
653 655
               "tag...", "Add tags to the cluster"),
654
  'remove-tags': (RemoveTags, ARGS_ANY, [DEBUG_OPT, TAG_SRC_OPT],
656
  'remove-tags': (RemoveTags, [ArgUnknown()], [DEBUG_OPT, TAG_SRC_OPT],
655 657
                  "tag...", "Remove tags from the cluster"),
656
  'search-tags': (SearchTags, ARGS_ONE,
658
  'search-tags': (SearchTags, [ArgUnknown(min=1, max=1)],
657 659
                  [DEBUG_OPT], "", "Searches the tags on all objects on"
658 660
                  " the cluster for a given pattern (regex)"),
659
  'queue': (QueueOps, ARGS_ONE, [DEBUG_OPT],
661
  'queue': (QueueOps,
662
            [ArgChoice(min=1, max=1, choices=["drain", "undrain", "info"])],
663
            [DEBUG_OPT],
660 664
            "drain|undrain|info", "Change queue properties"),
661
  'modify': (SetClusterParams, ARGS_NONE,
665
  'modify': (SetClusterParams, [],
662 666
             [DEBUG_OPT,
663 667
              make_option("-g", "--vg-name", dest="vg_name",
664 668
                          help="Specify the volume group name "
b/scripts/gnt-debug
131 131

  
132 132

  
133 133
commands = {
134
  'delay': (Delay, ARGS_ONE,
134
  'delay': (Delay, [ArgUnknown(min=1, max=1)],
135 135
            [DEBUG_OPT,
136 136
             make_option("--no-master", dest="on_master", default=True,
137 137
                         action="store_false",
......
141 141
                         help="Select nodes to sleep on"),
142 142
             ],
143 143
            "[opts...] <duration>", "Executes a TestDelay OpCode"),
144
  'submit-job': (GenericOpCodes, ARGS_ATLEAST(1),
145
                 [DEBUG_OPT,
146
                  ],
144
  'submit-job': (GenericOpCodes, [ArgFile(min=1)], [DEBUG_OPT],
147 145
                 "<op_list_file...>", "Submits jobs built from json files"
148 146
                 " containing a list of serialized opcodes"),
149
  'allocator': (TestAllocator, ARGS_ONE,
147
  'allocator': (TestAllocator, [ArgInstance(min=1, max=1)],
150 148
                [DEBUG_OPT,
151 149
                 make_option("--dir", dest="direction",
152 150
                             default="in", choices=["in", "out"],
b/scripts/gnt-instance
1417 1417
  ]
1418 1418

  
1419 1419
commands = {
1420
  'add': (AddInstance, ARGS_ONE, add_opts,
1420
  'add': (AddInstance, [ArgUnknown(min=1, max=1)], add_opts,
1421 1421
          "[...] -t disk-type -n node[:secondary-node] -o os-type <name>",
1422 1422
          "Creates and adds a new instance to the cluster"),
1423
  'batch-create': (BatchCreate, ARGS_ONE,
1423
  'batch-create': (BatchCreate, [ArgFile(min=1, max=1)],
1424 1424
                   [DEBUG_OPT],
1425 1425
                   "<instances_file.json>",
1426 1426
                   "Create a bunch of instances based on specs in the file."),
1427
  'console': (ConnectToInstanceConsole, ARGS_ONE,
1427
  'console': (ConnectToInstanceConsole, [ArgInstance(min=1, max=1)],
1428 1428
              [DEBUG_OPT,
1429 1429
               make_option("--show-cmd", dest="show_command",
1430 1430
                           action="store_true", default=False,
1431 1431
                           help=("Show command instead of executing it"))],
1432 1432
              "[--show-cmd] <instance>",
1433 1433
              "Opens a console on the specified instance"),
1434
  'failover': (FailoverInstance, ARGS_ONE,
1434
  'failover': (FailoverInstance, [ArgInstance(min=1, max=1)],
1435 1435
               [DEBUG_OPT, FORCE_OPT,
1436 1436
                make_option("--ignore-consistency", dest="ignore_consistency",
1437 1437
                            action="store_true", default=False,
......
1442 1442
               "[-f] <instance>",
1443 1443
               "Stops the instance and starts it on the backup node, using"
1444 1444
               " the remote mirror (only for instances of type drbd)"),
1445
  'migrate': (MigrateInstance, ARGS_ONE,
1445
  'migrate': (MigrateInstance, [ArgInstance(min=1, max=1)],
1446 1446
               [DEBUG_OPT, FORCE_OPT,
1447 1447
                make_option("--non-live", dest="live",
1448 1448
                            default=True, action="store_false",
......
1462 1462
               "[-f] <instance>",
1463 1463
               "Migrate instance to its secondary node"
1464 1464
               " (only for instances of type drbd)"),
1465
  'move': (MoveInstance, ARGS_ONE,
1465
  'move': (MoveInstance, [ArgInstance(min=1, max=1)],
1466 1466
           [DEBUG_OPT, FORCE_OPT, SUBMIT_OPT,
1467 1467
            make_option("-n", "--new-node", dest="target_node",
1468 1468
                        help="Destinattion node", metavar="NODE",
......
1471 1471
           "[-f] <instance>",
1472 1472
           "Move instance to an arbitrary node"
1473 1473
           " (only for instances of type file and lv)"),
1474
  'info': (ShowInstanceConfig, ARGS_ANY,
1474
  'info': (ShowInstanceConfig, [ArgInstance()],
1475 1475
           [DEBUG_OPT,
1476 1476
            make_option("-s", "--static", dest="static",
1477 1477
                        action="store_true", default=False,
......
1482 1482
                        " This can take a long time to run, use wisely."),
1483 1483
            ], "[-s] {--all | <instance>...}",
1484 1484
           "Show information on the specified instance(s)"),
1485
  'list': (ListInstances, ARGS_ANY,
1485
  'list': (ListInstances, [ArgInstance()],
1486 1486
           [DEBUG_OPT, NOHDR_OPT, SEP_OPT, USEUNITS_OPT, FIELDS_OPT, SYNC_OPT],
1487 1487
           "[<instance>...]",
1488 1488
           "Lists the instances and their status. The available fields are"
......
1493 1493
           " The default field"
1494 1494
           " list is (in order): %s." % ", ".join(_LIST_DEF_FIELDS),
1495 1495
           ),
1496
  'reinstall': (ReinstallInstance, ARGS_ANY,
1496
  'reinstall': (ReinstallInstance, [ArgInstance(min=1)],
1497 1497
                [DEBUG_OPT, FORCE_OPT, os_opt,
1498 1498
                 m_force_multi,
1499 1499
                 m_node_opt, m_pri_node_opt, m_sec_node_opt,
......
1505 1505
                 SUBMIT_OPT,
1506 1506
                 ],
1507 1507
                "[-f] <instance>", "Reinstall a stopped instance"),
1508
  'remove': (RemoveInstance, ARGS_ONE,
1508
  'remove': (RemoveInstance, [ArgInstance(min=1, max=1)],
1509 1509
             [DEBUG_OPT, FORCE_OPT,
1510 1510
              make_option("--ignore-failures", dest="ignore_failures",
1511 1511
                          action="store_true", default=False,
......
1515 1515
              SUBMIT_OPT,
1516 1516
              ],
1517 1517
             "[-f] <instance>", "Shuts down the instance and removes it"),
1518
  'rename': (RenameInstance, ARGS_FIXED(2),
1518
  'rename': (RenameInstance,
1519
             [ArgInstance(min=1, max=1), ArgUnknown(min=1, max=1)],
1519 1520
             [DEBUG_OPT,
1520 1521
              make_option("--no-ip-check", dest="ignore_ip",
1521 1522
                          help="Do not check that the IP of the new name"
......
1524 1525
              SUBMIT_OPT,
1525 1526
              ],
1526 1527
             "<instance> <new_name>", "Rename the instance"),
1527
  'replace-disks': (ReplaceDisks, ARGS_ONE,
1528
  'replace-disks': (ReplaceDisks, [ArgInstance(min=1, max=1)],
1528 1529
                    [DEBUG_OPT,
1529 1530
                     make_option("-n", "--new-secondary", dest="new_secondary",
1530 1531
                                 help=("New secondary node (for secondary"
......
1556 1557
                     ],
1557 1558
                    "[-s|-p|-n NODE|-I NAME] <instance>",
1558 1559
                    "Replaces all disks for the instance"),
1559
  'modify': (SetInstanceParams, ARGS_ONE,
1560
  'modify': (SetInstanceParams, [ArgInstance(min=1, max=1)],
1560 1561
             [DEBUG_OPT, FORCE_OPT,
1561 1562
              cli_option("-H", "--hypervisor", type="keyval",
1562 1563
                         default={}, dest="hypervisor",
......
1575 1576
              SUBMIT_OPT,
1576 1577
              ],
1577 1578
             "<instance>", "Alters the parameters of an instance"),
1578
  'shutdown': (ShutdownInstance, ARGS_ANY,
1579
  'shutdown': (ShutdownInstance, [ArgInstance(min=1)],
1579 1580
               [DEBUG_OPT, m_node_opt, m_pri_node_opt, m_sec_node_opt,
1580 1581
                m_clust_opt, m_inst_opt, m_force_multi,
1581 1582
                SUBMIT_OPT,
1582 1583
                ],
1583 1584
               "<instance>", "Stops an instance"),
1584
  'startup': (StartupInstance, ARGS_ANY,
1585
  'startup': (StartupInstance, [ArgInstance(min=1)],
1585 1586
              [DEBUG_OPT, FORCE_OPT, m_force_multi,
1586 1587
               m_node_opt, m_pri_node_opt, m_sec_node_opt,
1587 1588
               m_clust_opt, m_inst_opt,
......
1594 1595
                           help="Temporary backend parameters"),
1595 1596
               ],
1596 1597
              "<instance>", "Starts an instance"),
1597

  
1598
  'reboot': (RebootInstance, ARGS_ANY,
1598
  'reboot': (RebootInstance, [ArgInstance(min=1)],
1599 1599
              [DEBUG_OPT, m_force_multi,
1600 1600
               make_option("-t", "--type", dest="reboot_type",
1601 1601
                           help="Type of reboot: soft/hard/full",
......
1609 1609
               SUBMIT_OPT,
1610 1610
               ],
1611 1611
            "<instance>", "Reboots an instance"),
1612
  'activate-disks': (ActivateDisks, ARGS_ONE,
1612
  'activate-disks': (ActivateDisks, [ArgInstance(min=1, max=1)],
1613 1613
                     [DEBUG_OPT, SUBMIT_OPT,
1614 1614
                      make_option("--ignore-size", dest="ignore_size",
1615 1615
                                  default=False, action="store_true",
......
1619 1619
                      ],
1620 1620
                     "<instance>",
1621 1621
                     "Activate an instance's disks"),
1622
  'deactivate-disks': (DeactivateDisks, ARGS_ONE, [DEBUG_OPT, SUBMIT_OPT],
1622
  'deactivate-disks': (DeactivateDisks, [ArgInstance(min=1, max=1)],
1623
                       [DEBUG_OPT, SUBMIT_OPT],
1623 1624
                       "<instance>",
1624 1625
                       "Deactivate an instance's disks"),
1625
  'recreate-disks': (RecreateDisks, ARGS_ONE,
1626
  'recreate-disks': (RecreateDisks, [ArgInstance(min=1, max=1)],
1626 1627
                     [DEBUG_OPT, SUBMIT_OPT,
1627 1628
                     make_option("--disks", dest="disks", default=None,
1628 1629
                                 help="Comma-separated list of disks"
......
1631 1632
                      ],
1632 1633
                     "<instance>",
1633 1634
                     "Recreate an instance's disks"),
1634
  'grow-disk': (GrowDisk, ARGS_FIXED(3),
1635
  'grow-disk': (GrowDisk,
1636
                [ArgInstance(min=1, max=1), ArgUnknown(min=1, max=1),
1637
                 ArgUnknown(min=1, max=1)],
1635 1638
                [DEBUG_OPT, SUBMIT_OPT,
1636 1639
                 make_option("--no-wait-for-sync",
1637 1640
                             dest="wait_for_sync", default=True,
......
1639 1642
                             help="Don't wait for sync (DANGEROUS!)"),
1640 1643
                 ],
1641 1644
                "<instance> <disk> <size>", "Grow an instance's disk"),
1642
  'list-tags': (ListTags, ARGS_ONE, [DEBUG_OPT],
1645
  'list-tags': (ListTags, [ArgInstance(min=1, max=1)], [DEBUG_OPT],
1643 1646
                "<instance_name>", "List the tags of the given instance"),
1644
  'add-tags': (AddTags, ARGS_ATLEAST(1), [DEBUG_OPT, TAG_SRC_OPT],
1647
  'add-tags': (AddTags, [ArgInstance(min=1, max=1), ArgUnknown()],
1648
               [DEBUG_OPT, TAG_SRC_OPT],
1645 1649
               "<instance_name> tag...", "Add tags to the given instance"),
1646
  'remove-tags': (RemoveTags, ARGS_ATLEAST(1), [DEBUG_OPT, TAG_SRC_OPT],
1650
  'remove-tags': (RemoveTags, [ArgInstance(min=1, max=1), ArgUnknown()],
1651
                  [DEBUG_OPT, TAG_SRC_OPT],
1647 1652
                  "<instance_name> tag...", "Remove tags from given instance"),
1648 1653
  }
1649 1654

  
......
1655 1660
  'stop': 'shutdown',
1656 1661
  }
1657 1662

  
1663

  
1658 1664
if __name__ == '__main__':
1659 1665
  sys.exit(GenericMain(commands, aliases=aliases,
1660 1666
                       override={"tag_type": constants.TAG_INSTANCE}))
b/scripts/gnt-job
340 340

  
341 341

  
342 342
commands = {
343
  'list': (ListJobs, ARGS_ANY,
344
            [DEBUG_OPT, NOHDR_OPT, SEP_OPT, FIELDS_OPT],
345
            "[job_id ...]",
343
  'list': (ListJobs, [ArgJobId()],
344
           [DEBUG_OPT, NOHDR_OPT, SEP_OPT, FIELDS_OPT],
345
           "[job_id ...]",
346 346
           "List the jobs and their status. The available fields are"
347 347
           " (see the man page for details): id, status, op_list,"
348 348
           " op_status, op_result."
349 349
           " The default field"
350 350
           " list is (in order): %s." % ", ".join(_LIST_DEF_FIELDS)),
351
  'archive': (ArchiveJobs, ARGS_ANY,
352
              [DEBUG_OPT],
351
  'archive': (ArchiveJobs, [ArgJobId(min=1)], [DEBUG_OPT],
353 352
              "<job-id> [<job-id> ...]",
354 353
              "Archive specified jobs"),
355
  'autoarchive': (AutoArchiveJobs, ARGS_ONE,
356
              [DEBUG_OPT],
357
              "<age>",
358
              "Auto archive jobs older than the given age"),
359
  'cancel': (CancelJobs, ARGS_ANY,
360
             [DEBUG_OPT],
354
  'autoarchive': (AutoArchiveJobs,
355
                  [ArgSuggest(min=1, max=1, choices=["1d", "1w", "4w"])],
356
                  [DEBUG_OPT],
357
                  "<age>",
358
                  "Auto archive jobs older than the given age"),
359
  'cancel': (CancelJobs, [ArgJobId(min=1)], [DEBUG_OPT],
361 360
             "<job-id> [<job-id> ...]",
362 361
             "Cancel specified jobs"),
363
  'info': (ShowJobs, ARGS_ANY, [DEBUG_OPT],
362
  'info': (ShowJobs, [ArgJobId(min=1)], [DEBUG_OPT],
364 363
           "<job-id> [<job-id> ...]",
365 364
           "Show detailed information about the specified jobs"),
366
  'watch': (WatchJob, ARGS_ONE, [DEBUG_OPT],
367
           "<job-id>",
368
           "Follows a job and prints its output as it arrives"),
365
  'watch': (WatchJob, [ArgJobId(min=1, max=1)], [DEBUG_OPT],
366
            "<job-id>",
367
            "Follows a job and prints its output as it arrives"),
369 368
  }
370 369

  
371 370

  
b/scripts/gnt-node
67 67
  constants.ST_LVM_VG: "lvm-vg",
68 68
  }
69 69

  
70
_STORAGE_TYPE_OPT = \
71
  cli_option("--storage-type",
72
             dest="user_storage_type",
73
             choices=_USER_STORAGE_TYPE.keys(),
74
             default=None,
75
             metavar="STORAGE_TYPE",
76
             help=("Storage type (%s)" %
77
                   utils.CommaJoin(_USER_STORAGE_TYPE.keys())))
78

  
79
_REPAIRABLE_STORAGE_TYPES = \
80
  [st for st, so in constants.VALID_STORAGE_OPERATIONS.iteritems()
81
   if constants.SO_FIX_CONSISTENCY in so]
82

  
83
_MODIFIABLE_STORAGE_TYPES = constants.MODIFIABLE_STORAGE_FIELDS.keys()
84

  
70 85

  
71 86
def ConvertStorageType(user_storage_type):
72 87
  """Converts a user storage type to its internal name.
......
608 623

  
609 624

  
610 625
commands = {
611
  'add': (AddNode, ARGS_ONE,
626
  'add': (AddNode, [ArgUnknown(min=1, max=1)],
612 627
          [DEBUG_OPT,
613 628
           make_option("-s", "--secondary-ip", dest="secondary_ip",
614 629
                       help="Specify the secondary ip for the node",
......
622 637
           ],
623 638
          "[-s ip] [--readd] [--no-ssh-key-check] <node_name>",
624 639
          "Add a node to the cluster"),
625
  'evacuate': (EvacuateNode, ARGS_ONE,
640
  'evacuate': (EvacuateNode, [ArgNode(min=1, max=1)],
626 641
               [DEBUG_OPT, FORCE_OPT,
627 642
                make_option("-n", "--new-secondary", dest="dst_node",
628 643
                            help="New secondary node", metavar="NODE",
......
636 651
               "[-f] {-I <iallocator> | -n <dst>} <node>",
637 652
               "Relocate the secondary instances from a node"
638 653
               " to other nodes (only for instances with drbd disk template)"),
639
  'failover': (FailoverNode, ARGS_ONE,
654
  'failover': (FailoverNode, [ArgNode(min=1, max=1)],
640 655
               [DEBUG_OPT, FORCE_OPT,
641 656
                make_option("--ignore-consistency", dest="ignore_consistency",
642 657
                            action="store_true", default=False,
......
646 661
               "[-f] <node>",
647 662
               "Stops the primary instances on a node and start them on their"
648 663
               " secondary node (only for instances with drbd disk template)"),
649
  'migrate': (MigrateNode, ARGS_ONE,
664
  'migrate': (MigrateNode, [ArgNode(min=1, max=1)],
650 665
               [DEBUG_OPT, FORCE_OPT,
651 666
                make_option("--non-live", dest="live",
652 667
                            default=True, action="store_false",
......
658 673
               "[-f] <node>",
659 674
               "Migrate all the primary instance on a node away from it"
660 675
               " (only for instances of type drbd)"),
661
  'info': (ShowNodeConfig, ARGS_ANY, [DEBUG_OPT],
676
  'info': (ShowNodeConfig, [ArgNode()], [DEBUG_OPT],
662 677
           "[<node_name>...]", "Show information about the node(s)"),
663
  'list': (ListNodes, ARGS_ANY,
678
  'list': (ListNodes, [ArgNode()],
664 679
           [DEBUG_OPT, NOHDR_OPT, SEP_OPT, USEUNITS_OPT, FIELDS_OPT, SYNC_OPT],
665 680
           "[nodes...]",
666 681
           "Lists the nodes in the cluster. The available fields"
667 682
           " are (see the man page for details): %s"
668 683
           " The default field list is (in order): %s." %
669 684
           (", ".join(_LIST_HEADERS), ", ".join(_LIST_DEF_FIELDS))),
670
  'modify': (SetNodeParams, ARGS_ONE,
685
  'modify': (SetNodeParams, [ArgNode(min=1, max=1)],
671 686
             [DEBUG_OPT, FORCE_OPT,
672 687
              SUBMIT_OPT,
673 688
              make_option("-C", "--master-candidate", dest="master_candidate",
......
681 696
                          choices=('yes', 'no'), default=None,
682 697
                          help="Set the drained flag on the node"),
683 698
              ],
684
             "<instance>", "Alters the parameters of an instance"),
685
  'powercycle': (PowercycleNode, ARGS_ONE, [DEBUG_OPT, FORCE_OPT, CONFIRM_OPT],
699
             "<node>", "Alters the parameters of a node"),
700
  'powercycle': (PowercycleNode, [ArgNode(min=1, max=1)],
701
                 [DEBUG_OPT, FORCE_OPT, CONFIRM_OPT],
686 702
                 "<node_name>", "Tries to forcefully powercycle a node"),
687
  'remove': (RemoveNode, ARGS_ONE, [DEBUG_OPT],
703
  'remove': (RemoveNode, [ArgNode(min=1, max=1)], [DEBUG_OPT],
688 704
             "<node_name>", "Removes a node from the cluster"),
689
  'volumes': (ListVolumes, ARGS_ANY,
705
  'volumes': (ListVolumes, [ArgNode()],
690 706
              [DEBUG_OPT, NOHDR_OPT, SEP_OPT, USEUNITS_OPT, FIELDS_OPT],
691 707
              "[<node_name>...]", "List logical volumes on node(s)"),
692
  'physical-volumes': (ListPhysicalVolumes, ARGS_ANY,
708
  'physical-volumes': (ListPhysicalVolumes, [ArgNode()],
693 709
                       [DEBUG_OPT, NOHDR_OPT, SEP_OPT, USEUNITS_OPT,
694
                        FIELDS_OPT,
695
                        make_option("--storage-type",
696
                                    dest="user_storage_type",
697
                                    choices=_USER_STORAGE_TYPE.keys(),
698
                                    default=None,
699
                                    metavar="STORAGE_TYPE",
700
                                    help=("Storage type (%s)" %
701
                                          utils.CommaJoin(_USER_STORAGE_TYPE.keys()))),
702
                       ],
710
                        FIELDS_OPT, _STORAGE_TYPE_OPT],
703 711
                       "[<node_name>...]",
704 712
                       "List physical volumes on node(s)"),
705
  'modify-volume': (ModifyVolume, ARGS_FIXED(3),
713
  'modify-volume': (ModifyVolume,
714
                    [ArgNode(min=1, max=1),
715
                     ArgChoice(min=1, max=1,
716
                               choices=_MODIFIABLE_STORAGE_TYPES),
717
                     ArgFile(min=1, max=1)],
706 718
                    [DEBUG_OPT,
707 719
                     make_option("--allocatable", dest="allocatable",
708 720
                                 choices=["yes", "no"], default=None,
......
711 723
                     ],
712 724
                    "<node_name> <storage_type> <name>",
713 725
                    "Modify storage volume on a node"),
714
  'repair-volume': (RepairVolume, ARGS_FIXED(3),
726
  'repair-volume': (RepairVolume,
727
                    [ArgNode(min=1, max=1),
728
                     ArgChoice(min=1, max=1,
729
                               choices=_REPAIRABLE_STORAGE_TYPES),
730
                     ArgFile(min=1, max=1)],
715 731
                    [DEBUG_OPT],
716 732
                    "<node_name> <storage_type> <name>",
717 733
                    "Repairs a storage volume on a node"),
718
  'list-tags': (ListTags, ARGS_ONE, [DEBUG_OPT],
734
  'list-tags': (ListTags, [ArgNode(min=1, max=1)], [DEBUG_OPT],
719 735
                "<node_name>", "List the tags of the given node"),
720
  'add-tags': (AddTags, ARGS_ATLEAST(1), [DEBUG_OPT, TAG_SRC_OPT],
736
  'add-tags': (AddTags, [ArgNode(min=1, max=1), ArgUnknown()],
737
               [DEBUG_OPT, TAG_SRC_OPT],
721 738
               "<node_name> tag...", "Add tags to the given node"),
722
  'remove-tags': (RemoveTags, ARGS_ATLEAST(1), [DEBUG_OPT, TAG_SRC_OPT],
739
  'remove-tags': (RemoveTags, [ArgNode(min=1, max=1), ArgUnknown()],
740
                  [DEBUG_OPT, TAG_SRC_OPT],
723 741
                  "<node_name> tag...", "Remove tags from the given node"),
724 742
  }
725 743

  
b/scripts/gnt-os
146 146

  
147 147

  
148 148
commands = {
149
  'list': (ListOS, ARGS_NONE, [DEBUG_OPT, NOHDR_OPT], "",
149
  'list': (ListOS, [], [DEBUG_OPT, NOHDR_OPT], "",
150 150
           "Lists all valid OSes on the master"),
151
  'diagnose': (DiagnoseOS, ARGS_NONE, [DEBUG_OPT], "",
151
  'diagnose': (DiagnoseOS, [], [DEBUG_OPT], "",
152 152
               "Diagnose all OSes"),
153 153
  }
154 154

  

Also available in: Unified diff