bolt 2.31.0 → 2.35.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of bolt might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Puppetfile +7 -7
- data/bolt-modules/boltlib/lib/puppet/functions/catch_errors.rb +1 -3
- data/bolt-modules/boltlib/lib/puppet/functions/download_file.rb +17 -6
- data/bolt-modules/boltlib/lib/puppet/functions/facts.rb +6 -0
- data/bolt-modules/boltlib/lib/puppet/functions/parallelize.rb +56 -0
- data/bolt-modules/boltlib/lib/puppet/functions/puppetdb_query.rb +2 -2
- data/bolt-modules/boltlib/lib/puppet/functions/run_command.rb +24 -6
- data/bolt-modules/boltlib/lib/puppet/functions/run_script.rb +27 -8
- data/bolt-modules/boltlib/lib/puppet/functions/run_task.rb +21 -1
- data/bolt-modules/boltlib/lib/puppet/functions/run_task_with.rb +18 -1
- data/bolt-modules/boltlib/lib/puppet/functions/upload_file.rb +24 -6
- data/bolt-modules/out/lib/puppet/functions/out/message.rb +44 -1
- data/bolt-modules/prompt/lib/puppet/functions/prompt.rb +3 -0
- data/guides/logging.txt +18 -0
- data/guides/module.txt +19 -0
- data/guides/modulepath.txt +25 -0
- data/lib/bolt/bolt_option_parser.rb +6 -1
- data/lib/bolt/cli.rb +70 -144
- data/lib/bolt/config/options.rb +35 -17
- data/lib/bolt/config/transport/options.rb +1 -1
- data/lib/bolt/error.rb +37 -3
- data/lib/bolt/executor.rb +111 -13
- data/lib/bolt/inventory/group.rb +2 -1
- data/lib/bolt/module_installer.rb +71 -115
- data/lib/bolt/{puppetfile → module_installer}/installer.rb +3 -2
- data/lib/bolt/module_installer/puppetfile.rb +117 -0
- data/lib/bolt/module_installer/puppetfile/forge_module.rb +54 -0
- data/lib/bolt/module_installer/puppetfile/git_module.rb +37 -0
- data/lib/bolt/module_installer/puppetfile/module.rb +26 -0
- data/lib/bolt/module_installer/resolver.rb +76 -0
- data/lib/bolt/module_installer/specs.rb +93 -0
- data/lib/bolt/module_installer/specs/forge_spec.rb +85 -0
- data/lib/bolt/module_installer/specs/git_spec.rb +179 -0
- data/lib/bolt/outputter.rb +0 -47
- data/lib/bolt/outputter/human.rb +23 -11
- data/lib/bolt/outputter/json.rb +1 -1
- data/lib/bolt/pal.rb +48 -30
- data/lib/bolt/pal/yaml_plan.rb +11 -2
- data/lib/bolt/pal/yaml_plan/evaluator.rb +23 -1
- data/lib/bolt/pal/yaml_plan/loader.rb +14 -9
- data/lib/bolt/plan_creator.rb +160 -0
- data/lib/bolt/plugin.rb +1 -1
- data/lib/bolt/project.rb +5 -10
- data/lib/bolt/project_migrator/config.rb +2 -1
- data/lib/bolt/project_migrator/inventory.rb +2 -2
- data/lib/bolt/project_migrator/modules.rb +10 -8
- data/lib/bolt/puppetdb/client.rb +3 -2
- data/lib/bolt/puppetdb/config.rb +8 -6
- data/lib/bolt/result.rb +23 -11
- data/lib/bolt/shell/bash.rb +11 -6
- data/lib/bolt/shell/powershell.rb +12 -7
- data/lib/bolt/task/run.rb +1 -1
- data/lib/bolt/transport/base.rb +18 -18
- data/lib/bolt/transport/docker.rb +23 -6
- data/lib/bolt/transport/orch.rb +23 -19
- data/lib/bolt/transport/orch/connection.rb +10 -3
- data/lib/bolt/transport/remote.rb +3 -3
- data/lib/bolt/transport/simple.rb +6 -6
- data/lib/bolt/util.rb +5 -0
- data/lib/bolt/version.rb +1 -1
- data/lib/bolt/yarn.rb +23 -0
- data/lib/bolt_server/file_cache.rb +2 -0
- data/lib/bolt_server/schemas/partials/task.json +17 -2
- data/lib/bolt_server/transport_app.rb +38 -7
- data/lib/bolt_spec/plans/action_stubs/command_stub.rb +1 -1
- data/lib/bolt_spec/plans/action_stubs/script_stub.rb +1 -1
- data/lib/bolt_spec/plans/mock_executor.rb +9 -6
- metadata +25 -8
- data/lib/bolt/puppetfile.rb +0 -149
- data/lib/bolt/puppetfile/module.rb +0 -93
- data/modules/secure_env_vars/plans/init.pp +0 -20
data/lib/bolt/result.rb
CHANGED
@@ -7,47 +7,58 @@ module Bolt
|
|
7
7
|
class Result
|
8
8
|
attr_reader :target, :value, :action, :object
|
9
9
|
|
10
|
-
def self.from_exception(target, exception, action: 'action')
|
10
|
+
def self.from_exception(target, exception, action: 'action', position: [])
|
11
|
+
details = create_details(position)
|
11
12
|
if exception.is_a?(Bolt::Error)
|
12
|
-
error = exception.to_h
|
13
|
+
error = Bolt::Util.deep_merge({ 'details' => details }, exception.to_h)
|
13
14
|
else
|
15
|
+
details['class'] = exception.class.to_s
|
14
16
|
error = {
|
15
17
|
'kind' => 'puppetlabs.tasks/exception-error',
|
16
18
|
'issue_code' => 'EXCEPTION',
|
17
19
|
'msg' => exception.message,
|
18
|
-
'details' =>
|
20
|
+
'details' => details
|
19
21
|
}
|
20
22
|
error['details']['stack_trace'] = exception.backtrace.join('\n') if exception.backtrace
|
21
23
|
end
|
22
24
|
Result.new(target, error: error, action: action)
|
23
25
|
end
|
24
26
|
|
25
|
-
def self.
|
27
|
+
def self.create_details(position)
|
28
|
+
%w[file line].zip(position).to_h.compact
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.for_command(target, stdout, stderr, exit_code, action, command, position)
|
26
32
|
value = {
|
27
33
|
'stdout' => stdout,
|
28
34
|
'stderr' => stderr,
|
29
35
|
'exit_code' => exit_code
|
30
36
|
}
|
37
|
+
|
38
|
+
details = create_details(position)
|
31
39
|
unless exit_code == 0
|
40
|
+
details['exit_code'] = exit_code
|
32
41
|
value['_error'] = {
|
33
42
|
'kind' => 'puppetlabs.tasks/command-error',
|
34
43
|
'issue_code' => 'COMMAND_ERROR',
|
35
44
|
'msg' => "The command failed with exit code #{exit_code}",
|
36
|
-
'details' =>
|
45
|
+
'details' => details
|
37
46
|
}
|
38
47
|
end
|
39
48
|
new(target, value: value, action: action, object: command)
|
40
49
|
end
|
41
50
|
|
42
|
-
def self.for_task(target, stdout, stderr, exit_code, task)
|
51
|
+
def self.for_task(target, stdout, stderr, exit_code, task, position)
|
43
52
|
stdout.force_encoding('utf-8') unless stdout.encoding == Encoding::UTF_8
|
53
|
+
|
54
|
+
details = create_details(position)
|
44
55
|
value = if stdout.valid_encoding?
|
45
56
|
parse_hash(stdout) || { '_output' => stdout }
|
46
57
|
else
|
47
58
|
{ '_error' => { 'kind' => 'puppetlabs.tasks/task-error',
|
48
59
|
'issue_code' => 'TASK_ERROR',
|
49
60
|
'msg' => 'The task result contained invalid UTF-8 on stdout',
|
50
|
-
'details' =>
|
61
|
+
'details' => details } }
|
51
62
|
end
|
52
63
|
|
53
64
|
if exit_code != 0 && value['_error'].nil?
|
@@ -60,24 +71,26 @@ module Bolt
|
|
60
71
|
else
|
61
72
|
"The task failed with exit code #{exit_code}"
|
62
73
|
end
|
74
|
+
details['exit_code'] = exit_code
|
63
75
|
value['_error'] = { 'kind' => 'puppetlabs.tasks/task-error',
|
64
76
|
'issue_code' => 'TASK_ERROR',
|
65
77
|
'msg' => msg,
|
66
|
-
'details' =>
|
78
|
+
'details' => details }
|
67
79
|
end
|
68
80
|
|
69
81
|
if value.key?('_error')
|
70
82
|
unless value['_error'].is_a?(Hash) && value['_error'].key?('msg')
|
83
|
+
details['original_error'] = value['_error']
|
71
84
|
value['_error'] = {
|
72
85
|
'msg' => "Invalid error returned from task #{task}: #{value['_error'].inspect}. Error "\
|
73
86
|
"must be an object with a msg key.",
|
74
87
|
'kind' => 'bolt/invalid-task-error',
|
75
|
-
'details' =>
|
88
|
+
'details' => details
|
76
89
|
}
|
77
90
|
end
|
78
91
|
|
79
92
|
value['_error']['kind'] ||= 'bolt/error'
|
80
|
-
value['_error']['details'] ||=
|
93
|
+
value['_error']['details'] ||= details
|
81
94
|
end
|
82
95
|
|
83
96
|
if value.key?('_sensitive')
|
@@ -221,7 +234,6 @@ module Bolt
|
|
221
234
|
def error
|
222
235
|
if error_hash
|
223
236
|
Puppet::DataTypes::Error.from_asserted_hash(error_hash)
|
224
|
-
|
225
237
|
end
|
226
238
|
end
|
227
239
|
|
data/lib/bolt/shell/bash.rb
CHANGED
@@ -21,14 +21,16 @@ module Bolt
|
|
21
21
|
['shell']
|
22
22
|
end
|
23
23
|
|
24
|
-
def run_command(command, options = {})
|
24
|
+
def run_command(command, options = {}, position = [])
|
25
25
|
running_as(options[:run_as]) do
|
26
26
|
output = execute(command, environment: options[:env_vars], sudoable: true)
|
27
27
|
Bolt::Result.for_command(target,
|
28
28
|
output.stdout.string,
|
29
29
|
output.stderr.string,
|
30
30
|
output.exit_code,
|
31
|
-
'command',
|
31
|
+
'command',
|
32
|
+
command,
|
33
|
+
position)
|
32
34
|
end
|
33
35
|
end
|
34
36
|
|
@@ -71,7 +73,7 @@ module Bolt
|
|
71
73
|
end
|
72
74
|
end
|
73
75
|
|
74
|
-
def run_script(script, arguments, options = {})
|
76
|
+
def run_script(script, arguments, options = {}, position = [])
|
75
77
|
# unpack any Sensitive data
|
76
78
|
arguments = unwrap_sensitive_args(arguments)
|
77
79
|
|
@@ -84,12 +86,14 @@ module Bolt
|
|
84
86
|
output.stdout.string,
|
85
87
|
output.stderr.string,
|
86
88
|
output.exit_code,
|
87
|
-
'script',
|
89
|
+
'script',
|
90
|
+
script,
|
91
|
+
position)
|
88
92
|
end
|
89
93
|
end
|
90
94
|
end
|
91
95
|
|
92
|
-
def run_task(task, arguments, options = {})
|
96
|
+
def run_task(task, arguments, options = {}, position = [])
|
93
97
|
implementation = select_implementation(target, task)
|
94
98
|
executable = implementation['path']
|
95
99
|
input_method = implementation['input_method']
|
@@ -148,7 +152,8 @@ module Bolt
|
|
148
152
|
Bolt::Result.for_task(target, output.stdout.string,
|
149
153
|
output.stderr.string,
|
150
154
|
output.exit_code,
|
151
|
-
task.name
|
155
|
+
task.name,
|
156
|
+
position)
|
152
157
|
end
|
153
158
|
end
|
154
159
|
|
@@ -11,7 +11,7 @@ module Bolt
|
|
11
11
|
def initialize(target, conn)
|
12
12
|
super
|
13
13
|
|
14
|
-
extensions = [target.options['extensions'] || []].flatten.map { |ext| ext[0]
|
14
|
+
extensions = [target.options['extensions'] || []].flatten.map { |ext| ext[0] == '.' ? ext : '.' + ext }
|
15
15
|
extensions += target.options['interpreters'].keys if target.options['interpreters']
|
16
16
|
@extensions = DEFAULT_EXTENSIONS + extensions
|
17
17
|
end
|
@@ -174,7 +174,7 @@ module Bolt
|
|
174
174
|
Bolt::Result.for_download(target, source, destination, download)
|
175
175
|
end
|
176
176
|
|
177
|
-
def run_command(command, options = {})
|
177
|
+
def run_command(command, options = {}, position = [])
|
178
178
|
command = [*env_declarations(options[:env_vars]), command].join("\r\n") if options[:env_vars]
|
179
179
|
|
180
180
|
output = execute(command)
|
@@ -182,10 +182,12 @@ module Bolt
|
|
182
182
|
output.stdout.string,
|
183
183
|
output.stderr.string,
|
184
184
|
output.exit_code,
|
185
|
-
'command',
|
185
|
+
'command',
|
186
|
+
command,
|
187
|
+
position)
|
186
188
|
end
|
187
189
|
|
188
|
-
def run_script(script, arguments, options = {})
|
190
|
+
def run_script(script, arguments, options = {}, position = [])
|
189
191
|
# unpack any Sensitive data
|
190
192
|
arguments = unwrap_sensitive_args(arguments)
|
191
193
|
with_tmpdir do |dir|
|
@@ -204,11 +206,13 @@ module Bolt
|
|
204
206
|
output.stdout.string,
|
205
207
|
output.stderr.string,
|
206
208
|
output.exit_code,
|
207
|
-
'script',
|
209
|
+
'script',
|
210
|
+
script,
|
211
|
+
position)
|
208
212
|
end
|
209
213
|
end
|
210
214
|
|
211
|
-
def run_task(task, arguments, _options = {})
|
215
|
+
def run_task(task, arguments, _options = {}, position = [])
|
212
216
|
implementation = select_implementation(target, task)
|
213
217
|
executable = implementation['path']
|
214
218
|
input_method = implementation['input_method']
|
@@ -259,7 +263,8 @@ module Bolt
|
|
259
263
|
Bolt::Result.for_task(target, output.stdout.string,
|
260
264
|
output.stderr.string,
|
261
265
|
output.exit_code,
|
262
|
-
task.name
|
266
|
+
task.name,
|
267
|
+
position)
|
263
268
|
end
|
264
269
|
end
|
265
270
|
|
data/lib/bolt/task/run.rb
CHANGED
@@ -42,7 +42,7 @@ module Bolt
|
|
42
42
|
if targets.empty?
|
43
43
|
Bolt::ResultSet.new([])
|
44
44
|
else
|
45
|
-
result = executor.
|
45
|
+
result = executor.run_task_with_minimal_logging(targets, task, params, options)
|
46
46
|
|
47
47
|
if !result.ok && !options[:catch_errors]
|
48
48
|
raise Bolt::RunFailure.new(result, 'run_task', task.name)
|
data/lib/bolt/transport/base.rb
CHANGED
@@ -43,13 +43,13 @@ module Bolt
|
|
43
43
|
@logger = Bolt::Logger.logger(self)
|
44
44
|
end
|
45
45
|
|
46
|
-
def with_events(target, callback, action)
|
46
|
+
def with_events(target, callback, action, position)
|
47
47
|
callback&.call(type: :node_start, target: target)
|
48
48
|
|
49
49
|
result = begin
|
50
50
|
yield
|
51
51
|
rescue StandardError, NotImplementedError => e
|
52
|
-
Bolt::Result.from_exception(target, e, action: action)
|
52
|
+
Bolt::Result.from_exception(target, e, action: action, position: position)
|
53
53
|
end
|
54
54
|
|
55
55
|
callback&.call(type: :node_result, result: result)
|
@@ -100,12 +100,12 @@ module Bolt
|
|
100
100
|
# The default implementation only supports batches of size 1 and will fail otherwise.
|
101
101
|
#
|
102
102
|
# Transports may override this method to implement their own batch processing.
|
103
|
-
def batch_task(targets, task, arguments, options = {}, &callback)
|
103
|
+
def batch_task(targets, task, arguments, options = {}, position = [], &callback)
|
104
104
|
assert_batch_size_one("batch_task()", targets)
|
105
105
|
target = targets.first
|
106
|
-
with_events(target, callback, 'task') do
|
106
|
+
with_events(target, callback, 'task', position) do
|
107
107
|
@logger.debug { "Running task '#{task.name}' on #{target.safe_name}" }
|
108
|
-
run_task(target, task, arguments, options)
|
108
|
+
run_task(target, task, arguments, options, position)
|
109
109
|
end
|
110
110
|
end
|
111
111
|
|
@@ -114,14 +114,14 @@ module Bolt
|
|
114
114
|
# The default implementation only supports batches of size 1 and will fail otherwise.
|
115
115
|
#
|
116
116
|
# Transports may override this method to implment their own batch processing.
|
117
|
-
def batch_task_with(targets, task, target_mapping, options = {}, &callback)
|
117
|
+
def batch_task_with(targets, task, target_mapping, options = {}, position = [], &callback)
|
118
118
|
assert_batch_size_one("batch_task_with()", targets)
|
119
119
|
target = targets.first
|
120
120
|
arguments = target_mapping[target]
|
121
121
|
|
122
|
-
with_events(target, callback, 'task') do
|
122
|
+
with_events(target, callback, 'task', position) do
|
123
123
|
@logger.debug { "Running task '#{task.name}' on #{target.safe_name} with '#{arguments.to_json}'" }
|
124
|
-
run_task(target, task, arguments, options)
|
124
|
+
run_task(target, task, arguments, options, position)
|
125
125
|
end
|
126
126
|
end
|
127
127
|
|
@@ -130,12 +130,12 @@ module Bolt
|
|
130
130
|
# The default implementation only supports batches of size 1 and will fail otherwise.
|
131
131
|
#
|
132
132
|
# Transports may override this method to implement their own batch processing.
|
133
|
-
def batch_command(targets, command, options = {}, &callback)
|
133
|
+
def batch_command(targets, command, options = {}, position = [], &callback)
|
134
134
|
assert_batch_size_one("batch_command()", targets)
|
135
135
|
target = targets.first
|
136
|
-
with_events(target, callback, 'command') do
|
136
|
+
with_events(target, callback, 'command', position) do
|
137
137
|
@logger.debug("Running command '#{command}' on #{target.safe_name}")
|
138
|
-
run_command(target, command, options)
|
138
|
+
run_command(target, command, options, position)
|
139
139
|
end
|
140
140
|
end
|
141
141
|
|
@@ -144,12 +144,12 @@ module Bolt
|
|
144
144
|
# The default implementation only supports batches of size 1 and will fail otherwise.
|
145
145
|
#
|
146
146
|
# Transports may override this method to implement their own batch processing.
|
147
|
-
def batch_script(targets, script, arguments, options = {}, &callback)
|
147
|
+
def batch_script(targets, script, arguments, options = {}, position = [], &callback)
|
148
148
|
assert_batch_size_one("batch_script()", targets)
|
149
149
|
target = targets.first
|
150
|
-
with_events(target, callback, 'script') do
|
150
|
+
with_events(target, callback, 'script', position) do
|
151
151
|
@logger.debug { "Running script '#{script}' on #{target.safe_name}" }
|
152
|
-
run_script(target, script, arguments, options)
|
152
|
+
run_script(target, script, arguments, options, position)
|
153
153
|
end
|
154
154
|
end
|
155
155
|
|
@@ -158,10 +158,10 @@ module Bolt
|
|
158
158
|
# The default implementation only supports batches of size 1 and will fail otherwise.
|
159
159
|
#
|
160
160
|
# Transports may override this method to implement their own batch processing.
|
161
|
-
def batch_upload(targets, source, destination, options = {}, &callback)
|
161
|
+
def batch_upload(targets, source, destination, options = {}, position = [], &callback)
|
162
162
|
assert_batch_size_one("batch_upload()", targets)
|
163
163
|
target = targets.first
|
164
|
-
with_events(target, callback, 'upload') do
|
164
|
+
with_events(target, callback, 'upload', position) do
|
165
165
|
@logger.debug { "Uploading: '#{source}' to #{destination} on #{target.safe_name}" }
|
166
166
|
upload(target, source, destination, options)
|
167
167
|
end
|
@@ -173,12 +173,12 @@ module Bolt
|
|
173
173
|
# The default implementation only supports batches of size 1 and will fail otherwise.
|
174
174
|
#
|
175
175
|
# Transports may override this method to implement their own batch processing.
|
176
|
-
def batch_download(targets, source, destination, options = {}, &callback)
|
176
|
+
def batch_download(targets, source, destination, options = {}, position = [], &callback)
|
177
177
|
require 'erb'
|
178
178
|
|
179
179
|
assert_batch_size_one("batch_download()", targets)
|
180
180
|
target = targets.first
|
181
|
-
with_events(target, callback, 'download') do
|
181
|
+
with_events(target, callback, 'download', position) do
|
182
182
|
escaped_name = ERB::Util.url_encode(target.safe_name)
|
183
183
|
target_destination = File.expand_path(escaped_name, destination)
|
184
184
|
@logger.debug { "Downloading: '#{source}' on #{target.safe_name} to #{target_destination}" }
|
@@ -46,7 +46,7 @@ module Bolt
|
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
49
|
-
def run_command(target, command, options = {})
|
49
|
+
def run_command(target, command, options = {}, position = [])
|
50
50
|
execute_options = {}
|
51
51
|
execute_options[:tty] = target.options['tty']
|
52
52
|
execute_options[:environment] = options[:env_vars]
|
@@ -58,11 +58,17 @@ module Bolt
|
|
58
58
|
end
|
59
59
|
with_connection(target) do |conn|
|
60
60
|
stdout, stderr, exitcode = conn.execute(*Shellwords.split(command), execute_options)
|
61
|
-
Bolt::Result.for_command(target,
|
61
|
+
Bolt::Result.for_command(target,
|
62
|
+
stdout,
|
63
|
+
stderr,
|
64
|
+
exitcode,
|
65
|
+
'command',
|
66
|
+
command,
|
67
|
+
position)
|
62
68
|
end
|
63
69
|
end
|
64
70
|
|
65
|
-
def run_script(target, script, arguments, options = {})
|
71
|
+
def run_script(target, script, arguments, options = {}, position = [])
|
66
72
|
# unpack any Sensitive data
|
67
73
|
arguments = unwrap_sensitive_args(arguments)
|
68
74
|
execute_options = {}
|
@@ -72,12 +78,18 @@ module Bolt
|
|
72
78
|
conn.with_remote_tmpdir do |dir|
|
73
79
|
remote_path = conn.write_remote_executable(dir, script)
|
74
80
|
stdout, stderr, exitcode = conn.execute(remote_path, *arguments, execute_options)
|
75
|
-
Bolt::Result.for_command(target,
|
81
|
+
Bolt::Result.for_command(target,
|
82
|
+
stdout,
|
83
|
+
stderr,
|
84
|
+
exitcode,
|
85
|
+
'script',
|
86
|
+
script,
|
87
|
+
position)
|
76
88
|
end
|
77
89
|
end
|
78
90
|
end
|
79
91
|
|
80
|
-
def run_task(target, task, arguments, _options = {})
|
92
|
+
def run_task(target, task, arguments, _options = {}, position = [])
|
81
93
|
implementation = task.select_implementation(target, provided_features)
|
82
94
|
executable = implementation['path']
|
83
95
|
input_method = implementation['input_method']
|
@@ -113,7 +125,12 @@ module Bolt
|
|
113
125
|
end
|
114
126
|
|
115
127
|
stdout, stderr, exitcode = conn.execute(remote_task_path, execute_options)
|
116
|
-
Bolt::Result.for_task(target,
|
128
|
+
Bolt::Result.for_task(target,
|
129
|
+
stdout,
|
130
|
+
stderr,
|
131
|
+
exitcode,
|
132
|
+
task.name,
|
133
|
+
position)
|
117
134
|
end
|
118
135
|
end
|
119
136
|
end
|
data/lib/bolt/transport/orch.rb
CHANGED
@@ -10,11 +10,6 @@ require 'bolt/transport/orch/connection'
|
|
10
10
|
module Bolt
|
11
11
|
module Transport
|
12
12
|
class Orch < Base
|
13
|
-
CONF_FILE = if !ENV['HOME'].nil?
|
14
|
-
File.expand_path('~/.puppetlabs/client-tools/orchestrator.conf')
|
15
|
-
else
|
16
|
-
'/etc/puppetlabs/client-tools/orchestrator.conf'
|
17
|
-
end
|
18
13
|
BOLT_COMMAND_TASK = Struct.new(:name).new('bolt_shim::command').freeze
|
19
14
|
BOLT_SCRIPT_TASK = Struct.new(:name).new('bolt_shim::script').freeze
|
20
15
|
BOLT_UPLOAD_TASK = Struct.new(:name).new('bolt_shim::upload').freeze
|
@@ -53,7 +48,7 @@ module Bolt
|
|
53
48
|
conn
|
54
49
|
end
|
55
50
|
|
56
|
-
def process_run_results(targets, results, task_name)
|
51
|
+
def process_run_results(targets, results, task_name, position = [])
|
57
52
|
targets_by_name = Hash[targets.map { |t| t.host || t.name }.zip(targets)]
|
58
53
|
results.map do |node_result|
|
59
54
|
target = targets_by_name[node_result['name']]
|
@@ -63,25 +58,31 @@ module Bolt
|
|
63
58
|
# If it's finished or already has a proper error simply pass it to the
|
64
59
|
# the result otherwise make sure an error is generated
|
65
60
|
if state == 'finished' || (result && result['_error'])
|
61
|
+
if result['_error']
|
62
|
+
file_line = %w[file line].zip(position).to_h.compact
|
63
|
+
result['_error']['details'].merge!(file_line) unless result['_error']['details']['file']
|
64
|
+
end
|
65
|
+
|
66
66
|
Bolt::Result.new(target, value: result, action: 'task', object: task_name)
|
67
67
|
elsif state == 'skipped'
|
68
|
+
details = %w[file line].zip(position).to_h.compact
|
68
69
|
Bolt::Result.new(
|
69
70
|
target,
|
70
71
|
value: { '_error' => {
|
71
72
|
'kind' => 'puppetlabs.tasks/skipped-node',
|
72
73
|
'msg' => "Target #{target.safe_name} was skipped",
|
73
|
-
'details' =>
|
74
|
+
'details' => details
|
74
75
|
} },
|
75
76
|
action: 'task', object: task_name
|
76
77
|
)
|
77
78
|
else
|
78
79
|
# Make a generic error with a unkown exit_code
|
79
|
-
Bolt::Result.for_task(target, result.to_json, '', 'unknown', task_name)
|
80
|
+
Bolt::Result.for_task(target, result.to_json, '', 'unknown', task_name, position)
|
80
81
|
end
|
81
82
|
end
|
82
83
|
end
|
83
84
|
|
84
|
-
def batch_command(targets, command, options = {}, &callback)
|
85
|
+
def batch_command(targets, command, options = {}, position = [], &callback)
|
85
86
|
if options[:env_vars] && !options[:env_vars].empty?
|
86
87
|
raise NotImplementedError, "pcp transport does not support setting environment variables"
|
87
88
|
end
|
@@ -93,6 +94,7 @@ module Bolt
|
|
93
94
|
BOLT_COMMAND_TASK,
|
94
95
|
params,
|
95
96
|
options,
|
97
|
+
position,
|
96
98
|
&callback)
|
97
99
|
callback ||= proc {}
|
98
100
|
results.map! { |result| unwrap_bolt_result(result.target, result, 'command', command) }
|
@@ -101,7 +103,7 @@ module Bolt
|
|
101
103
|
end
|
102
104
|
end
|
103
105
|
|
104
|
-
def batch_script(targets, script, arguments, options = {}, &callback)
|
106
|
+
def batch_script(targets, script, arguments, options = {}, position = [], &callback)
|
105
107
|
if options[:env_vars] && !options[:env_vars].empty?
|
106
108
|
raise NotImplementedError, "pcp transport does not support setting environment variables"
|
107
109
|
end
|
@@ -114,7 +116,7 @@ module Bolt
|
|
114
116
|
'name' => Pathname(script).basename.to_s
|
115
117
|
}
|
116
118
|
callback ||= proc {}
|
117
|
-
results = run_task_job(targets, BOLT_SCRIPT_TASK, params, options, &callback)
|
119
|
+
results = run_task_job(targets, BOLT_SCRIPT_TASK, params, options, position, &callback)
|
118
120
|
results.map! { |result| unwrap_bolt_result(result.target, result, 'script', script) }
|
119
121
|
results.each do |result|
|
120
122
|
callback.call(type: :node_result, result: result)
|
@@ -155,7 +157,7 @@ module Bolt
|
|
155
157
|
output&.close
|
156
158
|
end
|
157
159
|
|
158
|
-
def batch_upload(targets, source, destination, options = {}, &callback)
|
160
|
+
def batch_upload(targets, source, destination, options = {}, position = [], &callback)
|
159
161
|
stat = File.stat(source)
|
160
162
|
content = if stat.directory?
|
161
163
|
pack(source)
|
@@ -171,7 +173,7 @@ module Bolt
|
|
171
173
|
'directory' => stat.directory?
|
172
174
|
}
|
173
175
|
callback ||= proc {}
|
174
|
-
results = run_task_job(targets, BOLT_UPLOAD_TASK, params, options, &callback)
|
176
|
+
results = run_task_job(targets, BOLT_UPLOAD_TASK, params, options, position, &callback)
|
175
177
|
results.map! do |result|
|
176
178
|
if result.error_hash
|
177
179
|
result
|
@@ -200,7 +202,7 @@ module Bolt
|
|
200
202
|
targets.group_by { |target| Connection.get_key(target.options) }.values
|
201
203
|
end
|
202
204
|
|
203
|
-
def run_task_job(targets, task, arguments, options)
|
205
|
+
def run_task_job(targets, task, arguments, options, position)
|
204
206
|
targets.each do |target|
|
205
207
|
yield(type: :node_start, target: target) if block_given?
|
206
208
|
end
|
@@ -210,7 +212,7 @@ module Bolt
|
|
210
212
|
arguments = unwrap_sensitive_args(arguments)
|
211
213
|
results = get_connection(targets.first.options).run_task(targets, task, arguments, options)
|
212
214
|
|
213
|
-
process_run_results(targets, results, task.name)
|
215
|
+
process_run_results(targets, results, task.name, position)
|
214
216
|
rescue OrchestratorClient::ApiError => e
|
215
217
|
targets.map do |target|
|
216
218
|
Bolt::Result.new(target, error: e.data)
|
@@ -222,15 +224,15 @@ module Bolt
|
|
222
224
|
end
|
223
225
|
end
|
224
226
|
|
225
|
-
def batch_task(targets, task, arguments, options = {}, &callback)
|
227
|
+
def batch_task(targets, task, arguments, options = {}, position = [], &callback)
|
226
228
|
callback ||= proc {}
|
227
|
-
results = run_task_job(targets, task, arguments, options, &callback)
|
229
|
+
results = run_task_job(targets, task, arguments, options, position, &callback)
|
228
230
|
results.each do |result|
|
229
231
|
callback.call(type: :node_result, result: result)
|
230
232
|
end
|
231
233
|
end
|
232
234
|
|
233
|
-
def batch_task_with(_targets, _task, _target_mapping, _options = {})
|
235
|
+
def batch_task_with(_targets, _task, _target_mapping, _options = {}, _position = [])
|
234
236
|
raise NotImplementedError, "pcp transport does not support run_task_with()"
|
235
237
|
end
|
236
238
|
|
@@ -248,11 +250,13 @@ module Bolt
|
|
248
250
|
return result
|
249
251
|
end
|
250
252
|
|
253
|
+
# If we get here, there's no error so we don't need the file or line
|
254
|
+
# number
|
251
255
|
Bolt::Result.for_command(target,
|
252
256
|
result.value['stdout'],
|
253
257
|
result.value['stderr'],
|
254
258
|
result.value['exit_code'],
|
255
|
-
action, obj)
|
259
|
+
action, obj, [])
|
256
260
|
end
|
257
261
|
end
|
258
262
|
end
|