bolt 3.6.1 → 3.9.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 +3 -3
- data/bolt-modules/boltlib/lib/puppet/datatypes/applyresult.rb +26 -0
- data/bolt-modules/boltlib/lib/puppet/datatypes/containerresult.rb +27 -0
- data/bolt-modules/boltlib/lib/puppet/datatypes/future.rb +25 -0
- data/bolt-modules/boltlib/lib/puppet/datatypes/resourceinstance.rb +43 -0
- data/bolt-modules/boltlib/lib/puppet/datatypes/result.rb +29 -0
- data/bolt-modules/boltlib/lib/puppet/datatypes/resultset.rb +34 -0
- data/bolt-modules/boltlib/lib/puppet/datatypes/target.rb +55 -0
- data/bolt-modules/boltlib/lib/puppet/functions/add_to_group.rb +1 -0
- data/bolt-modules/boltlib/lib/puppet/functions/apply_prep.rb +10 -6
- 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 +29 -13
- data/bolt-modules/boltlib/lib/puppet/functions/puppetdb_command.rb +66 -0
- data/bolt-modules/boltlib/lib/puppet/functions/remove_from_group.rb +1 -0
- data/bolt-modules/boltlib/lib/puppet/functions/run_command.rb +5 -15
- data/bolt-modules/boltlib/lib/puppet/functions/run_script.rb +10 -18
- data/bolt-modules/boltlib/lib/puppet/functions/run_task.rb +5 -17
- data/bolt-modules/boltlib/lib/puppet/functions/run_task_with.rb +5 -15
- data/bolt-modules/boltlib/lib/puppet/functions/upload_file.rb +10 -18
- data/bolt-modules/boltlib/lib/puppet/functions/wait.rb +91 -0
- data/bolt-modules/boltlib/lib/puppet/functions/write_file.rb +1 -0
- data/bolt-modules/boltlib/types/planresult.pp +1 -0
- data/bolt-modules/ctrl/lib/puppet/functions/ctrl/do_until.rb +2 -0
- data/bolt-modules/file/lib/puppet/functions/file/exists.rb +9 -3
- data/bolt-modules/file/lib/puppet/functions/file/read.rb +6 -2
- data/bolt-modules/file/lib/puppet/functions/file/readable.rb +8 -3
- data/guides/guide.txt +17 -0
- data/guides/inventory.txt +5 -0
- data/guides/links.txt +13 -0
- data/guides/targets.txt +29 -0
- data/guides/transports.txt +23 -0
- data/lib/bolt/applicator.rb +4 -3
- data/lib/bolt/bolt_option_parser.rb +353 -227
- data/lib/bolt/catalog.rb +2 -1
- data/lib/bolt/cli.rb +94 -36
- data/lib/bolt/config/options.rb +2 -1
- data/lib/bolt/config/transport/docker.rb +5 -1
- data/lib/bolt/config/transport/lxd.rb +1 -1
- data/lib/bolt/config/transport/options.rb +2 -1
- data/lib/bolt/config/transport/podman.rb +5 -1
- data/lib/bolt/error.rb +11 -1
- data/lib/bolt/executor.rb +51 -72
- data/lib/bolt/fiber_executor.rb +141 -0
- data/lib/bolt/inventory.rb +5 -4
- data/lib/bolt/inventory/inventory.rb +3 -2
- data/lib/bolt/logger.rb +1 -1
- data/lib/bolt/module_installer/specs.rb +1 -1
- data/lib/bolt/module_installer/specs/git_spec.rb +10 -6
- data/lib/bolt/outputter/human.rb +59 -29
- data/lib/bolt/outputter/json.rb +8 -4
- data/lib/bolt/pal.rb +64 -3
- data/lib/bolt/pal/yaml_plan/step.rb +4 -2
- data/lib/bolt/plan_creator.rb +2 -2
- data/lib/bolt/plan_future.rb +66 -0
- data/lib/bolt/puppetdb/client.rb +54 -0
- data/lib/bolt/result.rb +5 -0
- data/lib/bolt/transport/docker/connection.rb +7 -4
- data/lib/bolt/transport/lxd/connection.rb +4 -0
- data/lib/bolt/transport/podman/connection.rb +4 -0
- data/lib/bolt/transport/ssh/connection.rb +3 -6
- data/lib/bolt/util.rb +73 -1
- data/lib/bolt/version.rb +1 -1
- data/lib/bolt_spec/plans/mock_executor.rb +42 -45
- metadata +12 -3
- data/lib/bolt/yarn.rb +0 -23
data/lib/bolt/catalog.rb
CHANGED
@@ -65,7 +65,8 @@ module Bolt
|
|
65
65
|
puppet_overrides = {
|
66
66
|
bolt_pdb_client: pdb_client,
|
67
67
|
bolt_inventory: inv,
|
68
|
-
bolt_project: bolt_project
|
68
|
+
bolt_project: bolt_project,
|
69
|
+
future: request['future']
|
69
70
|
}
|
70
71
|
|
71
72
|
# Facts will be set by the catalog compiler, so we need to ensure
|
data/lib/bolt/cli.rb
CHANGED
@@ -33,20 +33,23 @@ module Bolt
|
|
33
33
|
|
34
34
|
class CLI
|
35
35
|
COMMANDS = {
|
36
|
-
'
|
37
|
-
'
|
38
|
-
'
|
39
|
-
'
|
40
|
-
'
|
41
|
-
'secret' => %w[encrypt decrypt createkeys],
|
36
|
+
'apply' => %w[],
|
37
|
+
'command' => %w[run],
|
38
|
+
'file' => %w[download upload],
|
39
|
+
'group' => %w[show],
|
40
|
+
'guide' => %w[],
|
42
41
|
'inventory' => %w[show],
|
43
|
-
'
|
44
|
-
'
|
45
|
-
'
|
46
|
-
'
|
47
|
-
'
|
42
|
+
'lookup' => %w[],
|
43
|
+
'module' => %w[add generate-types install show],
|
44
|
+
'plan' => %w[show run convert new],
|
45
|
+
'project' => %w[init migrate],
|
46
|
+
'script' => %w[run],
|
47
|
+
'secret' => %w[encrypt decrypt createkeys],
|
48
|
+
'task' => %w[show run]
|
48
49
|
}.freeze
|
49
50
|
|
51
|
+
TARGETING_OPTIONS = %i[query rerun targets].freeze
|
52
|
+
|
50
53
|
attr_reader :config, :options
|
51
54
|
|
52
55
|
def initialize(argv)
|
@@ -150,7 +153,6 @@ module Bolt
|
|
150
153
|
options[:subcommand] = nil unless COMMANDS.include?(options[:subcommand])
|
151
154
|
|
152
155
|
if Bolt::Util.first_run?
|
153
|
-
FileUtils.mkdir_p(Bolt::Util.first_runs_free.dirname)
|
154
156
|
FileUtils.touch(Bolt::Util.first_runs_free)
|
155
157
|
|
156
158
|
if options[:subcommand].nil? && $stdout.isatty
|
@@ -262,7 +264,7 @@ module Bolt
|
|
262
264
|
end
|
263
265
|
|
264
266
|
def update_targets(options)
|
265
|
-
target_opts = options.keys.select { |opt|
|
267
|
+
target_opts = options.keys.select { |opt| TARGETING_OPTIONS.include?(opt) }
|
266
268
|
target_string = "'--targets', '--rerun', or '--query'"
|
267
269
|
if target_opts.length > 1
|
268
270
|
raise Bolt::CLIError, "Only one targeting option #{target_string} can be specified"
|
@@ -324,6 +326,10 @@ module Bolt
|
|
324
326
|
raise Bolt::CLIError, "a manifest file or --execute is required"
|
325
327
|
end
|
326
328
|
|
329
|
+
if options[:subcommand] == 'lookup' && !options[:object]
|
330
|
+
raise Bolt::CLIError, "Must specify a key to look up"
|
331
|
+
end
|
332
|
+
|
327
333
|
if options[:subcommand] == 'command' && (!options[:object] || options[:object].empty?)
|
328
334
|
raise Bolt::CLIError, "Must specify a command to run"
|
329
335
|
end
|
@@ -509,6 +515,8 @@ module Bolt
|
|
509
515
|
when 'migrate'
|
510
516
|
code = Bolt::ProjectManager.new(config, outputter, pal).migrate
|
511
517
|
end
|
518
|
+
when 'lookup'
|
519
|
+
code = lookup(options[:object], options[:targets])
|
512
520
|
when 'plan'
|
513
521
|
case options[:action]
|
514
522
|
when 'new'
|
@@ -561,7 +569,8 @@ module Bolt
|
|
561
569
|
when 'command'
|
562
570
|
executor.run_command(targets, options[:object], executor_opts)
|
563
571
|
when 'script'
|
564
|
-
script_path = find_file(options[:object])
|
572
|
+
script_path = find_file(options[:object], executor.future&.fetch('file_paths', false))
|
573
|
+
validate_file('script', script_path)
|
565
574
|
executor.run_script(targets, script_path, options[:leftovers], executor_opts)
|
566
575
|
when 'task'
|
567
576
|
pal.run_task(options[:object],
|
@@ -586,8 +595,9 @@ module Bolt
|
|
586
595
|
dest = File.expand_path(dest, Dir.pwd)
|
587
596
|
executor.download_file(targets, src, dest, executor_opts)
|
588
597
|
when 'upload'
|
589
|
-
|
590
|
-
|
598
|
+
src_path = find_file(src, executor.future&.fetch('file_paths', false))
|
599
|
+
validate_file('source file', src_path, true)
|
600
|
+
executor.upload_file(targets, src_path, dest, executor_opts)
|
591
601
|
end
|
592
602
|
end
|
593
603
|
end
|
@@ -634,13 +644,33 @@ module Bolt
|
|
634
644
|
end
|
635
645
|
|
636
646
|
def list_targets
|
637
|
-
|
638
|
-
|
647
|
+
if options.keys.any? { |key| TARGETING_OPTIONS.include?(key) }
|
648
|
+
target_flag = true
|
649
|
+
else
|
650
|
+
options[:targets] = 'all'
|
651
|
+
end
|
652
|
+
|
653
|
+
outputter.print_targets(
|
654
|
+
group_targets_by_source,
|
655
|
+
inventory.source,
|
656
|
+
config.default_inventoryfile,
|
657
|
+
target_flag
|
658
|
+
)
|
639
659
|
end
|
640
660
|
|
641
661
|
def show_targets
|
642
|
-
|
643
|
-
|
662
|
+
if options.keys.any? { |key| TARGETING_OPTIONS.include?(key) }
|
663
|
+
target_flag = true
|
664
|
+
else
|
665
|
+
options[:targets] = 'all'
|
666
|
+
end
|
667
|
+
|
668
|
+
outputter.print_target_info(
|
669
|
+
group_targets_by_source,
|
670
|
+
inventory.source,
|
671
|
+
config.default_inventoryfile,
|
672
|
+
target_flag
|
673
|
+
)
|
644
674
|
end
|
645
675
|
|
646
676
|
# Returns a hash of targets sorted by those that are found in the
|
@@ -661,8 +691,39 @@ module Bolt
|
|
661
691
|
end
|
662
692
|
|
663
693
|
def list_groups
|
664
|
-
|
665
|
-
|
694
|
+
outputter.print_groups(inventory.group_names.sort, inventory.source, config.default_inventoryfile)
|
695
|
+
end
|
696
|
+
|
697
|
+
# Looks up a value with Hiera, using targets as the contexts to perform the
|
698
|
+
# look ups in.
|
699
|
+
#
|
700
|
+
def lookup(key, targets)
|
701
|
+
executor = Bolt::Executor.new(
|
702
|
+
config.concurrency,
|
703
|
+
analytics,
|
704
|
+
options[:noop],
|
705
|
+
config.modified_concurrency,
|
706
|
+
config.future
|
707
|
+
)
|
708
|
+
|
709
|
+
executor.subscribe(outputter) if options.fetch(:format, 'human') == 'human'
|
710
|
+
executor.subscribe(log_outputter)
|
711
|
+
executor.publish_event(type: :plan_start, plan: nil)
|
712
|
+
|
713
|
+
results = outputter.spin do
|
714
|
+
pal.lookup(
|
715
|
+
key,
|
716
|
+
targets,
|
717
|
+
inventory,
|
718
|
+
executor,
|
719
|
+
config.concurrency
|
720
|
+
)
|
721
|
+
end
|
722
|
+
|
723
|
+
executor.shutdown
|
724
|
+
outputter.print_result_set(results)
|
725
|
+
|
726
|
+
results.ok ? 0 : 1
|
666
727
|
end
|
667
728
|
|
668
729
|
def run_plan(plan_name, plan_arguments, nodes, options)
|
@@ -871,7 +932,7 @@ module Bolt
|
|
871
932
|
|
872
933
|
# Display the list of available Bolt guides.
|
873
934
|
def list_topics
|
874
|
-
outputter.print_topics(guides.keys)
|
935
|
+
outputter.print_topics(guides.keys - ['guide'])
|
875
936
|
0
|
876
937
|
end
|
877
938
|
|
@@ -908,20 +969,17 @@ module Bolt
|
|
908
969
|
# the path is a Puppet file path and looks for the file in a module's files
|
909
970
|
# directory.
|
910
971
|
#
|
911
|
-
def find_file(path)
|
912
|
-
|
913
|
-
|
914
|
-
|
915
|
-
|
916
|
-
|
917
|
-
|
918
|
-
|
919
|
-
|
920
|
-
|
972
|
+
def find_file(path, future_file_paths)
|
973
|
+
return path if File.exist?(path) || Pathname.new(path).absolute?
|
974
|
+
modulepath = Bolt::Config::Modulepath.new(config.modulepath)
|
975
|
+
modules = Bolt::Module.discover(modulepath.full_modulepath, config.project)
|
976
|
+
mod, file = path.split(File::SEPARATOR, 2)
|
977
|
+
|
978
|
+
if modules[mod]
|
979
|
+
@logger.debug("Did not find file at #{File.expand_path(path)}, checking in module '#{mod}'")
|
980
|
+
found = Bolt::Util.find_file_in_module(modules[mod].path, file || "", future_file_paths)
|
981
|
+
path = found.nil? ? File.join(modules[mod].path, 'files', file) : found
|
921
982
|
end
|
922
|
-
|
923
|
-
Bolt::Util.validate_file('script', path)
|
924
|
-
|
925
983
|
path
|
926
984
|
end
|
927
985
|
|
data/lib/bolt/config/options.rb
CHANGED
@@ -279,7 +279,8 @@ module Bolt
|
|
279
279
|
"modules" => {
|
280
280
|
description: "A list of module dependencies for the project. Each dependency is a map of data specifying "\
|
281
281
|
"the module to install. To install the project's module dependencies, run the `bolt module "\
|
282
|
-
"install` command."
|
282
|
+
"install` command. For more information about specifying modules, see [the "\
|
283
|
+
"documentation](https://pup.pt/bolt-module-specs).",
|
283
284
|
type: Array,
|
284
285
|
items: {
|
285
286
|
type: [Hash, String],
|
@@ -15,7 +15,7 @@ module Bolt
|
|
15
15
|
shell-command
|
16
16
|
tmpdir
|
17
17
|
tty
|
18
|
-
].freeze
|
18
|
+
].concat(RUN_AS_OPTIONS).sort.freeze
|
19
19
|
|
20
20
|
DEFAULTS = {
|
21
21
|
'cleanup' => true
|
@@ -27,6 +27,10 @@ module Bolt
|
|
27
27
|
if @config['interpreters']
|
28
28
|
@config['interpreters'] = normalize_interpreters(@config['interpreters'])
|
29
29
|
end
|
30
|
+
|
31
|
+
if Bolt::Util.windows? && @config['run-as']
|
32
|
+
raise Bolt::ValidationError, "run-as is not supported when using PowerShell"
|
33
|
+
end
|
30
34
|
end
|
31
35
|
end
|
32
36
|
end
|
@@ -235,7 +235,8 @@ module Bolt
|
|
235
235
|
"private-key" => {
|
236
236
|
type: [Hash, String],
|
237
237
|
description: "Either the path to the private key file to use for authentication, or "\
|
238
|
-
|
238
|
+
"a hash with the key `key-data` and the contents of the private key. Note that "\
|
239
|
+
"the key cannot be encrypted if using the `key-data` hash.",
|
239
240
|
required: ["key-data"],
|
240
241
|
properties: {
|
241
242
|
"key-data" => {
|
@@ -14,7 +14,7 @@ module Bolt
|
|
14
14
|
shell-command
|
15
15
|
tmpdir
|
16
16
|
tty
|
17
|
-
].freeze
|
17
|
+
].concat(RUN_AS_OPTIONS).sort.freeze
|
18
18
|
|
19
19
|
DEFAULTS = {
|
20
20
|
'cleanup' => true
|
@@ -26,6 +26,10 @@ module Bolt
|
|
26
26
|
if @config['interpreters']
|
27
27
|
@config['interpreters'] = normalize_interpreters(@config['interpreters'])
|
28
28
|
end
|
29
|
+
|
30
|
+
if Bolt::Util.windows? && @config['run-as']
|
31
|
+
raise Bolt::ValidationError, "run-as is not supported when using PowerShell"
|
32
|
+
end
|
29
33
|
end
|
30
34
|
end
|
31
35
|
end
|
data/lib/bolt/error.rb
CHANGED
@@ -105,6 +105,16 @@ module Bolt
|
|
105
105
|
end
|
106
106
|
end
|
107
107
|
|
108
|
+
class FutureTimeoutError < Bolt::Error
|
109
|
+
def initialize(name, timeout)
|
110
|
+
details = {
|
111
|
+
'future' => name
|
112
|
+
}
|
113
|
+
message = "Future '#{name}' timed out after #{timeout} seconds."
|
114
|
+
super(message, 'bolt/future-timeout-error', details)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
108
118
|
class ParallelFailure < Bolt::Error
|
109
119
|
def initialize(results, failed_indices)
|
110
120
|
details = {
|
@@ -162,7 +172,7 @@ module Bolt
|
|
162
172
|
|
163
173
|
class InvalidParallelResult < Error
|
164
174
|
def initialize(result_str, file, line)
|
165
|
-
super("
|
175
|
+
super("Background block returned an invalid result: #{result_str}",
|
166
176
|
'bolt/invalid-plan-result',
|
167
177
|
{ 'file' => file,
|
168
178
|
'line' => line,
|
data/lib/bolt/executor.rb
CHANGED
@@ -7,10 +7,11 @@ require 'logging'
|
|
7
7
|
require 'pathname'
|
8
8
|
require 'set'
|
9
9
|
require 'bolt/analytics'
|
10
|
-
require 'bolt/result'
|
11
10
|
require 'bolt/config'
|
12
|
-
require 'bolt/
|
11
|
+
require 'bolt/fiber_executor'
|
13
12
|
require 'bolt/puppetdb'
|
13
|
+
require 'bolt/result'
|
14
|
+
require 'bolt/result_set'
|
14
15
|
# Load transports
|
15
16
|
require 'bolt/transport/docker'
|
16
17
|
require 'bolt/transport/local'
|
@@ -20,7 +21,6 @@ require 'bolt/transport/podman'
|
|
20
21
|
require 'bolt/transport/remote'
|
21
22
|
require 'bolt/transport/ssh'
|
22
23
|
require 'bolt/transport/winrm'
|
23
|
-
require 'bolt/yarn'
|
24
24
|
|
25
25
|
module Bolt
|
26
26
|
TRANSPORTS = {
|
@@ -35,7 +35,7 @@ module Bolt
|
|
35
35
|
}.freeze
|
36
36
|
|
37
37
|
class Executor
|
38
|
-
attr_reader :noop, :transports, :
|
38
|
+
attr_reader :noop, :transports, :future
|
39
39
|
attr_accessor :run_as
|
40
40
|
|
41
41
|
def initialize(concurrency = 1,
|
@@ -66,7 +66,6 @@ module Bolt
|
|
66
66
|
|
67
67
|
@noop = noop
|
68
68
|
@run_as = nil
|
69
|
-
@in_parallel = false
|
70
69
|
@future = future
|
71
70
|
@pool = if concurrency > 0
|
72
71
|
Concurrent::ThreadPoolExecutor.new(name: 'exec', max_threads: concurrency)
|
@@ -77,6 +76,7 @@ module Bolt
|
|
77
76
|
|
78
77
|
@concurrency = concurrency
|
79
78
|
@warn_concurrency = modified_concurrency
|
79
|
+
@fiber_executor = Bolt::FiberExecutor.new
|
80
80
|
end
|
81
81
|
|
82
82
|
def transport(transport)
|
@@ -373,83 +373,62 @@ module Bolt
|
|
373
373
|
plan.call_by_name_with_scope(scope, params, true)
|
374
374
|
end
|
375
375
|
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
current_scope = scope.effective_symtable(true)
|
384
|
-
until current_scope.nil?
|
385
|
-
current_scope.instance_variable_get(:@symbols)&.each_pair { |k, v| local[k] = v }
|
386
|
-
current_scope = current_scope.parent
|
387
|
-
end
|
388
|
-
newscope.push_ephemerals([local])
|
389
|
-
|
390
|
-
begin
|
391
|
-
result = catch(:return) do
|
392
|
-
args = { block.parameters[0][1].to_s => object }
|
393
|
-
block.closure.call_by_name_with_scope(newscope, args, true)
|
394
|
-
end
|
395
|
-
|
396
|
-
# If we got a return from the block, get it's value
|
397
|
-
# Otherwise the result is the last line from the block
|
398
|
-
result = result.value if result.is_a?(Puppet::Pops::Evaluator::Return)
|
376
|
+
# Call into FiberExecutor to avoid this class getting
|
377
|
+
# overloaded while also minimizing the Puppet lookups needed from plan
|
378
|
+
# functions
|
379
|
+
#
|
380
|
+
def create_future(scope: nil, name: nil, &block)
|
381
|
+
@fiber_executor.create_future(scope: scope, name: name, &block)
|
382
|
+
end
|
399
383
|
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
end
|
384
|
+
def plan_complete?
|
385
|
+
@fiber_executor.plan_complete?
|
386
|
+
end
|
404
387
|
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
e.cause
|
409
|
-
else
|
410
|
-
raise e
|
411
|
-
end
|
412
|
-
end
|
413
|
-
end
|
388
|
+
def round_robin
|
389
|
+
@fiber_executor.round_robin
|
390
|
+
end
|
414
391
|
|
415
|
-
|
392
|
+
def in_parallel?
|
393
|
+
@fiber_executor.in_parallel?
|
416
394
|
end
|
417
395
|
|
418
|
-
def
|
419
|
-
|
420
|
-
when :node_result
|
421
|
-
@thread_completed = true
|
422
|
-
end
|
396
|
+
def wait(futures, **opts)
|
397
|
+
@fiber_executor.wait(futures, **opts)
|
423
398
|
end
|
424
399
|
|
425
|
-
def
|
426
|
-
|
427
|
-
|
428
|
-
@in_parallel = true
|
429
|
-
publish_event(type: :stop_spin)
|
400
|
+
def plan_futures
|
401
|
+
@fiber_executor.plan_futures
|
402
|
+
end
|
430
403
|
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
skein.delete(yarn)
|
442
|
-
end
|
443
|
-
end
|
404
|
+
# Execute a plan function concurrently. This function accepts the executor
|
405
|
+
# function to be run and the parameters to pass to it, and returns the
|
406
|
+
# result of running the executor function.
|
407
|
+
#
|
408
|
+
def run_in_thread
|
409
|
+
require 'concurrent'
|
410
|
+
require 'fiber'
|
411
|
+
future = Concurrent::Future.execute do
|
412
|
+
yield
|
413
|
+
end
|
444
414
|
|
445
|
-
|
446
|
-
|
415
|
+
# Used to track how often we resume the same executor function
|
416
|
+
still_running = 0
|
417
|
+
# While the thread is still running
|
418
|
+
while future.incomplete?
|
419
|
+
# If the Fiber gets resumed, increment the resume tracker. This means
|
420
|
+
# the tracker starts at 1 since it needs to increment before yielding,
|
421
|
+
# since it can't yield then increment.
|
422
|
+
still_running += 1
|
423
|
+
# If the Fiber has been resumed before, still_running will be 2 or
|
424
|
+
# more. Yield different values for when the same Fiber is resumed
|
425
|
+
# multiple times and when it's resumed the first time in order to know
|
426
|
+
# if progress was made in the plan.
|
427
|
+
Fiber.yield(still_running < 2 ? :something_happened : :returned_immediately)
|
447
428
|
end
|
448
429
|
|
449
|
-
|
450
|
-
|
451
|
-
unsubscribe(self, [:node_result])
|
452
|
-
results
|
430
|
+
# Once the thread completes, return the result.
|
431
|
+
future.value || future.reason
|
453
432
|
end
|
454
433
|
|
455
434
|
class TimeoutError < RuntimeError; end
|
@@ -519,7 +498,7 @@ module Bolt
|
|
519
498
|
# coupled with the orchestrator transport since the transport behaves
|
520
499
|
# differently when a plan is running. In order to limit how much this
|
521
500
|
# pollutes the transport API we only handle the orchestrator transport here.
|
522
|
-
# Since we
|
501
|
+
# Since we call this function without resolving targets this will result
|
523
502
|
# in the orchestrator transport always being initialized during plan runs.
|
524
503
|
# For now that's ok.
|
525
504
|
#
|