bolt 3.15.0 → 3.16.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/lib/bolt/analytics.rb +2 -19
- data/lib/bolt/application.rb +620 -0
- data/lib/bolt/bolt_option_parser.rb +12 -3
- data/lib/bolt/cli.rb +592 -792
- data/lib/bolt/fiber_executor.rb +7 -3
- data/lib/bolt/outputter/human.rb +83 -32
- data/lib/bolt/outputter/json.rb +63 -38
- data/lib/bolt/plan_creator.rb +2 -20
- data/lib/bolt/plan_future.rb +11 -6
- data/lib/bolt/plan_result.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/version.rb +1 -1
- metadata +3 -3
- data/lib/bolt/secret.rb +0 -37
data/lib/bolt/fiber_executor.rb
CHANGED
@@ -52,7 +52,7 @@ module Bolt
|
|
52
52
|
# tracking which Futures to wait on when `wait()` is called without
|
53
53
|
# arguments.
|
54
54
|
@id += 1
|
55
|
-
future = Bolt::PlanFuture.new(future, @id, name: name, plan_id: plan_id)
|
55
|
+
future = Bolt::PlanFuture.new(future, @id, name: name, plan_id: plan_id, scope: newscope)
|
56
56
|
@logger.trace("Created future #{future.name}")
|
57
57
|
|
58
58
|
# Register the PlanFuture with the FiberExecutor to be executed
|
@@ -68,11 +68,15 @@ module Bolt
|
|
68
68
|
#
|
69
69
|
def round_robin
|
70
70
|
active_futures.each do |future|
|
71
|
-
# If the Fiber is still running and can be resumed, then resume it
|
71
|
+
# If the Fiber is still running and can be resumed, then resume it.
|
72
|
+
# Override Puppet's global_scope to prevent ephemerals in other scopes
|
73
|
+
# from being popped off in the wrong order due to race conditions.
|
74
|
+
# This primarily happens when running executor functions from custom
|
75
|
+
# Puppet language functions, but may happen elsewhere.
|
72
76
|
@logger.trace("Checking future '#{future.name}'")
|
73
77
|
if future.alive?
|
74
78
|
@logger.trace("Resuming future '#{future.name}'")
|
75
|
-
future.resume
|
79
|
+
Puppet.override(global_scope: future.scope) { future.resume }
|
76
80
|
end
|
77
81
|
|
78
82
|
# Once we've restarted the Fiber, check to see if it's finished again
|
data/lib/bolt/outputter/human.rb
CHANGED
@@ -310,7 +310,12 @@ module Bolt
|
|
310
310
|
)
|
311
311
|
end
|
312
312
|
|
313
|
-
|
313
|
+
# List available tasks.
|
314
|
+
#
|
315
|
+
# @param tasks [Array] A list of task names and descriptions.
|
316
|
+
# @param modulepath [Array] The modulepath.
|
317
|
+
#
|
318
|
+
def print_tasks(tasks:, modulepath:)
|
314
319
|
command = Bolt::Util.powershell? ? 'Get-BoltTask -Name <TASK NAME>' : 'bolt task show <TASK NAME>'
|
315
320
|
|
316
321
|
tasks = tasks.map do |name, description|
|
@@ -330,8 +335,11 @@ module Bolt
|
|
330
335
|
@stream.puts indent(2, "Use '#{command}' to view details and parameters for a specific task.")
|
331
336
|
end
|
332
337
|
|
333
|
-
#
|
334
|
-
|
338
|
+
# Print information about a task.
|
339
|
+
#
|
340
|
+
# @param task [Bolt::Task] The task information.
|
341
|
+
#
|
342
|
+
def print_task_info(task:)
|
335
343
|
params = (task.parameters || []).sort
|
336
344
|
|
337
345
|
info = +''
|
@@ -443,7 +451,7 @@ module Bolt
|
|
443
451
|
@stream.puts info
|
444
452
|
end
|
445
453
|
|
446
|
-
def print_plans(plans
|
454
|
+
def print_plans(plans:, modulepath:)
|
447
455
|
command = Bolt::Util.powershell? ? 'Get-BoltPlan -Name <PLAN NAME>' : 'bolt plan show <PLAN NAME>'
|
448
456
|
|
449
457
|
plans = plans.map do |name, description|
|
@@ -463,7 +471,11 @@ module Bolt
|
|
463
471
|
@stream.puts indent(2, "Use '#{command}' to view details and parameters for a specific plan.")
|
464
472
|
end
|
465
473
|
|
466
|
-
|
474
|
+
# Print available guide topics.
|
475
|
+
#
|
476
|
+
# @param topics [Array] The available topics.
|
477
|
+
#
|
478
|
+
def print_topics(topics:, **_kwargs)
|
467
479
|
info = +"#{colorize(:cyan, 'Topics')}\n"
|
468
480
|
info << indent(2, topics.join("\n"))
|
469
481
|
info << "\n\n#{colorize(:cyan, 'Additional information')}\n"
|
@@ -471,7 +483,11 @@ module Bolt
|
|
471
483
|
@stream.puts info
|
472
484
|
end
|
473
485
|
|
474
|
-
|
486
|
+
# Print the guide for the specified topic.
|
487
|
+
#
|
488
|
+
# @param guide [String] The guide.
|
489
|
+
#
|
490
|
+
def print_guide(topic:, guide:, documentation: nil, **_kwargs)
|
475
491
|
info = +"#{colorize(:cyan, topic)}\n"
|
476
492
|
info << indent(2, guide)
|
477
493
|
|
@@ -595,17 +611,17 @@ module Bolt
|
|
595
611
|
@stream.puts info
|
596
612
|
end
|
597
613
|
|
598
|
-
def print_plugin_list(
|
614
|
+
def print_plugin_list(plugins:, modulepath:)
|
599
615
|
info = +''
|
600
|
-
length =
|
616
|
+
length = plugins.values.map(&:keys).flatten.map(&:length).max + 4
|
601
617
|
|
602
|
-
|
603
|
-
next if
|
618
|
+
plugins.each do |hook, plugin|
|
619
|
+
next if plugin.empty?
|
604
620
|
next if hook == :validate_resolve_reference
|
605
621
|
|
606
622
|
info << colorize(:cyan, "#{hook}\n")
|
607
623
|
|
608
|
-
|
624
|
+
plugin.each do |name, description|
|
609
625
|
info << indent(2, name.ljust(length))
|
610
626
|
info << truncate(description, 80 - length) if description
|
611
627
|
info << "\n"
|
@@ -623,12 +639,37 @@ module Bolt
|
|
623
639
|
@stream.puts info.chomp
|
624
640
|
end
|
625
641
|
|
626
|
-
def
|
627
|
-
|
642
|
+
def print_new_plan(name:, path:)
|
643
|
+
if Bolt::Util.powershell?
|
644
|
+
show_command = 'Get-BoltPlan -Name '
|
645
|
+
run_command = 'Invoke-BoltPlan -Name '
|
646
|
+
else
|
647
|
+
show_command = 'bolt plan show'
|
648
|
+
run_command = 'bolt plan run'
|
649
|
+
end
|
650
|
+
|
651
|
+
print_message(<<~OUTPUT)
|
652
|
+
Created plan '#{name}' at '#{path}'
|
653
|
+
|
654
|
+
Show this plan with:
|
655
|
+
#{show_command} #{name}
|
656
|
+
Run this plan with:
|
657
|
+
#{run_command} #{name}
|
658
|
+
OUTPUT
|
659
|
+
end
|
660
|
+
|
661
|
+
# Print target names and where they came from.
|
662
|
+
#
|
663
|
+
# @param adhoc [Hash] Adhoc targets provided on the command line.
|
664
|
+
# @param inventory [Hash] Targets provided from the inventory.
|
665
|
+
# @param flag [Boolean] Whether a targeting command-line option was used.
|
666
|
+
#
|
667
|
+
def print_targets(adhoc:, inventory:, flag:, **_kwargs)
|
668
|
+
adhoc_text = colorize(:yellow, "(Not found in inventory file)")
|
628
669
|
|
629
670
|
targets = []
|
630
|
-
targets +=
|
631
|
-
targets +=
|
671
|
+
targets += inventory[:targets].map { |target| [target['name'], nil] }
|
672
|
+
targets += adhoc[:targets].map { |target| [target['name'], adhoc_text] }
|
632
673
|
|
633
674
|
info = +''
|
634
675
|
|
@@ -641,27 +682,31 @@ module Bolt
|
|
641
682
|
end
|
642
683
|
info << "\n\n"
|
643
684
|
|
644
|
-
info << format_inventory_source(
|
645
|
-
info << format_target_summary(
|
685
|
+
info << format_inventory_source(inventory[:file], inventory[:default])
|
686
|
+
info << format_target_summary(inventory[:count], adhoc[:count], flag, false)
|
646
687
|
|
647
688
|
@stream.puts info
|
648
689
|
end
|
649
690
|
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
691
|
+
# Print detailed target information.
|
692
|
+
#
|
693
|
+
# @param adhoc [Hash] Adhoc targets provided on the command line.
|
694
|
+
# @param inventory [Hash] Targets provided from the inventory.
|
695
|
+
# @param flag [Boolean] Whether a targeting command-line option was used.
|
696
|
+
#
|
697
|
+
def print_target_info(adhoc:, inventory:, flag:, **_kwargs)
|
698
|
+
targets = (adhoc[:targets] + inventory[:targets]).sort_by { |t| t['name'] }
|
654
699
|
|
655
700
|
info = +''
|
656
701
|
|
657
702
|
if targets.any?
|
658
|
-
|
703
|
+
adhoc_text = colorize(:yellow, " (Not found in inventory file)")
|
659
704
|
|
660
705
|
targets.each do |target|
|
661
|
-
info << colorize(:cyan, target
|
662
|
-
info <<
|
706
|
+
info << colorize(:cyan, target['name'])
|
707
|
+
info << adhoc_text if adhoc[:targets].include?(target)
|
663
708
|
info << "\n"
|
664
|
-
info << indent(2, target.
|
709
|
+
info << indent(2, target.to_yaml.lines.drop(1).join)
|
665
710
|
info << "\n"
|
666
711
|
end
|
667
712
|
else
|
@@ -669,8 +714,8 @@ module Bolt
|
|
669
714
|
info << indent(2, "No targets\n\n")
|
670
715
|
end
|
671
716
|
|
672
|
-
info << format_inventory_source(
|
673
|
-
info << format_target_summary(
|
717
|
+
info << format_inventory_source(inventory[:file], inventory[:default])
|
718
|
+
info << format_target_summary(inventory[:count], adhoc[:count], flag, true)
|
674
719
|
|
675
720
|
@stream.puts info
|
676
721
|
end
|
@@ -716,7 +761,13 @@ module Bolt
|
|
716
761
|
info
|
717
762
|
end
|
718
763
|
|
719
|
-
|
764
|
+
# Print inventory group information.
|
765
|
+
#
|
766
|
+
# @param count [Integer] Number of groups in the inventory.
|
767
|
+
# @param groups [Array] Names of groups in the inventory.
|
768
|
+
# @param inventory [Hash] Where the inventory was loaded from.
|
769
|
+
#
|
770
|
+
def print_groups(count:, groups:, inventory:)
|
720
771
|
info = +''
|
721
772
|
|
722
773
|
# Add group list
|
@@ -725,18 +776,18 @@ module Bolt
|
|
725
776
|
info << "\n\n"
|
726
777
|
|
727
778
|
# Add inventory file source
|
728
|
-
info << format_inventory_source(
|
779
|
+
info << format_inventory_source(inventory[:source], inventory[:default])
|
729
780
|
|
730
781
|
# Add group count summary
|
731
782
|
info << colorize(:cyan, "Group count\n")
|
732
|
-
info << indent(2, "#{
|
783
|
+
info << indent(2, "#{count} total")
|
733
784
|
|
734
785
|
@stream.puts info
|
735
786
|
end
|
736
787
|
|
737
788
|
# @param [Bolt::ResultSet] apply_result A ResultSet object representing the result of a `bolt apply`
|
738
|
-
def print_apply_result(apply_result
|
739
|
-
print_summary(apply_result, elapsed_time)
|
789
|
+
def print_apply_result(apply_result)
|
790
|
+
print_summary(apply_result, apply_result.elapsed_time)
|
740
791
|
end
|
741
792
|
|
742
793
|
# @param [Bolt::PlanResult] plan_result A PlanResult object
|
data/lib/bolt/outputter/json.rb
CHANGED
@@ -49,7 +49,11 @@ module Bolt
|
|
49
49
|
alias print_module_list print_table
|
50
50
|
alias print_module_info print_table
|
51
51
|
|
52
|
-
|
52
|
+
# Print information about a task.
|
53
|
+
#
|
54
|
+
# @param task [Bolt::Task] The task information.
|
55
|
+
#
|
56
|
+
def print_task_info(task:)
|
53
57
|
path = task.files.first['path'].chomp("/tasks/#{task.files.first['name']}")
|
54
58
|
module_dir = if path.start_with?(Bolt::Config::Modulepath::MODULES_PATH)
|
55
59
|
"built-in module"
|
@@ -59,11 +63,16 @@ module Bolt
|
|
59
63
|
@stream.puts task.to_h.merge(module_dir: module_dir).to_json
|
60
64
|
end
|
61
65
|
|
62
|
-
|
63
|
-
|
66
|
+
# List available tasks.
|
67
|
+
#
|
68
|
+
# @param tasks [Array] A list of task names and descriptions.
|
69
|
+
# @param modulepath [Array] The modulepath.
|
70
|
+
#
|
71
|
+
def print_tasks(**kwargs)
|
72
|
+
print_table(**kwargs)
|
64
73
|
end
|
65
74
|
|
66
|
-
def print_plugin_list(plugins
|
75
|
+
def print_plugin_list(plugins:, modulepath:)
|
67
76
|
plugins.delete(:validate_resolve_reference)
|
68
77
|
print_table('plugins' => plugins, 'modulepath' => modulepath)
|
69
78
|
end
|
@@ -78,11 +87,15 @@ module Bolt
|
|
78
87
|
@stream.puts plan.to_json
|
79
88
|
end
|
80
89
|
|
81
|
-
def print_plans(
|
82
|
-
print_table(
|
90
|
+
def print_plans(**kwargs)
|
91
|
+
print_table(**kwargs)
|
83
92
|
end
|
84
93
|
|
85
|
-
def
|
94
|
+
def print_new_plan(**kwargs)
|
95
|
+
print_table(**kwargs)
|
96
|
+
end
|
97
|
+
|
98
|
+
def print_apply_result(apply_result)
|
86
99
|
@stream.puts apply_result.to_json
|
87
100
|
end
|
88
101
|
|
@@ -95,10 +108,19 @@ module Bolt
|
|
95
108
|
@stream.puts result_set.to_json
|
96
109
|
end
|
97
110
|
|
98
|
-
|
99
|
-
|
111
|
+
# Print available guide topics.
|
112
|
+
#
|
113
|
+
# @param topics [Array] The available topics.
|
114
|
+
#
|
115
|
+
def print_topics(**kwargs)
|
116
|
+
print_table(kwargs)
|
100
117
|
end
|
101
118
|
|
119
|
+
# Print the guide for the specified topic.
|
120
|
+
#
|
121
|
+
# @param guide [String] The guide.
|
122
|
+
# @param topic [String] The topic.
|
123
|
+
#
|
102
124
|
def print_guide(**kwargs)
|
103
125
|
@stream.puts(kwargs.to_json)
|
104
126
|
end
|
@@ -113,35 +135,38 @@ module Bolt
|
|
113
135
|
moduledir: moduledir.to_s }.to_json)
|
114
136
|
end
|
115
137
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
)
|
139
|
-
end
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
138
|
+
# Print target names and where they came from.
|
139
|
+
#
|
140
|
+
# @param adhoc [Hash] Adhoc targets provided on the command line.
|
141
|
+
# @param inventory [Hash] Targets provided from the inventory.
|
142
|
+
# @param targets [Array] All targets.
|
143
|
+
# @param count [Integer] Number of targets.
|
144
|
+
#
|
145
|
+
def print_targets(adhoc:, inventory:, targets:, count:, **_kwargs)
|
146
|
+
adhoc[:targets] = adhoc[:targets].map { |t| t['name'] }
|
147
|
+
inventory[:targets] = inventory[:targets].map { |t| t['name'] }
|
148
|
+
targets = targets.map { |t| t['name'] }
|
149
|
+
@stream.puts({ adhoc: adhoc, inventory: inventory, targets: targets, count: count }.to_json)
|
150
|
+
end
|
151
|
+
|
152
|
+
# Print target names and where they came from.
|
153
|
+
#
|
154
|
+
# @param adhoc [Hash] Adhoc targets provided on the command line.
|
155
|
+
# @param inventory [Hash] Targets provided from the inventory.
|
156
|
+
# @param targets [Array] All targets.
|
157
|
+
# @param count [Integer] Number of targets.
|
158
|
+
#
|
159
|
+
def print_target_info(adhoc:, inventory:, targets:, count:, **_kwargs)
|
160
|
+
@stream.puts({ adhoc: adhoc, inventory: inventory, targets: targets, count: count }.to_json)
|
161
|
+
end
|
162
|
+
|
163
|
+
# Print inventory group information.
|
164
|
+
#
|
165
|
+
# @param count [Integer] Number of groups in the inventory.
|
166
|
+
# @param groups [Array] Names of groups in the inventory.
|
167
|
+
#
|
168
|
+
def print_groups(count:, groups:, **_kwargs)
|
169
|
+
@stream.puts({ count: count, groups: groups }.to_json)
|
145
170
|
end
|
146
171
|
|
147
172
|
def fatal_error(err)
|
data/lib/bolt/plan_creator.rb
CHANGED
@@ -51,7 +51,7 @@ module Bolt
|
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
54
|
-
def self.create_plan(plans_path, plan_name,
|
54
|
+
def self.create_plan(plans_path, plan_name, is_puppet)
|
55
55
|
_, name_segments, basename = segment_plan_name(plan_name)
|
56
56
|
dir_path = plans_path.join(*name_segments)
|
57
57
|
|
@@ -77,25 +77,7 @@ module Bolt
|
|
77
77
|
)
|
78
78
|
end
|
79
79
|
|
80
|
-
|
81
|
-
show_command = 'Get-BoltPlan -Name '
|
82
|
-
run_command = 'Invoke-BoltPlan -Name '
|
83
|
-
else
|
84
|
-
show_command = 'bolt plan show'
|
85
|
-
run_command = 'bolt plan run'
|
86
|
-
end
|
87
|
-
|
88
|
-
output = <<~OUTPUT
|
89
|
-
Created plan '#{plan_name}' at '#{plan_path}'
|
90
|
-
|
91
|
-
Show this plan with:
|
92
|
-
#{show_command} #{plan_name}
|
93
|
-
Run this plan with:
|
94
|
-
#{run_command} #{plan_name}
|
95
|
-
OUTPUT
|
96
|
-
|
97
|
-
outputter.print_message(output)
|
98
|
-
0
|
80
|
+
{ name: plan_name, path: plan_path }
|
99
81
|
end
|
100
82
|
|
101
83
|
def self.segment_plan_name(plan_name)
|
data/lib/bolt/plan_future.rb
CHANGED
@@ -4,14 +4,19 @@ require 'fiber'
|
|
4
4
|
|
5
5
|
module Bolt
|
6
6
|
class PlanFuture
|
7
|
-
attr_reader :fiber, :id
|
7
|
+
attr_reader :fiber, :id, :scope
|
8
8
|
attr_accessor :value, :plan_stack
|
9
9
|
|
10
|
-
def initialize(fiber, id, plan_id:, name: nil)
|
11
|
-
@fiber
|
12
|
-
@id
|
13
|
-
@name
|
14
|
-
@value
|
10
|
+
def initialize(fiber, id, plan_id:, name: nil, scope: nil)
|
11
|
+
@fiber = fiber
|
12
|
+
@id = id
|
13
|
+
@name = name
|
14
|
+
@value = nil
|
15
|
+
|
16
|
+
# Default to Puppet's current global_scope, otherwise things will
|
17
|
+
# blow up when the Fiber Executor tries to override the global_scope.
|
18
|
+
@scope = scope || Puppet.lookup(:global_scope) { nil }
|
19
|
+
|
15
20
|
# The plan invocation ID when the Future is created may be
|
16
21
|
# different from the plan ID of the Future when we switch to it if a new
|
17
22
|
# plan was run inside the Future, so keep track of the plans that a
|