bolt 3.13.0 → 3.16.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 +1 -1
- data/bolt-modules/boltlib/lib/puppet/functions/apply_prep.rb +137 -104
- data/bolt-modules/boltlib/lib/puppet/functions/background.rb +2 -1
- data/bolt-modules/boltlib/lib/puppet/functions/parallelize.rb +5 -1
- data/bolt-modules/boltlib/lib/puppet/functions/run_plan.rb +13 -0
- data/bolt-modules/boltlib/lib/puppet/functions/wait.rb +47 -7
- data/bolt-modules/out/lib/puppet/functions/out/message.rb +4 -2
- data/bolt-modules/out/lib/puppet/functions/out/verbose.rb +4 -2
- data/guides/{debugging.txt → debugging.yaml} +5 -6
- data/guides/{inventory.txt → inventory.yaml} +6 -7
- data/guides/{links.txt → links.yaml} +3 -4
- data/guides/{logging.txt → logging.yaml} +5 -6
- data/guides/{module.txt → module.yaml} +5 -6
- data/guides/{modulepath.txt → modulepath.yaml} +5 -6
- data/guides/{project.txt → project.yaml} +6 -7
- data/guides/{targets.txt → targets.yaml} +5 -6
- data/guides/{transports.txt → transports.yaml} +6 -7
- data/lib/bolt/analytics.rb +3 -20
- data/lib/bolt/application.rb +620 -0
- data/lib/bolt/bolt_option_parser.rb +17 -5
- data/lib/bolt/cli.rb +592 -772
- data/lib/bolt/config/transport/options.rb +12 -0
- data/lib/bolt/config/transport/ssh.rb +7 -0
- data/lib/bolt/executor.rb +12 -4
- data/lib/bolt/fiber_executor.rb +63 -14
- data/lib/bolt/module_installer/puppetfile.rb +24 -10
- data/lib/bolt/outputter/human.rb +199 -43
- data/lib/bolt/outputter/json.rb +66 -43
- data/lib/bolt/outputter/logger.rb +1 -1
- data/lib/bolt/pal.rb +67 -14
- data/lib/bolt/pal/yaml_plan/step.rb +2 -0
- data/lib/bolt/pal/yaml_plan/step/message.rb +0 -8
- data/lib/bolt/pal/yaml_plan/step/verbose.rb +31 -0
- data/lib/bolt/pal/yaml_plan/transpiler.rb +1 -1
- data/lib/bolt/plan_creator.rb +2 -20
- data/lib/bolt/plan_future.rb +23 -3
- data/lib/bolt/plan_result.rb +1 -1
- data/lib/bolt/plugin/task.rb +1 -1
- data/lib/bolt/project.rb +0 -7
- data/lib/bolt/result_set.rb +2 -1
- data/lib/bolt/transport/local/connection.rb +17 -1
- data/lib/bolt/transport/orch/connection.rb +13 -1
- data/lib/bolt/transport/ssh/exec_connection.rb +3 -1
- data/lib/bolt/version.rb +1 -1
- data/lib/bolt_server/file_cache.rb +12 -0
- data/lib/bolt_server/schemas/action-apply.json +32 -0
- data/lib/bolt_server/schemas/action-apply_prep.json +19 -0
- data/lib/bolt_server/schemas/partials/target-ssh.json +4 -0
- data/lib/bolt_server/schemas/partials/target-winrm.json +4 -0
- data/lib/bolt_server/transport_app.rb +180 -60
- data/lib/bolt_spec/plans/mock_executor.rb +16 -6
- metadata +23 -15
- data/guides/guide.txt +0 -17
- data/lib/bolt/secret.rb +0 -37
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 71d383b473f9356ff41f574bb0abe4aea9a9f8c3ac5055a459acffe0da290af1
|
4
|
+
data.tar.gz: 00d10803d865a9d6f0cb6eb7162e4a17f619b88e6702b559e0153b3796d732d0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: eaad9c12aab69e9d7c9f1d8b312623b8bcca4f26f983beb08b1d09c4568aafe0e430d639b88903df4e1a498a58c4c9d8add5d4b8b3930fe1dec3124bc15afad3
|
7
|
+
data.tar.gz: a05ec6c181fc6aa51c73ebfd928d73513d5506c1b0705bed4637bfa9490a6f1c010019c9209f7ed28c134f003a063ff6f4add490a55d658998f566d00c5ff017
|
data/Puppetfile
CHANGED
@@ -35,7 +35,7 @@ mod 'puppetlabs-stdlib', '7.1.0'
|
|
35
35
|
mod 'puppetlabs-aws_inventory', '0.7.0'
|
36
36
|
mod 'puppetlabs-azure_inventory', '0.5.0'
|
37
37
|
mod 'puppetlabs-gcloud_inventory', '0.3.0'
|
38
|
-
mod 'puppetlabs-http_request', '0.
|
38
|
+
mod 'puppetlabs-http_request', '0.3.1'
|
39
39
|
mod 'puppetlabs-pkcs7', '0.1.2'
|
40
40
|
mod 'puppetlabs-secure_env_vars', '0.2.0'
|
41
41
|
mod 'puppetlabs-terraform', '0.6.1'
|
@@ -8,16 +8,18 @@ require 'bolt/task'
|
|
8
8
|
# installed using either the configured plugin or the `task` plugin with the
|
9
9
|
# `puppet_agent::install` task.
|
10
10
|
#
|
11
|
-
# Agent installation will be skipped if the target includes the `puppet-agent`
|
12
|
-
# property of its transport (PCP) or by explicitly setting
|
11
|
+
# Agent installation will be skipped if the target includes the `puppet-agent`
|
12
|
+
# feature, either as a property of its transport (PCP) or by explicitly setting
|
13
|
+
# it as a feature in Bolt's inventory.
|
13
14
|
#
|
14
15
|
# > **Note:** Not available in apply block
|
15
16
|
Puppet::Functions.create_function(:apply_prep) do
|
16
17
|
# @param targets A pattern or array of patterns identifying a set of targets.
|
17
18
|
# @param options Options hash.
|
19
|
+
# @option options [Boolean] _catch_errors Whether to catch raised errors.
|
18
20
|
# @option options [Array] _required_modules An array of modules to sync to the target.
|
19
21
|
# @option options [String] _run_as User to run as using privilege escalation.
|
20
|
-
# @return [
|
22
|
+
# @return [Bolt::ResultSet]
|
21
23
|
# @example Prepare targets by name.
|
22
24
|
# apply_prep('target1,target2')
|
23
25
|
dispatch :apply_prep do
|
@@ -25,138 +27,169 @@ Puppet::Functions.create_function(:apply_prep) do
|
|
25
27
|
optional_param 'Hash[String, Data]', :options
|
26
28
|
end
|
27
29
|
|
28
|
-
def
|
29
|
-
|
30
|
-
|
30
|
+
def apply_prep(target_spec, options = {})
|
31
|
+
unless Puppet[:tasks]
|
32
|
+
raise Puppet::ParseErrorWithIssue
|
33
|
+
.from_issue_and_stack(Bolt::PAL::Issues::PLAN_OPERATION_NOT_SUPPORTED_WHEN_COMPILING, action: 'apply_prep')
|
34
|
+
end
|
31
35
|
|
32
|
-
|
33
|
-
|
34
|
-
end
|
36
|
+
options = options.slice(*%w[_catch_errors _required_modules _run_as])
|
37
|
+
targets = inventory.get_targets(target_spec)
|
35
38
|
|
36
|
-
|
37
|
-
tasksig = script_compiler.task_signature(name)
|
38
|
-
raise Bolt::Error.new("Task '#{name}' could not be found", 'bolt/apply-prep') unless tasksig
|
39
|
+
executor.report_function_call(self.class.name)
|
39
40
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
41
|
+
executor.log_action('install puppet and gather facts', targets) do
|
42
|
+
executor.without_default_logging do
|
43
|
+
install_results = install_agents(targets, options)
|
44
|
+
facts_results = get_facts(install_results.ok_set.targets, options)
|
45
|
+
|
46
|
+
Bolt::ResultSet.new(install_results.error_set.results + facts_results.results)
|
47
|
+
end
|
44
48
|
end
|
49
|
+
end
|
45
50
|
|
46
|
-
|
51
|
+
def applicator
|
52
|
+
@applicator ||= Puppet.lookup(:apply_executor)
|
47
53
|
end
|
48
54
|
|
49
|
-
|
50
|
-
|
51
|
-
inventory.set_feature(target, 'puppet-agent')
|
55
|
+
def executor
|
56
|
+
@executor ||= Puppet.lookup(:bolt_executor)
|
52
57
|
end
|
53
|
-
# rubocop:enable Naming/AccessorMethodName
|
54
58
|
|
59
|
+
def inventory
|
60
|
+
@inventory ||= Puppet.lookup(:bolt_inventory)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Runs a task. This method is called by the puppet_library hook.
|
64
|
+
#
|
55
65
|
def run_task(targets, task, args = {}, options = {})
|
56
66
|
executor.run_task(targets, task, args, options)
|
57
67
|
end
|
58
68
|
|
59
|
-
# Returns true if the target has the puppet-agent feature defined, either from
|
60
|
-
|
69
|
+
# Returns true if the target has the puppet-agent feature defined, either from
|
70
|
+
# inventory or transport.
|
71
|
+
#
|
72
|
+
private def agent?(target)
|
61
73
|
inventory.features(target).include?('puppet-agent') ||
|
62
|
-
|
74
|
+
executor.transport(target.transport).provided_features.include?('puppet-agent') ||
|
75
|
+
target.remote?
|
63
76
|
end
|
64
77
|
|
65
|
-
|
66
|
-
|
78
|
+
# Generate the plugin tarball.
|
79
|
+
#
|
80
|
+
private def build_plugin_tarball(required_modules)
|
81
|
+
if required_modules.any?
|
82
|
+
Puppet.debug("Syncing only required modules: #{required_modules.join(',')}.")
|
83
|
+
end
|
84
|
+
|
85
|
+
tarball = applicator.build_plugin_tarball do |mod|
|
86
|
+
next unless required_modules.empty? || required_modules.include?(mod.name)
|
87
|
+
search_dirs = []
|
88
|
+
search_dirs << mod.plugins if mod.plugins?
|
89
|
+
search_dirs << mod.pluginfacts if mod.pluginfacts?
|
90
|
+
search_dirs
|
91
|
+
end
|
92
|
+
|
93
|
+
Puppet::Pops::Types::PSensitiveType::Sensitive.new(tarball)
|
67
94
|
end
|
68
95
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
96
|
+
# Install the puppet-agent package on targets that need it.
|
97
|
+
#
|
98
|
+
private def install_agents(targets, options)
|
99
|
+
results = []
|
100
|
+
|
101
|
+
agent_targets, agentless_targets = targets.partition { |target| agent?(target) }
|
102
|
+
|
103
|
+
agent_targets.each do |target|
|
104
|
+
Puppet.debug("Puppet Agent feature declared for #{target}")
|
105
|
+
results << Bolt::Result.new(target)
|
73
106
|
end
|
74
107
|
|
75
|
-
|
76
|
-
|
108
|
+
unless agentless_targets.empty?
|
109
|
+
hooks, errors = get_hooks(agentless_targets, options)
|
110
|
+
hook_results = run_hooks(hooks)
|
77
111
|
|
78
|
-
|
112
|
+
hook_results.each do |result|
|
113
|
+
next unless result.ok?
|
114
|
+
inventory.set_feature(result.target, 'puppet-agent')
|
115
|
+
end
|
79
116
|
|
80
|
-
|
117
|
+
results.concat(hook_results).concat(errors)
|
118
|
+
end
|
81
119
|
|
82
|
-
|
120
|
+
Bolt::ResultSet.new(results).tap do |resultset|
|
121
|
+
unless resultset.ok? || options['_catch_errors']
|
122
|
+
raise Bolt::RunFailure.new(resultset.error_set, 'apply_prep')
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
83
126
|
|
84
|
-
|
85
|
-
|
86
|
-
|
127
|
+
# Retrieve facts from each target and add them to inventory.
|
128
|
+
#
|
129
|
+
private def get_facts(targets, options)
|
130
|
+
return Bolt::ResultSet.new([]) unless targets.any?
|
131
|
+
|
132
|
+
task = applicator.custom_facts_task
|
133
|
+
args = { 'plugins' => build_plugin_tarball(options.delete('_required_modules').to_a) }
|
134
|
+
results = run_task(targets, task, args, options)
|
135
|
+
|
136
|
+
unless results.ok? || options['_catch_errors']
|
137
|
+
raise Bolt::RunFailure.new(results, 'run_task', task.name)
|
87
138
|
end
|
88
139
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
140
|
+
results.each do |result|
|
141
|
+
next unless result.ok?
|
142
|
+
|
143
|
+
if unsupported_puppet?(result['clientversion'])
|
144
|
+
Bolt::Logger.deprecate(
|
145
|
+
"unsupported_puppet",
|
146
|
+
"Detected unsupported Puppet agent version #{result['clientversion']} on target "\
|
147
|
+
"#{result.target}. Bolt supports Puppet agent 6.0.0 and higher."
|
148
|
+
)
|
149
|
+
end
|
150
|
+
|
151
|
+
inventory.add_facts(result.target, result.value)
|
96
152
|
end
|
97
153
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
raise Bolt::RunFailure.new(set.error_set, 'apply_prep') unless set.ok
|
132
|
-
|
133
|
-
need_install_targets.each { |target| set_agent_feature(target) }
|
134
|
-
end
|
135
|
-
|
136
|
-
task = applicator.custom_facts_task
|
137
|
-
arguments = { 'plugins' => Puppet::Pops::Types::PSensitiveType::Sensitive.new(plugins) }
|
138
|
-
results = run_task(targets, task, arguments, options)
|
139
|
-
|
140
|
-
# TODO: Standardize RunFailure type with error above
|
141
|
-
raise Bolt::RunFailure.new(results, 'run_task', task.name) unless results.ok?
|
142
|
-
|
143
|
-
results.each do |result|
|
144
|
-
# Log a warning if the client version is < 6
|
145
|
-
if unsupported_puppet?(result['clientversion'])
|
146
|
-
Bolt::Logger.deprecate(
|
147
|
-
"unsupported_puppet",
|
148
|
-
"Detected unsupported Puppet agent version #{result['clientversion']} on target "\
|
149
|
-
"#{result.target}. Bolt supports Puppet agent 6.0.0 and higher."
|
150
|
-
)
|
151
|
-
end
|
152
|
-
|
153
|
-
inventory.add_facts(result.target, result.value)
|
154
|
-
end
|
154
|
+
results
|
155
|
+
end
|
156
|
+
|
157
|
+
# Return a list of targets and their puppet_library hooks.
|
158
|
+
#
|
159
|
+
private def get_hooks(targets, options)
|
160
|
+
hooks = []
|
161
|
+
errors = []
|
162
|
+
|
163
|
+
targets.each do |target|
|
164
|
+
plugin_opts = target.plugin_hooks.fetch('puppet_library').dup
|
165
|
+
plugin_name = plugin_opts.delete('plugin')
|
166
|
+
hook = inventory.plugins.get_hook(plugin_name, :puppet_library)
|
167
|
+
|
168
|
+
hooks << { 'target' => target,
|
169
|
+
'proc' => hook.call(plugin_opts.merge(options), target, self) }
|
170
|
+
rescue StandardError => e
|
171
|
+
errors << Bolt::Result.from_exception(target, e)
|
172
|
+
end
|
173
|
+
|
174
|
+
[hooks, errors]
|
175
|
+
end
|
176
|
+
|
177
|
+
# Runs the puppet_library hook for each target, returning the result
|
178
|
+
# of each.
|
179
|
+
#
|
180
|
+
private def run_hooks(hooks)
|
181
|
+
require 'concurrent'
|
182
|
+
pool = Concurrent::ThreadPoolExecutor.new
|
183
|
+
|
184
|
+
futures = hooks.map do |hook|
|
185
|
+
Concurrent::Future.execute(executor: pool) do
|
186
|
+
hook['proc'].call
|
155
187
|
end
|
156
188
|
end
|
157
189
|
|
158
|
-
|
159
|
-
|
190
|
+
futures.zip(hooks).map do |future, hook|
|
191
|
+
future.value || Bolt::Result.from_exception(hook['target'], future.reason)
|
192
|
+
end
|
160
193
|
end
|
161
194
|
|
162
195
|
# Returns true if the client's major version is < 6.
|
@@ -31,7 +31,8 @@ Puppet::Functions.create_function(:background, Puppet::Functions::InternalFuncti
|
|
31
31
|
executor = Puppet.lookup(:bolt_executor)
|
32
32
|
executor.report_function_call(self.class.name)
|
33
33
|
|
34
|
-
executor.
|
34
|
+
plan_id = executor.get_current_plan_id(fiber: Fiber.current)
|
35
|
+
executor.create_future(scope: scope, name: name, plan_id: plan_id) do |newscope|
|
35
36
|
# Catch 'return' calls inside the block
|
36
37
|
result = catch(:return) do
|
37
38
|
# Execute the block. Individual plan steps in the block will yield
|
@@ -34,7 +34,11 @@ Puppet::Functions.create_function(:parallelize, Puppet::Functions::InternalFunct
|
|
34
34
|
executor.report_function_call(self.class.name)
|
35
35
|
|
36
36
|
futures = data.map do |object|
|
37
|
-
|
37
|
+
# We're going to immediately wait for these futures, *and* don't want
|
38
|
+
# their results to be returned as part of `wait()`, so use a 'dummy'
|
39
|
+
# value as the plan_id. This could also be nil, though in general we want
|
40
|
+
# to require Futures to have a plan stack so that they don't get lost.
|
41
|
+
executor.create_future(scope: scope, plan_id: 'parallel') do |newscope|
|
38
42
|
# Catch 'return' calls inside the block
|
39
43
|
result = catch(:return) do
|
40
44
|
# Add the object to the block parameters
|
@@ -125,6 +125,17 @@ Puppet::Functions.create_function(:run_plan, Puppet::Functions::InternalFunction
|
|
125
125
|
params = wrap_sensitive_parameters(params, closure.parameters)
|
126
126
|
end
|
127
127
|
|
128
|
+
# This can be anything as long as it's unique
|
129
|
+
plan_instance_id = SecureRandom.uuid
|
130
|
+
|
131
|
+
# Add the plan invocation ID to the plan_stack for the PlanFuture the plan is
|
132
|
+
# running in so that we know the PlanFuture is running in a new plan
|
133
|
+
# invocation. This can be nil in test cases and when `wait()` isn't
|
134
|
+
# supported.
|
135
|
+
current_future = executor.get_current_future(fiber: Fiber.current)
|
136
|
+
# Safe operator to make testing easier
|
137
|
+
current_future&.plan_stack&.unshift(plan_instance_id)
|
138
|
+
|
128
139
|
# wrap plan execution in logging messages
|
129
140
|
executor.log_plan(plan_name) do
|
130
141
|
result = nil
|
@@ -150,6 +161,8 @@ Puppet::Functions.create_function(:run_plan, Puppet::Functions::InternalFunction
|
|
150
161
|
raise e
|
151
162
|
end
|
152
163
|
ensure
|
164
|
+
# Pop the plan invocation ID off of the plan_id stack for the Future.
|
165
|
+
current_future&.plan_stack&.shift
|
153
166
|
if run_as
|
154
167
|
executor.run_as = old_run_as
|
155
168
|
end
|
@@ -1,14 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'bolt/logger'
|
4
|
-
require 'bolt/target'
|
5
4
|
|
6
5
|
# Wait for a Future or array of Futures to finish and return results,
|
7
6
|
# optionally with a timeout.
|
8
7
|
#
|
9
8
|
# > **Note:** Not available in apply block
|
10
9
|
Puppet::Functions.create_function(:wait, Puppet::Functions::InternalFunction) do
|
11
|
-
# Wait for
|
10
|
+
# Wait for Futures to finish.
|
12
11
|
# @param futures A Bolt Future object or array of Bolt Futures to wait on.
|
13
12
|
# @param options A hash of additional options.
|
14
13
|
# @option options [Boolean] _catch_errors Whether to catch raised errors.
|
@@ -27,7 +26,37 @@ Puppet::Functions.create_function(:wait, Puppet::Functions::InternalFunction) do
|
|
27
26
|
return_type 'Array[Boltlib::PlanResult]'
|
28
27
|
end
|
29
28
|
|
30
|
-
# Wait for
|
29
|
+
# Wait for all Futures in the current plan to finish.
|
30
|
+
# @param options A hash of additional options.
|
31
|
+
# @option options [Boolean] _catch_errors Whether to catch raised errors.
|
32
|
+
# @return A Result or Results from the Futures
|
33
|
+
# @example Perform multiple tasks in the background, then wait for all of them to finish
|
34
|
+
# background() || { upload_file("./large_file", "/opt/jfrog/...", $targets) }
|
35
|
+
# background() || { run_task("db::migrate", $targets) }
|
36
|
+
# # Wait for all futures in the plan to finish and return all results
|
37
|
+
# $results = wait()
|
38
|
+
dispatch :wait_for_all do
|
39
|
+
optional_param 'Hash[String[1], Any]', :options
|
40
|
+
return_type 'Array[Boltlib::PlanResult]'
|
41
|
+
end
|
42
|
+
|
43
|
+
# Wait for all Futures in the current plan to finish with a timeout.
|
44
|
+
# @param timeout How long to wait for Futures to finish before raising a Timeout error.
|
45
|
+
# @param options A hash of additional options.
|
46
|
+
# @option options [Boolean] _catch_errors Whether to catch raised errors.
|
47
|
+
# @return A Result or Results from the Futures
|
48
|
+
# @example Perform multiple tasks in the background, then wait for all of them to finish with a timeout
|
49
|
+
# background() || { upload_file("./large_file", "/opt/jfrog/...", $targets) }
|
50
|
+
# background() || { run_task("db::migrate", $targets) }
|
51
|
+
# # Wait for all futures in the plan to finish and return all results
|
52
|
+
# $results = wait(30)
|
53
|
+
dispatch :wait_for_all_with_timeout do
|
54
|
+
param 'Variant[Integer[0], Float[0.0]]', :timeout
|
55
|
+
optional_param 'Hash[String[1], Any]', :options
|
56
|
+
return_type 'Array[Boltlib::PlanResult]'
|
57
|
+
end
|
58
|
+
|
59
|
+
# Wait for Futures to finish with timeout.
|
31
60
|
# @param futures A Bolt Future object or array of Bolt Futures to wait on.
|
32
61
|
# @param timeout How long to wait for Futures to finish before raising a Timeout error.
|
33
62
|
# @param options A hash of additional options.
|
@@ -58,14 +87,22 @@ Puppet::Functions.create_function(:wait, Puppet::Functions::InternalFunction) do
|
|
58
87
|
end
|
59
88
|
|
60
89
|
def wait(futures, options = {})
|
61
|
-
inner_wait(futures
|
90
|
+
inner_wait(futures: futures, options: options)
|
91
|
+
end
|
92
|
+
|
93
|
+
def wait_for_all(options = {})
|
94
|
+
inner_wait(options: options)
|
95
|
+
end
|
96
|
+
|
97
|
+
def wait_for_all_with_timeout(timeout, options = {})
|
98
|
+
inner_wait(timeout: timeout, options: options)
|
62
99
|
end
|
63
100
|
|
64
101
|
def wait_with_timeout(futures, timeout, options = {})
|
65
|
-
inner_wait(futures, timeout, options)
|
102
|
+
inner_wait(futures: futures, timeout: timeout, options: options)
|
66
103
|
end
|
67
104
|
|
68
|
-
def inner_wait(futures, timeout
|
105
|
+
def inner_wait(futures: nil, timeout: nil, options: {})
|
69
106
|
unless Puppet[:tasks]
|
70
107
|
raise Puppet::ParseErrorWithIssue
|
71
108
|
.from_issue_and_stack(Bolt::PAL::Issues::PLAN_OPERATION_NOT_SUPPORTED_WHEN_COMPILING, action: 'wait')
|
@@ -85,7 +122,10 @@ Puppet::Functions.create_function(:wait, Puppet::Functions::InternalFunction) do
|
|
85
122
|
executor = Puppet.lookup(:bolt_executor)
|
86
123
|
executor.report_function_call(self.class.name)
|
87
124
|
|
88
|
-
|
125
|
+
# If we get a single Future, make sure it's an array. If we didn't get any
|
126
|
+
# futures pass that on to wait so we can continue collecting any futures
|
127
|
+
# that are created while waiting on existing futures.
|
128
|
+
futures = Array(futures) unless futures.nil?
|
89
129
|
executor.wait(futures, **valid)
|
90
130
|
end
|
91
131
|
end
|