Revision b74c0684 tools/ganeti-listrunner

b/tools/ganeti-listrunner
53 53
# C0103: Invalid name ganeti-listrunner
54 54

  
55 55
import errno
56
import getopt
56
import optparse
57 57
import getpass
58 58
import logging
59 59
import os
......
69 69

  
70 70
REMOTE_PATH_BASE = "/tmp/listrunner"
71 71

  
72
USAGE = ("%prog -l logdir {-c command | -x /path/to/file} [-b batch_size]"
73
         " {-f hostfile|-h hosts} [-u username]"
74
         " [-p password_file | -A]")
75

  
72 76

  
73 77
def LogDirUseable(logdir):
74 78
  """Ensure log file directory is available and usable."""
......
89 93
    return False
90 94

  
91 95

  
92
def ShowHelp(executable):
93
  """Print short usage information."""
94
  print ("usage: %s -l logdir [-c|-x] value [-b batch_size]"
95
         " [-f hostfile|-h hosts] [-u username]"
96
         " [-p password_file]" % executable)
97
  print """        -l logdir to write logfiles to
98
        -x executable to run on remote host(s)
99
        -c shell command to run on remote host(s)
100
        -f hostlist file (one host per line)
101
        -a optional auxiliary file to upload (can be given multiple times)
102
        -b batch-size, how many hosts to process in parallel [15]
103
        -h comma-separated list of hosts or single hostname
104
        -u username used to connect [root]
105
        -p password used to authenticate"""
106

  
107

  
108 96
def GetTimeStamp(timestamp=None):
109 97
  """Return ISO8601 timestamp.
110 98

  
......
434 422
               executable, command, filelist)
435 423

  
436 424

  
425
def ParseOptions():
426
  """Parses the command line options.
427

  
428
  In case of command line errors, it will show the usage and exit the
429
  program.
430

  
431
  @return: the options in a tuple
432

  
433
  """
434
  # resolve because original used -h for hostfile, which conflicts
435
  # with -h for help
436
  parser = optparse.OptionParser(usage="\n%s" % USAGE,
437
                                 conflict_handler="resolve")
438

  
439
  parser.add_option("-l", dest="logdir", default=None,
440
                    help="directory to write logfiles to")
441
  parser.add_option("-x", dest="executable", default=None,
442
                    help="executable to run on remote host(s)",)
443
  parser.add_option("-f", dest="hostfile", default=None,
444
                    help="hostlist file (one host per line)")
445
  parser.add_option("-h", dest="hostlist", default=None, metavar="HOSTS",
446
                    help="comma-separated list of hosts or single hostname",)
447
  parser.add_option("-a", dest="auxfiles", action="append", default=[],
448
                    help="optional auxiliary file to upload"
449
                    " (can be given multiple times",
450
                    metavar="FILE")
451
  parser.add_option("-c", dest="command", default=None,
452
                    help="shell command to run on remote host(s)")
453
  parser.add_option("-b", dest="batch_size", default=15, type="int",
454
                    help="batch-size, how many hosts to process"
455
                    " in parallel [15]")
456
  parser.add_option("-u", dest="username", default="root",
457
                    help="username used to connect [root]")
458
  parser.add_option("-p", dest="password", default=None,
459
                    help="password used to authenticate (when not"
460
                    " using an agent)")
461
  parser.add_option("-A", dest="use_agent", default=False, action="store_true",
462
                    help="instead of password, use keys from an SSH agent")
463

  
464
  opts, args = parser.parse_args()
465

  
466
  if opts.executable and opts.command:
467
    parser.error("Options -x and -c conflict with each other")
468
  if not (opts.executable or opts.command):
469
    parser.error("One of -x and -c must be given")
470
  if not opts.logdir:
471
    parser.error("Option -l is required")
472
  if opts.hostfile and opts.hostlist:
473
    parser.error("Options -f and -h conflict with each other")
474
  if not (opts.hostfile or opts.hostlist):
475
    parser.error("One of -f or -h must be given")
476
  if args:
477
    parser.error("This program doesn't take any arguments, passed in: %s" %
478
                 ", ".join(args))
479

  
480
  return (opts.logdir, opts.executable, opts.hostfile, opts.hostlist,
481
          opts.command, opts.use_agent, opts.auxfiles, opts.username,
482
          opts.password, opts.batch_size)
483

  
484

  
437 485
def main():
438 486
  """main."""
439
  try:
440
    optlist, _ = getopt.getopt(sys.argv[1:], "l:x:h:f:a:c:b:u:p:A")
441
  except getopt.GetoptError, err:
442
    print str(err)
443
    ShowHelp(sys.argv[0])
444
    sys.exit(2)
445

  
446
  logdir = executable = hostfile = hostlist = command = None
447
  use_agent = False
448
  auxfiles = []
449
  username = "root"
450
  password = None
451
  batch_size = 15
452
  for option in optlist:
453
    if option[0] == "-l":
454
      logdir = option[1]
455
    if option[0] == "-x":
456
      executable = option[1]
457
    if option[0] == "-f":
458
      hostfile = option[1]
459
    if option[0] == "-h":
460
      hostlist = option[1]
461
    if option[0] == "-a":
462
      auxfiles.append(option[1])
463
    if option[0] == "-c":
464
      command = option[1]
465
    if option[0] == "-b":
466
      batch_size = int(option[1])
467
    if option[0] == "-u":
468
      username = option[1]
469
    if option[0] == "-p":
470
      password = option[1]
471
    if option[0] == "-A":
472
      use_agent = True
473

  
474
  if not (logdir and (executable or command) and (hostfile or hostlist)):
475
    print "error: missing required commandline argument(s)"
476
    ShowHelp(sys.argv[0])
477
    sys.exit(3)
478

  
479
  if executable and command:
480
    print "error: can run either a command or an executable, not both"
481
    ShowHelp(sys.argv[0])
482
    sys.exit(3)
483

  
484
  if hostlist and hostfile:
485
    print "error: specify either -f or -h arguments, not both"
486
    ShowHelp(sys.argv[0])
487
    sys.exit(3)
487
  (logdir, executable, hostfile, hostlist,
488
   command, use_agent, auxfiles, username,
489
   password, batch_size) = ParseOptions()
488 490

  
489 491
  ### Unbuffered sys.stdout
490 492
  sys.stdout = os.fdopen(1, "w", 0)

Also available in: Unified diff