dapp 0.26.14 → 0.27.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/dapp +0 -4
- data/config/en/common.yml +1 -0
- data/config/en/net_status.yml +2 -0
- data/lib/dapp.rb +1 -4
- data/lib/dapp/cli.rb +0 -4
- data/lib/dapp/cli/command/base.rb +1 -7
- data/lib/dapp/dapp.rb +4 -22
- data/lib/dapp/dapp/dappfile.rb +2 -2
- data/lib/dapp/dapp/deps/base.rb +6 -2
- data/lib/dapp/dapp/option_tags.rb +1 -7
- data/lib/dapp/dimg/artifact.rb +4 -0
- data/lib/dapp/dimg/build/stage/artifact_base.rb +7 -7
- data/lib/dapp/dimg/build/stage/artifact_default.rb +4 -5
- data/lib/dapp/dimg/build/stage/base.rb +1 -3
- data/lib/dapp/dimg/build/stage/before_install.rb +2 -3
- data/lib/dapp/dimg/build/stage/from.rb +31 -5
- data/lib/dapp/dimg/build/stage/ga_base.rb +1 -1
- data/lib/dapp/dimg/build/stage/ga_latest_patch.rb +1 -3
- data/lib/dapp/dimg/build/stage/import_artifact.rb +3 -4
- data/lib/dapp/dimg/builder/ansible.rb +167 -2
- data/lib/dapp/dimg/builder/ansible/assets.rb +332 -0
- data/lib/dapp/dimg/builder/chef.rb +2 -2
- data/lib/dapp/dimg/cli/command/base.rb +14 -0
- data/lib/dapp/dimg/cli/command/dimg/build.rb +15 -24
- data/lib/dapp/dimg/cli/command/dimg/run.rb +14 -1
- data/lib/dapp/dimg/config/directive/dimg/instance_methods.rb +2 -1
- data/lib/dapp/dimg/config/directive/dimg_group_base.rb +2 -2
- data/lib/dapp/dimg/config/directive/git_artifact_remote.rb +4 -3
- data/lib/dapp/dimg/dapp/command/cleanup.rb +2 -2
- data/lib/dapp/dimg/dapp/command/common.rb +16 -5
- data/lib/dapp/dimg/dapp/command/mrproper.rb +6 -8
- data/lib/dapp/dimg/dapp/command/push.rb +1 -1
- data/lib/dapp/dimg/dapp/command/run.rb +3 -2
- data/lib/dapp/dimg/dapp/command/stages/cleanup_local.rb +3 -0
- data/lib/dapp/dimg/dapp/command/tag.rb +1 -1
- data/lib/dapp/dimg/dapp/dimg.rb +8 -0
- data/lib/dapp/dimg/dimg.rb +14 -3
- data/lib/dapp/dimg/dimg/stages.rb +1 -1
- data/lib/dapp/dimg/docker_registry/base.rb +10 -0
- data/lib/dapp/dimg/docker_registry/base/authorization.rb +1 -16
- data/lib/dapp/dimg/git_artifact.rb +9 -2
- data/lib/dapp/dimg/git_repo/base.rb +2 -2
- data/lib/dapp/dimg/git_repo/local.rb +2 -2
- data/lib/dapp/kube/dapp/command/deploy.rb +0 -1
- data/lib/dapp/kube/dapp/command/lint.rb +11 -4
- data/lib/dapp/kube/helm/values.rb +7 -7
- data/lib/dapp/version.rb +2 -2
- metadata +5 -34
- data/lib/dapp/dapp/sentry.rb +0 -106
- 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
|
-
|
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
|