bolt 1.32.0 → 1.33.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/bolt-modules/boltlib/lib/puppet/datatypes/resultset.rb +3 -0
- data/bolt-modules/boltlib/lib/puppet/functions/run_command.rb +6 -5
- data/bolt-modules/boltlib/lib/puppet/functions/run_plan.rb +14 -13
- data/bolt-modules/boltlib/lib/puppet/functions/run_script.rb +8 -6
- data/bolt-modules/boltlib/lib/puppet/functions/run_task.rb +24 -24
- data/bolt-modules/boltlib/lib/puppet/functions/upload_file.rb +6 -5
- data/lib/bolt/applicator.rb +7 -6
- data/lib/bolt/cli.rb +2 -2
- data/lib/bolt/executor.rb +9 -9
- data/lib/bolt/outputter/human.rb +5 -5
- data/lib/bolt/plugin.rb +2 -1
- data/lib/bolt/plugin/module.rb +1 -1
- data/lib/bolt/plugin/pkcs7.rb +2 -2
- data/lib/bolt/plugin/task.rb +1 -1
- data/lib/bolt/result_set.rb +8 -0
- data/lib/bolt/target.rb +9 -6
- data/lib/bolt/task/run.rb +1 -1
- data/lib/bolt/transport/base.rb +4 -4
- data/lib/bolt/transport/docker/connection.rb +5 -3
- data/lib/bolt/transport/local/shell.rb +1 -0
- data/lib/bolt/transport/local_windows.rb +2 -1
- data/lib/bolt/transport/orch.rb +1 -1
- data/lib/bolt/transport/orch/connection.rb +1 -1
- data/lib/bolt/transport/ssh.rb +1 -1
- data/lib/bolt/transport/ssh/connection.rb +10 -15
- data/lib/bolt/transport/sudoable.rb +4 -4
- data/lib/bolt/transport/sudoable/connection.rb +1 -1
- data/lib/bolt/transport/winrm.rb +1 -1
- data/lib/bolt/transport/winrm/connection.rb +7 -13
- data/lib/bolt/version.rb +1 -1
- data/lib/bolt_spec/plans/action_stubs/command_stub.rb +2 -1
- data/lib/bolt_spec/plans/action_stubs/script_stub.rb +1 -0
- data/lib/bolt_spec/plans/action_stubs/task_stub.rb +1 -0
- data/lib/bolt_spec/plans/action_stubs/upload_stub.rb +2 -1
- data/lib/bolt_spec/run.rb +1 -1
- data/lib/plan_executor/executor.rb +4 -4
- data/lib/plan_executor/orch_client.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8529a13b894e496846dd0720d8980e98b4fa6146216089e7792e30ece43e7e17
|
4
|
+
data.tar.gz: 319d8cfe5375164d4c94868131a8b5a048d3b8b7b95e45e892e79a470ec4b8d9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 12b4179334e1849115a5648148193c7aab3da768061ce17b4694c35fa836ccb7184258dca2a3376e0a7bca8c9edbe1439d49f5a1f3e3a30929bd67a7ea5e0930
|
7
|
+
data.tar.gz: b57dc487c0ae46c76206a51f9ed27a1791595e8eab63aa9701f1dcc0785e2b52dc051900109b7f3a74d4a7d9ba1b507b879f5fca4a6b9611737e0e092588dc88
|
@@ -17,6 +17,9 @@ Puppet::DataTypes.create_type('ResultSet') do
|
|
17
17
|
ok_set => Callable[[], ResultSet],
|
18
18
|
targets => Callable[[], Array[Target]],
|
19
19
|
to_data => Callable[[], Array[Hash]],
|
20
|
+
'[]' => Variant[Callable[[Integer], Optional[Variant[Result, ApplyResult, Array[Variant[Result, ApplyResult]]]]],
|
21
|
+
Callable[[Integer, Integer], Optional[Variant[Result, ApplyResult, Array[Variant[Result, ApplyResult]]]]]
|
22
|
+
]
|
20
23
|
}
|
21
24
|
PUPPET
|
22
25
|
|
@@ -37,18 +37,19 @@ Puppet::Functions.create_function(:run_command) do
|
|
37
37
|
return_type 'ResultSet'
|
38
38
|
end
|
39
39
|
|
40
|
-
def run_command(command, targets, options =
|
40
|
+
def run_command(command, targets, options = {})
|
41
41
|
run_command_with_description(command, targets, nil, options)
|
42
42
|
end
|
43
43
|
|
44
|
-
def run_command_with_description(command, targets, description = nil, options =
|
44
|
+
def run_command_with_description(command, targets, description = nil, options = {})
|
45
45
|
unless Puppet[:tasks]
|
46
46
|
raise Puppet::ParseErrorWithIssue
|
47
47
|
.from_issue_and_stack(Bolt::PAL::Issues::PLAN_OPERATION_NOT_SUPPORTED_WHEN_COMPILING, action: 'run_command')
|
48
48
|
end
|
49
49
|
|
50
|
-
options
|
51
|
-
options =
|
50
|
+
options = options.map { |k, v| [k.sub(/^_/, '').to_sym, v] }.to_h
|
51
|
+
options[:description] = description if description
|
52
|
+
|
52
53
|
executor = Puppet.lookup(:bolt_executor)
|
53
54
|
inventory = Puppet.lookup(:bolt_inventory)
|
54
55
|
|
@@ -64,7 +65,7 @@ Puppet::Functions.create_function(:run_command) do
|
|
64
65
|
r = executor.run_command(targets, command, options)
|
65
66
|
end
|
66
67
|
|
67
|
-
if !r.ok && !options[
|
68
|
+
if !r.ok && !options[:catch_errors]
|
68
69
|
raise Bolt::RunFailure.new(r, 'run_command', command)
|
69
70
|
end
|
70
71
|
r
|
@@ -8,20 +8,20 @@ require 'bolt/error'
|
|
8
8
|
Puppet::Functions.create_function(:run_plan, Puppet::Functions::InternalFunction) do
|
9
9
|
# Run a plan
|
10
10
|
# @param plan_name The plan to run.
|
11
|
-
# @param
|
11
|
+
# @param args Arguments to the plan. Can also include additional options: '_catch_errors', '_run_as'.
|
12
12
|
# @return [PlanResult] The result of running the plan. Undef if plan does not explicitly return results.
|
13
13
|
# @example Run a plan
|
14
14
|
# run_plan('canary', 'command' => 'false', 'nodes' => $targets, '_catch_errors' => true)
|
15
15
|
dispatch :run_plan do
|
16
16
|
scope_param
|
17
17
|
param 'String', :plan_name
|
18
|
-
optional_param 'Hash', :
|
18
|
+
optional_param 'Hash', :args
|
19
19
|
return_type 'Boltlib::PlanResult'
|
20
20
|
end
|
21
21
|
|
22
22
|
# Run a plan, specifying $nodes as a positional argument.
|
23
23
|
# @param plan_name The plan to run.
|
24
|
-
# @param
|
24
|
+
# @param args Arguments to the plan. Can also include additional options: '_catch_errors', '_run_as'.
|
25
25
|
# @param targets A pattern identifying zero or more targets. See {get_targets} for accepted patterns.
|
26
26
|
# @return [PlanResult] The result of running the plan. Undef if plan does not explicitly return results.
|
27
27
|
# @example Run a plan
|
@@ -30,21 +30,21 @@ Puppet::Functions.create_function(:run_plan, Puppet::Functions::InternalFunction
|
|
30
30
|
scope_param
|
31
31
|
param 'String', :plan_name
|
32
32
|
param 'Boltlib::TargetSpec', :targets
|
33
|
-
optional_param 'Hash', :
|
33
|
+
optional_param 'Hash', :args
|
34
34
|
return_type 'Boltlib::PlanResult'
|
35
35
|
end
|
36
36
|
|
37
|
-
def run_plan_with_targetspec(scope, plan_name, targets,
|
38
|
-
unless
|
37
|
+
def run_plan_with_targetspec(scope, plan_name, targets, args = {})
|
38
|
+
unless args['nodes'].nil?
|
39
39
|
raise ArgumentError,
|
40
40
|
"A plan's 'nodes' parameter may be specified as the second positional argument to " \
|
41
41
|
"run_plan(), but in that case 'nodes' must not be specified in the named arguments " \
|
42
42
|
"hash."
|
43
43
|
end
|
44
|
-
run_plan(scope, plan_name,
|
44
|
+
run_plan(scope, plan_name, args.merge('nodes' => targets))
|
45
45
|
end
|
46
46
|
|
47
|
-
def run_plan(scope, plan_name,
|
47
|
+
def run_plan(scope, plan_name, args = {})
|
48
48
|
unless Puppet[:tasks]
|
49
49
|
raise Puppet::ParseErrorWithIssue
|
50
50
|
.from_issue_and_stack(Bolt::PAL::Issues::PLAN_OPERATION_NOT_SUPPORTED_WHEN_COMPILING, action: 'run_plan')
|
@@ -52,17 +52,18 @@ Puppet::Functions.create_function(:run_plan, Puppet::Functions::InternalFunction
|
|
52
52
|
|
53
53
|
executor = Puppet.lookup(:bolt_executor)
|
54
54
|
|
55
|
+
options, params = args.partition { |k, _v| k.start_with?('_') }.map(&:to_h)
|
56
|
+
options = options.map { |k, v| [k.sub(/^_/, '').to_sym, v] }.to_h
|
57
|
+
|
55
58
|
# Bolt calls this function internally to trigger plans from the CLI. We
|
56
59
|
# don't want to count those invocations.
|
57
|
-
unless
|
60
|
+
unless options[:bolt_api_call]
|
58
61
|
executor.report_function_call(self.class.name)
|
59
62
|
end
|
60
63
|
|
61
64
|
# Report bundled content, this should capture plans run from both CLI and Plans
|
62
65
|
executor.report_bundled_content('Plan', plan_name)
|
63
66
|
|
64
|
-
params = named_args.reject { |k, _| k.start_with?('_') }
|
65
|
-
|
66
67
|
loaders = closure_scope.compiler.loaders
|
67
68
|
# The perspective of the environment is wanted here (for now) to not have to
|
68
69
|
# require modules to have dependencies defined in meta data.
|
@@ -73,7 +74,7 @@ Puppet::Functions.create_function(:run_plan, Puppet::Functions::InternalFunction
|
|
73
74
|
raise Bolt::Error.unknown_plan(plan_name)
|
74
75
|
end
|
75
76
|
|
76
|
-
if (run_as =
|
77
|
+
if (run_as = options[:run_as])
|
77
78
|
old_run_as = executor.run_as
|
78
79
|
executor.run_as = run_as
|
79
80
|
end
|
@@ -118,7 +119,7 @@ Puppet::Functions.create_function(:run_plan, Puppet::Functions::InternalFunction
|
|
118
119
|
|
119
120
|
result
|
120
121
|
rescue Puppet::PreformattedError => e
|
121
|
-
if
|
122
|
+
if options[:catch_errors] && e.cause.is_a?(Bolt::Error)
|
122
123
|
result = e.cause.to_puppet_error
|
123
124
|
else
|
124
125
|
raise e
|
@@ -43,18 +43,20 @@ Puppet::Functions.create_function(:run_script, Puppet::Functions::InternalFuncti
|
|
43
43
|
return_type 'ResultSet'
|
44
44
|
end
|
45
45
|
|
46
|
-
def run_script(scope, script, targets, options =
|
46
|
+
def run_script(scope, script, targets, options = {})
|
47
47
|
run_script_with_description(scope, script, targets, nil, options)
|
48
48
|
end
|
49
49
|
|
50
|
-
def run_script_with_description(scope, script, targets, description = nil, options =
|
50
|
+
def run_script_with_description(scope, script, targets, description = nil, options = {})
|
51
51
|
unless Puppet[:tasks]
|
52
52
|
raise Puppet::ParseErrorWithIssue
|
53
53
|
.from_issue_and_stack(Bolt::PAL::Issues::PLAN_OPERATION_NOT_SUPPORTED_WHEN_COMPILING, action: 'run_script')
|
54
54
|
end
|
55
55
|
|
56
|
-
options
|
57
|
-
options = options.
|
56
|
+
arguments = options['arguments'] || []
|
57
|
+
options = options.select { |opt| opt.start_with?('_') }.map { |k, v| [k.sub(/^_/, '').to_sym, v] }.to_h
|
58
|
+
options[:description] = description if description
|
59
|
+
|
58
60
|
executor = Puppet.lookup(:bolt_executor)
|
59
61
|
inventory = Puppet.lookup(:bolt_inventory)
|
60
62
|
|
@@ -78,10 +80,10 @@ Puppet::Functions.create_function(:run_script, Puppet::Functions::InternalFuncti
|
|
78
80
|
r = if targets.empty?
|
79
81
|
Bolt::ResultSet.new([])
|
80
82
|
else
|
81
|
-
executor.run_script(targets, found,
|
83
|
+
executor.run_script(targets, found, arguments, options)
|
82
84
|
end
|
83
85
|
|
84
|
-
if !r.ok && !options[
|
86
|
+
if !r.ok && !options[:catch_errors]
|
85
87
|
raise Bolt::RunFailure.new(r, 'run_script', script)
|
86
88
|
end
|
87
89
|
r
|
@@ -12,14 +12,14 @@ Puppet::Functions.create_function(:run_task) do
|
|
12
12
|
# Run a task.
|
13
13
|
# @param task_name The task to run.
|
14
14
|
# @param targets A pattern identifying zero or more targets. See {get_targets} for accepted patterns.
|
15
|
-
# @param
|
15
|
+
# @param args Arguments to the plan. Can also include additional options: '_catch_errors', '_run_as'.
|
16
16
|
# @return A list of results, one entry per target.
|
17
17
|
# @example Run a task as root
|
18
18
|
# run_task('facts', $targets, '_run_as' => 'root')
|
19
19
|
dispatch :run_task do
|
20
20
|
param 'String[1]', :task_name
|
21
21
|
param 'Boltlib::TargetSpec', :targets
|
22
|
-
optional_param 'Hash[String[1], Any]', :
|
22
|
+
optional_param 'Hash[String[1], Any]', :args
|
23
23
|
return_type 'ResultSet'
|
24
24
|
end
|
25
25
|
|
@@ -27,7 +27,7 @@ Puppet::Functions.create_function(:run_task) do
|
|
27
27
|
# @param task_name The task to run.
|
28
28
|
# @param targets A pattern identifying zero or more targets. See {get_targets} for accepted patterns.
|
29
29
|
# @param description A description to be output when calling this function.
|
30
|
-
# @param
|
30
|
+
# @param args Arguments to the plan. Can also include additional options: '_catch_errors', '_run_as'.
|
31
31
|
# @return A list of results, one entry per target.
|
32
32
|
# @example Run a task
|
33
33
|
# run_task('facts', $targets, 'Gather OS facts')
|
@@ -35,27 +35,29 @@ Puppet::Functions.create_function(:run_task) do
|
|
35
35
|
param 'String[1]', :task_name
|
36
36
|
param 'Boltlib::TargetSpec', :targets
|
37
37
|
param 'Optional[String]', :description
|
38
|
-
optional_param 'Hash[String[1], Any]', :
|
38
|
+
optional_param 'Hash[String[1], Any]', :args
|
39
39
|
return_type 'ResultSet'
|
40
40
|
end
|
41
41
|
|
42
|
-
def run_task(task_name, targets,
|
43
|
-
run_task_with_description(task_name, targets, nil,
|
42
|
+
def run_task(task_name, targets, args = {})
|
43
|
+
run_task_with_description(task_name, targets, nil, args)
|
44
44
|
end
|
45
45
|
|
46
|
-
def run_task_with_description(task_name, targets, description,
|
46
|
+
def run_task_with_description(task_name, targets, description, args = {})
|
47
47
|
unless Puppet[:tasks]
|
48
48
|
raise Puppet::ParseErrorWithIssue
|
49
49
|
.from_issue_and_stack(Bolt::PAL::Issues::PLAN_OPERATION_NOT_SUPPORTED_WHEN_COMPILING, action: 'run_task')
|
50
50
|
end
|
51
51
|
|
52
|
-
|
52
|
+
options, params = args.partition { |k, _v| k.start_with?('_') }.map(&:to_h)
|
53
|
+
options = options.map { |k, v| [k.sub(/^_/, '').to_sym, v] }.to_h
|
54
|
+
|
53
55
|
executor = Puppet.lookup(:bolt_executor)
|
54
56
|
inventory = Puppet.lookup(:bolt_inventory)
|
55
57
|
|
56
58
|
# Bolt calls this function internally to trigger tasks from the CLI. We
|
57
59
|
# don't want to count those invocations.
|
58
|
-
unless
|
60
|
+
unless options[:bolt_api_call]
|
59
61
|
executor.report_function_call(self.class.name)
|
60
62
|
end
|
61
63
|
|
@@ -65,9 +67,7 @@ Puppet::Functions.create_function(:run_task) do
|
|
65
67
|
# Ensure that given targets are all Target instances
|
66
68
|
targets = inventory.get_targets(targets)
|
67
69
|
|
68
|
-
options
|
69
|
-
|
70
|
-
options['_description'] = description if description
|
70
|
+
options[:description] = description if description
|
71
71
|
|
72
72
|
# Don't bother loading the local task definition if all targets use the 'pcp' transport.
|
73
73
|
if !targets.empty? && targets.all? { |t| t.transport == 'pcp' }
|
@@ -80,37 +80,37 @@ Puppet::Functions.create_function(:run_task) do
|
|
80
80
|
raise Bolt::Error.unknown_task(task_name)
|
81
81
|
end
|
82
82
|
|
83
|
-
task_signature.runnable_with?(
|
83
|
+
task_signature.runnable_with?(params) do |mismatch_message|
|
84
84
|
raise with_stack(:TYPE_MISMATCH, mismatch_message)
|
85
85
|
end || (raise with_stack(:TYPE_MISMATCH, 'Task parameters do not match'))
|
86
86
|
|
87
87
|
task = Bolt::Task.new(task_signature.task_hash)
|
88
88
|
end
|
89
89
|
|
90
|
-
unless Puppet::Pops::Types::TypeFactory.data.instance?(
|
90
|
+
unless Puppet::Pops::Types::TypeFactory.data.instance?(params)
|
91
91
|
# generate a helpful error message about the type-mismatch between the type Data
|
92
|
-
# and the actual type of
|
93
|
-
|
92
|
+
# and the actual type of params
|
93
|
+
params_t = Puppet::Pops::Types::TypeCalculator.infer_set(params)
|
94
94
|
desc = Puppet::Pops::Types::TypeMismatchDescriber.singleton.describe_mismatch(
|
95
95
|
'Task parameters are not of type Data. run_task()',
|
96
|
-
Puppet::Pops::Types::TypeFactory.data,
|
96
|
+
Puppet::Pops::Types::TypeFactory.data, params_t
|
97
97
|
)
|
98
98
|
raise with_stack(:TYPE_NOT_DATA, desc)
|
99
99
|
end
|
100
100
|
|
101
101
|
# Wrap parameters marked with '"sensitive": true' in the task metadata with a
|
102
102
|
# Sensitive wrapper type. This way it's not shown in logs.
|
103
|
-
if (
|
104
|
-
|
105
|
-
if
|
106
|
-
|
103
|
+
if (param_spec = task.parameters)
|
104
|
+
params.each do |k, v|
|
105
|
+
if param_spec[k] && param_spec[k]['sensitive']
|
106
|
+
params[k] = Puppet::Pops::Types::PSensitiveType::Sensitive.new(v)
|
107
107
|
end
|
108
108
|
end
|
109
109
|
end
|
110
110
|
|
111
111
|
if executor.noop
|
112
112
|
if task.supports_noop
|
113
|
-
|
113
|
+
params['_noop'] = true
|
114
114
|
else
|
115
115
|
raise with_stack(:TASK_NO_NOOP, 'Task does not support noop')
|
116
116
|
end
|
@@ -119,8 +119,8 @@ Puppet::Functions.create_function(:run_task) do
|
|
119
119
|
if targets.empty?
|
120
120
|
Bolt::ResultSet.new([])
|
121
121
|
else
|
122
|
-
result = executor.run_task(targets, task,
|
123
|
-
if !result.ok && !
|
122
|
+
result = executor.run_task(targets, task, params, options)
|
123
|
+
if !result.ok && !options[:catch_errors]
|
124
124
|
raise Bolt::RunFailure.new(result, 'run_task', task_name)
|
125
125
|
end
|
126
126
|
result
|
@@ -47,18 +47,19 @@ Puppet::Functions.create_function(:upload_file, Puppet::Functions::InternalFunct
|
|
47
47
|
return_type 'ResultSet'
|
48
48
|
end
|
49
49
|
|
50
|
-
def upload_file(scope, source, destination, targets, options =
|
50
|
+
def upload_file(scope, source, destination, targets, options = {})
|
51
51
|
upload_file_with_description(scope, source, destination, targets, nil, options)
|
52
52
|
end
|
53
53
|
|
54
|
-
def upload_file_with_description(scope, source, destination, targets, description = nil, options =
|
54
|
+
def upload_file_with_description(scope, source, destination, targets, description = nil, options = {})
|
55
55
|
unless Puppet[:tasks]
|
56
56
|
raise Puppet::ParseErrorWithIssue
|
57
57
|
.from_issue_and_stack(Bolt::PAL::Issues::PLAN_OPERATION_NOT_SUPPORTED_WHEN_COMPILING, action: 'upload_file')
|
58
58
|
end
|
59
59
|
|
60
|
-
options
|
61
|
-
options =
|
60
|
+
options = options.select { |opt| opt.start_with?('_') }.map { |k, v| [k.sub(/^_/, '').to_sym, v] }.to_h
|
61
|
+
options[:description] = description if description
|
62
|
+
|
62
63
|
executor = Puppet.lookup(:bolt_executor)
|
63
64
|
inventory = Puppet.lookup(:bolt_inventory)
|
64
65
|
|
@@ -80,7 +81,7 @@ Puppet::Functions.create_function(:upload_file, Puppet::Functions::InternalFunct
|
|
80
81
|
r = executor.upload_file(targets, found, destination, options)
|
81
82
|
end
|
82
83
|
|
83
|
-
if !r.ok && !options[
|
84
|
+
if !r.ok && !options[:catch_errors]
|
84
85
|
raise Bolt::RunFailure.new(r, 'upload_file', source)
|
85
86
|
end
|
86
87
|
r
|
data/lib/bolt/applicator.rb
CHANGED
@@ -81,7 +81,7 @@ module Bolt
|
|
81
81
|
end
|
82
82
|
|
83
83
|
def compile(target, ast, plan_vars)
|
84
|
-
trusted = Puppet::Context::TrustedInformation.new('local', target.
|
84
|
+
trusted = Puppet::Context::TrustedInformation.new('local', target.name, {})
|
85
85
|
facts = @inventory.facts(target).merge('bolt' => true)
|
86
86
|
|
87
87
|
catalog_input = {
|
@@ -90,7 +90,7 @@ module Bolt
|
|
90
90
|
pdb_config: @pdb_client.config.to_hash,
|
91
91
|
hiera_config: @hiera_config,
|
92
92
|
target: {
|
93
|
-
name: target.
|
93
|
+
name: target.name,
|
94
94
|
facts: facts,
|
95
95
|
variables: @inventory.vars(target).merge(plan_vars),
|
96
96
|
trusted: trusted.to_h
|
@@ -150,7 +150,7 @@ module Bolt
|
|
150
150
|
if args.count > 1
|
151
151
|
type1 = Puppet.lookup(:pal_script_compiler).type('Hash[String, Data]')
|
152
152
|
Puppet::Pal.assert_type(type1, args[1], 'apply options')
|
153
|
-
options = args[1]
|
153
|
+
options = args[1].map { |k, v| [k.sub(/^_/, '').to_sym, v] }.to_h
|
154
154
|
end
|
155
155
|
|
156
156
|
# collect plan vars and merge them over target vars
|
@@ -196,7 +196,7 @@ module Bolt
|
|
196
196
|
'catalog' => Puppet::Pops::Types::PSensitiveType::Sensitive.new(catalog),
|
197
197
|
'plugins' => Puppet::Pops::Types::PSensitiveType::Sensitive.new(plugins),
|
198
198
|
'_task' => catalog_apply_task.name,
|
199
|
-
'_noop' => options[
|
199
|
+
'_noop' => options[:noop]
|
200
200
|
}
|
201
201
|
|
202
202
|
callback = proc do |event|
|
@@ -206,7 +206,8 @@ module Bolt
|
|
206
206
|
@executor.publish_event(event)
|
207
207
|
end
|
208
208
|
# Respect the run_as default set on the executor
|
209
|
-
options =
|
209
|
+
options[:run_as] = @executor.run_as if @executor.run_as && !options.key?(:run_as)
|
210
|
+
|
210
211
|
results = transport.batch_task(batch, catalog_apply_task, arguments, options, &callback)
|
211
212
|
Array(results).map { |result| ApplyResult.from_task_result(result) }
|
212
213
|
end
|
@@ -220,7 +221,7 @@ module Bolt
|
|
220
221
|
resource_counts = r.ok_set.map { |result| result.event_metrics&.fetch('total') }.compact
|
221
222
|
@executor.report_apply(count_statements(raw_ast), resource_counts)
|
222
223
|
|
223
|
-
if !r.ok && !options[
|
224
|
+
if !r.ok && !options[:catch_errors]
|
224
225
|
raise Bolt::ApplyFailure, r
|
225
226
|
end
|
226
227
|
r
|
data/lib/bolt/cli.rb
CHANGED
@@ -341,7 +341,7 @@ module Bolt
|
|
341
341
|
|
342
342
|
elapsed_time = Benchmark.realtime do
|
343
343
|
executor_opts = {}
|
344
|
-
executor_opts[
|
344
|
+
executor_opts[:description] = options[:description] if options.key?(:description)
|
345
345
|
executor.subscribe(outputter)
|
346
346
|
executor.subscribe(log_outputter)
|
347
347
|
results =
|
@@ -462,7 +462,7 @@ module Bolt
|
|
462
462
|
end
|
463
463
|
|
464
464
|
results = pal.with_bolt_executor(executor, inventory, puppetdb_client) do
|
465
|
-
Puppet.lookup(:apply_executor).apply_ast(ast, targets,
|
465
|
+
Puppet.lookup(:apply_executor).apply_ast(ast, targets, catch_errors: true, noop: noop)
|
466
466
|
end
|
467
467
|
end
|
468
468
|
|
data/lib/bolt/executor.rb
CHANGED
@@ -218,16 +218,16 @@ module Bolt
|
|
218
218
|
end
|
219
219
|
|
220
220
|
def with_node_logging(description, batch)
|
221
|
-
@logger.info("#{description} on #{batch.map(&:
|
221
|
+
@logger.info("#{description} on #{batch.map(&:safe_name)}")
|
222
222
|
result = yield
|
223
223
|
@logger.info(result.to_json)
|
224
224
|
result
|
225
225
|
end
|
226
226
|
|
227
227
|
def run_command(targets, command, options = {})
|
228
|
-
description = options.fetch(
|
228
|
+
description = options.fetch(:description, "command '#{command}'")
|
229
229
|
log_action(description, targets) do
|
230
|
-
options =
|
230
|
+
options[:run_as] = run_as if run_as && !options.key?(:run_as)
|
231
231
|
|
232
232
|
batch_execute(targets) do |transport, batch|
|
233
233
|
with_node_logging("Running command '#{command}'", batch) do
|
@@ -238,9 +238,9 @@ module Bolt
|
|
238
238
|
end
|
239
239
|
|
240
240
|
def run_script(targets, script, arguments, options = {})
|
241
|
-
description = options.fetch(
|
241
|
+
description = options.fetch(:description, "script #{script}")
|
242
242
|
log_action(description, targets) do
|
243
|
-
options =
|
243
|
+
options[:run_as] = run_as if run_as && !options.key?(:run_as)
|
244
244
|
|
245
245
|
batch_execute(targets) do |transport, batch|
|
246
246
|
with_node_logging("Running script #{script} with '#{arguments.to_json}'", batch) do
|
@@ -251,9 +251,9 @@ module Bolt
|
|
251
251
|
end
|
252
252
|
|
253
253
|
def run_task(targets, task, arguments, options = {})
|
254
|
-
description = options.fetch(
|
254
|
+
description = options.fetch(:description, "task #{task.name}")
|
255
255
|
log_action(description, targets) do
|
256
|
-
options =
|
256
|
+
options[:run_as] = run_as if run_as && !options.key?(:run_as)
|
257
257
|
arguments['_task'] = task.name
|
258
258
|
|
259
259
|
batch_execute(targets) do |transport, batch|
|
@@ -265,9 +265,9 @@ module Bolt
|
|
265
265
|
end
|
266
266
|
|
267
267
|
def upload_file(targets, source, destination, options = {})
|
268
|
-
description = options.fetch(
|
268
|
+
description = options.fetch(:description, "file upload from #{source} to #{destination}")
|
269
269
|
log_action(description, targets) do
|
270
|
-
options =
|
270
|
+
options[:run_as] = run_as if run_as && !options.key?(:run_as)
|
271
271
|
|
272
272
|
batch_execute(targets) do |transport, batch|
|
273
273
|
with_node_logging("Uploading file #{source} to #{destination}", batch) do
|
data/lib/bolt/outputter/human.rb
CHANGED
@@ -73,14 +73,14 @@ module Bolt
|
|
73
73
|
end
|
74
74
|
|
75
75
|
def print_start(target)
|
76
|
-
@stream.puts(colorize(:green, "Started on #{target.
|
76
|
+
@stream.puts(colorize(:green, "Started on #{target.safe_name}..."))
|
77
77
|
end
|
78
78
|
|
79
79
|
def print_result(result)
|
80
80
|
if result.success?
|
81
|
-
@stream.puts(colorize(:green, "Finished on #{result.target.
|
81
|
+
@stream.puts(colorize(:green, "Finished on #{result.target.safe_name}:"))
|
82
82
|
else
|
83
|
-
@stream.puts(colorize(:red, "Failed on #{result.target.
|
83
|
+
@stream.puts(colorize(:red, "Failed on #{result.target.safe_name}:"))
|
84
84
|
end
|
85
85
|
|
86
86
|
if result.error_hash
|
@@ -170,7 +170,7 @@ module Bolt
|
|
170
170
|
@stream.puts format('Successful on %<size>d node%<plural>s: %<names>s',
|
171
171
|
size: ok_set.size,
|
172
172
|
plural: ok_set.size == 1 ? '' : 's',
|
173
|
-
names: ok_set.
|
173
|
+
names: ok_set.targets.map(&:safe_name).join(','))
|
174
174
|
end
|
175
175
|
|
176
176
|
error_set = results.error_set
|
@@ -179,7 +179,7 @@ module Bolt
|
|
179
179
|
format('Failed on %<size>d node%<plural>s: %<names>s',
|
180
180
|
size: error_set.size,
|
181
181
|
plural: error_set.size == 1 ? '' : 's',
|
182
|
-
names: error_set.
|
182
|
+
names: error_set.targets.map(&:safe_name).join(',')))
|
183
183
|
end
|
184
184
|
|
185
185
|
total_msg = format('Ran on %<size>d node%<plural>s',
|
data/lib/bolt/plugin.rb
CHANGED
@@ -143,11 +143,12 @@ module Bolt
|
|
143
143
|
@analytics = analytics
|
144
144
|
@plugin_context = PluginContext.new(config, pal)
|
145
145
|
@plugins = {}
|
146
|
+
@pal = pal
|
146
147
|
@unknown = Set.new
|
147
148
|
end
|
148
149
|
|
149
150
|
def modules
|
150
|
-
@modules ||= Bolt::Module.discover(@
|
151
|
+
@modules ||= Bolt::Module.discover(@pal.modulepath)
|
151
152
|
end
|
152
153
|
|
153
154
|
# Generally this is private. Puppetdb is special though
|
data/lib/bolt/plugin/module.rb
CHANGED
data/lib/bolt/plugin/pkcs7.rb
CHANGED
@@ -39,7 +39,7 @@ module Bolt
|
|
39
39
|
|
40
40
|
def private_key_path
|
41
41
|
path = @options['private-key'] || 'keys/private_key.pkcs7.pem'
|
42
|
-
path = File.
|
42
|
+
path = File.expand_path(path, boltdir)
|
43
43
|
@logger.debug("Using private-key: #{path}")
|
44
44
|
path
|
45
45
|
end
|
@@ -50,7 +50,7 @@ module Bolt
|
|
50
50
|
|
51
51
|
def public_key_path
|
52
52
|
path = @options['public-key'] || 'keys/public_key.pkcs7.pem'
|
53
|
-
path = File.
|
53
|
+
path = File.expand_path(path, boltdir)
|
54
54
|
@logger.debug("Using public-key: #{path}")
|
55
55
|
path
|
56
56
|
end
|
data/lib/bolt/plugin/task.rb
CHANGED
@@ -19,7 +19,7 @@ module Bolt
|
|
19
19
|
|
20
20
|
def run_task(opts)
|
21
21
|
params = opts['parameters'] || {}
|
22
|
-
options = {
|
22
|
+
options = { catch_errors: true }
|
23
23
|
|
24
24
|
raise Bolt::ValidationError, "Task plugin requires that the 'task' is specified" unless opts['task']
|
25
25
|
task = @context.get_validated_task(opts['task'], params)
|
data/lib/bolt/result_set.rb
CHANGED
data/lib/bolt/target.rb
CHANGED
@@ -147,6 +147,11 @@ module Bolt
|
|
147
147
|
Addressable::URI.unencode_component(component)
|
148
148
|
end
|
149
149
|
private :unencode
|
150
|
+
|
151
|
+
def eql?(other)
|
152
|
+
self.class.equal?(other.class) && @name == other.name
|
153
|
+
end
|
154
|
+
alias == eql?
|
150
155
|
end
|
151
156
|
|
152
157
|
class Target
|
@@ -247,13 +252,10 @@ module Bolt
|
|
247
252
|
# should we just compare names? is there something else that is meaninful?
|
248
253
|
def eql?(other)
|
249
254
|
if self.class.equal?(other.class)
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
@name = other.name
|
254
|
-
end
|
255
|
+
@uri ? @uri == other.uri : @name == other.name
|
256
|
+
else
|
257
|
+
false
|
255
258
|
end
|
256
|
-
false
|
257
259
|
end
|
258
260
|
alias == eql?
|
259
261
|
|
@@ -281,6 +283,7 @@ module Bolt
|
|
281
283
|
def host
|
282
284
|
@uri_obj&.hostname || @host
|
283
285
|
end
|
286
|
+
alias safe_name host
|
284
287
|
|
285
288
|
def name
|
286
289
|
@name || @uri
|
data/lib/bolt/task/run.rb
CHANGED
data/lib/bolt/transport/base.rb
CHANGED
@@ -125,7 +125,7 @@ module Bolt
|
|
125
125
|
assert_batch_size_one("batch_task()", targets)
|
126
126
|
target = targets.first
|
127
127
|
with_events(target, callback) do
|
128
|
-
@logger.debug { "Running task run '#{task}' on #{target.
|
128
|
+
@logger.debug { "Running task run '#{task}' on #{target.safe_name}" }
|
129
129
|
run_task(target, task, arguments, options)
|
130
130
|
end
|
131
131
|
end
|
@@ -139,7 +139,7 @@ module Bolt
|
|
139
139
|
assert_batch_size_one("batch_command()", targets)
|
140
140
|
target = targets.first
|
141
141
|
with_events(target, callback) do
|
142
|
-
@logger.debug("Running command '#{command}' on #{target.
|
142
|
+
@logger.debug("Running command '#{command}' on #{target.safe_name}")
|
143
143
|
run_command(target, command, options)
|
144
144
|
end
|
145
145
|
end
|
@@ -153,7 +153,7 @@ module Bolt
|
|
153
153
|
assert_batch_size_one("batch_script()", targets)
|
154
154
|
target = targets.first
|
155
155
|
with_events(target, callback) do
|
156
|
-
@logger.debug { "Running script '#{script}' on #{target.
|
156
|
+
@logger.debug { "Running script '#{script}' on #{target.safe_name}" }
|
157
157
|
run_script(target, script, arguments, options)
|
158
158
|
end
|
159
159
|
end
|
@@ -167,7 +167,7 @@ module Bolt
|
|
167
167
|
assert_batch_size_one("batch_upload()", targets)
|
168
168
|
target = targets.first
|
169
169
|
with_events(target, callback) do
|
170
|
-
@logger.debug { "Uploading: '#{source}' to #{destination} on #{target.
|
170
|
+
@logger.debug { "Uploading: '#{source}' to #{destination} on #{target.safe_name}" }
|
171
171
|
upload(target, source, destination, options)
|
172
172
|
end
|
173
173
|
end
|
@@ -8,9 +8,9 @@ module Bolt
|
|
8
8
|
class Docker < Base
|
9
9
|
class Connection
|
10
10
|
def initialize(target)
|
11
|
-
raise Bolt::ValidationError, "Target #{target.
|
11
|
+
raise Bolt::ValidationError, "Target #{target.safe_name} does not have a host" unless target.host
|
12
12
|
@target = target
|
13
|
-
@logger = Logging.logger[target.
|
13
|
+
@logger = Logging.logger[target.safe_name]
|
14
14
|
@docker_host = @target.options['service-url']
|
15
15
|
end
|
16
16
|
|
@@ -28,7 +28,7 @@ module Bolt
|
|
28
28
|
true
|
29
29
|
rescue StandardError => e
|
30
30
|
raise Bolt::Node::ConnectError.new(
|
31
|
-
"Failed to connect to #{@target.
|
31
|
+
"Failed to connect to #{@target.safe_name}: #{e.message}",
|
32
32
|
'CONNECT_ERROR'
|
33
33
|
)
|
34
34
|
end
|
@@ -79,6 +79,7 @@ module Bolt
|
|
79
79
|
end
|
80
80
|
|
81
81
|
def write_remote_file(source, destination)
|
82
|
+
@logger.debug { "Uploading #{source}, to #{destination}" }
|
82
83
|
_, stdout_str, status = execute_local_docker_command('cp', [source, "#{container_id}:#{destination}"])
|
83
84
|
raise "Error writing file to container #{@container_id}: #{stdout_str}" unless status.exitstatus.zero?
|
84
85
|
rescue StandardError => e
|
@@ -86,6 +87,7 @@ module Bolt
|
|
86
87
|
end
|
87
88
|
|
88
89
|
def write_remote_directory(source, destination)
|
90
|
+
@logger.debug { "Uploading #{source}, to #{destination}" }
|
89
91
|
_, stdout_str, status = execute_local_docker_command('cp', [source, "#{container_id}:#{destination}"])
|
90
92
|
raise "Error writing directory to container #{@container_id}: #{stdout_str}" unless status.exitstatus.zero?
|
91
93
|
rescue StandardError => e
|
@@ -27,7 +27,7 @@ module Bolt
|
|
27
27
|
|
28
28
|
def self.validate(options)
|
29
29
|
logger = Logging.logger[self]
|
30
|
-
if options['sudo-password'] || options['run-as'] || options['run-as-command'] || options[
|
30
|
+
if options['sudo-password'] || options['run-as'] || options['run-as-command'] || options[:run_as]
|
31
31
|
logger.warn("run-as is not supported for Windows hosts using the local transport")
|
32
32
|
end
|
33
33
|
end
|
@@ -47,6 +47,7 @@ module Bolt
|
|
47
47
|
private :in_tmpdir
|
48
48
|
|
49
49
|
def copy_file(source, destination)
|
50
|
+
logger.debug { "Uploading #{source}, to #{destination}" }
|
50
51
|
FileUtils.cp_r(source, destination, remove_destination: true)
|
51
52
|
rescue StandardError => e
|
52
53
|
raise Bolt::Node::FileError.new(e.message, 'WRITE_ERROR')
|
data/lib/bolt/transport/orch.rb
CHANGED
data/lib/bolt/transport/ssh.rb
CHANGED
@@ -19,7 +19,7 @@ module Bolt
|
|
19
19
|
require 'net/ssh'
|
20
20
|
require 'net/ssh/proxy/jump'
|
21
21
|
|
22
|
-
raise Bolt::ValidationError, "Target #{target.
|
22
|
+
raise Bolt::ValidationError, "Target #{target.safe_name} does not have a host" unless target.host
|
23
23
|
@sudo_id = SecureRandom.uuid
|
24
24
|
|
25
25
|
@target = target
|
@@ -30,7 +30,7 @@ module Bolt
|
|
30
30
|
@run_as = nil
|
31
31
|
@strict_host_key_checking = ssh_config[:strict_host_key_checking]
|
32
32
|
|
33
|
-
@logger = Logging.logger[@target.
|
33
|
+
@logger = Logging.logger[@target.safe_name]
|
34
34
|
@transport_logger = transport_logger
|
35
35
|
|
36
36
|
if target.options['private-key']&.instance_of?(String)
|
@@ -119,17 +119,17 @@ module Bolt
|
|
119
119
|
)
|
120
120
|
rescue Net::SSH::HostKeyError => e
|
121
121
|
raise Bolt::Node::ConnectError.new(
|
122
|
-
"Host key verification failed for #{target.
|
122
|
+
"Host key verification failed for #{target.safe_name}: #{e.message}",
|
123
123
|
'HOST_KEY_ERROR'
|
124
124
|
)
|
125
125
|
rescue Net::SSH::ConnectionTimeout
|
126
126
|
raise Bolt::Node::ConnectError.new(
|
127
|
-
"Timeout after #{target.options['connect-timeout']} seconds connecting to #{target.
|
127
|
+
"Timeout after #{target.options['connect-timeout']} seconds connecting to #{target.safe_name}",
|
128
128
|
'CONNECT_ERROR'
|
129
129
|
)
|
130
130
|
rescue StandardError => e
|
131
131
|
raise Bolt::Node::ConnectError.new(
|
132
|
-
"Failed to connect to #{target.
|
132
|
+
"Failed to connect to #{target.safe_name}: #{e.message}",
|
133
133
|
'CONNECT_ERROR'
|
134
134
|
)
|
135
135
|
end
|
@@ -155,7 +155,7 @@ module Bolt
|
|
155
155
|
# Cancel the sudo prompt to prevent later commands getting stuck
|
156
156
|
channel.close
|
157
157
|
raise Bolt::Node::EscalateError.new(
|
158
|
-
"Sudo password for user #{@user} was not provided for #{target.
|
158
|
+
"Sudo password for user #{@user} was not provided for #{target.safe_name}",
|
159
159
|
'NO_PASSWORD'
|
160
160
|
)
|
161
161
|
end
|
@@ -168,13 +168,13 @@ module Bolt
|
|
168
168
|
elsif data =~ /^#{@user} is not in the sudoers file\./
|
169
169
|
@logger.debug { data }
|
170
170
|
raise Bolt::Node::EscalateError.new(
|
171
|
-
"User #{@user} does not have sudo permission on #{target.
|
171
|
+
"User #{@user} does not have sudo permission on #{target.safe_name}",
|
172
172
|
'SUDO_DENIED'
|
173
173
|
)
|
174
174
|
elsif data =~ /^Sorry, try again\./
|
175
175
|
@logger.debug { data }
|
176
176
|
raise Bolt::Node::EscalateError.new(
|
177
|
-
"Sudo password for user #{@user} not recognized on #{target.
|
177
|
+
"Sudo password for user #{@user} not recognized on #{target.safe_name}",
|
178
178
|
'BAD_PASSWORD'
|
179
179
|
)
|
180
180
|
end
|
@@ -261,18 +261,13 @@ module Bolt
|
|
261
261
|
end
|
262
262
|
|
263
263
|
def copy_file(source, destination)
|
264
|
+
# Do not log wrapper script content
|
265
|
+
@logger.debug { "Uploading #{source}, to #{destination}" } unless source.is_a?(StringIO)
|
264
266
|
@session.scp.upload!(source, destination, recursive: true)
|
265
267
|
rescue StandardError => e
|
266
268
|
raise Bolt::Node::FileError.new(e.message, 'WRITE_ERROR')
|
267
269
|
end
|
268
270
|
|
269
|
-
def write_executable_from_content(dest, content, filename)
|
270
|
-
remote_path = File.join(dest.to_s, filename)
|
271
|
-
@session.scp.upload!(StringIO.new(content), remote_path)
|
272
|
-
make_executable(remote_path)
|
273
|
-
remote_path
|
274
|
-
end
|
275
|
-
|
276
271
|
# This handles renaming Net::SSH verifiers between version 4.x and 5.x
|
277
272
|
# of the gem
|
278
273
|
def net_ssh_verifier(verifier)
|
@@ -19,7 +19,7 @@ module Bolt
|
|
19
19
|
|
20
20
|
def run_command(target, command, options = {})
|
21
21
|
with_connection(target) do |conn|
|
22
|
-
conn.running_as(options[
|
22
|
+
conn.running_as(options[:run_as]) do
|
23
23
|
output = conn.execute(command, sudoable: true)
|
24
24
|
Bolt::Result.for_command(target,
|
25
25
|
output.stdout.string,
|
@@ -32,7 +32,7 @@ module Bolt
|
|
32
32
|
|
33
33
|
def upload(target, source, destination, options = {})
|
34
34
|
with_connection(target) do |conn|
|
35
|
-
conn.running_as(options[
|
35
|
+
conn.running_as(options[:run_as]) do
|
36
36
|
conn.with_tempdir do |dir|
|
37
37
|
basename = File.basename(destination)
|
38
38
|
tmpfile = File.join(dir.to_s, basename)
|
@@ -55,7 +55,7 @@ module Bolt
|
|
55
55
|
arguments = unwrap_sensitive_args(arguments)
|
56
56
|
|
57
57
|
with_connection(target) do |conn|
|
58
|
-
conn.running_as(options[
|
58
|
+
conn.running_as(options[:run_as]) do
|
59
59
|
conn.with_tempdir do |dir|
|
60
60
|
path = conn.write_executable(dir.to_s, script)
|
61
61
|
dir.chown(conn.run_as)
|
@@ -77,7 +77,7 @@ module Bolt
|
|
77
77
|
extra_files = implementation['files']
|
78
78
|
|
79
79
|
with_connection(target) do |conn|
|
80
|
-
conn.running_as(options[
|
80
|
+
conn.running_as(options[:run_as]) do
|
81
81
|
stdin, output = nil
|
82
82
|
execute_options = {}
|
83
83
|
execute_options[:interpreter] = select_interpreter(executable, target.options['interpreters'])
|
data/lib/bolt/transport/winrm.rb
CHANGED
@@ -12,7 +12,7 @@ module Bolt
|
|
12
12
|
DEFAULT_EXTENSIONS = ['.ps1', '.rb', '.pp'].freeze
|
13
13
|
|
14
14
|
def initialize(target, transport_logger)
|
15
|
-
raise Bolt::ValidationError, "Target #{target.
|
15
|
+
raise Bolt::ValidationError, "Target #{target.safe_name} does not have a host" unless target.host
|
16
16
|
@target = target
|
17
17
|
|
18
18
|
default_port = target.options['ssl'] ? HTTPS_PORT : HTTP_PORT
|
@@ -23,7 +23,7 @@ module Bolt
|
|
23
23
|
extensions += target.options['interpreters'].keys if target.options['interpreters']
|
24
24
|
@extensions = DEFAULT_EXTENSIONS.to_set.merge(extensions)
|
25
25
|
|
26
|
-
@logger = Logging.logger[@target.
|
26
|
+
@logger = Logging.logger[@target.safe_name]
|
27
27
|
@transport_logger = transport_logger
|
28
28
|
end
|
29
29
|
|
@@ -148,6 +148,7 @@ module Bolt
|
|
148
148
|
end
|
149
149
|
|
150
150
|
def write_remote_file(source, destination)
|
151
|
+
@logger.debug { "Uploading #{source}, to #{destination}" }
|
151
152
|
if target.options['file-protocol'] == 'smb'
|
152
153
|
write_remote_file_smb(source, destination)
|
153
154
|
else
|
@@ -223,13 +224,6 @@ module Bolt
|
|
223
224
|
remote_path
|
224
225
|
end
|
225
226
|
|
226
|
-
def write_executable_from_content(dir, content, filename)
|
227
|
-
validate_extensions(File.extname(filename))
|
228
|
-
remote_path = "#{dir}\\#{filename}"
|
229
|
-
write_remote_file(content, remote_path)
|
230
|
-
remote_path
|
231
|
-
end
|
232
|
-
|
233
227
|
private
|
234
228
|
|
235
229
|
def smb_client_login
|
@@ -243,12 +237,12 @@ module Bolt
|
|
243
237
|
@logger.debug { "Connected to #{@client.dns_host_name}" }
|
244
238
|
when WindowsError::NTStatus::STATUS_LOGON_FAILURE
|
245
239
|
raise Bolt::Node::ConnectError.new(
|
246
|
-
"SMB authentication failed for #{target.
|
240
|
+
"SMB authentication failed for #{target.safe_name}",
|
247
241
|
'AUTH_ERROR'
|
248
242
|
)
|
249
243
|
else
|
250
244
|
raise Bolt::Node::ConnectError.new(
|
251
|
-
"Failed to connect to #{target.
|
245
|
+
"Failed to connect to #{target.safe_name} using SMB: #{status.description}",
|
252
246
|
'CONNECT_ERROR'
|
253
247
|
)
|
254
248
|
end
|
@@ -267,12 +261,12 @@ module Bolt
|
|
267
261
|
rescue Errno::ECONNREFUSED => e
|
268
262
|
# handle this to prevent obscuring error message as SMB problem
|
269
263
|
raise Bolt::Node::ConnectError.new(
|
270
|
-
"Failed to connect to #{target.
|
264
|
+
"Failed to connect to #{target.safe_name} using SMB: #{e.message}",
|
271
265
|
'CONNECT_ERROR'
|
272
266
|
)
|
273
267
|
rescue Timeout::Error
|
274
268
|
raise Bolt::Node::ConnectError.new(
|
275
|
-
"Timeout after #{target.options['connect-timeout']} seconds connecting to #{target.
|
269
|
+
"Timeout after #{target.options['connect-timeout']} seconds connecting to #{target.safe_name}",
|
276
270
|
'CONNECT_ERROR'
|
277
271
|
)
|
278
272
|
end
|
data/lib/bolt/version.rb
CHANGED
@@ -46,6 +46,7 @@ module BoltSpec
|
|
46
46
|
@invocation[:params] = params
|
47
47
|
@invocation[:arguments] = params.reject { |k, _v| k.start_with?('_') }
|
48
48
|
@invocation[:options] = params.select { |k, _v| k.start_with?('_') }
|
49
|
+
.map { |k, v| [k.sub(/^_/, '').to_sym, v] }.to_h
|
49
50
|
self
|
50
51
|
end
|
51
52
|
end
|
data/lib/bolt_spec/run.rb
CHANGED
@@ -202,7 +202,7 @@ module BoltSpec
|
|
202
202
|
end
|
203
203
|
|
204
204
|
pal.with_bolt_executor(executor, inventory, puppetdb_client) do
|
205
|
-
Puppet.lookup(:apply_executor).apply_ast(ast, targets,
|
205
|
+
Puppet.lookup(:apply_executor).apply_ast(ast, targets, catch_errors: true, noop: noop)
|
206
206
|
end
|
207
207
|
end
|
208
208
|
end
|
@@ -79,7 +79,7 @@ module PlanExecutor
|
|
79
79
|
end
|
80
80
|
|
81
81
|
def run_command(targets, command, options = {})
|
82
|
-
description = options.fetch(
|
82
|
+
description = options.fetch(:description, "command '#{command}'")
|
83
83
|
log_action(description, targets) do
|
84
84
|
results = as_resultset(targets) do
|
85
85
|
@orch_client.run_command(targets, command, options)
|
@@ -90,7 +90,7 @@ module PlanExecutor
|
|
90
90
|
end
|
91
91
|
|
92
92
|
def run_script(targets, script, arguments, options = {})
|
93
|
-
description = options.fetch(
|
93
|
+
description = options.fetch(:description, "script #{script}")
|
94
94
|
log_action(description, targets) do
|
95
95
|
results = as_resultset(targets) do
|
96
96
|
@orch_client.run_script(targets, script, arguments, options)
|
@@ -101,7 +101,7 @@ module PlanExecutor
|
|
101
101
|
end
|
102
102
|
|
103
103
|
def run_task(targets, task, arguments, options = {})
|
104
|
-
description = options.fetch(
|
104
|
+
description = options.fetch(:description, "task #{task.name}")
|
105
105
|
log_action(description, targets) do
|
106
106
|
arguments['_task'] = task.name
|
107
107
|
|
@@ -114,7 +114,7 @@ module PlanExecutor
|
|
114
114
|
end
|
115
115
|
|
116
116
|
def upload_file(targets, source, destination, options = {})
|
117
|
-
description = options.fetch(
|
117
|
+
description = options.fetch(:description, "file upload from #{source} to #{destination}")
|
118
118
|
log_action(description, targets) do
|
119
119
|
results = as_resultset(targets) do
|
120
120
|
@orch_client.file_upload(targets, source, destination, options)
|
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: 1.
|
4
|
+
version: 1.33.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Puppet
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-10-
|
11
|
+
date: 2019-10-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: addressable
|