bolt 2.32.0 → 2.33.1
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 +5 -5
- data/bolt-modules/boltlib/lib/puppet/functions/download_file.rb +1 -1
- data/bolt-modules/boltlib/lib/puppet/functions/facts.rb +6 -0
- data/bolt-modules/boltlib/lib/puppet/functions/puppetdb_query.rb +2 -2
- data/bolt-modules/boltlib/lib/puppet/functions/run_command.rb +1 -1
- data/bolt-modules/boltlib/lib/puppet/functions/run_script.rb +1 -1
- data/bolt-modules/boltlib/lib/puppet/functions/run_task.rb +1 -1
- data/bolt-modules/boltlib/lib/puppet/functions/run_task_with.rb +1 -1
- data/bolt-modules/boltlib/lib/puppet/functions/upload_file.rb +1 -1
- data/guides/logging.txt +18 -0
- data/lib/bolt/config/transport/options.rb +1 -1
- data/lib/bolt/error.rb +4 -0
- data/lib/bolt/executor.rb +12 -12
- data/lib/bolt/module_installer.rb +1 -0
- data/lib/bolt/pal.rb +30 -24
- data/lib/bolt/pal/yaml_plan.rb +4 -2
- data/lib/bolt/pal/yaml_plan/evaluator.rb +23 -1
- data/lib/bolt/pal/yaml_plan/loader.rb +14 -9
- data/lib/bolt/result.rb +23 -11
- data/lib/bolt/shell/bash.rb +11 -6
- data/lib/bolt/shell/powershell.rb +11 -6
- data/lib/bolt/transport/base.rb +18 -18
- data/lib/bolt/transport/docker.rb +23 -6
- data/lib/bolt/transport/orch.rb +23 -14
- data/lib/bolt/transport/remote.rb +2 -2
- data/lib/bolt/transport/simple.rb +6 -6
- data/lib/bolt/version.rb +1 -1
- 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 +5 -5
- metadata +3 -3
- data/modules/secure_env_vars/plans/init.pp +0 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cf27b6c8b1a7e3cfb2eb61617bd7ab4927161c577df4915d959182fd8bce7eaf
|
4
|
+
data.tar.gz: '05578a39ce18d1d63bf9455c8890e1e328bdcb3f52dacc3d6d5047251bca833e'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 11b3fad81f576fa435b570b15ee7cbab14b7c099b4b179770eb20dbc7f2a2db9b2d2de6c4a52eb09021a9794d13c4da704eb3a2ed362cfd50ab1946e7ef5998d
|
7
|
+
data.tar.gz: 300b9fa2214a66d239218b7a8c12518a97c2cf2fafd401c860a3ff9cdd439355608b30d72d5a82f157eea842a25a7c5bc9d484dd9f616837ebfe4beff26c0795
|
data/Puppetfile
CHANGED
@@ -6,16 +6,16 @@ moduledir File.join(File.dirname(__FILE__), 'modules')
|
|
6
6
|
|
7
7
|
# Core modules used by 'apply'
|
8
8
|
mod 'puppetlabs-service', '1.3.0'
|
9
|
-
mod 'puppetlabs-puppet_agent', '4.
|
9
|
+
mod 'puppetlabs-puppet_agent', '4.2.0'
|
10
10
|
mod 'puppetlabs-facts', '1.1.0'
|
11
11
|
|
12
12
|
# Core types and providers for Puppet 6
|
13
13
|
mod 'puppetlabs-augeas_core', '1.1.1'
|
14
14
|
mod 'puppetlabs-host_core', '1.0.3'
|
15
15
|
mod 'puppetlabs-scheduled_task', '2.2.1'
|
16
|
-
mod 'puppetlabs-sshkeys_core', '2.
|
17
|
-
mod 'puppetlabs-zfs_core', '1.
|
18
|
-
mod 'puppetlabs-cron_core', '1.0.
|
16
|
+
mod 'puppetlabs-sshkeys_core', '2.2.0'
|
17
|
+
mod 'puppetlabs-zfs_core', '1.2.0'
|
18
|
+
mod 'puppetlabs-cron_core', '1.0.5'
|
19
19
|
mod 'puppetlabs-mount_core', '1.0.4'
|
20
20
|
mod 'puppetlabs-selinux_core', '1.0.4'
|
21
21
|
mod 'puppetlabs-yumrepo_core', '1.0.7'
|
@@ -36,6 +36,7 @@ mod 'puppetlabs-azure_inventory', '0.4.1'
|
|
36
36
|
mod 'puppetlabs-gcloud_inventory', '0.1.3'
|
37
37
|
mod 'puppetlabs-http_request', '0.2.0'
|
38
38
|
mod 'puppetlabs-pkcs7', '0.1.1'
|
39
|
+
mod 'puppetlabs-secure_env_vars', '0.1.0'
|
39
40
|
mod 'puppetlabs-terraform', '0.5.0'
|
40
41
|
mod 'puppetlabs-vault', '0.3.0'
|
41
42
|
mod 'puppetlabs-yaml', '0.2.0'
|
@@ -44,4 +45,3 @@ mod 'puppetlabs-yaml', '0.2.0'
|
|
44
45
|
mod 'canary', local: true
|
45
46
|
mod 'aggregate', local: true
|
46
47
|
mod 'puppetdb_fact', local: true
|
47
|
-
mod 'secure_env_vars', local: true
|
@@ -112,7 +112,7 @@ Puppet::Functions.create_function(:download_file, Puppet::Functions::InternalFun
|
|
112
112
|
call_function('debug', "Simulating file download of '#{source}' - no targets given - no action taken")
|
113
113
|
r = Bolt::ResultSet.new([])
|
114
114
|
else
|
115
|
-
r = executor.download_file(targets, source, destination, options)
|
115
|
+
r = executor.download_file(targets, source, destination, options, Puppet::Pops::PuppetStack.top_of_stack)
|
116
116
|
end
|
117
117
|
|
118
118
|
if !r.ok && !options[:catch_errors]
|
@@ -3,6 +3,12 @@
|
|
3
3
|
require 'bolt/error'
|
4
4
|
|
5
5
|
# Returns the facts hash for a target.
|
6
|
+
#
|
7
|
+
# Using the `facts` function does not automatically collect facts for a target,
|
8
|
+
# and will only return facts that are currently set in the inventory. To collect
|
9
|
+
# facts from a target and set them in the inventory, run the
|
10
|
+
# [facts](writing_plans.md#collect-facts-from-targets) plan or
|
11
|
+
# [puppetdb_fact](writing_plans.md#collect-facts-from-puppetdb) plan.
|
6
12
|
Puppet::Functions.create_function(:facts) do
|
7
13
|
# @param target A target.
|
8
14
|
# @return The target's facts.
|
@@ -2,12 +2,12 @@
|
|
2
2
|
|
3
3
|
require 'bolt/error'
|
4
4
|
|
5
|
-
# Makes a query to
|
5
|
+
# Makes a query to [puppetdb](https://puppet.com/docs/puppetdb/latest/index.html)
|
6
6
|
# using Bolt's PuppetDB client.
|
7
7
|
Puppet::Functions.create_function(:puppetdb_query) do
|
8
8
|
# rubocop:disable Layout/LineLength
|
9
9
|
# @param query A PQL query.
|
10
|
-
#
|
10
|
+
# Learn more about [Puppet's query language](https://puppet.com/docs/puppetdb/latest/api/query/tutorial-pql.html), PQL.
|
11
11
|
# @return Results of the PuppetDB query.
|
12
12
|
# @example Request certnames for all nodes
|
13
13
|
# puppetdb_query('nodes[certname] {}')
|
@@ -69,7 +69,7 @@ Puppet::Functions.create_function(:run_command) do
|
|
69
69
|
call_function('debug', "Simulating run_command('#{command}') - no targets given - no action taken")
|
70
70
|
r = Bolt::ResultSet.new([])
|
71
71
|
else
|
72
|
-
r = executor.run_command(targets, command, options)
|
72
|
+
r = executor.run_command(targets, command, options, Puppet::Pops::PuppetStack.top_of_stack)
|
73
73
|
end
|
74
74
|
|
75
75
|
if !r.ok && !options[:catch_errors]
|
@@ -87,7 +87,7 @@ Puppet::Functions.create_function(:run_script, Puppet::Functions::InternalFuncti
|
|
87
87
|
r = if targets.empty?
|
88
88
|
Bolt::ResultSet.new([])
|
89
89
|
else
|
90
|
-
executor.run_script(targets, found, arguments, options)
|
90
|
+
executor.run_script(targets, found, arguments, options, Puppet::Pops::PuppetStack.top_of_stack)
|
91
91
|
end
|
92
92
|
|
93
93
|
if !r.ok && !options[:catch_errors]
|
@@ -133,7 +133,7 @@ Puppet::Functions.create_function(:run_task) do
|
|
133
133
|
if targets.empty?
|
134
134
|
Bolt::ResultSet.new([])
|
135
135
|
else
|
136
|
-
result = executor.run_task(targets, task, params, options)
|
136
|
+
result = executor.run_task(targets, task, params, options, Puppet::Pops::PuppetStack.top_of_stack)
|
137
137
|
if !result.ok && !options[:catch_errors]
|
138
138
|
raise Bolt::RunFailure.new(result, 'run_task', task_name)
|
139
139
|
end
|
@@ -180,7 +180,7 @@ Puppet::Functions.create_function(:run_task_with) do
|
|
180
180
|
else
|
181
181
|
# Combine the results from the task run with any failing results that were
|
182
182
|
# generated earlier when creating the target mapping
|
183
|
-
task_result = executor.run_task_with(target_mapping, task, options)
|
183
|
+
task_result = executor.run_task_with(target_mapping, task, options, Puppet::Pops::PuppetStack.top_of_stack)
|
184
184
|
result = Bolt::ResultSet.new(task_result.results + error_set)
|
185
185
|
|
186
186
|
if !result.ok && !options[:catch_errors]
|
@@ -83,7 +83,7 @@ Puppet::Functions.create_function(:upload_file, Puppet::Functions::InternalFunct
|
|
83
83
|
call_function('debug', "Simulating file upload of '#{found}' - no targets given - no action taken")
|
84
84
|
r = Bolt::ResultSet.new([])
|
85
85
|
else
|
86
|
-
r = executor.upload_file(targets, found, destination, options)
|
86
|
+
r = executor.upload_file(targets, found, destination, options, Puppet::Pops::PuppetStack.top_of_stack)
|
87
87
|
end
|
88
88
|
|
89
89
|
if !r.ok && !options[:catch_errors]
|
data/guides/logging.txt
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
TOPIC
|
2
|
+
logging
|
3
|
+
|
4
|
+
DESCRIPTION
|
5
|
+
Bolt prints messages both to the console and to log files. Messages can
|
6
|
+
either come from Bolt's 'outputter', which logs user-facing messages like
|
7
|
+
progress and results, or from the 'logger', which logs warnings, errors, and
|
8
|
+
log-structured output to log files. Both of these message streams are
|
9
|
+
configurable.
|
10
|
+
|
11
|
+
By default, Bolt logs to the console at 'warn' level and writes a log file to
|
12
|
+
'<project>/bolt-debug.log' at 'debug' level. Unless you are running a plan,
|
13
|
+
Bolt runs in verbose mode by default.
|
14
|
+
|
15
|
+
To learn more about projects, see the 'project' guide.
|
16
|
+
|
17
|
+
DOCUMENTATION
|
18
|
+
https://pup.pt/bolt-logging
|
data/lib/bolt/error.rb
CHANGED
data/lib/bolt/executor.rb
CHANGED
@@ -253,33 +253,33 @@ module Bolt
|
|
253
253
|
result
|
254
254
|
end
|
255
255
|
|
256
|
-
def run_command(targets, command, options = {})
|
256
|
+
def run_command(targets, command, options = {}, position = [])
|
257
257
|
description = options.fetch(:description, "command '#{command}'")
|
258
258
|
log_action(description, targets) do
|
259
259
|
options[:run_as] = run_as if run_as && !options.key?(:run_as)
|
260
260
|
|
261
261
|
batch_execute(targets) do |transport, batch|
|
262
262
|
with_node_logging("Running command '#{command}'", batch) do
|
263
|
-
transport.batch_command(batch, command, options, &method(:publish_event))
|
263
|
+
transport.batch_command(batch, command, options, position, &method(:publish_event))
|
264
264
|
end
|
265
265
|
end
|
266
266
|
end
|
267
267
|
end
|
268
268
|
|
269
|
-
def run_script(targets, script, arguments, options = {})
|
269
|
+
def run_script(targets, script, arguments, options = {}, position = [])
|
270
270
|
description = options.fetch(:description, "script #{script}")
|
271
271
|
log_action(description, targets) do
|
272
272
|
options[:run_as] = run_as if run_as && !options.key?(:run_as)
|
273
273
|
|
274
274
|
batch_execute(targets) do |transport, batch|
|
275
275
|
with_node_logging("Running script #{script} with '#{arguments.to_json}'", batch) do
|
276
|
-
transport.batch_script(batch, script, arguments, options, &method(:publish_event))
|
276
|
+
transport.batch_script(batch, script, arguments, options, position, &method(:publish_event))
|
277
277
|
end
|
278
278
|
end
|
279
279
|
end
|
280
280
|
end
|
281
281
|
|
282
|
-
def run_task(targets, task, arguments, options = {})
|
282
|
+
def run_task(targets, task, arguments, options = {}, position = [])
|
283
283
|
description = options.fetch(:description, "task #{task.name}")
|
284
284
|
log_action(description, targets) do
|
285
285
|
options[:run_as] = run_as if run_as && !options.key?(:run_as)
|
@@ -287,13 +287,13 @@ module Bolt
|
|
287
287
|
|
288
288
|
batch_execute(targets) do |transport, batch|
|
289
289
|
with_node_logging("Running task #{task.name} with '#{arguments.to_json}'", batch) do
|
290
|
-
transport.batch_task(batch, task, arguments, options, &method(:publish_event))
|
290
|
+
transport.batch_task(batch, task, arguments, options, position, &method(:publish_event))
|
291
291
|
end
|
292
292
|
end
|
293
293
|
end
|
294
294
|
end
|
295
295
|
|
296
|
-
def run_task_with(target_mapping, task, options = {})
|
296
|
+
def run_task_with(target_mapping, task, options = {}, position = [])
|
297
297
|
targets = target_mapping.keys
|
298
298
|
description = options.fetch(:description, "task #{task.name}")
|
299
299
|
|
@@ -303,26 +303,26 @@ module Bolt
|
|
303
303
|
|
304
304
|
batch_execute(targets) do |transport, batch|
|
305
305
|
with_node_logging("Running task #{task.name}'", batch) do
|
306
|
-
transport.batch_task_with(batch, task, target_mapping, options, &method(:publish_event))
|
306
|
+
transport.batch_task_with(batch, task, target_mapping, options, position, &method(:publish_event))
|
307
307
|
end
|
308
308
|
end
|
309
309
|
end
|
310
310
|
end
|
311
311
|
|
312
|
-
def upload_file(targets, source, destination, options = {})
|
312
|
+
def upload_file(targets, source, destination, options = {}, position = [])
|
313
313
|
description = options.fetch(:description, "file upload from #{source} to #{destination}")
|
314
314
|
log_action(description, targets) do
|
315
315
|
options[:run_as] = run_as if run_as && !options.key?(:run_as)
|
316
316
|
|
317
317
|
batch_execute(targets) do |transport, batch|
|
318
318
|
with_node_logging("Uploading file #{source} to #{destination}", batch) do
|
319
|
-
transport.batch_upload(batch, source, destination, options, &method(:publish_event))
|
319
|
+
transport.batch_upload(batch, source, destination, options, position, &method(:publish_event))
|
320
320
|
end
|
321
321
|
end
|
322
322
|
end
|
323
323
|
end
|
324
324
|
|
325
|
-
def download_file(targets, source, destination, options = {})
|
325
|
+
def download_file(targets, source, destination, options = {}, position = [])
|
326
326
|
description = options.fetch(:description, "file download from #{source} to #{destination}")
|
327
327
|
|
328
328
|
begin
|
@@ -337,7 +337,7 @@ module Bolt
|
|
337
337
|
|
338
338
|
batch_execute(targets) do |transport, batch|
|
339
339
|
with_node_logging("Downloading file #{source} to #{destination}", batch) do
|
340
|
-
transport.batch_download(batch, source, destination, options, &method(:publish_event))
|
340
|
+
transport.batch_download(batch, source, destination, options, position, &method(:publish_event))
|
341
341
|
end
|
342
342
|
end
|
343
343
|
end
|
@@ -187,6 +187,7 @@ module Bolt
|
|
187
187
|
ok = Installer.new(config).install(path, moduledir)
|
188
188
|
|
189
189
|
# Automatically generate types after installing modules
|
190
|
+
@outputter.print_action_step("Generating type references")
|
190
191
|
@pal.generate_types
|
191
192
|
|
192
193
|
@outputter.print_puppetfile_result(ok, path, moduledir)
|
data/lib/bolt/pal.rb
CHANGED
@@ -14,17 +14,11 @@ module Bolt
|
|
14
14
|
# Bolt::Errors
|
15
15
|
class PALError < Bolt::Error
|
16
16
|
def self.from_preformatted_error(err)
|
17
|
-
if err.cause.is_a? Bolt::Error
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
end
|
23
|
-
|
24
|
-
# Generate a Bolt::Pal::PALError for non-bolt errors
|
25
|
-
def self.from_error(err)
|
26
|
-
# Use the original error message if available
|
27
|
-
message = err.cause ? err.cause.message : err.message
|
17
|
+
error = if err.cause.is_a? Bolt::Error
|
18
|
+
err.cause
|
19
|
+
else
|
20
|
+
from_error(err)
|
21
|
+
end
|
28
22
|
|
29
23
|
# Provide the location of an error if it came from a plan
|
30
24
|
details = {}
|
@@ -32,8 +26,15 @@ module Bolt
|
|
32
26
|
details[:line] = err.line if defined?(err.line)
|
33
27
|
details[:column] = err.pos if defined?(err.pos)
|
34
28
|
|
35
|
-
|
29
|
+
error.add_filelineno(details)
|
30
|
+
error
|
31
|
+
end
|
36
32
|
|
33
|
+
# Generate a Bolt::Pal::PALError for non-bolt errors
|
34
|
+
def self.from_error(err)
|
35
|
+
# Use the original error message if available
|
36
|
+
message = err.cause ? err.cause.message : err.message
|
37
|
+
e = new(message)
|
37
38
|
e.set_backtrace(err.backtrace)
|
38
39
|
e
|
39
40
|
end
|
@@ -256,19 +257,24 @@ module Bolt
|
|
256
257
|
|
257
258
|
# TODO: PUP-8553 should replace this
|
258
259
|
def with_puppet_settings
|
259
|
-
Dir.mktmpdir('bolt')
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
Puppet.settings.send(:clear_everything_for_tests)
|
265
|
-
Puppet.initialize_settings(cli)
|
266
|
-
Puppet::GettextConfig.create_default_text_domain
|
267
|
-
Puppet[:trusted_external_command] = @trusted_external
|
268
|
-
Puppet.settings[:hiera_config] = @hiera_config
|
269
|
-
self.class.configure_logging
|
270
|
-
yield
|
260
|
+
dir = Dir.mktmpdir('bolt')
|
261
|
+
|
262
|
+
cli = []
|
263
|
+
Puppet::Settings::REQUIRED_APP_SETTINGS.each do |setting|
|
264
|
+
cli << "--#{setting}" << dir
|
271
265
|
end
|
266
|
+
Puppet.settings.send(:clear_everything_for_tests)
|
267
|
+
Puppet.initialize_settings(cli)
|
268
|
+
Puppet::GettextConfig.create_default_text_domain
|
269
|
+
Puppet[:trusted_external_command] = @trusted_external
|
270
|
+
Puppet.settings[:hiera_config] = @hiera_config
|
271
|
+
self.class.configure_logging
|
272
|
+
yield
|
273
|
+
ensure
|
274
|
+
# Delete the tmpdir if it still exists. This check is needed to
|
275
|
+
# prevent Bolt from erroring if the tmpdir is somehow deleted
|
276
|
+
# before reaching this point.
|
277
|
+
FileUtils.remove_entry_secure(dir) if File.exist?(dir)
|
272
278
|
end
|
273
279
|
|
274
280
|
# Parses a snippet of Puppet manifest code and returns the AST represented
|
data/lib/bolt/pal/yaml_plan.rb
CHANGED
@@ -98,10 +98,12 @@ module Bolt
|
|
98
98
|
# subclasses this parent class in order to implement its own evaluation
|
99
99
|
# logic.
|
100
100
|
class EvaluableString
|
101
|
-
attr_reader :value
|
101
|
+
attr_reader :file, :line, :value
|
102
102
|
|
103
|
-
def initialize(value)
|
103
|
+
def initialize(value, file = nil, line = nil)
|
104
104
|
@value = value
|
105
|
+
@file = file
|
106
|
+
@line = line
|
105
107
|
end
|
106
108
|
|
107
109
|
def ==(other)
|
@@ -191,7 +191,11 @@ module Bolt
|
|
191
191
|
o[key] = evaluate_code_blocks(scope, v)
|
192
192
|
end
|
193
193
|
when EvaluableString
|
194
|
-
|
194
|
+
begin
|
195
|
+
value.evaluate(scope, @evaluator)
|
196
|
+
rescue StandardError => e
|
197
|
+
raise format_evaluate_error(e, value)
|
198
|
+
end
|
195
199
|
else
|
196
200
|
value
|
197
201
|
end
|
@@ -203,6 +207,24 @@ module Bolt
|
|
203
207
|
def evaluate(value, _scope)
|
204
208
|
value
|
205
209
|
end
|
210
|
+
|
211
|
+
def format_evaluate_error(error, value)
|
212
|
+
# The Puppet::PreformattedError includes the line number of the
|
213
|
+
# evaluable string that caused the error, while the value includes the
|
214
|
+
# line number of the YAML plan that the string began on. To get the
|
215
|
+
# actual line number of the error, add these two numbers together.
|
216
|
+
line = error.line + value.line
|
217
|
+
|
218
|
+
# If the evaluable string is not a scalar literal, correct for it
|
219
|
+
# being on the same line as the step key.
|
220
|
+
line -= 1 if value.is_a?(BareString)
|
221
|
+
|
222
|
+
Bolt::PlanFailure.new(
|
223
|
+
error.basic_message,
|
224
|
+
'bolt/evaluation-error',
|
225
|
+
{ file: value.file, line: line }
|
226
|
+
)
|
227
|
+
end
|
206
228
|
end
|
207
229
|
end
|
208
230
|
end
|
@@ -9,10 +9,15 @@ module Bolt
|
|
9
9
|
class YamlPlan
|
10
10
|
class Loader
|
11
11
|
class PuppetVisitor < Psych::Visitors::NoAliasRuby
|
12
|
-
def
|
12
|
+
def initialize(scanner, class_loader, file)
|
13
|
+
super(scanner, class_loader)
|
14
|
+
@file = file
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.create_visitor(source_ref)
|
13
18
|
class_loader = Psych::ClassLoader::Restricted.new([], [])
|
14
19
|
scanner = Psych::ScalarScanner.new(class_loader)
|
15
|
-
new(scanner, class_loader)
|
20
|
+
new(scanner, class_loader, source_ref)
|
16
21
|
end
|
17
22
|
|
18
23
|
def deserialize(node)
|
@@ -23,18 +28,18 @@ module Bolt
|
|
23
28
|
# @ss is a ScalarScanner, from the base ToRuby visitor class
|
24
29
|
node.value
|
25
30
|
when Psych::Nodes::Scalar::DOUBLE_QUOTED
|
26
|
-
DoubleQuotedString.new(node.value)
|
27
|
-
# | style string
|
28
|
-
when Psych::Nodes::Scalar::LITERAL
|
29
|
-
CodeLiteral.new(node.value)
|
30
|
-
#
|
31
|
+
DoubleQuotedString.new(node.value, @file, node.start_line + 1)
|
32
|
+
# | style string
|
33
|
+
when Psych::Nodes::Scalar::LITERAL
|
34
|
+
CodeLiteral.new(node.value, @file, node.start_line + 1)
|
35
|
+
# > style string
|
31
36
|
else
|
32
37
|
@ss.tokenize(node.value)
|
33
38
|
end
|
34
39
|
else
|
35
40
|
value = @ss.tokenize(node.value)
|
36
41
|
if value.is_a?(String)
|
37
|
-
BareString.new(value)
|
42
|
+
BareString.new(value, @file, node.start_line + 1)
|
38
43
|
else
|
39
44
|
value
|
40
45
|
end
|
@@ -50,7 +55,7 @@ module Bolt
|
|
50
55
|
else
|
51
56
|
Psych.parse(yaml_string, source_ref)
|
52
57
|
end
|
53
|
-
PuppetVisitor.create_visitor.accept(parse_tree)
|
58
|
+
PuppetVisitor.create_visitor(source_ref).accept(parse_tree)
|
54
59
|
end
|
55
60
|
|
56
61
|
def self.from_string(name, yaml_string, source_ref)
|
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
|
|
@@ -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/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
@@ -53,7 +53,7 @@ module Bolt
|
|
53
53
|
conn
|
54
54
|
end
|
55
55
|
|
56
|
-
def process_run_results(targets, results, task_name)
|
56
|
+
def process_run_results(targets, results, task_name, position = [])
|
57
57
|
targets_by_name = Hash[targets.map { |t| t.host || t.name }.zip(targets)]
|
58
58
|
results.map do |node_result|
|
59
59
|
target = targets_by_name[node_result['name']]
|
@@ -63,25 +63,31 @@ module Bolt
|
|
63
63
|
# If it's finished or already has a proper error simply pass it to the
|
64
64
|
# the result otherwise make sure an error is generated
|
65
65
|
if state == 'finished' || (result && result['_error'])
|
66
|
+
if result['_error']
|
67
|
+
file_line = %w[file line].zip(position).to_h.compact
|
68
|
+
result['_error']['details'].merge!(file_line) unless result['_error']['details']['file']
|
69
|
+
end
|
70
|
+
|
66
71
|
Bolt::Result.new(target, value: result, action: 'task', object: task_name)
|
67
72
|
elsif state == 'skipped'
|
73
|
+
details = %w[file line].zip(position).to_h.compact
|
68
74
|
Bolt::Result.new(
|
69
75
|
target,
|
70
76
|
value: { '_error' => {
|
71
77
|
'kind' => 'puppetlabs.tasks/skipped-node',
|
72
78
|
'msg' => "Target #{target.safe_name} was skipped",
|
73
|
-
'details' =>
|
79
|
+
'details' => details
|
74
80
|
} },
|
75
81
|
action: 'task', object: task_name
|
76
82
|
)
|
77
83
|
else
|
78
84
|
# Make a generic error with a unkown exit_code
|
79
|
-
Bolt::Result.for_task(target, result.to_json, '', 'unknown', task_name)
|
85
|
+
Bolt::Result.for_task(target, result.to_json, '', 'unknown', task_name, position)
|
80
86
|
end
|
81
87
|
end
|
82
88
|
end
|
83
89
|
|
84
|
-
def batch_command(targets, command, options = {}, &callback)
|
90
|
+
def batch_command(targets, command, options = {}, position = [], &callback)
|
85
91
|
if options[:env_vars] && !options[:env_vars].empty?
|
86
92
|
raise NotImplementedError, "pcp transport does not support setting environment variables"
|
87
93
|
end
|
@@ -93,6 +99,7 @@ module Bolt
|
|
93
99
|
BOLT_COMMAND_TASK,
|
94
100
|
params,
|
95
101
|
options,
|
102
|
+
position,
|
96
103
|
&callback)
|
97
104
|
callback ||= proc {}
|
98
105
|
results.map! { |result| unwrap_bolt_result(result.target, result, 'command', command) }
|
@@ -101,7 +108,7 @@ module Bolt
|
|
101
108
|
end
|
102
109
|
end
|
103
110
|
|
104
|
-
def batch_script(targets, script, arguments, options = {}, &callback)
|
111
|
+
def batch_script(targets, script, arguments, options = {}, position = [], &callback)
|
105
112
|
if options[:env_vars] && !options[:env_vars].empty?
|
106
113
|
raise NotImplementedError, "pcp transport does not support setting environment variables"
|
107
114
|
end
|
@@ -114,7 +121,7 @@ module Bolt
|
|
114
121
|
'name' => Pathname(script).basename.to_s
|
115
122
|
}
|
116
123
|
callback ||= proc {}
|
117
|
-
results = run_task_job(targets, BOLT_SCRIPT_TASK, params, options, &callback)
|
124
|
+
results = run_task_job(targets, BOLT_SCRIPT_TASK, params, options, position, &callback)
|
118
125
|
results.map! { |result| unwrap_bolt_result(result.target, result, 'script', script) }
|
119
126
|
results.each do |result|
|
120
127
|
callback.call(type: :node_result, result: result)
|
@@ -155,7 +162,7 @@ module Bolt
|
|
155
162
|
output&.close
|
156
163
|
end
|
157
164
|
|
158
|
-
def batch_upload(targets, source, destination, options = {}, &callback)
|
165
|
+
def batch_upload(targets, source, destination, options = {}, position = [], &callback)
|
159
166
|
stat = File.stat(source)
|
160
167
|
content = if stat.directory?
|
161
168
|
pack(source)
|
@@ -171,7 +178,7 @@ module Bolt
|
|
171
178
|
'directory' => stat.directory?
|
172
179
|
}
|
173
180
|
callback ||= proc {}
|
174
|
-
results = run_task_job(targets, BOLT_UPLOAD_TASK, params, options, &callback)
|
181
|
+
results = run_task_job(targets, BOLT_UPLOAD_TASK, params, options, position, &callback)
|
175
182
|
results.map! do |result|
|
176
183
|
if result.error_hash
|
177
184
|
result
|
@@ -200,7 +207,7 @@ module Bolt
|
|
200
207
|
targets.group_by { |target| Connection.get_key(target.options) }.values
|
201
208
|
end
|
202
209
|
|
203
|
-
def run_task_job(targets, task, arguments, options)
|
210
|
+
def run_task_job(targets, task, arguments, options, position)
|
204
211
|
targets.each do |target|
|
205
212
|
yield(type: :node_start, target: target) if block_given?
|
206
213
|
end
|
@@ -210,7 +217,7 @@ module Bolt
|
|
210
217
|
arguments = unwrap_sensitive_args(arguments)
|
211
218
|
results = get_connection(targets.first.options).run_task(targets, task, arguments, options)
|
212
219
|
|
213
|
-
process_run_results(targets, results, task.name)
|
220
|
+
process_run_results(targets, results, task.name, position)
|
214
221
|
rescue OrchestratorClient::ApiError => e
|
215
222
|
targets.map do |target|
|
216
223
|
Bolt::Result.new(target, error: e.data)
|
@@ -222,15 +229,15 @@ module Bolt
|
|
222
229
|
end
|
223
230
|
end
|
224
231
|
|
225
|
-
def batch_task(targets, task, arguments, options = {}, &callback)
|
232
|
+
def batch_task(targets, task, arguments, options = {}, position = [], &callback)
|
226
233
|
callback ||= proc {}
|
227
|
-
results = run_task_job(targets, task, arguments, options, &callback)
|
234
|
+
results = run_task_job(targets, task, arguments, options, position, &callback)
|
228
235
|
results.each do |result|
|
229
236
|
callback.call(type: :node_result, result: result)
|
230
237
|
end
|
231
238
|
end
|
232
239
|
|
233
|
-
def batch_task_with(_targets, _task, _target_mapping, _options = {})
|
240
|
+
def batch_task_with(_targets, _task, _target_mapping, _options = {}, _position = [])
|
234
241
|
raise NotImplementedError, "pcp transport does not support run_task_with()"
|
235
242
|
end
|
236
243
|
|
@@ -248,11 +255,13 @@ module Bolt
|
|
248
255
|
return result
|
249
256
|
end
|
250
257
|
|
258
|
+
# If we get here, there's no error so we don't need the file or line
|
259
|
+
# number
|
251
260
|
Bolt::Result.for_command(target,
|
252
261
|
result.value['stdout'],
|
253
262
|
result.value['stderr'],
|
254
263
|
result.value['exit_code'],
|
255
|
-
action, obj)
|
264
|
+
action, obj, [])
|
256
265
|
end
|
257
266
|
end
|
258
267
|
end
|
@@ -26,14 +26,14 @@ module Bolt
|
|
26
26
|
end
|
27
27
|
|
28
28
|
# Cannot batch because arugments differ
|
29
|
-
def run_task(target, task, arguments, options = {})
|
29
|
+
def run_task(target, task, arguments, options = {}, position = [])
|
30
30
|
proxy_target = get_proxy(target)
|
31
31
|
transport = @executor.transport(proxy_target.transport)
|
32
32
|
arguments = arguments.merge('_target' => target.to_h.reject { |_, v| v.nil? })
|
33
33
|
|
34
34
|
remote_task = task.remote_instance
|
35
35
|
|
36
|
-
result = transport.run_task(proxy_target, remote_task, arguments, options)
|
36
|
+
result = transport.run_task(proxy_target, remote_task, arguments, options, position)
|
37
37
|
Bolt::Result.new(target, value: result.value, action: 'task', object: task.name)
|
38
38
|
end
|
39
39
|
end
|
@@ -20,9 +20,9 @@ module Bolt
|
|
20
20
|
false
|
21
21
|
end
|
22
22
|
|
23
|
-
def run_command(target, command, options = {})
|
23
|
+
def run_command(target, command, options = {}, position = [])
|
24
24
|
with_connection(target) do |conn|
|
25
|
-
conn.shell.run_command(command, options)
|
25
|
+
conn.shell.run_command(command, options, position)
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
@@ -38,15 +38,15 @@ module Bolt
|
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
|
-
def run_script(target, script, arguments, options = {})
|
41
|
+
def run_script(target, script, arguments, options = {}, position = [])
|
42
42
|
with_connection(target) do |conn|
|
43
|
-
conn.shell.run_script(script, arguments, options)
|
43
|
+
conn.shell.run_script(script, arguments, options, position)
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
47
|
-
def run_task(target, task, arguments, options = {})
|
47
|
+
def run_task(target, task, arguments, options = {}, position = [])
|
48
48
|
with_connection(target) do |conn|
|
49
|
-
conn.shell.run_task(task, arguments, options)
|
49
|
+
conn.shell.run_task(task, arguments, options, position)
|
50
50
|
end
|
51
51
|
end
|
52
52
|
end
|
data/lib/bolt/version.rb
CHANGED
@@ -48,7 +48,7 @@ module BoltSpec
|
|
48
48
|
([segments[0]] + segments[2..-1]).join('/')
|
49
49
|
end
|
50
50
|
|
51
|
-
def run_command(targets, command, options = {})
|
51
|
+
def run_command(targets, command, options = {}, _position = [])
|
52
52
|
result = nil
|
53
53
|
if (doub = @command_doubles[command] || @command_doubles[:default])
|
54
54
|
result = doub.process(targets, command, options)
|
@@ -61,7 +61,7 @@ module BoltSpec
|
|
61
61
|
result
|
62
62
|
end
|
63
63
|
|
64
|
-
def run_script(targets, script_path, arguments, options = {})
|
64
|
+
def run_script(targets, script_path, arguments, options = {}, _position = [])
|
65
65
|
script = module_file_id(script_path)
|
66
66
|
result = nil
|
67
67
|
if (doub = @script_doubles[script] || @script_doubles[:default])
|
@@ -76,7 +76,7 @@ module BoltSpec
|
|
76
76
|
result
|
77
77
|
end
|
78
78
|
|
79
|
-
def run_task(targets, task, arguments, options = {})
|
79
|
+
def run_task(targets, task, arguments, options = {}, _position = [])
|
80
80
|
result = nil
|
81
81
|
if (doub = @task_doubles[task.name] || @task_doubles[:default])
|
82
82
|
result = doub.process(targets, task.name, arguments, options)
|
@@ -90,7 +90,7 @@ module BoltSpec
|
|
90
90
|
result
|
91
91
|
end
|
92
92
|
|
93
|
-
def download_file(targets, source, destination, options = {})
|
93
|
+
def download_file(targets, source, destination, options = {}, _position = [])
|
94
94
|
result = nil
|
95
95
|
if (doub = @download_doubles[source] || @download_doubles[:default])
|
96
96
|
result = doub.process(targets, source, destination, options)
|
@@ -103,7 +103,7 @@ module BoltSpec
|
|
103
103
|
result
|
104
104
|
end
|
105
105
|
|
106
|
-
def upload_file(targets, source_path, destination, options = {})
|
106
|
+
def upload_file(targets, source_path, destination, options = {}, _position = [])
|
107
107
|
source = module_file_id(source_path)
|
108
108
|
result = nil
|
109
109
|
if (doub = @upload_doubles[source] || @upload_doubles[:default])
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bolt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.33.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Puppet
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-11-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: addressable
|
@@ -438,6 +438,7 @@ files:
|
|
438
438
|
- bolt-modules/system/lib/puppet/functions/system/env.rb
|
439
439
|
- exe/bolt
|
440
440
|
- guides/inventory.txt
|
441
|
+
- guides/logging.txt
|
441
442
|
- guides/module.txt
|
442
443
|
- guides/modulepath.txt
|
443
444
|
- guides/project.txt
|
@@ -597,7 +598,6 @@ files:
|
|
597
598
|
- modules/canary/lib/puppet/functions/canary/skip.rb
|
598
599
|
- modules/canary/plans/init.pp
|
599
600
|
- modules/puppetdb_fact/plans/init.pp
|
600
|
-
- modules/secure_env_vars/plans/init.pp
|
601
601
|
homepage: https://github.com/puppetlabs/bolt
|
602
602
|
licenses:
|
603
603
|
- Apache-2.0
|
@@ -1,20 +0,0 @@
|
|
1
|
-
plan secure_env_vars(
|
2
|
-
TargetSpec $targets,
|
3
|
-
Optional[String] $command = undef,
|
4
|
-
Optional[String] $script = undef
|
5
|
-
) {
|
6
|
-
$env_vars = parsejson(system::env('BOLT_ENV_VARS'))
|
7
|
-
unless type($command) == Undef or type($script) == Undef {
|
8
|
-
fail_plan('Cannot specify both script and command for secure_env_vars')
|
9
|
-
}
|
10
|
-
|
11
|
-
return if $command {
|
12
|
-
run_command($command, $targets, '_env_vars' => $env_vars)
|
13
|
-
}
|
14
|
-
elsif $script {
|
15
|
-
run_script($script, $targets, '_env_vars' => $env_vars)
|
16
|
-
}
|
17
|
-
else {
|
18
|
-
fail_plan('Must specify either script or command for secure_env_vars')
|
19
|
-
}
|
20
|
-
}
|