bolt 3.14.1 → 3.17.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 +1 -1
- data/bolt-modules/boltlib/lib/puppet/functions/apply_prep.rb +137 -104
- data/guides/debugging.yaml +27 -0
- data/guides/inventory.yaml +23 -0
- data/guides/links.yaml +12 -0
- data/guides/logging.yaml +17 -0
- data/guides/module.yaml +18 -0
- data/guides/modulepath.yaml +24 -0
- data/guides/project.yaml +21 -0
- data/guides/targets.yaml +28 -0
- data/guides/transports.yaml +22 -0
- data/lib/bolt/analytics.rb +2 -19
- data/lib/bolt/application.rb +634 -0
- data/lib/bolt/bolt_option_parser.rb +28 -4
- data/lib/bolt/cli.rb +592 -788
- data/lib/bolt/fiber_executor.rb +7 -3
- data/lib/bolt/inventory/inventory.rb +68 -39
- data/lib/bolt/inventory.rb +2 -9
- data/lib/bolt/module_installer/puppetfile.rb +24 -10
- data/lib/bolt/outputter/human.rb +83 -32
- data/lib/bolt/outputter/json.rb +63 -38
- data/lib/bolt/pal/yaml_plan/transpiler.rb +1 -1
- data/lib/bolt/pal.rb +31 -11
- data/lib/bolt/plan_creator.rb +84 -25
- data/lib/bolt/plan_future.rb +11 -6
- data/lib/bolt/plan_result.rb +1 -1
- data/lib/bolt/plugin/task.rb +1 -1
- data/lib/bolt/plugin.rb +11 -17
- 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
- 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/transport_app.rb +113 -24
- data/lib/bolt_spec/bolt_context.rb +1 -1
- data/lib/bolt_spec/run.rb +1 -1
- metadata +14 -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
|
@@ -6,7 +6,7 @@ require 'bolt/inventory/target'
|
|
6
6
|
module Bolt
|
7
7
|
class Inventory
|
8
8
|
class Inventory
|
9
|
-
attr_reader :
|
9
|
+
attr_reader :plugins, :source, :targets, :transport
|
10
10
|
|
11
11
|
class WildcardError < Bolt::Error
|
12
12
|
def initialize(target)
|
@@ -14,25 +14,15 @@ module Bolt
|
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
|
-
# TODO: Pass transport config instead of config object
|
18
17
|
def initialize(data, transport, transports, plugins, source = nil)
|
19
|
-
@logger
|
20
|
-
@data
|
21
|
-
@transport
|
22
|
-
@config
|
23
|
-
@
|
24
|
-
@
|
25
|
-
@
|
26
|
-
@
|
27
|
-
@source = source
|
28
|
-
|
29
|
-
@groups.resolve_string_targets(@groups.target_aliases, @groups.all_targets)
|
30
|
-
|
31
|
-
collect_groups
|
32
|
-
end
|
33
|
-
|
34
|
-
def validate
|
35
|
-
@groups.validate
|
18
|
+
@logger = Bolt::Logger.logger(self)
|
19
|
+
@data = data || {}
|
20
|
+
@transport = transport
|
21
|
+
@config = transports
|
22
|
+
@config_resolved = transports.values.all?(&:resolved?)
|
23
|
+
@plugins = plugins
|
24
|
+
@targets = {}
|
25
|
+
@source = source
|
36
26
|
end
|
37
27
|
|
38
28
|
def version
|
@@ -43,13 +33,52 @@ module Bolt
|
|
43
33
|
Bolt::Target
|
44
34
|
end
|
45
35
|
|
46
|
-
|
47
|
-
|
48
|
-
|
36
|
+
# Load and resolve the groups in the inventory. Loading groups resolves
|
37
|
+
# all plugin references except for those for target data and config.
|
38
|
+
#
|
39
|
+
# @return [Bolt::Inventory::Group]
|
40
|
+
#
|
41
|
+
def groups
|
42
|
+
@groups ||= Group.new(@data, @plugins, all_group: true).tap do |groups|
|
43
|
+
groups.resolve_string_targets(groups.target_aliases, groups.all_targets)
|
44
|
+
groups.validate
|
45
|
+
end
|
49
46
|
end
|
50
47
|
|
48
|
+
# Return a list of all group names in the inventory.
|
49
|
+
#
|
50
|
+
# @return [Array[String]]
|
51
|
+
#
|
51
52
|
def group_names
|
52
|
-
|
53
|
+
group_lookup.keys
|
54
|
+
end
|
55
|
+
|
56
|
+
# Return a map of all groups in the inventory.
|
57
|
+
#
|
58
|
+
# @return [Hash[String, Bolt::Inventory::Group]]
|
59
|
+
#
|
60
|
+
def group_lookup
|
61
|
+
@group_lookup ||= groups.collect_groups
|
62
|
+
end
|
63
|
+
|
64
|
+
# Return a map of transport configuration for the inventory. Any
|
65
|
+
# unresolved plugin references are resolved.
|
66
|
+
#
|
67
|
+
# @return [Hash[String, Bolt::Config::Transport]]
|
68
|
+
#
|
69
|
+
def config
|
70
|
+
if @config_resolved
|
71
|
+
@config
|
72
|
+
else
|
73
|
+
@config_resolved = true
|
74
|
+
@config.transform_values! { |t| t.resolved? ? t : t.resolve(@plugins) }
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# Validates the inventory.
|
79
|
+
#
|
80
|
+
def validate
|
81
|
+
groups.validate
|
53
82
|
end
|
54
83
|
|
55
84
|
def group_names_for(target_name)
|
@@ -57,7 +86,7 @@ module Bolt
|
|
57
86
|
end
|
58
87
|
|
59
88
|
def target_names
|
60
|
-
|
89
|
+
groups.all_targets
|
61
90
|
end
|
62
91
|
# alias for analytics
|
63
92
|
alias node_names target_names
|
@@ -81,7 +110,7 @@ module Bolt
|
|
81
110
|
|
82
111
|
#### PRIVATE ####
|
83
112
|
def group_data_for(target_name)
|
84
|
-
|
113
|
+
groups.group_collect(target_name)
|
85
114
|
end
|
86
115
|
|
87
116
|
# If target is a group name, expand it to the members of that group.
|
@@ -89,15 +118,15 @@ module Bolt
|
|
89
118
|
# If a wildcard string, error if no matches are found.
|
90
119
|
# Else fall back to [target] if no matches are found.
|
91
120
|
def resolve_name(target)
|
92
|
-
if (group =
|
121
|
+
if (group = group_lookup[target])
|
93
122
|
group.all_targets
|
94
123
|
else
|
95
124
|
# Try to wildcard match targets in inventory
|
96
125
|
# Ignore case because hostnames are generally case-insensitive
|
97
126
|
regexp = Regexp.new("^#{Regexp.escape(target).gsub('\*', '.*?')}$", Regexp::IGNORECASE)
|
98
127
|
|
99
|
-
targets =
|
100
|
-
targets +=
|
128
|
+
targets = groups.all_targets.select { |targ| targ =~ regexp }
|
129
|
+
targets += groups.target_aliases.select { |target_alias, _target| target_alias =~ regexp }.values
|
101
130
|
|
102
131
|
if targets.empty?
|
103
132
|
raise(WildcardError, target) if target.include?('*')
|
@@ -165,7 +194,7 @@ module Bolt
|
|
165
194
|
# associated references. This is used when a target is resolved by
|
166
195
|
# get_targets.
|
167
196
|
def create_target_from_inventory(target_name)
|
168
|
-
target_data =
|
197
|
+
target_data = groups.target_collect(target_name) || { 'uri' => target_name }
|
169
198
|
|
170
199
|
target = Bolt::Inventory::Target.new(target_data, self)
|
171
200
|
@targets[target.name] = target
|
@@ -187,24 +216,24 @@ module Bolt
|
|
187
216
|
@targets[new_target.name] = new_target
|
188
217
|
|
189
218
|
if existing_target
|
190
|
-
clear_alia_from_group(
|
219
|
+
clear_alia_from_group(groups, new_target.name)
|
191
220
|
else
|
192
221
|
add_to_group([new_target], 'all')
|
193
222
|
end
|
194
223
|
|
195
224
|
if new_target.target_alias
|
196
|
-
|
225
|
+
groups.insert_alia(new_target.name, Array(new_target.target_alias))
|
197
226
|
end
|
198
227
|
|
199
228
|
new_target
|
200
229
|
end
|
201
230
|
|
202
231
|
def validate_target_from_hash(target)
|
203
|
-
|
204
|
-
|
232
|
+
used_groups = Set.new(group_names)
|
233
|
+
used_targets = target_names
|
205
234
|
|
206
235
|
# Make sure there are no group name conflicts
|
207
|
-
if
|
236
|
+
if used_groups.include?(target.name)
|
208
237
|
raise ValidationError.new("Target name #{target.name} conflicts with group of the same name", nil)
|
209
238
|
end
|
210
239
|
|
@@ -217,11 +246,11 @@ module Bolt
|
|
217
246
|
end
|
218
247
|
|
219
248
|
# Make sure there are no conflicts with the new target aliases
|
220
|
-
used_aliases =
|
249
|
+
used_aliases = groups.target_aliases
|
221
250
|
Array(target.target_alias).each do |alia|
|
222
|
-
if
|
251
|
+
if used_groups.include?(alia)
|
223
252
|
raise ValidationError.new("Alias #{alia} conflicts with group of the same name", nil)
|
224
|
-
elsif
|
253
|
+
elsif used_targets.include?(alia)
|
225
254
|
raise ValidationError.new("Alias #{alia} conflicts with target of the same name", nil)
|
226
255
|
elsif used_aliases[alia] && used_aliases[alia] != target.name
|
227
256
|
raise ValidationError.new(
|
@@ -250,7 +279,7 @@ module Bolt
|
|
250
279
|
end
|
251
280
|
|
252
281
|
if group_names.include?(desired_group)
|
253
|
-
remove_target(
|
282
|
+
remove_target(groups, @targets[target.first.name], desired_group)
|
254
283
|
else
|
255
284
|
raise ValidationError.new("Group #{desired_group} does not exist in inventory", nil)
|
256
285
|
end
|
@@ -260,7 +289,7 @@ module Bolt
|
|
260
289
|
if group_names.include?(desired_group)
|
261
290
|
targets.each do |target|
|
262
291
|
# Add the inventory copy of the target
|
263
|
-
add_target(
|
292
|
+
add_target(groups, @targets[target.name], desired_group)
|
264
293
|
end
|
265
294
|
else
|
266
295
|
raise ValidationError.new("Group #{desired_group} does not exist in inventory", nil)
|
data/lib/bolt/inventory.rb
CHANGED
@@ -91,19 +91,12 @@ module Bolt
|
|
91
91
|
end
|
92
92
|
end
|
93
93
|
|
94
|
-
# Resolve plugin references from transport config
|
95
|
-
config.transports.each_value do |t|
|
96
|
-
t.resolve(plugins) unless t.resolved?
|
97
|
-
end
|
98
|
-
|
99
94
|
Bolt::Validator.new.tap do |validator|
|
100
95
|
validator.validate(data, schema, source)
|
101
96
|
validator.warnings.each { |warning| Bolt::Logger.warn(warning[:id], warning[:msg]) }
|
102
97
|
end
|
103
98
|
|
104
|
-
|
105
|
-
inventory.validate
|
106
|
-
inventory
|
99
|
+
create_version(data, config.transport, config.transports, plugins, source)
|
107
100
|
end
|
108
101
|
|
109
102
|
def self.create_version(data, transport, transports, plugins, source = nil)
|
@@ -119,7 +112,7 @@ module Bolt
|
|
119
112
|
|
120
113
|
def self.empty
|
121
114
|
config = Bolt::Config.default
|
122
|
-
plugins = Bolt::Plugin.
|
115
|
+
plugins = Bolt::Plugin.new(config, nil)
|
123
116
|
|
124
117
|
create_version({}, config.transport, config.transports, plugins, nil)
|
125
118
|
end
|
@@ -97,20 +97,34 @@ module Bolt
|
|
97
97
|
end
|
98
98
|
end
|
99
99
|
|
100
|
-
|
101
|
-
|
100
|
+
versionless_mods = @modules.select { |mod| mod.is_a?(ForgeModule) && mod.version.nil? }
|
102
101
|
command = Bolt::Util.windows? ? 'Install-BoltModule -Force' : 'bolt module install --force'
|
103
102
|
|
104
|
-
|
105
|
-
|
103
|
+
if unsatisfied_specs.any?
|
104
|
+
message = <<~MESSAGE.chomp
|
105
|
+
Puppetfile does not include modules that satisfy the following specifications:
|
106
|
+
|
107
|
+
#{unsatisfied_specs.map(&:to_hash).to_yaml.lines.drop(1).join.chomp}
|
108
|
+
|
109
|
+
This Puppetfile might not be managed by Bolt. To forcibly overwrite the
|
110
|
+
Puppetfile, run '#{command}'.
|
111
|
+
MESSAGE
|
106
112
|
|
107
|
-
|
108
|
-
|
109
|
-
This Puppetfile might not be managed by Bolt. To forcibly overwrite the
|
110
|
-
Puppetfile, run '#{command}'.
|
111
|
-
MESSAGE
|
113
|
+
raise Bolt::Error.new(message, 'bolt/missing-module-specs')
|
114
|
+
end
|
112
115
|
|
113
|
-
|
116
|
+
if versionless_mods.any?
|
117
|
+
message = <<~MESSAGE.chomp
|
118
|
+
Puppetfile includes Forge modules without a version requirement:
|
119
|
+
|
120
|
+
#{versionless_mods.map(&:to_spec).join.chomp}
|
121
|
+
|
122
|
+
This Puppetfile might not be managed by Bolt. To forcibly overwrite the
|
123
|
+
Puppetfile, run '#{command}'.
|
124
|
+
MESSAGE
|
125
|
+
|
126
|
+
raise Bolt::Error.new(message, 'bolt/missing-module-version-specs')
|
127
|
+
end
|
114
128
|
end
|
115
129
|
end
|
116
130
|
end
|
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
|