bolt 3.8.1 → 3.11.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of bolt might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Puppetfile +4 -4
- data/bolt-modules/boltlib/lib/puppet/datatypes/future.rb +25 -0
- data/bolt-modules/boltlib/lib/puppet/functions/background.rb +61 -0
- data/bolt-modules/boltlib/lib/puppet/functions/download_file.rb +5 -9
- data/bolt-modules/boltlib/lib/puppet/functions/parallelize.rb +28 -13
- data/bolt-modules/boltlib/lib/puppet/functions/run_command.rb +5 -15
- data/bolt-modules/boltlib/lib/puppet/functions/run_script.rb +5 -17
- data/bolt-modules/boltlib/lib/puppet/functions/run_task.rb +8 -17
- data/bolt-modules/boltlib/lib/puppet/functions/run_task_with.rb +8 -15
- data/bolt-modules/boltlib/lib/puppet/functions/upload_file.rb +5 -17
- data/bolt-modules/boltlib/lib/puppet/functions/wait.rb +91 -0
- data/bolt-modules/boltlib/types/planresult.pp +1 -0
- data/guides/debugging.txt +28 -0
- data/guides/inventory.txt +5 -0
- data/lib/bolt/applicator.rb +3 -2
- data/lib/bolt/bolt_option_parser.rb +51 -4
- data/lib/bolt/cli.rb +38 -9
- data/lib/bolt/config/transport/docker.rb +1 -1
- data/lib/bolt/config/transport/lxd.rb +1 -1
- data/lib/bolt/config/transport/podman.rb +1 -1
- data/lib/bolt/error.rb +11 -1
- data/lib/bolt/executor.rb +55 -72
- data/lib/bolt/fiber_executor.rb +141 -0
- data/lib/bolt/module_installer/installer.rb +1 -1
- data/lib/bolt/outputter/human.rb +46 -2
- data/lib/bolt/outputter/json.rb +9 -0
- data/lib/bolt/pal.rb +117 -17
- data/lib/bolt/plan_future.rb +66 -0
- data/lib/bolt/plugin.rb +38 -0
- data/lib/bolt/plugin/env_var.rb +8 -1
- data/lib/bolt/plugin/module.rb +1 -1
- data/lib/bolt/plugin/prompt.rb +8 -1
- data/lib/bolt/plugin/puppet_connect_data.rb +8 -1
- data/lib/bolt/plugin/puppetdb.rb +7 -1
- data/lib/bolt/plugin/task.rb +9 -1
- data/lib/bolt/project.rb +2 -1
- data/lib/bolt/task.rb +7 -0
- data/lib/bolt/transport/docker/connection.rb +5 -2
- data/lib/bolt/transport/lxd/connection.rb +4 -0
- data/lib/bolt/transport/podman/connection.rb +4 -0
- data/lib/bolt/version.rb +1 -1
- data/lib/bolt_server/config.rb +1 -1
- data/lib/bolt_server/request_error.rb +11 -0
- data/lib/bolt_server/transport_app.rb +133 -95
- data/lib/bolt_spec/plans/mock_executor.rb +40 -45
- data/lib/bolt_spec/run.rb +4 -1
- data/modules/puppet_connect/plans/test_input_data.pp +8 -3
- data/resources/bolt_bash_completion.sh +214 -0
- metadata +10 -3
- data/lib/bolt/yarn.rb +0 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ef5e67102ddbc1b3ef1c0d08352fd5392766b73f3686e54ca62e9f5e09141356
|
4
|
+
data.tar.gz: dc371bb5483705f7c7dbca0be037aad53338e27480faf1f884eb669f8c14fbb2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7efd326949ec4d661ff4d4471d9626dcf2688a5e0f699f777d70537135493b2b55250054b6de1989f933a23c8aafb6e2124a7062d32f398218529fd6550ff2b7
|
7
|
+
data.tar.gz: ac92568d449f852bc39e0c824c9fe6e3c13cee329fa6c5a3bfc1794b01a9b4b9278124456fe4adfd9cebe2ec0056ab42651b5f1aa4f1a56402a743c7893e42a3
|
data/Puppetfile
CHANGED
@@ -6,13 +6,13 @@ moduledir File.join(File.dirname(__FILE__), 'modules')
|
|
6
6
|
|
7
7
|
# Core modules used by 'apply'
|
8
8
|
mod 'puppetlabs-service', '2.0.0'
|
9
|
-
mod 'puppetlabs-puppet_agent', '4.
|
9
|
+
mod 'puppetlabs-puppet_agent', '4.7.0'
|
10
10
|
mod 'puppetlabs-facts', '1.4.0'
|
11
11
|
|
12
12
|
# Core types and providers for Puppet 6
|
13
13
|
mod 'puppetlabs-augeas_core', '1.1.2'
|
14
14
|
mod 'puppetlabs-host_core', '1.0.3'
|
15
|
-
mod 'puppetlabs-scheduled_task', '3.0.
|
15
|
+
mod 'puppetlabs-scheduled_task', '3.0.1'
|
16
16
|
mod 'puppetlabs-sshkeys_core', '2.2.0'
|
17
17
|
mod 'puppetlabs-zfs_core', '1.2.0'
|
18
18
|
mod 'puppetlabs-cron_core', '1.0.5'
|
@@ -29,14 +29,14 @@ mod 'puppetlabs-python_task_helper', '0.5.0'
|
|
29
29
|
mod 'puppetlabs-reboot', '4.0.2'
|
30
30
|
mod 'puppetlabs-ruby_task_helper', '0.6.0'
|
31
31
|
mod 'puppetlabs-ruby_plugin_helper', '0.2.0'
|
32
|
-
mod 'puppetlabs-stdlib', '7.0
|
32
|
+
mod 'puppetlabs-stdlib', '7.1.0'
|
33
33
|
|
34
34
|
# Plugin modules
|
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
38
|
mod 'puppetlabs-http_request', '0.2.2'
|
39
|
-
mod 'puppetlabs-pkcs7', '0.1.
|
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'
|
42
42
|
mod 'puppetlabs-vault', '0.4.0'
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# The [`background()` plan function](plan_functions.md#background) returns a
|
4
|
+
# `Future` object, which can be passed to the [`wait()` plan
|
5
|
+
# function](plan_functions.md#wait) to block on the result of the backgrounded
|
6
|
+
# code block.
|
7
|
+
#
|
8
|
+
# @!method state
|
9
|
+
# Either 'running' if the Future is still executing, 'done' if the Future
|
10
|
+
# finished successfully, or 'error' if the Future finished with an error.
|
11
|
+
#
|
12
|
+
Puppet::DataTypes.create_type('Future') do
|
13
|
+
interface <<-PUPPET
|
14
|
+
attributes => {},
|
15
|
+
functions => {
|
16
|
+
state => Callable[[], Enum['running', 'done', 'error']],
|
17
|
+
}
|
18
|
+
PUPPET
|
19
|
+
|
20
|
+
load_file('bolt/plan_future')
|
21
|
+
|
22
|
+
# Needed for Puppet to recognize Bolt::Result as a Puppet object when deserializing
|
23
|
+
Bolt::PlanFuture.include(Puppet::Pops::Types::PuppetObject)
|
24
|
+
implementation_class Bolt::PlanFuture
|
25
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Starts a block of code in parallel with the main plan without blocking.
|
4
|
+
# Returns a Future object.
|
5
|
+
#
|
6
|
+
# > **Note:** Not available in apply block
|
7
|
+
Puppet::Functions.create_function(:background, Puppet::Functions::InternalFunction) do
|
8
|
+
# Starts a block of code in parallel with the main plan without blocking.
|
9
|
+
# Returns a Future object.
|
10
|
+
# @param name An optional name for legible logs.
|
11
|
+
# @param block The code block to run in the background.
|
12
|
+
# @return A Bolt Future object
|
13
|
+
# @example Start a long-running process
|
14
|
+
# background() || {
|
15
|
+
# run_task('superlong::task', $targets)
|
16
|
+
# }
|
17
|
+
# run_command("echo 'Continue immediately'", $targets)
|
18
|
+
dispatch :background do
|
19
|
+
scope_param
|
20
|
+
optional_param 'String[1]', :name
|
21
|
+
block_param 'Callable[0, 0]', :block
|
22
|
+
return_type 'Future'
|
23
|
+
end
|
24
|
+
|
25
|
+
def background(scope, name = nil, &block)
|
26
|
+
unless Puppet[:tasks]
|
27
|
+
raise Puppet::ParseErrorWithIssue
|
28
|
+
.from_issue_and_stack(Bolt::PAL::Issues::PLAN_OPERATION_NOT_SUPPORTED_WHEN_COMPILING, action: 'background')
|
29
|
+
end
|
30
|
+
|
31
|
+
executor = Puppet.lookup(:bolt_executor)
|
32
|
+
executor.report_function_call(self.class.name)
|
33
|
+
|
34
|
+
executor.create_future(scope: scope, name: name) do |newscope|
|
35
|
+
# Catch 'return' calls inside the block
|
36
|
+
result = catch(:return) do
|
37
|
+
# Execute the block. Individual plan steps in the block will yield
|
38
|
+
# the Fiber if they haven't finished, so all this needs to do is run
|
39
|
+
# the block.
|
40
|
+
block.closure.call_by_name_with_scope(newscope, {}, true)
|
41
|
+
end
|
42
|
+
|
43
|
+
# If we got a return from the block, get its value
|
44
|
+
# Otherwise the result is the last line from the block
|
45
|
+
result = result.value if result.is_a?(Puppet::Pops::Evaluator::Return)
|
46
|
+
|
47
|
+
# Validate the result is a PlanResult
|
48
|
+
unless Puppet::Pops::Types::TypeParser.singleton.parse('Boltlib::PlanResult').instance?(result)
|
49
|
+
raise Bolt::InvalidParallelResult.new(result.to_s, *Puppet::Pops::PuppetStack.top_of_stack)
|
50
|
+
end
|
51
|
+
|
52
|
+
result
|
53
|
+
rescue Puppet::PreformattedError => e
|
54
|
+
if e.cause.is_a?(Bolt::Error)
|
55
|
+
e.cause
|
56
|
+
else
|
57
|
+
raise e
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -112,17 +112,13 @@ 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
|
Bolt::ResultSet.new([])
|
114
114
|
else
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
executor.download_file(targets, source, destination, options, Puppet::Pops::PuppetStack.top_of_stack)
|
115
|
+
file_line = Puppet::Pops::PuppetStack.top_of_stack
|
116
|
+
r = if executor.in_parallel?
|
117
|
+
executor.run_in_thread do
|
118
|
+
executor.download_file(targets, source, destination, options, file_line)
|
120
119
|
end
|
121
|
-
|
122
|
-
Fiber.yield('unfinished') while future.incomplete?
|
123
|
-
future.value || future.reason
|
124
120
|
else
|
125
|
-
executor.download_file(targets, source, destination, options,
|
121
|
+
executor.download_file(targets, source, destination, options, file_line)
|
126
122
|
end
|
127
123
|
|
128
124
|
if !r.ok && !options[:catch_errors]
|
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'bolt/yarn'
|
4
|
-
|
5
3
|
# Map a code block onto an array, where each array element executes in parallel.
|
6
4
|
# This function is experimental.
|
7
5
|
#
|
@@ -35,21 +33,38 @@ Puppet::Functions.create_function(:parallelize, Puppet::Functions::InternalFunct
|
|
35
33
|
executor = Puppet.lookup(:bolt_executor)
|
36
34
|
executor.report_function_call(self.class.name)
|
37
35
|
|
38
|
-
|
39
|
-
executor.
|
40
|
-
|
36
|
+
futures = data.map do |object|
|
37
|
+
executor.create_future(scope: scope) do |newscope|
|
38
|
+
# Catch 'return' calls inside the block
|
39
|
+
result = catch(:return) do
|
40
|
+
# Add the object to the block parameters
|
41
|
+
args = { block.parameters[0][1].to_s => object }
|
42
|
+
# Execute the block. Individual plan steps in the block will yield
|
43
|
+
# the Fiber if they haven't finished, so all this needs to do is run
|
44
|
+
# the block.
|
45
|
+
block.closure.call_by_name_with_scope(newscope, args, true)
|
46
|
+
end
|
41
47
|
|
42
|
-
|
48
|
+
# If we got a return from the block, get its value
|
49
|
+
# Otherwise the result is the last line from the block
|
50
|
+
result = result.value if result.is_a?(Puppet::Pops::Evaluator::Return)
|
43
51
|
|
44
|
-
|
45
|
-
|
46
|
-
|
52
|
+
# Validate the result is a PlanResult
|
53
|
+
unless Puppet::Pops::Types::TypeParser.singleton.parse('Boltlib::PlanResult').instance?(result)
|
54
|
+
raise Bolt::InvalidParallelResult.new(result.to_s, *Puppet::Pops::PuppetStack.top_of_stack)
|
55
|
+
end
|
47
56
|
|
48
|
-
|
49
|
-
|
50
|
-
|
57
|
+
result
|
58
|
+
rescue Puppet::PreformattedError => e
|
59
|
+
if e.cause.is_a?(Bolt::Error)
|
60
|
+
e.cause
|
61
|
+
else
|
62
|
+
raise e
|
63
|
+
end
|
64
|
+
end
|
51
65
|
end
|
52
66
|
|
53
|
-
|
67
|
+
# We may eventually want parallelize to accept a timeout
|
68
|
+
executor.wait(futures)
|
54
69
|
end
|
55
70
|
end
|
@@ -87,23 +87,13 @@ Puppet::Functions.create_function(:run_command) do
|
|
87
87
|
call_function('debug', "Simulating run_command('#{command}') - no targets given - no action taken")
|
88
88
|
Bolt::ResultSet.new([])
|
89
89
|
else
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
executor.run_command(targets,
|
95
|
-
command,
|
96
|
-
options,
|
97
|
-
Puppet::Pops::PuppetStack.top_of_stack)
|
90
|
+
file_line = Puppet::Pops::PuppetStack.top_of_stack
|
91
|
+
r = if executor.in_parallel?
|
92
|
+
executor.run_in_thread do
|
93
|
+
executor.run_command(targets, command, options, file_line)
|
98
94
|
end
|
99
|
-
|
100
|
-
Fiber.yield('unfinished') while future.incomplete?
|
101
|
-
future.value || future.reason
|
102
95
|
else
|
103
|
-
executor.run_command(targets,
|
104
|
-
command,
|
105
|
-
options,
|
106
|
-
Puppet::Pops::PuppetStack.top_of_stack)
|
96
|
+
executor.run_command(targets, command, options, file_line)
|
107
97
|
end
|
108
98
|
|
109
99
|
if !r.ok && !options[:catch_errors]
|
@@ -130,25 +130,13 @@ Puppet::Functions.create_function(:run_script, Puppet::Functions::InternalFuncti
|
|
130
130
|
if targets.empty?
|
131
131
|
Bolt::ResultSet.new([])
|
132
132
|
else
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
executor.run_script(targets,
|
138
|
-
found,
|
139
|
-
arguments,
|
140
|
-
options,
|
141
|
-
Puppet::Pops::PuppetStack.top_of_stack)
|
133
|
+
file_line = Puppet::Pops::PuppetStack.top_of_stack
|
134
|
+
r = if executor.in_parallel?
|
135
|
+
executor.run_in_thread do
|
136
|
+
executor.run_script(targets, found, arguments, options, file_line)
|
142
137
|
end
|
143
|
-
|
144
|
-
Fiber.yield('unfinished') while future.incomplete?
|
145
|
-
future.value || future.reason
|
146
138
|
else
|
147
|
-
executor.run_script(targets,
|
148
|
-
found,
|
149
|
-
arguments,
|
150
|
-
options,
|
151
|
-
Puppet::Pops::PuppetStack.top_of_stack)
|
139
|
+
executor.run_script(targets, found, arguments, options, file_line)
|
152
140
|
end
|
153
141
|
|
154
142
|
if !r.ok && !options[:catch_errors]
|
@@ -130,28 +130,19 @@ Puppet::Functions.create_function(:run_task) do
|
|
130
130
|
end
|
131
131
|
end
|
132
132
|
|
133
|
+
# Report whether the task was run in noop mode.
|
134
|
+
executor.report_noop_mode(executor.noop || options[:noop])
|
135
|
+
|
133
136
|
if targets.empty?
|
134
137
|
Bolt::ResultSet.new([])
|
135
138
|
else
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
executor.run_task(targets,
|
141
|
-
task,
|
142
|
-
params,
|
143
|
-
options,
|
144
|
-
Puppet::Pops::PuppetStack.top_of_stack)
|
139
|
+
file_line = Puppet::Pops::PuppetStack.top_of_stack
|
140
|
+
result = if executor.in_parallel?
|
141
|
+
executor.run_in_thread do
|
142
|
+
executor.run_task(targets, task, params, options, file_line)
|
145
143
|
end
|
146
|
-
|
147
|
-
Fiber.yield('unfinished') while future.incomplete?
|
148
|
-
future.value || future.reason
|
149
144
|
else
|
150
|
-
executor.run_task(targets,
|
151
|
-
task,
|
152
|
-
params,
|
153
|
-
options,
|
154
|
-
Puppet::Pops::PuppetStack.top_of_stack)
|
145
|
+
executor.run_task(targets, task, params, options, file_line)
|
155
146
|
end
|
156
147
|
|
157
148
|
if !result.ok && !options[:catch_errors]
|
@@ -175,28 +175,21 @@ Puppet::Functions.create_function(:run_task_with) do
|
|
175
175
|
end
|
176
176
|
end
|
177
177
|
|
178
|
+
# Report whether the task was run in noop mode.
|
179
|
+
executor.report_noop_mode(executor.noop || options[:noop])
|
180
|
+
|
178
181
|
if targets.empty?
|
179
182
|
Bolt::ResultSet.new([])
|
180
183
|
else
|
181
184
|
# Combine the results from the task run with any failing results that were
|
182
185
|
# generated earlier when creating the target mapping
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
executor.run_task_with(target_mapping,
|
188
|
-
task,
|
189
|
-
options,
|
190
|
-
Puppet::Pops::PuppetStack.top_of_stack)
|
186
|
+
file_line = Puppet::Pops::PuppetStack.top_of_stack
|
187
|
+
task_result = if executor.in_parallel?
|
188
|
+
executor.run_in_thread do
|
189
|
+
executor.run_task_with(target_mapping, task, options, file_line)
|
191
190
|
end
|
192
|
-
|
193
|
-
Fiber.yield('unfinished') while future.incomplete?
|
194
|
-
future.value || future.reason
|
195
191
|
else
|
196
|
-
executor.run_task_with(target_mapping,
|
197
|
-
task,
|
198
|
-
options,
|
199
|
-
Puppet::Pops::PuppetStack.top_of_stack)
|
192
|
+
executor.run_task_with(target_mapping, task, options, file_line)
|
200
193
|
end
|
201
194
|
result = Bolt::ResultSet.new(task_result.results + error_set)
|
202
195
|
|
@@ -87,25 +87,13 @@ Puppet::Functions.create_function(:upload_file, Puppet::Functions::InternalFunct
|
|
87
87
|
call_function('debug', "Simulating file upload of '#{found}' - no targets given - no action taken")
|
88
88
|
Bolt::ResultSet.new([])
|
89
89
|
else
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
executor.upload_file(targets,
|
95
|
-
found,
|
96
|
-
destination,
|
97
|
-
options,
|
98
|
-
Puppet::Pops::PuppetStack.top_of_stack)
|
90
|
+
file_line = Puppet::Pops::PuppetStack.top_of_stack
|
91
|
+
r = if executor.in_parallel?
|
92
|
+
executor.run_in_thread do
|
93
|
+
executor.upload_file(targets, found, destination, options, file_line)
|
99
94
|
end
|
100
|
-
|
101
|
-
Fiber.yield('unfinished') while future.incomplete?
|
102
|
-
future.value || future.reason
|
103
95
|
else
|
104
|
-
executor.upload_file(targets,
|
105
|
-
found,
|
106
|
-
destination,
|
107
|
-
options,
|
108
|
-
Puppet::Pops::PuppetStack.top_of_stack)
|
96
|
+
executor.upload_file(targets, found, destination, options, file_line)
|
109
97
|
end
|
110
98
|
if !r.ok && !options[:catch_errors]
|
111
99
|
raise Bolt::RunFailure.new(r, 'upload_file', source)
|
@@ -0,0 +1,91 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bolt/logger'
|
4
|
+
require 'bolt/target'
|
5
|
+
|
6
|
+
# Wait for a Future or array of Futures to finish and return results,
|
7
|
+
# optionally with a timeout.
|
8
|
+
#
|
9
|
+
# > **Note:** Not available in apply block
|
10
|
+
Puppet::Functions.create_function(:wait, Puppet::Functions::InternalFunction) do
|
11
|
+
# Wait for Future(s) to finish
|
12
|
+
# @param futures A Bolt Future object or array of Bolt Futures to wait on.
|
13
|
+
# @param options A hash of additional options.
|
14
|
+
# @option options [Boolean] _catch_errors Whether to catch raised errors.
|
15
|
+
# @return A Result or Results from the Futures
|
16
|
+
# @example Upload a large file in the background, then wait until it's loaded
|
17
|
+
# $futures = background() || {
|
18
|
+
# upload_file("./very_large_file", "/opt/jfrog/artifactory/var/etc/artifactory", $targets)
|
19
|
+
# }
|
20
|
+
# # Run an unrelated task
|
21
|
+
# run_task("deploy", $targets)
|
22
|
+
# # Wait for the file upload to finish
|
23
|
+
# $results = wait($futures)
|
24
|
+
dispatch :wait do
|
25
|
+
param 'Variant[Future, Array[Future]]', :futures
|
26
|
+
optional_param 'Hash[String[1], Any]', :options
|
27
|
+
return_type 'Array[Boltlib::PlanResult]'
|
28
|
+
end
|
29
|
+
|
30
|
+
# Wait for Future(s) to finish with timeout
|
31
|
+
# @param futures A Bolt Future object or array of Bolt Futures to wait on.
|
32
|
+
# @param timeout How long to wait for Futures to finish before raising a Timeout error.
|
33
|
+
# @param options A hash of additional options.
|
34
|
+
# @option options [Boolean] _catch_errors Whether to catch raised errors.
|
35
|
+
# @return A Result or Results from the Futures
|
36
|
+
# @example Upload a large file in the background with a 30 second timeout.
|
37
|
+
# $futures = background() || {
|
38
|
+
# upload_file("./very_large_file", "/opt/jfrog/artifactory/var/etc/artifactory", $targets)
|
39
|
+
# }
|
40
|
+
# # Run an unrelated task
|
41
|
+
# run_task("deploy", $targets)
|
42
|
+
# # Wait for the file upload to finish
|
43
|
+
# $results = wait($futures, 30)
|
44
|
+
#
|
45
|
+
# @example Upload a large file in the background with a 30 second timeout, catching any errors.
|
46
|
+
# $futures = background() || {
|
47
|
+
# upload_file("./very_large_file", "/opt/jfrog/artifactory/var/etc/artifactory", $targets)
|
48
|
+
# }
|
49
|
+
# # Run an unrelated task
|
50
|
+
# run_task("deploy", $targets)
|
51
|
+
# # Wait for the file upload to finish
|
52
|
+
# $results = wait($futures, 30, '_catch_errors' => true)
|
53
|
+
dispatch :wait_with_timeout do
|
54
|
+
param 'Variant[Future, Array[Future]]', :futures
|
55
|
+
param 'Variant[Integer[0], Float[0.0]]', :timeout
|
56
|
+
optional_param 'Hash[String[1], Any]', :options
|
57
|
+
return_type 'Array[Boltlib::PlanResult]'
|
58
|
+
end
|
59
|
+
|
60
|
+
def wait(futures, options = {})
|
61
|
+
inner_wait(futures, nil, options)
|
62
|
+
end
|
63
|
+
|
64
|
+
def wait_with_timeout(futures, timeout, options = {})
|
65
|
+
inner_wait(futures, timeout, options)
|
66
|
+
end
|
67
|
+
|
68
|
+
def inner_wait(futures, timeout = nil, options = {})
|
69
|
+
unless Puppet[:tasks]
|
70
|
+
raise Puppet::ParseErrorWithIssue
|
71
|
+
.from_issue_and_stack(Bolt::PAL::Issues::PLAN_OPERATION_NOT_SUPPORTED_WHEN_COMPILING, action: 'wait')
|
72
|
+
end
|
73
|
+
|
74
|
+
valid, unknown = options.partition { |k, _v| %w[_catch_errors].include?(k) }.map(&:to_h)
|
75
|
+
if unknown.any?
|
76
|
+
file, line = Puppet::Pops::PuppetStack.top_of_stack
|
77
|
+
msg = "The wait() function call in #{file}#L#{line} received unknown options "\
|
78
|
+
"#{unknown.keys}. Removing unknown options and continuing..."
|
79
|
+
Bolt::Logger.warn("plan_function_options", msg)
|
80
|
+
end
|
81
|
+
|
82
|
+
valid = valid.transform_keys { |k| k.sub(/^_/, '').to_sym }
|
83
|
+
valid[:timeout] = timeout if timeout
|
84
|
+
|
85
|
+
executor = Puppet.lookup(:bolt_executor)
|
86
|
+
executor.report_function_call(self.class.name)
|
87
|
+
|
88
|
+
futures = Array(futures)
|
89
|
+
executor.wait(futures, **valid)
|
90
|
+
end
|
91
|
+
end
|