18from __future__
import (absolute_import, division, print_function)
33from struct
import unpack, pack
34from termios
import TIOCGWINSZ
36from ansible
import constants
as C
54 self.
blacklistblacklist = [logging.Filter(name)
for name
in blacklist]
57 return not any(f.filter(record)
for f
in self.
blacklistblacklist)
62 This is a filter which injects the current user
as the
'user' attribute on each record. We need to add this filter
63 to all logger handlers so that 3rd party libraries won
't print an exception due to user not being defined.
67 username = getpass.getuser()
70 username =
'uid=%s' % os.getuid()
73 record.user = FilterUserInjector.username
79if getattr(C,
'DEFAULT_LOG_PATH'):
80 path = C.DEFAULT_LOG_PATH
81 if path
and (os.path.exists(path)
and os.access(path, os.W_OK))
or os.access(os.path.dirname(path), os.W_OK):
83 logging.basicConfig(filename=path, level=logging.INFO,
84 format=
'%(asctime)s p=%(process)d u=%(user)s n=%(name)s | %(message)s')
86 logger = logging.getLogger(
'ansible')
87 for handler
in logging.root.handlers:
88 handler.addFilter(
FilterBlackList(getattr(C,
'DEFAULT_LOG_FILTER', [])))
91 print(
"[WARNING]: log file at %s is not writeable and we cannot create it, aborting\n" % path, file=sys.stderr)
94color_to_log_level = {C.COLOR_ERROR: logging.ERROR,
95 C.COLOR_WARN: logging.WARNING,
96 C.COLOR_OK: logging.INFO,
97 C.COLOR_SKIP: logging.WARNING,
98 C.COLOR_UNREACHABLE: logging.ERROR,
99 C.COLOR_DEBUG: logging.DEBUG,
100 C.COLOR_CHANGED: logging.INFO,
101 C.COLOR_DEPRECATE: logging.WARNING,
102 C.COLOR_VERBOSE: logging.INFO}
106 b
"/usr/games/cowsay",
107 b
"/usr/local/bin/cowsay",
108 b
"/opt/local/bin/cowsay",
125 self.
noncownoncow = C.ANSIBLE_COW_SELECTION
131 cmd = subprocess.Popen([self.
b_cowsayb_cowsay,
"-l"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
132 (out, err) = cmd.communicate()
134 if C.ANSIBLE_COW_WHITELIST
and any(C.ANSIBLE_COW_WHITELIST):
146 if C.ANSIBLE_COW_PATH:
147 self.
b_cowsayb_cowsay = C.ANSIBLE_COW_PATH
149 for b_cow_path
in b_COW_PATHS:
150 if os.path.exists(b_cow_path):
153 def display(self, msg, color=None, stderr=False, screen_only=False, log_only=False, newline=True):
154 """ Display a message to the user
156 Note: msg *must* be a unicode string to prevent UnicodeError tracebacks.
163 has_newline = msg.endswith(
u'\n')
172 if has_newline
or newline:
176 if sys.version_info >= (3,):
196 if e.errno != errno.EPIPE:
199 if logger
and not screen_only:
202 msg2 =
to_bytes(nocolor.lstrip(
u'\n'))
204 if sys.version_info >= (3,):
212 lvl = color_to_log_level[color]
217 logger.log(lvl, msg2)
219 def v(self, msg, host=None):
220 return self.
verboseverbose(msg, host=host, caplevel=0)
222 def vv(self, msg, host=None):
223 return self.
verboseverbose(msg, host=host, caplevel=1)
225 def vvv(self, msg, host=None):
226 return self.
verboseverbose(msg, host=host, caplevel=2)
228 def vvvv(self, msg, host=None):
229 return self.
verboseverbose(msg, host=host, caplevel=3)
232 return self.
verboseverbose(msg, host=host, caplevel=4)
235 return self.
verboseverbose(msg, host=host, caplevel=5)
240 self.
displaydisplay(
"%6d %0.5f: %s" % (os.getpid(), time.time(), msg), color=C.COLOR_DEBUG)
242 self.
displaydisplay(
"%6d %0.5f [%s]: %s" % (os.getpid(), time.time(), host, msg), color=C.COLOR_DEBUG)
244 def verbose(self, msg, host=None, caplevel=2):
246 to_stderr = C.VERBOSE_TO_STDERR
249 self.
displaydisplay(msg, color=C.COLOR_VERBOSE, stderr=to_stderr)
251 self.
displaydisplay(
"<%s> %s" % (host, msg), color=C.COLOR_VERBOSE, stderr=to_stderr)
253 def deprecated(self, msg, version=None, removed=False, date=None, collection_name=None):
254 ''' used to print out a deprecation message.'''
260 if not removed
and not C.DEPRECATION_WARNINGS:
265 new_msg =
"[DEPRECATION WARNING]: %s. This feature will be removed in version %s." % (msg, version)
267 new_msg =
"[DEPRECATION WARNING]: %s. This feature will be removed in a future release." % (msg)
268 new_msg = new_msg +
" Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.\n\n"
270 raise AnsibleError(
"[DEPRECATED]: %s.\nPlease update your playbooks." % msg)
272 wrapped = textwrap.wrap(new_msg, self.
columnscolumns, drop_whitespace=
False)
273 new_msg =
"\n".join(wrapped) +
"\n"
276 self.
displaydisplay(new_msg.strip(), color=C.COLOR_DEPRECATE, stderr=
True)
282 new_msg =
"[WARNING]: %s" % msg
283 wrapped = textwrap.wrap(new_msg, self.
columnscolumns)
284 new_msg =
"\n".join(wrapped) +
"\n"
286 new_msg =
"\n[WARNING]: \n%s" % msg
288 if new_msg
not in self.
_warns_warns:
289 self.
displaydisplay(new_msg, color=C.COLOR_WARN, stderr=
True)
290 self.
_warns_warns[new_msg] = 1
293 if C.SYSTEM_WARNINGS:
296 def banner(self, msg, color=None, cows=True):
298 Prints a header-looking line with cowsay
or stars
with length depending on terminal width (3 minimum)
305 self.
warningwarning(
"somebody cleverly deleted cowsay or something during the PB run. heh.")
308 star_len = self.
columnscolumns - len(msg)
311 stars =
u"*" * star_len
312 self.
displaydisplay(
u"\n%s %s" % (msg, stars), color=color)
316 msg = msg.replace(
u"[",
u"")
317 if msg.endswith(
u"]"):
319 runcmd = [self.
b_cowsayb_cowsay, b
"-W", b
"60"]
321 thecow = self.
noncownoncow
322 if thecow ==
'random':
327 cmd = subprocess.Popen(runcmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
328 (out, err) = cmd.communicate()
331 def error(self, msg, wrap_text=True):
333 new_msg =
u"\n[ERROR]: %s" % msg
334 wrapped = textwrap.wrap(new_msg, self.
columnscolumns)
335 new_msg =
u"\n".join(wrapped) +
u"\n"
337 new_msg =
u"ERROR! %s" % msg
338 if new_msg
not in self.
_errors_errors:
339 self.
displaydisplay(new_msg, color=C.COLOR_ERROR, stderr=
True)
340 self.
_errors_errors[new_msg] = 1
344 prompt_string =
to_bytes(msg, encoding=Display._output_encoding())
345 if sys.version_info >= (3,):
348 prompt_string =
to_text(prompt_string)
351 return getpass.getpass(prompt_string)
353 return input(prompt_string)
355 def do_var_prompt(self, varname, private=True, prompt=None, encrypt=None, confirm=False, salt_size=None, salt=None, default=None, unsafe=None):
358 if sys.__stdin__.isatty():
360 do_prompt = self.
promptprompt
362 if prompt
and default
is not None:
363 msg =
"%s [%s]: " % (prompt, default)
365 msg =
"%s: " % prompt
367 msg =
'input for %s: ' % varname
371 result = do_prompt(msg, private)
372 second = do_prompt(
"confirm " + msg, private)
375 self.
displaydisplay(
"***** VALUES ENTERED DO NOT MATCH ****")
377 result = do_prompt(msg, private)
380 self.
warningwarning(
"Not prompting as we are not in interactive mode")
383 if not result
and default
is not None:
389 result =
do_encrypt(result, encrypt, salt_size, salt)
392 result =
to_text(result, errors=
'surrogate_or_strict')
400 encoding = locale.getpreferredencoding()
404 if encoding
in (
'mac-roman',):
410 tty_size = unpack(
'HHHH', fcntl.ioctl(0, TIOCGWINSZ, pack(
'HHHH', 0, 0, 0, 0)))[1]
def vvvv(self, msg, host=None)
def vvvvvv(self, msg, host=None)
def system_warning(self, msg)
def set_cowsay_info(self)
def display(self, msg, color=None, stderr=False, screen_only=False, log_only=False, newline=True)
def vvvvv(self, msg, host=None)
def __init__(self, verbosity=0)
def do_var_prompt(self, varname, private=True, prompt=None, encrypt=None, confirm=False, salt_size=None, salt=None, default=None, unsafe=None)
def _output_encoding(stderr=False)
def vv(self, msg, host=None)
def prompt(msg, private=False)
def warning(self, msg, formatted=False)
def vvv(self, msg, host=None)
def verbose(self, msg, host=None, caplevel=2)
def banner_cowsay(self, msg, color=None)
def error(self, msg, wrap_text=True)
def _set_column_width(self)
def deprecated(self, msg, version=None, removed=False, date=None, collection_name=None)
def banner(self, msg, color=None, cows=True)
def v(self, msg, host=None)
def debug(self, msg, host=None)
def __init__(self, blacklist)
def to_bytes(obj, encoding='utf-8', errors=None, nonstring='simplerepr')
def to_text(obj, encoding='utf-8', errors=None, nonstring='simplerepr')
def with_metaclass(meta, *bases)
def do_encrypt(result, encrypt, salt_size=None, salt=None)