Add -vvv support for debugging activity

pull/812/merge
Michael DeHaan 12 years ago
parent c82f06258c
commit 846186e2fc

@ -15,6 +15,7 @@ Ansible Changes By Release
* better changed=True/False detection in user module on older Linux distros * better changed=True/False detection in user module on older Linux distros
* when using paramiko and SFTP is not accessible, do not traceback, but return a nice human readable msg * when using paramiko and SFTP is not accessible, do not traceback, but return a nice human readable msg
* nicer errors from modules when arguments are not key=value * nicer errors from modules when arguments are not key=value
* use -vvv for extreme debug levels. -v gives more playbook output as before, -vv not really used yet
0.6 "Cabo" -- August 6, 2012 0.6 "Cabo" -- August 6, 2012

@ -96,7 +96,7 @@ class Cli(object):
pattern=pattern, pattern=pattern,
callbacks=self.callbacks, sudo=options.sudo, callbacks=self.callbacks, sudo=options.sudo,
sudo_pass=sudopass,sudo_user=options.sudo_user, sudo_pass=sudopass,sudo_user=options.sudo_user,
transport=options.connection, verbose=options.verbose transport=options.connection
) )
if options.seconds: if options.seconds:

@ -81,15 +81,14 @@ def main(args):
for playbook in args: for playbook in args:
stats = callbacks.AggregateStats() stats = callbacks.AggregateStats()
playbook_cb = callbacks.PlaybookCallbacks(verbose=options.verbose) playbook_cb = callbacks.PlaybookCallbacks(verbose=utils.VERBOSITY)
runner_cb = callbacks.PlaybookRunnerCallbacks(stats, verbose=options.verbose) runner_cb = callbacks.PlaybookRunnerCallbacks(stats, verbose=utils.VERBOSITY)
pb = ansible.playbook.PlayBook( pb = ansible.playbook.PlayBook(
playbook=playbook, playbook=playbook,
module_path=options.module_path, module_path=options.module_path,
host_list=options.inventory, host_list=options.inventory,
forks=options.forks, forks=options.forks,
verbose=options.verbose,
remote_user=options.remote_user, remote_user=options.remote_user,
remote_pass=sshpass, remote_pass=sshpass,
callbacks=playbook_cb, callbacks=playbook_cb,

@ -28,6 +28,13 @@ if os.path.exists("/usr/bin/cowsay"):
elif os.path.exists("/usr/games/cowsay"): elif os.path.exists("/usr/games/cowsay"):
cowsay = "/usr/games/cowsay" cowsay = "/usr/games/cowsay"
def vvv(msg, host=None):
if utils.VERBOSITY > 2:
if host is None:
print stringc(msg, 'blue')
else:
print stringc("<%s> %s" % (host, msg), 'blue')
class AggregateStats(object): class AggregateStats(object):
''' holds stats about per-host activity during playbook runs ''' ''' holds stats about per-host activity during playbook runs '''
@ -242,11 +249,11 @@ class CliRunnerCallbacks(DefaultRunnerCallbacks):
class PlaybookRunnerCallbacks(DefaultRunnerCallbacks): class PlaybookRunnerCallbacks(DefaultRunnerCallbacks):
''' callbacks used for Runner() from /usr/bin/ansible-playbook ''' ''' callbacks used for Runner() from /usr/bin/ansible-playbook '''
def __init__(self, stats, verbose=False): def __init__(self, stats, verbose=utils.VERBOSITY):
self.verbose = verbose
self.stats = stats self.stats = stats
self._async_notified = {} self._async_notified = {}
self.verbose = verbose
def on_unreachable(self, host, msg): def on_unreachable(self, host, msg):

@ -51,7 +51,6 @@ class PlayBook(object):
remote_port = C.DEFAULT_REMOTE_PORT, remote_port = C.DEFAULT_REMOTE_PORT,
transport = C.DEFAULT_TRANSPORT, transport = C.DEFAULT_TRANSPORT,
private_key_file = C.DEFAULT_PRIVATE_KEY_FILE, private_key_file = C.DEFAULT_PRIVATE_KEY_FILE,
verbose = False,
callbacks = None, callbacks = None,
runner_callbacks = None, runner_callbacks = None,
stats = None, stats = None,
@ -94,7 +93,6 @@ class PlayBook(object):
self.remote_pass = remote_pass self.remote_pass = remote_pass
self.remote_port = remote_port self.remote_port = remote_port
self.transport = transport self.transport = transport
self.verbose = verbose
self.callbacks = callbacks self.callbacks = callbacks
self.runner_callbacks = runner_callbacks self.runner_callbacks = runner_callbacks
self.stats = stats self.stats = stats
@ -191,7 +189,7 @@ class PlayBook(object):
private_key_file=self.private_key_file, private_key_file=self.private_key_file,
setup_cache=self.SETUP_CACHE, basedir=self.basedir, setup_cache=self.SETUP_CACHE, basedir=self.basedir,
conditional=task.only_if, callbacks=self.runner_callbacks, conditional=task.only_if, callbacks=self.runner_callbacks,
verbose=self.verbose, sudo=task.play.sudo, sudo_user=task.play.sudo_user, sudo=task.play.sudo, sudo_user=task.play.sudo_user,
transport=task.play.transport, sudo_pass=self.sudo_pass, is_playbook=True transport=task.play.transport, sudo_pass=self.sudo_pass, is_playbook=True
) )
@ -272,7 +270,7 @@ class PlayBook(object):
forks=self.forks, module_path=self.module_path, timeout=self.timeout, remote_user=play.remote_user, forks=self.forks, module_path=self.module_path, timeout=self.timeout, remote_user=play.remote_user,
remote_pass=self.remote_pass, remote_port=play.remote_port, private_key_file=self.private_key_file, remote_pass=self.remote_pass, remote_port=play.remote_port, private_key_file=self.private_key_file,
setup_cache=self.SETUP_CACHE, callbacks=self.runner_callbacks, sudo=play.sudo, sudo_user=play.sudo_user, setup_cache=self.SETUP_CACHE, callbacks=self.runner_callbacks, sudo=play.sudo, sudo_user=play.sudo_user,
verbose=self.verbose, transport=play.transport, sudo_pass=self.sudo_pass, is_playbook=True transport=play.transport, sudo_pass=self.sudo_pass, is_playbook=True
).run() ).run()
self.stats.compute(setup_results, setup=True) self.stats.compute(setup_results, setup=True)

@ -122,7 +122,6 @@ class Runner(object):
transport=C.DEFAULT_TRANSPORT, # 'ssh', 'paramiko', 'local' transport=C.DEFAULT_TRANSPORT, # 'ssh', 'paramiko', 'local'
conditional='True', # run only if this fact expression evals to true conditional='True', # run only if this fact expression evals to true
callbacks=None, # used for output callbacks=None, # used for output
verbose=False, # whether to show more or less
sudo=False, # whether to run sudo or not sudo=False, # whether to run sudo or not
sudo_user=C.DEFAULT_SUDO_USER, # ex: 'root' sudo_user=C.DEFAULT_SUDO_USER, # ex: 'root'
module_vars=None, # a playbooks internals thing module_vars=None, # a playbooks internals thing
@ -147,7 +146,6 @@ class Runner(object):
self.pattern = pattern self.pattern = pattern
self.module_args = module_args self.module_args = module_args
self.timeout = timeout self.timeout = timeout
self.verbose = verbose
self.remote_user = remote_user self.remote_user = remote_user
self.remote_pass = remote_pass self.remote_pass = remote_pass
self.remote_port = remote_port self.remote_port = remote_port

@ -20,6 +20,7 @@ import os
import shutil import shutil
import subprocess import subprocess
from ansible import errors from ansible import errors
from ansible.callbacks import vvv
class LocalConnection(object): class LocalConnection(object):
''' Local based connections ''' ''' Local based connections '''
@ -44,6 +45,7 @@ class LocalConnection(object):
raise errors.AnsibleError("sudo with password is presently only supported on the paramiko (SSH) connection type") raise errors.AnsibleError("sudo with password is presently only supported on the paramiko (SSH) connection type")
cmd = "sudo -u {0} -s {1}".format(sudo_user, cmd) cmd = "sudo -u {0} -s {1}".format(sudo_user, cmd)
vvv("EXEC %s" % cmd, host=self.host)
p = subprocess.Popen(cmd, shell=True, stdin=None, p = subprocess.Popen(cmd, shell=True, stdin=None,
stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = p.communicate() stdout, stderr = p.communicate()
@ -52,6 +54,7 @@ class LocalConnection(object):
def put_file(self, in_path, out_path): def put_file(self, in_path, out_path):
''' transfer a file from local to local ''' ''' transfer a file from local to local '''
vvv("PUT %s TO %s" % (in_path, out_path), host=self.host)
if not os.path.exists(in_path): if not os.path.exists(in_path):
raise errors.AnsibleFileNotFound("file or module does not exist: %s" % in_path) raise errors.AnsibleFileNotFound("file or module does not exist: %s" % in_path)
try: try:
@ -64,6 +67,7 @@ class LocalConnection(object):
raise errors.AnsibleError("failed to transfer file to %s" % out_path) raise errors.AnsibleError("failed to transfer file to %s" % out_path)
def fetch_file(self, in_path, out_path): def fetch_file(self, in_path, out_path):
vvv("FETCH %s TO %s" % (in_path, out_path), host=self.host)
''' fetch a file from local to local -- for copatibility ''' ''' fetch a file from local to local -- for copatibility '''
self.put_file(in_path, out_path) self.put_file(in_path, out_path)

@ -24,6 +24,8 @@ import subprocess
import pipes import pipes
import socket import socket
import random import random
from ansible import utils
from ansible.callbacks import vvv
from ansible import errors from ansible import errors
# prevent paramiko warning noise -- see http://stackoverflow.com/questions/3920502/ # prevent paramiko warning noise -- see http://stackoverflow.com/questions/3920502/
@ -84,6 +86,7 @@ class ParamikoConnection(object):
if not self.runner.sudo or not sudoable: if not self.runner.sudo or not sudoable:
quoted_command = '"$SHELL" -c ' + pipes.quote(cmd) quoted_command = '"$SHELL" -c ' + pipes.quote(cmd)
vvv("EXEC %s" % quoted_command, host=self.host)
chan.exec_command(quoted_command) chan.exec_command(quoted_command)
else: else:
# Rather than detect if sudo wants a password this time, -k makes # Rather than detect if sudo wants a password this time, -k makes
@ -98,6 +101,7 @@ class ParamikoConnection(object):
prompt = '[sudo via ansible, key=%s] password: ' % randbits prompt = '[sudo via ansible, key=%s] password: ' % randbits
sudocmd = 'sudo -k && sudo -p "%s" -u %s -- "$SHELL" -c %s' % ( sudocmd = 'sudo -k && sudo -p "%s" -u %s -- "$SHELL" -c %s' % (
prompt, sudo_user, pipes.quote(cmd)) prompt, sudo_user, pipes.quote(cmd))
vvv("EXEC %s" % sudo_cmd, host=self.host)
sudo_output = '' sudo_output = ''
try: try:
chan.exec_command(sudocmd) chan.exec_command(sudocmd)
@ -120,6 +124,7 @@ class ParamikoConnection(object):
def put_file(self, in_path, out_path): def put_file(self, in_path, out_path):
''' transfer a file from local to remote ''' ''' transfer a file from local to remote '''
vvv("PUT %s TO %s" % (in_path, out_path), host=self.host)
if not os.path.exists(in_path): if not os.path.exists(in_path):
raise errors.AnsibleFileNotFound("file or module does not exist: %s" % in_path) raise errors.AnsibleFileNotFound("file or module does not exist: %s" % in_path)
try: try:
@ -134,6 +139,7 @@ class ParamikoConnection(object):
def fetch_file(self, in_path, out_path): def fetch_file(self, in_path, out_path):
''' save a remote file to the specified path ''' ''' save a remote file to the specified path '''
vvv("FETCH %s TO %s" % (in_path, out_path), host=self.host)
try: try:
sftp = self.ssh.open_sftp() sftp = self.ssh.open_sftp()
except: except:

@ -23,6 +23,7 @@ import pipes
import random import random
import select import select
import fcntl import fcntl
from ansible.callbacks import vvv
from ansible import errors from ansible import errors
class SSHConnection(object): class SSHConnection(object):
@ -72,6 +73,7 @@ class SSHConnection(object):
prompt, sudo_user, pipes.quote(cmd)) prompt, sudo_user, pipes.quote(cmd))
sudo_output = '' sudo_output = ''
ssh_cmd.append(sudocmd) ssh_cmd.append(sudocmd)
vvv("EXEC %s" % ssh_cmd, host=self.host)
p = subprocess.Popen(ssh_cmd, stdin=subprocess.PIPE, p = subprocess.Popen(ssh_cmd, stdin=subprocess.PIPE,
stdout=subprocess.PIPE, stderr=subprocess.STDOUT) stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
if self.runner.sudo_pass: if self.runner.sudo_pass:
@ -92,6 +94,7 @@ class SSHConnection(object):
fcntl.fcntl(p.stdout, fcntl.F_SETFL, fcntl.fcntl(p.stdout, fcntl.F_GETFL) & ~os.O_NONBLOCK) fcntl.fcntl(p.stdout, fcntl.F_SETFL, fcntl.fcntl(p.stdout, fcntl.F_GETFL) & ~os.O_NONBLOCK)
else: else:
ssh_cmd.append(cmd) ssh_cmd.append(cmd)
vvv("EXEC %s" % ssh_cmd, host=self.host)
p = subprocess.Popen(ssh_cmd, stdin=subprocess.PIPE, p = subprocess.Popen(ssh_cmd, stdin=subprocess.PIPE,
stdout=subprocess.PIPE, stderr=subprocess.STDOUT) stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
@ -114,6 +117,7 @@ class SSHConnection(object):
def put_file(self, in_path, out_path): def put_file(self, in_path, out_path):
''' transfer a file from local to remote ''' ''' transfer a file from local to remote '''
vvv("PUT %s TO %s" % (in_path, out_path), host=self.host)
if not os.path.exists(in_path): if not os.path.exists(in_path):
raise errors.AnsibleFileNotFound("file or module does not exist: %s" % in_path) raise errors.AnsibleFileNotFound("file or module does not exist: %s" % in_path)
sftp_cmd = ["sftp"] + self.common_args + [self.host] sftp_cmd = ["sftp"] + self.common_args + [self.host]
@ -125,6 +129,7 @@ class SSHConnection(object):
def fetch_file(self, in_path, out_path): def fetch_file(self, in_path, out_path):
''' fetch a file from remote to local ''' ''' fetch a file from remote to local '''
vvv("FETCH %s TO %s" % (in_path, out_path), host=self.host)
sftp_cmd = ["sftp"] + self.common_args + [self.host] sftp_cmd = ["sftp"] + self.common_args + [self.host]
p = subprocess.Popen(sftp_cmd, stdin=subprocess.PIPE, p = subprocess.Popen(sftp_cmd, stdin=subprocess.PIPE,
stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout=subprocess.PIPE, stderr=subprocess.PIPE)

@ -29,6 +29,8 @@ from ansible import color
from ansible import __version__ from ansible import __version__
import ansible.constants as C import ansible.constants as C
VERBOSITY=0
try: try:
import json import json
except ImportError: except ImportError:
@ -318,12 +320,17 @@ class SortedOptParser(optparse.OptionParser):
self.option_list.sort(key=operator.methodcaller('get_opt_string')) self.option_list.sort(key=operator.methodcaller('get_opt_string'))
return optparse.OptionParser.format_help(self, formatter=None) return optparse.OptionParser.format_help(self, formatter=None)
def increment_debug(option, opt, value, parser):
global VERBOSITY
VERBOSITY += 1
def base_parser(constants=C, usage="", output_opts=False, runas_opts=False, async_opts=False, connect_opts=False): def base_parser(constants=C, usage="", output_opts=False, runas_opts=False, async_opts=False, connect_opts=False):
''' create an options parser for any ansible script ''' ''' create an options parser for any ansible script '''
parser = SortedOptParser(usage, version=version("%prog")) parser = SortedOptParser(usage, version=version("%prog"))
parser.add_option('-v','--verbose', default=False, action="store_true", parser.add_option('-v','--verbose', default=False, action="callback",
help='verbose mode') callback=increment_debug, help="verbose mode (-vvv for more)")
parser.add_option('-f','--forks', dest='forks', default=constants.DEFAULT_FORKS, type='int', parser.add_option('-f','--forks', dest='forks', default=constants.DEFAULT_FORKS, type='int',
help="specify number of parallel processes to use (default=%s)" % constants.DEFAULT_FORKS) help="specify number of parallel processes to use (default=%s)" % constants.DEFAULT_FORKS)
parser.add_option('-i', '--inventory-file', dest='inventory', parser.add_option('-i', '--inventory-file', dest='inventory',

Loading…
Cancel
Save