condensed.py 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. # -*- coding: utf-8 -*-
  2. from __future__ import (absolute_import, division, print_function)
  3. __metaclass__ = type
  4. import sys
  5. from collections import OrderedDict
  6. from ansible.plugins.callback.default import CallbackModule as CallbackModule_default
  7. from ansible import constants as C
  8. from ansible.utils.color import stringc, hostcolor, colorize
  9. from ansible.module_utils._text import to_bytes, to_text
  10. from ansible.utils.display import Display
  11. try:
  12. from __main__ import display as global_display
  13. except ImportError:
  14. global_display = Display()
  15. class CallbackModule(CallbackModule_default):
  16. '''
  17. This is the default callback interface, which simply prints messages
  18. to stdout when new callback events are received.
  19. '''
  20. CALLBACK_VERSION = 2.0
  21. CALLBACK_TYPE = 'stdout'
  22. CALLBACK_NAME = 'condensed'
  23. _progress = OrderedDict()
  24. class CallbackDisplay(Display):
  25. def banner(self, msg, color=None, cows=False, newline=True):
  26. msg = msg.strip()
  27. if newline:
  28. msg = u"\n" + msg
  29. self.display(u"%s" % (msg), color=color)
  30. def display(self, msg, color=None, stderr=False, screen_only=False, log_only=False):
  31. if color:
  32. msg = stringc(msg, color)
  33. msg2 = to_bytes(msg, encoding=self._output_encoding(stderr=stderr))
  34. if sys.version_info >= (3,):
  35. msg2 = to_text(msg2, self._output_encoding(stderr=stderr), errors='replace')
  36. if not stderr:
  37. fileobj = sys.stdout
  38. else:
  39. fileobj = sys.stderr
  40. fileobj.write(msg2)
  41. try:
  42. fileobj.flush()
  43. except IOError as e:
  44. if e.errno != errno.EPIPE:
  45. raise
  46. def clear_line(self):
  47. sys.stdout.write("\r" + " " * self.columns + "\r")
  48. sys.stdout.flush()
  49. def __init__(self):
  50. self.super_ref = super(CallbackModule, self)
  51. self.super_ref.__init__()
  52. self._display = self.CallbackDisplay(verbosity=global_display.verbosity)
  53. def v2_runner_on_skipped(self, result):
  54. pass
  55. def v2_runner_item_on_skipped(self, result):
  56. pass
  57. def _print_task_banner(self, task):
  58. newline = True
  59. while self._progress != {}:
  60. last = self._progress.keys()[-1]
  61. if self._progress[last] == None:
  62. del self._progress[last]
  63. self._display.clear_line()
  64. newline = False
  65. else:
  66. break
  67. self._progress[task._uuid] = None
  68. args = ''
  69. if not task.no_log and C.DISPLAY_ARGS_TO_STDOUT:
  70. args = u', '.join(u'%s=%s' % a for a in task.args.items())
  71. args = u' %s' % args
  72. self._display.banner(u"TASK [%s%s]" % (task.get_name().strip(), args), newline=newline)
  73. if self._display.verbosity >= 2:
  74. path = task.get_path()
  75. if path:
  76. self._display.display(u"task path: %s" % path, color=C.COLOR_DEBUG)
  77. self._last_task_banner = task._uuid
  78. def v2_runner_on_ok(self, result):
  79. self._progress[result._task._uuid] = True
  80. if self._play.strategy == 'free' and self._last_task_banner != result._task._uuid:
  81. self._print_task_banner(result._task)
  82. self._clean_results(result._result, result._task.action)
  83. delegated_vars = result._result.get('_ansible_delegated_vars', None)
  84. self._clean_results(result._result, result._task.action)
  85. msg = u'\n %s' % (result._host.get_name())
  86. if result._task.action in ('include', 'include_role'):
  87. return
  88. elif result._result.get('changed', False):
  89. color = C.COLOR_CHANGED
  90. else:
  91. color = C.COLOR_OK
  92. self._handle_warnings(result._result)
  93. if result._task.loop and 'results' in result._result:
  94. self._process_items(result)
  95. else:
  96. if (self._display.verbosity > 0 or '_ansible_verbose_always' in result._result) and not '_ansible_verbose_override' in result._result:
  97. msg += " => %s" % (self._dump_results(result._result),)
  98. self._display.display(msg, color=color)
  99. def v2_runner_item_on_ok(self, result):
  100. delegated_vars = result._result.get('_ansible_delegated_vars', None)
  101. msg = "\n "
  102. if result._task.action in ('include', 'include_role'):
  103. return
  104. elif result._result.get('changed', False):
  105. color = C.COLOR_CHANGED
  106. else:
  107. color = C.COLOR_OK
  108. if delegated_vars:
  109. msg += "[%s -> %s]" % (result._host.get_name(), delegated_vars['ansible_host'])
  110. else:
  111. msg += "%s" % result._host.get_name()
  112. msg += " => (item=%s)" % (self._get_item(result._result),)
  113. if (self._display.verbosity > 0 or '_ansible_verbose_always' in result._result) and not '_ansible_verbose_override' in result._result:
  114. msg += " => %s" % self._dump_results(result._result)
  115. self._display.display(msg, color=color)
  116. def v2_on_file_diff(self, result):
  117. if result._task.loop and 'results' in result._result:
  118. for res in result._result['results']:
  119. if 'diff' in res and res['diff'] and res.get('changed', False):
  120. diff = self._get_diff(res['diff'])
  121. if diff:
  122. self._display.display(u"\n" + diff.strip())
  123. elif 'diff' in result._result and result._result['diff'] and result._result.get('changed', False):
  124. diff = self._get_diff(result._result['diff'])
  125. if diff:
  126. self._display.display(u"\n" + diff.strip())
  127. def v2_playbook_on_stats(self, stats):
  128. self._display.display("\nPLAY RECAP\n")
  129. hosts = sorted(stats.processed.keys())
  130. for h in hosts:
  131. t = stats.summarize(h)
  132. self._display.display(u"%s : %s %s %s %s\n" % (
  133. hostcolor(h, t),
  134. colorize(u'ok', t['ok'], C.COLOR_OK),
  135. colorize(u'changed', t['changed'], C.COLOR_CHANGED),
  136. colorize(u'unreachable', t['unreachable'], C.COLOR_UNREACHABLE),
  137. colorize(u'failed', t['failures'], C.COLOR_ERROR)),
  138. screen_only=True
  139. )