dapp 0.26.14 → 0.27.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/bin/dapp +0 -4
  3. data/config/en/common.yml +1 -0
  4. data/config/en/net_status.yml +2 -0
  5. data/lib/dapp.rb +1 -4
  6. data/lib/dapp/cli.rb +0 -4
  7. data/lib/dapp/cli/command/base.rb +1 -7
  8. data/lib/dapp/dapp.rb +4 -22
  9. data/lib/dapp/dapp/dappfile.rb +2 -2
  10. data/lib/dapp/dapp/deps/base.rb +6 -2
  11. data/lib/dapp/dapp/option_tags.rb +1 -7
  12. data/lib/dapp/dimg/artifact.rb +4 -0
  13. data/lib/dapp/dimg/build/stage/artifact_base.rb +7 -7
  14. data/lib/dapp/dimg/build/stage/artifact_default.rb +4 -5
  15. data/lib/dapp/dimg/build/stage/base.rb +1 -3
  16. data/lib/dapp/dimg/build/stage/before_install.rb +2 -3
  17. data/lib/dapp/dimg/build/stage/from.rb +31 -5
  18. data/lib/dapp/dimg/build/stage/ga_base.rb +1 -1
  19. data/lib/dapp/dimg/build/stage/ga_latest_patch.rb +1 -3
  20. data/lib/dapp/dimg/build/stage/import_artifact.rb +3 -4
  21. data/lib/dapp/dimg/builder/ansible.rb +167 -2
  22. data/lib/dapp/dimg/builder/ansible/assets.rb +332 -0
  23. data/lib/dapp/dimg/builder/chef.rb +2 -2
  24. data/lib/dapp/dimg/cli/command/base.rb +14 -0
  25. data/lib/dapp/dimg/cli/command/dimg/build.rb +15 -24
  26. data/lib/dapp/dimg/cli/command/dimg/run.rb +14 -1
  27. data/lib/dapp/dimg/config/directive/dimg/instance_methods.rb +2 -1
  28. data/lib/dapp/dimg/config/directive/dimg_group_base.rb +2 -2
  29. data/lib/dapp/dimg/config/directive/git_artifact_remote.rb +4 -3
  30. data/lib/dapp/dimg/dapp/command/cleanup.rb +2 -2
  31. data/lib/dapp/dimg/dapp/command/common.rb +16 -5
  32. data/lib/dapp/dimg/dapp/command/mrproper.rb +6 -8
  33. data/lib/dapp/dimg/dapp/command/push.rb +1 -1
  34. data/lib/dapp/dimg/dapp/command/run.rb +3 -2
  35. data/lib/dapp/dimg/dapp/command/stages/cleanup_local.rb +3 -0
  36. data/lib/dapp/dimg/dapp/command/tag.rb +1 -1
  37. data/lib/dapp/dimg/dapp/dimg.rb +8 -0
  38. data/lib/dapp/dimg/dimg.rb +14 -3
  39. data/lib/dapp/dimg/dimg/stages.rb +1 -1
  40. data/lib/dapp/dimg/docker_registry/base.rb +10 -0
  41. data/lib/dapp/dimg/docker_registry/base/authorization.rb +1 -16
  42. data/lib/dapp/dimg/git_artifact.rb +9 -2
  43. data/lib/dapp/dimg/git_repo/base.rb +2 -2
  44. data/lib/dapp/dimg/git_repo/local.rb +2 -2
  45. data/lib/dapp/kube/dapp/command/deploy.rb +0 -1
  46. data/lib/dapp/kube/dapp/command/lint.rb +11 -4
  47. data/lib/dapp/kube/helm/values.rb +7 -7
  48. data/lib/dapp/version.rb +2 -2
  49. metadata +5 -34
  50. data/lib/dapp/dapp/sentry.rb +0 -106
  51. data/lib/dapp/helper/url.rb +0 -23
@@ -1,10 +1,23 @@
1
1
  module Dapp
2
2
  module Dimg
3
3
  class Builder::Ansible < Builder::Base
4
- ANSIBLE_IMAGE_VERSION = "2.4.1.0-1"
4
+
5
+ ANSIBLE_IMAGE_VERSION = "2.4.4.0-10"
5
6
 
6
7
  def ansible_bin
7
- "/.dapp/deps/ansible/#{ANSIBLE_IMAGE_VERSION}/bin/ansible"
8
+ "/.dapp/deps/ansible/#{ANSIBLE_IMAGE_VERSION}/embedded/bin/ansible"
9
+ end
10
+
11
+ def ansible_playbook_bin
12
+ "/.dapp/deps/ansible/#{ANSIBLE_IMAGE_VERSION}/embedded/bin/ansible-playbook"
13
+ end
14
+
15
+ def python_path
16
+ "/.dapp/deps/ansible/#{ANSIBLE_IMAGE_VERSION}/embedded/bin/python"
17
+ end
18
+
19
+ def ansible_playbook_solo_cmd
20
+ "#{ansible_playbook_bin} -c local"
8
21
  end
9
22
 
10
23
  def ansible_image
@@ -35,6 +48,158 @@ module Dapp
35
48
  end
36
49
  end
37
50
 
51
+ # query tasks from ansible config
52
+ # create dump_config structure
53
+ # returns structure:
54
+ # { 'tasks' => [array of tasks for stage],
55
+ # 'dump_config' => {
56
+ # 'dump_config_doc' => 'dump of doc',
57
+ # 'dump_config_sections' => {'task_0'=>'dump for task 0', 'task_1'=>'dump for task 1', ... }}
58
+ def stage_config(stage)
59
+ @stage_configs ||= {}
60
+ @stage_configs[stage.to_s] ||= begin
61
+ {}.tap do |stage_config|
62
+ stage_config['dump_config'] = {
63
+ 'dump_config_doc' => dimg.config._ansible['dump_config_doc'],
64
+ 'dump_config_sections' => {},
65
+ }
66
+ stage_config['tasks'] = dimg.config._ansible[stage.to_s].map.with_index do |dapp_task, task_num|
67
+ {}.tap do |task|
68
+ task.merge!(dapp_task['config'])
69
+ task['tags'] = [].tap do |tags|
70
+ tags << dapp_task['config']['tags']
71
+ dump_tag = "task_#{task_num}"
72
+ tags << dump_tag
73
+ stage_config['dump_config']['dump_config_sections'][dump_tag] = dapp_task['dump_config_section']
74
+ end.flatten.compact
75
+ end
76
+ end || []
77
+ end
78
+ end
79
+ end
80
+
81
+ def stage_playbook(stage)
82
+ @stage_playbooks ||= {}
83
+ @stage_playbooks[stage.to_s] ||= begin
84
+ [{
85
+ 'hosts' => 'all',
86
+ 'gather_facts' => 'no',
87
+ 'tasks' => [],
88
+ }].tap do |playbook|
89
+ playbook[0]['tasks'].concat(stage_config(stage)['tasks'])
90
+ end
91
+ end
92
+ end
93
+
94
+ def create_workdir_structure(stage)
95
+ @workdir_structures ||= {}
96
+ @workdir_structures[stage.to_s] ||= true.tap do
97
+ host_workdir(stage).tap do |workdir|
98
+ # playbook with tasks for a stage
99
+ workdir.join('playbook.yml').write YAML.dump(stage_playbook(stage))
100
+ #puts YAML.dump(stage_playbook(stage))
101
+
102
+ # generate inventory with localhost and python in dappdeps-ansible
103
+ workdir.join('hosts').write Assets.hosts(python_path)
104
+
105
+ # generate ansible config for solo mode
106
+ workdir.join('ansible.cfg').write Assets.ansible_cfg(container_workdir.join('hosts'),
107
+ container_workdir.join('lib', 'callback'),
108
+ dimg.dapp.sudo_bin,
109
+ container_tmpdir.join('local'),
110
+ container_tmpdir.join('remote'),
111
+ )
112
+
113
+ # save config dump for pretty errors
114
+ workdir.join('dump_config.json').write JSON.generate(stage_config(stage)['dump_config'])
115
+
116
+ # python modules
117
+ workdir.join('lib').tap do |libdir|
118
+ libdir.mkpath
119
+ # crypt.py hack
120
+ # TODO must be in dappdeps-ansible
121
+ libdir.join('crypt.py').write Assets.crypt_py
122
+ libdir.join('callback').tap do |callbackdir|
123
+ callbackdir.mkpath
124
+ callbackdir.join('__init__.py').write '# module callback'
125
+ callbackdir.join('live.py').write Assets.live_py
126
+ # add dapp specific stdout callback for ansible
127
+ callbackdir.join('dapp.py').write Assets.dapp_py
128
+ end
129
+ end
130
+ end
131
+ end
132
+ end
133
+
134
+ %i(before_install install before_setup setup build_artifact).each do |stage|
135
+ define_method("#{stage}?") {
136
+ !stage_empty?(stage)
137
+ }
138
+
139
+ define_method("#{stage}_checksum") do
140
+ dimg.hashsum [JSON.dump(stage_config(stage)['tasks'])]
141
+ end
142
+
143
+ define_method(stage.to_s) do |image|
144
+ unless stage_empty?(stage)
145
+ create_workdir_structure(stage)
146
+ image.add_env('ANSIBLE_CONFIG', container_workdir.join('ansible.cfg'))
147
+ image.add_env('DAPP_DUMP_CONFIG_DOC_PATH', container_workdir.join('dump_config.json'))
148
+ image.add_env('PYTHONPATH', container_workdir.join('lib'))
149
+ image.add_env('PYTHONIOENCODING', 'utf-8')
150
+ image.add_env('ANSIBLE_PREPEND_SYSTEM_PATH', dimg.dapp.dappdeps_base_path)
151
+ image.add_env('LC_ALL', 'C.UTF-8')
152
+ image.add_volumes_from("#{ansible_container}:rw")
153
+ image.add_volume "#{host_workdir(stage)}:#{container_workdir}:ro"
154
+ image.add_volume "#{host_tmpdir(stage)}:#{container_tmpdir}:rw"
155
+ image.add_command [ansible_playbook_bin,
156
+ container_workdir.join('playbook.yml'),
157
+ ENV['ANSIBLE_ARGS']
158
+ ].join(' ')
159
+ end
160
+ end
161
+ end
162
+
163
+ def before_build_check
164
+ end
165
+
166
+ def before_dimg_should_be_built_check
167
+ end
168
+
169
+ def stage_empty?(stage)
170
+ stage_config(stage)['tasks'].empty?
171
+ end
172
+
173
+ # host directory in tmp_dir with directories structure
174
+ def host_workdir(stage)
175
+ @host_workdirs ||= {}
176
+ @host_workdirs[stage.to_s] ||= begin
177
+ dimg.tmp_path(dimg.dapp.consistent_uniq_slugify(dimg.config._name || "nameless"), "ansible-workdir-#{stage.to_s}").tap {|p| p.mkpath}
178
+ end
179
+ end
180
+
181
+ # temporary directories for ansible
182
+ def host_tmpdir(stage)
183
+ @host_tmpdirs ||= {}
184
+ @host_tmpdirs[stage.to_s] ||= begin
185
+ dimg.tmp_path(dimg.dapp.consistent_uniq_slugify(dimg.config._name || "nameless"), "ansible-tmpdir-#{stage.to_s}").tap do |p|
186
+ p.mkpath
187
+ p.join('local').mkpath
188
+ p.join('remote').mkpath
189
+ end
190
+ end
191
+ end
192
+
193
+ # directory with playbook in container
194
+ def container_workdir
195
+ dimg.container_dapp_path("ansible-workdir")
196
+ end
197
+
198
+ # temporary directory for ansible
199
+ def container_tmpdir
200
+ dimg.container_dapp_path("ansible-tmpdir")
201
+ end
202
+
38
203
  end # Builder::Ansible
39
204
  end # Dimg
40
205
  end # Dapp
@@ -0,0 +1,332 @@
1
+ module Dapp
2
+ module Dimg
3
+ class Builder::Ansible::Assets
4
+ class << self
5
+ def ansible_cfg(inventory, callback_plugins, become_exe, local_tmp, remote_tmp)
6
+ %{
7
+ [defaults]
8
+ inventory = #{inventory}
9
+ transport = local
10
+ ; do not generate retry files in ro volumes
11
+ retry_files_enabled = False
12
+ ; more verbose stdout like ad-hoc ansible command from flant/ansible fork
13
+ callback_plugins = #{callback_plugins}
14
+ stdout_callback = dapp
15
+ ; force color
16
+ force_color = 1
17
+ module_compression = 'ZIP_STORED'
18
+ local_tmp = #{local_tmp}
19
+ remote_tmp = #{remote_tmp}
20
+ ; keep ansiballz for debug
21
+ ;keep_remote_files = 1
22
+ [privilege_escalation]
23
+ become = yes
24
+ become_method = sudo
25
+ become_exe = #{become_exe}
26
+ become_flags = -E
27
+ }
28
+ end
29
+
30
+ def hosts(python_path)
31
+ %{
32
+ localhost ansible_raw_live_stdout=yes ansible_script_live_stdout=yes ansible_python_interpreter=#{python_path}
33
+ }
34
+ end
35
+
36
+ # Python script! Do not enable string interpolation!
37
+ def dapp_py
38
+ %q{
39
+ # (c) 2018, Ivan Mikheykin <ivan.mikheykin@flant.com>
40
+ # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
41
+
42
+ # Make coding more python3-ish
43
+ from __future__ import (absolute_import, division, print_function)
44
+ __metaclass__ = type
45
+
46
+
47
+ DOCUMENTATION = '''
48
+ callback: dapp
49
+ type: stdout
50
+ short_description: live output for raw and script with dapp specific additions
51
+ version_added: "2.4"
52
+ description:
53
+ - Solo mode with live stdout for raw and script tasks
54
+ - Dapp specific error messages
55
+ requirements:
56
+ - set as stdout callback in configuration
57
+ '''
58
+
59
+ #from ansible.plugins.callback.live import CallbackModule as CallbackModule_live
60
+ # live.py moved to dapp
61
+ from callback.live import CallbackModule as CallbackModule_live
62
+ from ansible import constants as C
63
+
64
+ import os
65
+ import json
66
+
67
+ class CallbackModule(CallbackModule_live):
68
+
69
+ CALLBACK_VERSION = 2.0
70
+ CALLBACK_TYPE = 'stdout'
71
+ CALLBACK_NAME = 'dapp'
72
+
73
+ def __init__(self):
74
+ self.super_ref = super(CallbackModule, self)
75
+ self.super_ref.__init__()
76
+
77
+ def v2_runner_on_failed(self, result, ignore_errors=False):
78
+ self.super_ref.v2_runner_on_failed(result, ignore_errors)
79
+
80
+ # get config sections from dapp
81
+ # task config text is in a last tag
82
+ # doctext is in a file DAPP_DUMP_CONFIG_DOC_PATH
83
+ self._display_dapp_config(result._task)
84
+
85
+ def _read_dump_config_doc(self):
86
+ # read content from file in DAPP_DUMP_CONFIG_DOC_PATH env
87
+ if 'DAPP_DUMP_CONFIG_DOC_PATH' not in os.environ:
88
+ return ''
89
+ dump_path = os.environ['DAPP_DUMP_CONFIG_DOC_PATH']
90
+ res = ''
91
+ try:
92
+ fh = open(dump_path, 'r')
93
+ res = json.load(fh) #.read()
94
+ fh.close()
95
+ except:
96
+ pass
97
+
98
+ return res
99
+
100
+ # dapp_stage_name commented for consistency with dappfile-yml behaviour
101
+ def _display_dapp_config(self, task):
102
+ tags = task.tags
103
+ dump_config_section_key = ''
104
+ #dapp_stage_name = ''
105
+ if len(tags) > 0:
106
+ # stage name appended before dump
107
+ #dapp_stage_name = tags[-2]
108
+ # last tag is dump of section
109
+ dump_config_section_key = tags[-1]
110
+
111
+ dump_config = self._read_dump_config_doc()
112
+ dump_config_doc = dump_config['dump_config_doc']
113
+ dump_config_section = dump_config['dump_config_sections'][dump_config_section_key]
114
+ self._display.display("\n\n%s\n%s" % (dump_config_section, dump_config_doc), color=C.COLOR_DEBUG)
115
+
116
+ }
117
+ end
118
+
119
+ def crypt_py
120
+ %q{
121
+ def crypt(word, salt):
122
+ return "FAKE_CRYPT"
123
+ }
124
+ end
125
+
126
+ def live_py
127
+ %{
128
+ # (c) 2012-2014, Michael DeHaan <michael.dehaan@gmail.com>
129
+ # (c) 2017 Ansible Project
130
+ # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
131
+
132
+ # Make coding more python3-ish
133
+ from __future__ import (absolute_import, division, print_function)
134
+ __metaclass__ = type
135
+
136
+ DOCUMENTATION = '''
137
+ callback: live
138
+ type: stdout
139
+ short_description: screen output for solo mode
140
+ version_added: historical
141
+ description:
142
+ - Solo mode with live stdout for raw and script tasks with fallback to minimal
143
+ '''
144
+
145
+ from ansible.plugins.callback import CallbackBase
146
+ from ansible import constants as C
147
+ from ansible.vars.manager import strip_internal_keys
148
+
149
+ import json, re
150
+
151
+
152
+ class CallbackModule(CallbackBase):
153
+
154
+ '''
155
+ This is the default callback interface, which simply prints messages
156
+ to stdout when new callback events are received.
157
+ '''
158
+
159
+ CALLBACK_VERSION = 2.0
160
+ CALLBACK_TYPE = 'stdout'
161
+ CALLBACK_NAME = 'live'
162
+
163
+ # name for this tasks can be generated from free_form
164
+ FREE_FORM_MODULES = ('raw', 'script', 'command', 'shell')
165
+ #ERROR! this task 'debug' has extra params, which is only allowed in the following modules: command, win_command, shell, win_shell, script, include, include_vars, include_tasks, include_role, import_tasks, import_role, add_host, group_by, set_fact, raw, meta
166
+
167
+ def __init__(self):
168
+ super(CallbackModule, self).__init__()
169
+ self._play = None
170
+
171
+ def _task_header(self, task, msg):
172
+ name = task.name
173
+ if not name:
174
+ if task.action in self.FREE_FORM_MODULES:
175
+ name = task.args['_raw_params']
176
+ if task.action == 'getent':
177
+ db = task.args.get('database')
178
+ key = task.args.get('key')
179
+ name = '%s %s' % (db, key)
180
+ if task.action == 'apt':
181
+ name = task.args.get('name')
182
+ name = re.sub(r'\s+', r' ', name)
183
+ if len(name) > 25 :
184
+ name = '%s...' % name[0:22]
185
+ return u'%s [%s] %s' % (task.action, name, msg)
186
+
187
+ def _display_command_generic_msg(self, task, result, caption, color):
188
+ ''' output the result of a command run '''
189
+
190
+ self._display.display("%s | rc=%s >>" % (self._task_header(task, caption), result.get('rc', -1)), color)
191
+ # prevent dublication in case of live_stdout
192
+ if not result.get('live_stdout', False):
193
+ self._display.display("stdout was:", color=C.COLOR_HIGHLIGHT)
194
+ self._display.display(result.get('stdout', ''))
195
+ stderr = result.get('stderr', '')
196
+ if stderr:
197
+ self._display.display("stderr was:", color=C.COLOR_HIGHLIGHT)
198
+ self._display.display(stderr, color=C.COLOR_ERROR)
199
+
200
+
201
+ def _display_debug_msg(self, task, result):
202
+ color = C.COLOR_OK
203
+ if task.args.get('msg'):
204
+ self._display.display("debug msg", color=C.COLOR_HIGHLIGHT)
205
+ self._display.display(result.get('msg', ''), color)
206
+ if task.args.get('var'):
207
+ self._display.display("debug var \'%s\'" % task.args.get('var'), color=C.COLOR_HIGHLIGHT)
208
+ var_obj = result.get(task.args.get('var'), '')
209
+ if isinstance(var_obj, str):
210
+ if 'IS NOT DEFINED' in var_obj:
211
+ color = C.COLOR_ERROR
212
+ path = task.get_path()
213
+ if path:
214
+ self._display.display(u"task path: %s" % path, color=C.COLOR_DEBUG)
215
+ self._display.display(var_obj, color)
216
+ else:
217
+ self._display.display(json.dumps(var_obj, indent=4), color)
218
+
219
+ # TODO remove stdout here if live_stdout!
220
+ # TODO handle results for looped tasks
221
+ def _dump_results(self, result, indent=None, sort_keys=True, keep_invocation=False):
222
+
223
+ if not indent and (result.get('_ansible_verbose_always') or self._display.verbosity > 2):
224
+ indent = 4
225
+
226
+ # All result keys stating with _ansible_ are internal, so remove them from the result before we output anything.
227
+ abridged_result = strip_internal_keys(result)
228
+
229
+ # remove invocation unless specifically wanting it
230
+ if not keep_invocation and self._display.verbosity < 3 and 'invocation' in result:
231
+ del abridged_result['invocation']
232
+
233
+ # remove diff information from screen output
234
+ if self._display.verbosity < 3 and 'diff' in result:
235
+ del abridged_result['diff']
236
+
237
+ # remove exception from screen output
238
+ if 'exception' in abridged_result:
239
+ del abridged_result['exception']
240
+
241
+ # remove msg, failed, changed
242
+ if 'msg' in abridged_result:
243
+ del abridged_result['msg']
244
+ if 'failed' in abridged_result:
245
+ del abridged_result['failed']
246
+ if 'changed' in abridged_result:
247
+ del abridged_result['changed']
248
+
249
+ if len(abridged_result) > 0:
250
+ return json.dumps(abridged_result, indent=indent, ensure_ascii=False, sort_keys=sort_keys)
251
+
252
+ return ''
253
+
254
+ def v2_playbook_on_play_start(self, play):
255
+ self._play = play
256
+
257
+ # command [copy artifacts] started
258
+ # stdout
259
+ # ...
260
+ # command [copy artifacts] OK/FAILED/CHANGED
261
+ # STDERR: if failed
262
+ # ...
263
+ #
264
+ def v2_playbook_on_task_start(self, task, is_conditional):
265
+ self._display.v("TASK action=%s args=%s" % (task.action, json.dumps(task.args, indent=4)))
266
+
267
+ if task.action == 'debug':
268
+ return
269
+
270
+ if self._play.strategy != 'free':
271
+ self._display.display(self._task_header(task, "started"), color=C.COLOR_HIGHLIGHT)
272
+
273
+ def v2_runner_on_ok(self, result):
274
+ self._display.v("TASK action=%s OK => %s" % (result._task.action, json.dumps(result._result, indent=4)))
275
+
276
+ self._clean_results(result._result, result._task.action)
277
+ self._handle_warnings(result._result)
278
+
279
+ task = result._task
280
+
281
+ if task.action == 'debug':
282
+ self._display_debug_msg(result._task, result._result)
283
+ elif task.action in self.FREE_FORM_MODULES:
284
+ self._display_command_generic_msg(result._task, result._result, "SUCCESS", C.COLOR_OK)
285
+ else:
286
+ if 'changed' in result._result and result._result['changed']:
287
+ self._display.display("%s => %s" % (self._task_header(result._task, "SUCCESS"), self._dump_results(result._result, indent=4)), color=C.COLOR_CHANGED)
288
+ #self._display.display(self._task_header(task, "OK")"%s | SUCCESS => %s" % (result._host.get_name(), self._dump_results(result._result, indent=4)), color=C.COLOR_CHANGED)
289
+ #self._display.display("%s | SUCCESS => %s" % (result._host.get_name(), ), color=C.COLOR_CHANGED)
290
+ else:
291
+ self._display.display("%s => %s" % (self._task_header(result._task, "SUCCESS"), self._dump_results(result._result, indent=4)), color=C.COLOR_OK)
292
+ #self._display.display("%s | SUCCESS => %s" % (result._host.get_name(), self._dump_results(result._result, indent=4)), color=C.COLOR_OK)
293
+
294
+ def v2_runner_on_failed(self, result, ignore_errors=False):
295
+ self._display.v("TASK action=%s FAILED => %s" % (result._task.action, json.dumps(result._result, indent=4)))
296
+
297
+ self._handle_exception(result._result)
298
+ self._handle_warnings(result._result)
299
+
300
+ task = result._task
301
+
302
+ if task.action in self.FREE_FORM_MODULES:
303
+ self._display_command_generic_msg(result._task, result._result, "FAILED", C.COLOR_ERROR)
304
+ #elif result._task.action in C.MODULE_NO_JSON and 'module_stderr' not in result._result:
305
+ # self._display.display(self._command_generic_msg(result._host.get_name(), result._result, "FAILED"), color=C.COLOR_ERROR)
306
+ else:
307
+ self._display.display(self._task_header(result._task, "FAILED"), color=C.COLOR_ERROR)
308
+ if 'msg' in result._result:
309
+ self._display.display(result._result['msg'], color=C.COLOR_ERROR)
310
+ # clean system values from result and return a json
311
+ dump_result = self._dump_results(result._result, indent=4)
312
+ if dump_result:
313
+ self._display.display("Task result => %s" % (self._dump_results(result._result, indent=4)), color=C.COLOR_ERROR)
314
+
315
+
316
+ def v2_runner_on_skipped(self, result):
317
+ self._display.display("%s | SKIPPED" % (result._host.get_name()), color=C.COLOR_SKIP)
318
+
319
+ def v2_runner_on_unreachable(self, result):
320
+ self._display.display("%s | UNREACHABLE! => %s" % (result._host.get_name(), self._dump_results(result._result, indent=4)), color=C.COLOR_UNREACHABLE)
321
+
322
+ def v2_on_file_diff(self, result):
323
+ if 'diff' in result._result and result._result['diff']:
324
+ self._display.display(self._get_diff(result._result['diff']))
325
+
326
+ }
327
+ end
328
+
329
+ end # << self
330
+ end # Builder::Ansible::Assets
331
+ end # Dimg
332
+ end # Dapp