|
|
@ -28,10 +28,11 @@ import sys
|
|
|
|
import os
|
|
|
|
import os
|
|
|
|
import getpass
|
|
|
|
import getpass
|
|
|
|
import shlex
|
|
|
|
import shlex
|
|
|
|
|
|
|
|
import time
|
|
|
|
|
|
|
|
from optparse import OptionParser
|
|
|
|
import ansible.runner
|
|
|
|
import ansible.runner
|
|
|
|
import ansible.playbook
|
|
|
|
import ansible.playbook
|
|
|
|
import ansible.constants as C
|
|
|
|
import ansible.constants as C
|
|
|
|
from optparse import OptionParser
|
|
|
|
|
|
|
|
from ansible.utils import *
|
|
|
|
from ansible.utils import *
|
|
|
|
|
|
|
|
|
|
|
|
########################################################
|
|
|
|
########################################################
|
|
|
@ -91,7 +92,7 @@ class Cli(object):
|
|
|
|
if options.ask_pass:
|
|
|
|
if options.ask_pass:
|
|
|
|
sshpass = getpass.getpass(prompt="SSH password: ")
|
|
|
|
sshpass = getpass.getpass(prompt="SSH password: ")
|
|
|
|
|
|
|
|
|
|
|
|
return ansible.runner.Runner(
|
|
|
|
runner = ansible.runner.Runner(
|
|
|
|
module_name=options.module_name,
|
|
|
|
module_name=options.module_name,
|
|
|
|
module_path=options.module_path,
|
|
|
|
module_path=options.module_path,
|
|
|
|
module_args=shlex.split(options.module_args),
|
|
|
|
module_args=shlex.split(options.module_args),
|
|
|
@ -101,15 +102,40 @@ class Cli(object):
|
|
|
|
timeout=options.timeout,
|
|
|
|
timeout=options.timeout,
|
|
|
|
forks=options.forks,
|
|
|
|
forks=options.forks,
|
|
|
|
background=options.seconds,
|
|
|
|
background=options.seconds,
|
|
|
|
poll_interval=options.poll_interval,
|
|
|
|
|
|
|
|
async_poll_callback=async_poll_status,
|
|
|
|
|
|
|
|
pattern=pattern,
|
|
|
|
pattern=pattern,
|
|
|
|
verbose=True,
|
|
|
|
verbose=True,
|
|
|
|
).run()
|
|
|
|
)
|
|
|
|
|
|
|
|
return (runner, runner.run())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# ----------------------------------------------
|
|
|
|
# ----------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
def output(self, results, options, args):
|
|
|
|
def get_polling_runner(self, old_runner, hosts, jid):
|
|
|
|
|
|
|
|
return ansible.runner.Runner(
|
|
|
|
|
|
|
|
module_name='async_status',
|
|
|
|
|
|
|
|
module_path=old_runner.module_path,
|
|
|
|
|
|
|
|
module_args=[ "jid=%s" % jid ],
|
|
|
|
|
|
|
|
remote_user=old_runner.remote_user,
|
|
|
|
|
|
|
|
remote_pass=old_runner.remote_pass,
|
|
|
|
|
|
|
|
host_list=hosts,
|
|
|
|
|
|
|
|
timeout=old_runner.timeout,
|
|
|
|
|
|
|
|
forks=old_runner.forks,
|
|
|
|
|
|
|
|
pattern='*',
|
|
|
|
|
|
|
|
verbose=True,
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# ----------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def hosts_to_poll(self, results):
|
|
|
|
|
|
|
|
hosts = []
|
|
|
|
|
|
|
|
for (host, res) in results['contacted'].iteritems():
|
|
|
|
|
|
|
|
if res.get('started',False):
|
|
|
|
|
|
|
|
hosts.append(host)
|
|
|
|
|
|
|
|
return hosts
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# ----------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def output(self, runner, results, options, args):
|
|
|
|
''' summarize results from Runner '''
|
|
|
|
''' summarize results from Runner '''
|
|
|
|
|
|
|
|
|
|
|
|
if results is None:
|
|
|
|
if results is None:
|
|
|
@ -117,6 +143,34 @@ class Cli(object):
|
|
|
|
if options.tree:
|
|
|
|
if options.tree:
|
|
|
|
prepare_writeable_dir(options.tree)
|
|
|
|
prepare_writeable_dir(options.tree)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# BACKGROUND POLL LOGIC when -B and -P are specified
|
|
|
|
|
|
|
|
# FIXME: refactor
|
|
|
|
|
|
|
|
if options.seconds and options.poll_interval > 0:
|
|
|
|
|
|
|
|
poll_hosts = results['contacted'].keys()
|
|
|
|
|
|
|
|
if len(poll_hosts) == 0:
|
|
|
|
|
|
|
|
exit("no jobs were launched successfully")
|
|
|
|
|
|
|
|
ahost = poll_hosts[0]
|
|
|
|
|
|
|
|
jid = results['contacted'][ahost].get('ansible_job_id', None)
|
|
|
|
|
|
|
|
if jid is None:
|
|
|
|
|
|
|
|
exit("unexpected error: unable to determine jid")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
clock = options.seconds
|
|
|
|
|
|
|
|
while (clock >= 0):
|
|
|
|
|
|
|
|
polling_runner = self.get_polling_runner(runner, poll_hosts, jid)
|
|
|
|
|
|
|
|
poll_results = polling_runner.run()
|
|
|
|
|
|
|
|
if poll_results is None:
|
|
|
|
|
|
|
|
break
|
|
|
|
|
|
|
|
for (host, host_result) in poll_results['contacted'].iteritems():
|
|
|
|
|
|
|
|
# override last result with current status result for report
|
|
|
|
|
|
|
|
results['contacted'][host] = host_result
|
|
|
|
|
|
|
|
print async_poll_status(jid, host, clock, host_result)
|
|
|
|
|
|
|
|
clock = clock - options.poll_interval
|
|
|
|
|
|
|
|
time.sleep(options.poll_interval)
|
|
|
|
|
|
|
|
poll_hosts = self.hosts_to_poll(poll_results)
|
|
|
|
|
|
|
|
for (host, host_result) in results['contacted'].iteritems():
|
|
|
|
|
|
|
|
if 'started' in host_result:
|
|
|
|
|
|
|
|
results['contacted'][host] = { 'failed' : 1, 'rc' : None, 'msg' : 'timed out' }
|
|
|
|
|
|
|
|
|
|
|
|
buf = ''
|
|
|
|
buf = ''
|
|
|
|
for hostname in contacted_hosts(results):
|
|
|
|
for hostname in contacted_hosts(results):
|
|
|
|
msg = host_report_msg(
|
|
|
|
msg = host_report_msg(
|
|
|
@ -139,7 +193,7 @@ class Cli(object):
|
|
|
|
if __name__ == '__main__':
|
|
|
|
if __name__ == '__main__':
|
|
|
|
cli = Cli()
|
|
|
|
cli = Cli()
|
|
|
|
(options, args) = cli.parse()
|
|
|
|
(options, args) = cli.parse()
|
|
|
|
results = cli.run(options, args)
|
|
|
|
(runner, results) = cli.run(options, args)
|
|
|
|
cli.output(results, options, args)
|
|
|
|
cli.output(runner, results, options, args)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|