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